public PiercingVM(AmfObject obj, string prefix, string suffix, PiercingLocation location) : base(obj) { _prefix = prefix; _suffix = suffix; _location = location; }
AmfObject ReadArray() { // Stored by ref? bool isInstance; var indexOrCount = ReadU29(out isInstance); if (!isInstance) return (AmfObject)_objectLookup[indexOrCount]; // Stored by value var result = new AmfObject(AmfTypes.Array); _objectLookup.Add(result); // Associative part (key-value pairs) while (true) { var key = ReadString(); if (key == "") break; var value = ReadValue(); result[key] = value; } // Dense part (consecutive indices >=0 and <count) for (int i = 0; i < indexOrCount; i++) { var value = ReadValue(); result.Push(value); } return result; }
public FlagVM(GameVM game, AmfObject flags, XmlEnum data, int index) { _flagArray = flags; _game = game; _index = index; _label = data != null ? data.Name : ""; _comment = data != null ? data.Description : ""; if (!String.IsNullOrEmpty(_comment)) _label = _label + "\u202F*"; var value = flags[_index]; if (value is AmfObject) _valueTrait = ((AmfObject)value).Trait; _valueLabel = flags.GetString(_index); GameVMProperties = new HashSet<string>(); }
void WriteArray(AmfObject array) { if (TryWriteRef(array)) return; WriteU29(array.DenseCount, true); // Associative part (key-value pairs) foreach(var pair in array.GetSparseAndAssociativePairs()) { WriteString(pair.Key.ToString()); WriteValue(pair.Value); } WriteString(""); // Dense part (consecutive indices >=0 and <count) foreach (var value in array.GetDensePart()) { WriteValue(value); } }
protected override bool IsObject(AmfObject obj) { var id = obj.GetString("id"); // Save format fixup, only needed when editing older saves if (id == null && obj.Contains("perkName")) { obj["id"] = obj["perkName"]; obj["perkName"] = null; obj["perkDesc"] = null; id = obj.GetString("id"); } // Fixes saves which have NaNs for some perk values, which crashes CoC if (double.IsNaN(obj.GetDouble("value1"))) obj["value1"] = 0; if (double.IsNaN(obj.GetDouble("value2"))) obj["value2"] = 0; if (double.IsNaN(obj.GetDouble("value3"))) obj["value3"] = 0; if (double.IsNaN(obj.GetDouble("value4"))) obj["value4"] = 0; return id == _xml.Name; }
public void ApplyValues() { var writer = new AmfWriter(); writer.WriteString("connect"); writer.WriteNumber(TransactionId); var obj = new AmfObject(); obj.Strings.Add("app", App); obj.Strings.Add("flashver", FlashVersion); obj.Strings.Add("swfUrl", SwfUrl); obj.Strings.Add("tcUrl", ServerUrl); obj.Booleans.Add("fpad", Proxy); obj.Numbers.Add("audioCodecs", AudioCodecs); obj.Numbers.Add("videoCodecs", VideoCodecs); obj.Numbers.Add("videoFunction", VideoFunction); obj.Strings.Add("pageUrl", PageUrl); obj.Numbers.Add("objectEncoding", ObjectEncoding); writer.WriteObject(obj); Data = writer.GetByteArray(); }
void WriteObject(AmfObject obj) { if (TryWriteRef(obj)) return; WriteTrait(obj.Trait); // Trait's properties foreach (var name in obj.Trait.Properties) { var value = obj[name]; WriteValue(value); } // Dynamic properties if (obj.Trait.IsDynamic) { foreach(var pair in obj) { // Is prop from trait or dynamic? if (obj.Trait.Properties.Contains(pair.Key)) continue; WriteString(pair.Key.ToString()); WriteValue(pair.Value); } WriteString(""); } if (obj.Trait.IsExternalizable) { WriteCustomData(obj); } }
public PerkArrayVM(GameVM game, AmfObject obj) : base(obj, x => new PerkVM(game, x)) { }
public KeyItemVM(GameVM game, AmfObject keyItems, XmlNamedVector4 xml) : base(game, keyItems, xml) { }
void ReadCustomData(AmfObject obj) { switch (obj.Trait.Name) { case "CockTypesEnum": ReadCustomDataForEnum(obj); break; default: throw new NotImplementedException("Unsupported externalized trait: " + (obj.Trait.Name ?? "<noname>")); } }
AmfObject ReadVector(AmfTypes type) { // Stored by ref? bool isInstance; int lengthOrIndex = ReadU29(out isInstance); if (!isInstance) return (AmfObject)_objectLookup[lengthOrIndex]; // Stored by value var result = new AmfObject(type); _objectLookup.Add(result); result.IsFixedVector = _reader.ReadBoolean(); if (type == AmfTypes.VectorGeneric) result.GenericElementType = ReadString(); for (int j = 0; j < lengthOrIndex; ++j) { switch (type) { case AmfTypes.VectorInt: result.Push(ReadI32()); break; case AmfTypes.VectorUInt: result.Push(ReadU32()); break; case AmfTypes.VectorDouble: result.Push(ReadDouble()); break; case AmfTypes.VectorGeneric: result.Push(ReadValue()); break; default: throw new NotImplementedException(); } } return result; }
public StatusEffectVM(CharacterVM character, AmfObject statuses, XmlStorageClass xml) : base(character, statuses, xml) { }
protected override bool IsObject(AmfObject obj) { return obj.GetString("statusAffectName") == _xml.Name; }
public BreastArrayVM(GameVM game, AmfObject obj) : base(obj, x => new BreastsVM(game, x)) { }
public BreastsVM(GameVM game, AmfObject obj) : base(obj) { _game = game; }
public CockVM(GameVM game, AmfObject obj) : base(obj) { _game = game; }
protected override void InitializeObject(AmfObject obj) { PerkVM.initialize(obj); obj["storageName"] = _xml.Name; }
public PerkVectorVM(GameVM game, AmfObject perksArray, XmlNamedVector4 xml) : base(game, perksArray, xml) { }
void WriteVector(AmfObject vector) { if (vector.IsSparse) throw new InvalidOperationException("Vectors must be dense."); if (TryWriteRef(vector)) return; WriteU29(vector.DenseCount, true); _writer.Write(vector.IsFixedVector); if (vector.Type == AmfTypes.VectorGeneric) WriteString(vector.GenericElementType); foreach (var value in vector.GetDensePart()) { switch (vector.Type) { case AmfTypes.VectorInt: WriteI32((int)value); break; case AmfTypes.VectorUInt: WriteU32((uint)value); break; case AmfTypes.VectorDouble: WriteDouble((double)value); break; case AmfTypes.VectorGeneric: WriteValue(value); break; default: throw new NotImplementedException(); } } }
protected override void InitializeObject(AmfObject obj) { base.InitializeObject(obj); obj["hidden"] = _xml.IsHidden ?? false; }
public StatusVM(GameVM game, AmfObject allStatuses, XmlNamedVector4 xml) : base(game, allStatuses, xml) { }
public LowerBodyVM(GameVM game, AmfObject obj) : base(game, obj) { }
public void Add(AmfObject obj) { _slots.Add(new ItemSlotVM(_game, obj, Categories)); }
public AmfObjectVM(AmfObject obj, AmfPair keyPair) : base(obj) { _keyPair = keyPair; }
AmfObject ReadDictionary() { // Stored by ref? bool isInstance; int lengthOrIndex = ReadU29(out isInstance); if (!isInstance) return (AmfObject)_objectLookup[lengthOrIndex]; // Stored by value var result = new AmfObject(AmfTypes.Dictionary); _objectLookup.Add(result); result.HasWeakKeys = _reader.ReadBoolean(); for (int j = 0; j < lengthOrIndex; ++j) { var key = ReadValue(); var value = ReadValue(); result[key] = value; } return result; }
public AmfObjectVM(AmfObject obj, string key, string value) : base(obj) { _keyOverride = key; _valueOverride = value; }
protected override bool IsObject(AmfObject obj) { return(obj.GetString("keyName") == _xml.Name); }
public void Add(AmfObject obj) { _slots.Add(new ItemSlotVM(_character, obj, Types)); }
public AssVM(AmfObject obj) : base(obj) { }
void WriteCustomDataForEnum(AmfObject obj) { WriteI32((int)obj.EnumValue); }
protected ObjectVM(AmfObject obj) { _obj = obj; }
private XmlItem getXmlItemForSlot() { var className = GetString("classInstance"); //we will need to make this smarter eventually using the hasRandomProperties data //we should match all the data defined in the item fields against the actual item properties AmfObject tmp = _obj; XmlItem bestItem = XmlItem.Empty; int bestFieldMatch = -1; foreach (XmlItemGroup type in XmlData.Current.ItemGroups) { foreach (XmlItem item in type.Items) { //class name must match, otherwise skip it if (item.ID == className) { //if there are any fields, try and match them int fieldMatch = 0; if (null != item.Fields) { foreach (XmlObjectField field in item.Fields) { //field.Name if (HasValue(field.Name)) { //do it by type switch (field.Type.ToLower()) { case "bool": if (field.Value.StartsWith("t", true, null) == GetBool(field.Name)) { fieldMatch++; } break; case "int": if (int.Parse(field.Value) == GetInt(field.Name)) { fieldMatch++; } break; case "string": if (field.Value == GetString(field.Name)) { fieldMatch++; } break; default: //no match since we have no idea what type it is break; } } } } if (fieldMatch > bestFieldMatch) { bestFieldMatch = fieldMatch; bestItem = item; } } } } return(bestItem); }
protected override void InitializeObject(AmfObject obj) { obj["keyName"] = _xml.Name; }
protected ArrayVM(AmfObject obj, Func <AmfObject, TResult> selector) : base(obj.Select(x => x.Value as AmfObject), selector) { _object = obj; }
void WriteDictionary(AmfObject obj) { if (TryWriteRef(obj)) return; WriteU29(obj.Count, true); _writer.Write(obj.HasWeakKeys); foreach (var pair in obj) { WriteValue(pair.Key); WriteValue(pair.Value); } }
protected ArrayVM(AmfObject obj, IEnumerable <AmfObject> values, Func <AmfObject, TResult> selector) : base(values, selector) { _object = obj; }
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); }
public void Create() { AmfObject node = CreateNewObject(); Add(node); }
public PregnancyDataVM(CharacterVM character, AmfObject obj) : base(obj) { _character = character; }
public PregnancyDataArrayVM(CharacterVM character, AmfObject obj) : base(obj, x => new PregnancyDataVM(character, x)) { _character = character; }
protected override void InitializeObject(AmfObject obj) { obj["statusAffectName"] = _xml.Name; }
public VaginaArrayVM(CharacterVM character, AmfObject obj) : base(obj, x => new VaginaVM(character, x)) { }
public ItemSlotVM(GameVM game, AmfObject obj, ItemCategories categories) : base(obj) { Categories = categories; _game = game; _allGroups = XmlData.Current.ItemGroups.Where(group => Categories.HasFlag(group.Category)).Select(x => new ItemGroupVM(_game, x, this)).ToArray(); AllGroups = new UpdatableCollection<ItemGroupVM>(_allGroups.Where(x => x.Items.Count != 0)); }
public VaginaVM(CharacterVM character, AmfObject obj) : base(obj) { _character = character; }
public void OnKeyItemAddedOrRemoved(string name, bool isOwned) { // Creates/destroys the corresponding item slots when a container is added/removed. switch (name) { case "Camp - Chest": case "Camp - Murky Chest": case "Camp - Ornate Chest": if (IsRevampMod || name == "Camp - Chest") { var array = GetObj("itemStorage"); // max chest slots are 6 in CoC and 14 in CoC-Revamp-Mod int count = name == "Camp - Chest" ? 6 : 4; // the CoC-Revamp-Mod addon chests add 4 slots a piece if (isOwned) { for (int i = 0; i < count; i++) { var slot = new AmfObject(AmfTypes.Object); slot["id"] = "NOTHING!"; // having to set this to "NOTHING!" is daft slot["quantity"] = 0; slot["unlocked"] = false; // must now be false or the camp chest will break in-game array.Push(slot); } } else { for (int i = 0; i < count; i++) array.Pop(array.DenseCount - 1); } UpdateChest(); ItemContainers.Update(); } break; case "Equipment Rack - Weapons": _allFlags[254].SetValue(isOwned ? 1 : 0); UpdateWeaponRack(); ItemContainers.Update(); break; case "Equipment Rack - Armor": _allFlags[255].SetValue(isOwned ? 1 : 0); UpdateArmorRack(); ItemContainers.Update(); break; case "Equipment Storage - Jewelry Box": UpdateJewelryBox(); ItemContainers.Update(); break; case "Equipment Rack - Shields": UpdateShieldRack(); ItemContainers.Update(); break; } }
public CockArrayVM(GameVM game, AmfObject obj) : base(obj, x => new CockVM(game, x)) { }
void ReadCustomDataForEnum(AmfObject obj) { obj.Trait.IsEnum = true; obj.EnumValue = ReadI32(); }
private AmfObject createGeneralAmfValue() { var obj = new AmfObject(); obj["test"] = AmfValue.CreateStringValue("testvalue"); return obj; }
AmfObject ReadObject() { // Stored by ref? bool isInstance; int refIndex = ReadU29(out isInstance); if (!isInstance) return (AmfObject)_objectLookup[refIndex]; // Stored by value var result = new AmfObject(AmfTypes.Object); _objectLookup.Add(result); result.Trait = ReadTrait(refIndex); foreach (var name in result.Trait.Properties) { var value = ReadValue(); result[name] = value; } if (result.Trait.IsDynamic) { while(true) { var name = ReadString(); if (name == "") break; var value = ReadValue(); result[name] = value; } } if (result.Trait.IsExternalizable) { ReadCustomData(result); } return result; }
protected abstract bool IsObject(AmfObject obj);
public TailVM(GameVM game, AmfObject obj) : base(game, obj) { }
protected abstract void InitializeObject(AmfObject obj);
public CockArrayVM(CharacterVM character, AmfObject obj) : base(obj, x => new CockVM(character, x)) { }
protected NamedVector4VM(GameVM game, AmfObject items, XmlNamedVector4 xml) { _xml = xml; _game = game; _items = items; }
public CockVM(CharacterVM character, AmfObject obj) : base(obj) { _character = character; }
static void ImportMissingNamedVectors(AmfObject cocItems, IEnumerable<XmlNamedVector4> xmlItems, string cocNameProperty, Func<AmfObject, String> descriptionGetter = null, IList<XmlNamedVector4> targetXmlList = null) { if (targetXmlList == null) targetXmlList = (IList<XmlNamedVector4>)xmlItems; var xmlNames = new HashSet<String>(xmlItems.Select(x => x.Name)); foreach (var pair in cocItems) { var name = pair.ValueAsObject.GetString(cocNameProperty); if (xmlNames.Contains(name)) continue; xmlNames.Add(name); var xml = new XmlNamedVector4 { Name = name }; if (descriptionGetter != null) xml.Description = descriptionGetter(pair.ValueAsObject); targetXmlList.Add(xml); } }
public PiercingVM(AmfObject obj, string prefix, PiercingLocation location) : this(obj, prefix, "", location) { }
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)); }
protected virtual bool IsObject(AmfObject obj) { var storageName = (null != obj) ? obj.GetString("storageName") : ""; return(storageName == Name); }