Пример #1
0
        private static bool AddFileToDirectory(FlashDirectory dir, string filePath)
        {
            if (!File.Exists(filePath))
            {
                return(false);
            }

            var amfFile = new AmfFile(filePath);

            if (amfFile.Error != null)
            {
                switch (amfFile.Error.Type)
                {
                case AmfFileError.Error.NoPermission:
                    Result     = FileEnumerationResult.NoPermission;
                    ResultPath = filePath;
                    return(false);

                case AmfFileError.Error.Unreadable:
                    Result     = FileEnumerationResult.Unreadable;
                    ResultPath = filePath;
                    return(false);
                }
            }
            dir.Files.Add(amfFile);
            return(true);
        }
Пример #2
0
        void ReadStandardFile(AmfFile file, out string name)
        {
            // Endianness
            if (_reader.ReadByte() != 0)
            {
                throw new NotImplementedException("Unknown endianness");
            }
            if (_reader.ReadByte() != 0xBF)
            {
                throw new NotImplementedException("Unknown endianness");
            }

            // Size
            int size = (int)ReadU32();

            if (size + 6 != _reader.BaseStream.Length)
            {
                throw new InvalidOperationException("Wrong file size");
            }

            // Magic signature
            if (ReadPlainString(4) != "TCSO")
            {
                throw new InvalidOperationException("Wrong file tag");
            }
            _reader.BaseStream.Seek(6, SeekOrigin.Current);

            // Read name
            size = ReadU16();
            name = ReadPlainString(size);

            // Version
            int version = (int)ReadU32();

            if (version < 3)
            {
                throw new NotImplementedException("Wrong AMF version");
            }

            // Read content
            while (true)
            {
                var key   = ReadString();
                var value = ReadValue();
                file[key] = value;

                _reader.ReadByte(); // Trailer. No official documentation. Usually zero.
                if (_reader.BaseStream.Position == _reader.BaseStream.Length)
                {
                    break;
                }
            }
        }
Пример #3
0
        void ReadPlainDataFile(AmfFile file, out string name)
        {
            name = Path.GetFileNameWithoutExtension(file.FilePath);

            var dataContainer = (AmfObject)ReadValue();
            var data          = dataContainer.GetObj("data");

            foreach (var pair in data)
            {
                file[pair.Key] = pair.Value;
            }
        }
Пример #4
0
        void WritePlainDataFile(AmfFile file)
        {
            var data = new AmfObject(AmfTypes.Object);

            foreach (var pair in file)
            {
                data[pair.Key] = pair.Value;
            }

            var dataContainer = new AmfObject(AmfTypes.Object);

            dataContainer["data"] = data;

            WriteValue(dataContainer);
        }
Пример #5
0
 public void Run(AmfFile file, out string name, out SerializationFormat format)
 {
     // Case for "save to file". Fenoxo only serializes ones object and there is no header.
     if (_reader.PeekChar() == 0x0A)
     {
         format = SerializationFormat.Exported;
         ReadPlainDataFile(file, out name);
     }
     // Case for "save to slot". Real AMF3 file with a proper header.
     else
     {
         format = SerializationFormat.Slot;
         ReadStandardFile(file, out name);
     }
 }
Пример #6
0
 public void Run(AmfFile file, out string name, out SerializationFormat format)
 {
     // Case for "save to file". Fenoxo only serializes ones object and there is no header.
     if (_reader.PeekChar() == 0x0A)
     {
         format = SerializationFormat.Exported;
         ReadPlainDataFile(file, out name);
     }
     // Case for "save to slot". Real AMF3 file with a proper header.
     else
     {
         format = SerializationFormat.Slot;
         ReadStandardFile(file, out name);
     }
 }
Пример #7
0
        void WriteStandardFile(AmfFile file, string newName)
        {
            // Endianness
            _writer.Write((byte)0x00);
            _writer.Write((byte)0xBF);

            // Placeholder for size
            _writer.Write((int)0);

            // Magic signature
            _writer.Write('T');
            _writer.Write('C');
            _writer.Write('S');
            _writer.Write('O');
            _writer.Write((byte)0x00);
            _writer.Write((byte)0x04);
            _writer.Write((byte)0x00);
            _writer.Write((byte)0x00);
            _writer.Write((byte)0x00);
            _writer.Write((byte)0x00);

            // Name
            var countBytes = BitConverter.GetBytes((UInt16)newName.Length);

            WriteReversedBytes(countBytes);
            _writer.Write(newName.ToArray());

            // AMF version number
            _writer.Write((byte)0x00);
            _writer.Write((byte)0x00);
            _writer.Write((byte)0x00);
            _writer.Write((byte)0x03);

            // Key-value pairs
            foreach (var pair in file)
            {
                WriteString((string)pair.Key);
                WriteValue(pair.Value);
                _writer.Write((byte)0);
            }

            // Replace size
            _writer.BaseStream.Seek(2, SeekOrigin.Begin);
            uint dataSize = (uint)_writer.BaseStream.Length - 6;

            WriteU32(dataSize);
        }
Пример #8
0
        public void Run(AmfFile file, string newName, SerializationFormat format)
        {
            switch (format)
            {
                case SerializationFormat.Slot:
                    WriteStandardFile(file, newName);
                    break;

                case SerializationFormat.Exported:
                    WritePlainDataFile(file);
                    break;

                default:
                    throw new NotImplementedException();
            }

            // Flush
            _writer.Flush();
        }
Пример #9
0
        public void Run(AmfFile file, string newName, SerializationFormat format)
        {
            switch (format)
            {
            case SerializationFormat.Slot:
                WriteStandardFile(file, newName);
                break;

            case SerializationFormat.Exported:
                WritePlainDataFile(file);
                break;

            default:
                throw new NotImplementedException();
            }


            // Flush
            _writer.Flush();
        }
Пример #10
0
 static void PrintStatuses(AmfFile file)
 {
     foreach (AmfPair pair in file.GetObj("statusAffects"))
     {
         int key = Int32.Parse(pair.Key as string);
         var name = pair.ValueAsObject.GetString("statusAffectName");
         Debug.WriteLine(key.ToString("000") + " - " + name);
     }
 }
Пример #11
0
        private static bool AddFileToDirectory(FlashDirectory dir, string filePath)
        {
            if (!File.Exists(filePath)) return false;

            var amfFile = new AmfFile(filePath);
            if (amfFile.Error != null)
            {
                switch (amfFile.Error.Type)
                {
                    case AmfFileError.Error.NoPermission:
                        Result = FileEnumerationResult.NoPermission;
                        ResultPath = filePath;
                        return false;

                    case AmfFileError.Error.Unreadable:
                        Result = FileEnumerationResult.Unreadable;
                        ResultPath = filePath;
                        return false;
                }
            }
            dir.Files.Add(amfFile);
            return true;
        }
Пример #12
0
        public GameVM(AmfFile file, GameVM previousVM, bool isRevampMod = false)
            : base(file)
        {
            if (previousVM != null)
            {
                _itemSearchText = previousVM._itemSearchText;
                _perkSearchText = previousVM._perkSearchText;
                _rawDataSearchText = previousVM._rawDataSearchText;
                _keyItemSearchText = previousVM._keyItemSearchText;
            }

            // Is this save from vanilla CoC or the CoC-Revamp-Mod?
            IsRevampMod = isRevampMod;

            // Unique children
            Ass = new AssVM(file.GetObj("ass"));
            LipPiercing = new PiercingVM(file, "lip", PiercingLocation.Lip);
            NosePiercing = new PiercingVM(file, "nose", PiercingLocation.Nose);
            EarsPiercing = new PiercingVM(file, "ears", PiercingLocation.Ears);
            EyebrowPiercing = new PiercingVM(file, "eyebrow", PiercingLocation.Eyebrow);
            NipplesPiercing = new PiercingVM(file, "nipples", PiercingLocation.Nipples);
            TonguePiercing = new PiercingVM(file, "tongue", PiercingLocation.Tongue);

            // Collections
            Cocks = new CockArrayVM(this, file.GetObj("cocks"));
            Vaginas = new VaginaArrayVM(file.GetObj("vaginas"));
            Breasts = new BreastArrayVM(this, file.GetObj("breastRows"));
            Vaginas.CollectionChanged += OnGenitalCollectionChanged;
            Breasts.CollectionChanged += OnGenitalCollectionChanged;
            Cocks.CollectionChanged += OnGenitalCollectionChanged;

            // Flags
            int numFlags = XmlData.Current.Flags.Max(x => x.ID) + 25; // was 200; I'm unsure if there's really a need for a buffer at all anymore
            var xmlFlagByID = new XmlEnum[numFlags];
            foreach(var xml in XmlData.Current.Flags) xmlFlagByID[xml.ID] = xml;

            var flagsArray = GetObj("flags");
            if (flagsArray == null)
            {
                // For very old versions of CoC
                _obj["flags"] = flagsArray = new AmfObject(AmfTypes.Array);
                for (int i = 0; i < 3000; ++i) flagsArray.Push(0);
            }
            _allFlags = new FlagVM[numFlags];
            for (int i = 0; i < _allFlags.Length; ++i) _allFlags[i] = new FlagVM(this, flagsArray, xmlFlagByID[i], i);
            Flags = new UpdatableCollection<FlagVM>(_allFlags.Where(x => x.Index > 0 && x.Match(_rawDataSearchText)));

            // Statuses
            var cocStatuses = file.GetObj("statusAffects");
            var xmlStatuses = XmlData.Current.Statuses;
            ImportMissingNamedVectors(cocStatuses, xmlStatuses, "statusAffectName");
            _allStatuses = XmlData.Current.Statuses.OrderBy(x => x.Name).Select(x => new StatusVM(this, cocStatuses, x)).ToArray();
            Statuses = new UpdatableCollection<StatusVM>(_allStatuses.Where(x => x.Match(_rawDataSearchText)));

            // KeyItems
            var cocKeys = file.GetObj("keyItems");
            var xmlKeys = XmlData.Current.KeyItems;
            ImportMissingNamedVectors(cocKeys, xmlKeys, "keyName");
            _allKeyitems = XmlData.Current.KeyItems.OrderBy(x => x.Name).Select(x => new KeyItemVM(this, cocKeys, x)).ToArray();
            KeyItems = new UpdatableCollection<KeyItemVM>(_allKeyitems.Where(x => x.Match(_keyItemSearchText)));

            // Perks
            var cocPerks = _obj.GetObj("perks");
            var xmlPerks = XmlData.Current.PerkGroups.SelectMany(x => x.Perks).ToArray();
            var unknownPerkGroup = XmlData.Current.PerkGroups.Last();
            ImportMissingNamedVectors(cocPerks, xmlPerks, "id", null, unknownPerkGroup.Perks);

            PerkGroups = new List<PerkGroupVM>();
            foreach (var xmlGroup in XmlData.Current.PerkGroups)
            {
                var perksVM = xmlGroup.Perks.OrderBy(x => x.Name).Select(x => new PerkVM(this, cocPerks, x)).ToArray();
                _allPerks.AddRange(perksVM);

                var groupVM = new PerkGroupVM(this, xmlGroup.Name, perksVM);
                PerkGroups.Add(groupVM);
            }

            // Item containers
            var containers = new List<ItemContainerVM>();
            _inventory = new ItemContainerVM(this, "Inventory", ItemCategories.All);
            containers.Add(_inventory);
            UpdateInventory();

            _chest = new ItemContainerVM(this, IsRevampMod ? "Chest(s)" : "Chest", ItemCategories.All);
            containers.Add(_chest);
            UpdateChest();

            _weaponRack = new ItemContainerVM(this, "Weapon rack", ItemCategories.Weapon | ItemCategories.Unknown);
            containers.Add(_weaponRack);
            UpdateWeaponRack();

            _armorRack = new ItemContainerVM(this, "Armor rack", ItemCategories.Armor | ItemCategories.ArmorCursed | ItemCategories.Unknown);
            containers.Add(_armorRack);
            UpdateArmorRack();

            if (IsRevampMod)
            {
                _shieldRack = new ItemContainerVM(this, "Shield rack", ItemCategories.Shield | ItemCategories.Unknown);
                containers.Add(_shieldRack);
                UpdateShieldRack();

                _dresser = new ItemContainerVM(this, "Dresser", ItemCategories.Undergarment | ItemCategories.Unknown);
                containers.Add(_dresser);
                UpdateDresser();

                _jewelryBox = new ItemContainerVM(this, "Jewelry box", ItemCategories.Jewelry | ItemCategories.Unknown);
                containers.Add(_jewelryBox);
                UpdateJewelryBox();
            }

            // Import missing items
            var unknownItemGroup = XmlData.Current.ItemGroups.Last();

            foreach (var slot in containers.SelectMany(x => x.Slots))
            {
                // Add this item to the DB if it does not exist
                var type = slot.Type;
                if (String.IsNullOrEmpty(type)) continue;
                if (XmlData.Current.ItemGroups.SelectMany(x => x.Items).Any(x => x.ID == type)) continue;

                var xml = new XmlItem { ID = type, Name = type };
                unknownItemGroup.Items.Add(xml);
            }
            foreach (var slot in containers.SelectMany(x => x.Slots)) slot.UpdateGroups(); // Update item groups after new items have been added

            // Complete slots creation
            ItemContainers = new UpdatableCollection<ItemContainerVM>(containers.Where(x => x.Slots.Count != 0));
        }
Пример #13
0
        void WritePlainDataFile(AmfFile file)
        {
            var data = new AmfObject(AmfTypes.Object);
            foreach(var pair in file) data[pair.Key] = pair.Value;

            var dataContainer = new AmfObject(AmfTypes.Object);
            dataContainer["data"] = data;

            WriteValue(dataContainer);
        }
Пример #14
0
        void ReadStandardFile(AmfFile file, out string name)
        {
            // Endianness
            if (_reader.ReadByte() != 0) throw new NotImplementedException("Unknown endianness");
            if (_reader.ReadByte() != 0xBF) throw new NotImplementedException("Unknown endianness");

            // Size
            int size = (int)ReadU32();
            if (size + 6 != _reader.BaseStream.Length) throw new InvalidOperationException("Wrong file size");

            // Magic signature
            if (ReadPlainString(4) != "TCSO") throw new InvalidOperationException("Wrong file tag");
            _reader.BaseStream.Seek(6, SeekOrigin.Current);

            // Read name
            size = ReadU16();
            name = ReadPlainString(size);

            // Version
            int version = (int)ReadU32();
            if (version < 3) throw new NotImplementedException("Wrong AMF version");

            // Read content
            while (true)
            {
                var key = ReadString();
                var value = ReadValue();
                file[key] = value;

                _reader.ReadByte(); // Trailer. No official documentation. Usually zero.
                if (_reader.BaseStream.Position == _reader.BaseStream.Length) break;
            }
        }
Пример #15
0
        void ReadPlainDataFile(AmfFile file, out string name)
        {
            name = Path.GetFileNameWithoutExtension(file.FilePath);

            var dataContainer = (AmfObject)ReadValue();
            var data = dataContainer.GetObj("data");
            foreach (var pair in data) file[pair.Key] = pair.Value;
        }
Пример #16
0
        void WriteStandardFile(AmfFile file, string newName)
        {
            // Endianness
            _writer.Write((byte)0x00);
            _writer.Write((byte)0xBF);

            // Placeholder for size
            _writer.Write((int)0);

            // Magic signature
            _writer.Write('T');
            _writer.Write('C');
            _writer.Write('S');
            _writer.Write('O');
            _writer.Write((byte)0x00);
            _writer.Write((byte)0x04);
            _writer.Write((byte)0x00);
            _writer.Write((byte)0x00);
            _writer.Write((byte)0x00);
            _writer.Write((byte)0x00);

            // Name
            var countBytes = BitConverter.GetBytes((UInt16)newName.Length);
            WriteReversedBytes(countBytes);
            _writer.Write(newName.ToArray());

            // AMF version number
            _writer.Write((byte)0x00);
            _writer.Write((byte)0x00);
            _writer.Write((byte)0x00);
            _writer.Write((byte)0x03);

            // Key-value pairs
            foreach (var pair in file)
            {
                WriteString((string)pair.Key);
                WriteValue(pair.Value);
                _writer.Write((byte)0);
            }

            // Replace size
            _writer.BaseStream.Seek(2, SeekOrigin.Begin);
            uint dataSize = (uint)_writer.BaseStream.Length - 6;
            WriteU32(dataSize);
        }
Пример #17
0
 public FileVM(AmfFile source, DirectoryKind directoryKind, bool openOnClick)
 {
     Source = source;
     _openOnClick = openOnClick;
     _directoryKind = directoryKind;
 }