public CProperty GetProperty() { // First, read the length and value of the following property name string int propNameLength = GetInt(); string propName = GetString(propNameLength); SkipPadding(); // If this is a "None" ending type property, just return - nothing else will follow this if (propName == "None") { return(null); } // Get the property type string int typeNameLength = GetInt(); string typeName = GetString(typeNameLength); SkipPadding(); // Skip past the size of the following data and its padding GetInt(); SkipPadding(); // Finally, read the data based on the property type CProperty returnProperty; switch (typeName) { case "ArrayProperty": returnProperty = new ArrayProperty(propName, this); break; case "IntProperty": returnProperty = new IntProperty(propName, this); break; case "StrProperty": returnProperty = new StrProperty(propName, this); break; case "NameProperty": returnProperty = new NameProperty(propName, this); break; case "StructProperty": returnProperty = new StructProperty(propName, this, _outputter); break; case "BoolProperty": returnProperty = new BoolProperty(propName, this); break; default: throw new Exception($"Unexpected property type: {typeName}"); } returnProperty.ParseData(); return(returnProperty); }
public void StrPropertyWrite() { using (var stream = new MemoryStream()) using (var writer = new BinaryWriter(stream)) { var prop = new StrProperty(StrName) { Value = StrValue }; prop.Serialize(writer); Assert.AreEqual(14, prop.SerializedLength); CollectionAssert.AreEqual(StrBytes, stream.ToArray()); } }
public string GetStringProperty(string name, int index = 0, string defaultValue = null) { StrProperty p = GetPropertyByName <StrProperty>(name, index); if (p == null && defaultValue == null) { throw new Exception($"No values found for {name}:{index}, and no defaults were given!"); } else if (p == null) { return(defaultValue); } else { return(p.value); } }
private Character(IOutputter outputter, string nickname) : base(null, outputter) { properties.Add(StrProperty.Create("strFirstName", "New")); properties.Add(StrProperty.Create("strLastName", "Character")); properties.Add(StrProperty.Create("strNickName")); properties.Add(NameProperty.Create("CharacterTemplateName", "Soldier")); properties.Add(NameProperty.Create("m_SoldierClassTemplateName", "Rookie")); properties.Add(NameProperty.Create("Country", "Country_USA")); var appearance = Appearance.CreateAppearanceProperty(); properties.Add(appearance); Appearance = new Appearance(outputter, appearance.Properties.Properties); properties.Add(BoolProperty.Create("AllowedTypeSoldier", true)); properties.Add(BoolProperty.Create("AllowedTypeVIP")); properties.Add(BoolProperty.Create("AllowedTypeDarkVIP")); properties.Add(StrProperty.Create("PoolTimestamp", DateTime.Now.ToString("MMMM d, yyyy - h:m tt"))); properties.Add(StrProperty.Create("BackgroundText")); NickName.Data = $"'{nickname}'"; IsDirty = true; }
public string GetPropertyStringOrName(string name, int index = -1) { UProperty p = GetProperty(name, index); if (p == null) { return(null); } if (p.GetType() == typeof(NameProperty)) { NameProperty np = (NameProperty)p; return(np.data); } else if (p.GetType() == typeof(StrProperty)) { StrProperty np = (StrProperty)p; return(np.data); } return(null); }
public bool ApplyUpdate(IMEPackage package, PropertyCollection properties, MergeFileChange1 mfc) { var propKeys = PropertyName.Split('.'); PropertyCollection operatingCollection = properties; int i = 0; while (i < propKeys.Length - 1) { var matchingProp = operatingCollection.FirstOrDefault(x => x.Name.Instanced == propKeys[i]); if (matchingProp is StructProperty sp) { operatingCollection = sp.Properties; } // ARRAY PROPERTIES NOT SUPPORTED i++; } Log.Information($@"Applying property update: {PropertyName} -> {PropertyValue}"); switch (PropertyType) { case @"FloatProperty": FloatProperty fp = new FloatProperty(float.Parse(PropertyValue, CultureInfo.InvariantCulture), propKeys.Last()); operatingCollection.AddOrReplaceProp(fp); break; case @"IntProperty": IntProperty ip = new IntProperty(int.Parse(PropertyValue), propKeys.Last()); operatingCollection.AddOrReplaceProp(ip); break; case @"BoolProperty": BoolProperty bp = new BoolProperty(bool.Parse(PropertyValue), propKeys.Last()); operatingCollection.AddOrReplaceProp(bp); break; case @"NameProperty": var index = 0; var baseName = PropertyValue; var indexIndex = PropertyValue.IndexOf(@"|", StringComparison.InvariantCultureIgnoreCase); if (indexIndex > 0) { baseName = baseName.Substring(0, indexIndex); index = int.Parse(baseName.Substring(indexIndex + 1)); } NameProperty np = new NameProperty(new NameReference(baseName, index), PropertyName); operatingCollection.AddOrReplaceProp(np); break; case @"ObjectProperty": // This does not support porting in, only relinking existing items ObjectProperty op = new ObjectProperty(0, PropertyName); if (PropertyValue != null && PropertyValue != @"M3M_NULL") //M3M_NULL is a keyword for setting it to null to satisfy the schema { var entry = package.FindEntry(PropertyValue); if (entry == null) { throw new Exception(M3L.GetString(M3L.string_interp_mergefile_failedToUpdateObjectPropertyItemNotInPackage, PropertyName, PropertyValue, PropertyValue, package.FilePath)); } op.Value = entry.UIndex; } operatingCollection.AddOrReplaceProp(op); break; case @"EnumProperty": var enumInfo = PropertyValue.Split('.'); EnumProperty ep = new EnumProperty(enumInfo[0], mfc.OwningMM.Game, PropertyName); ep.Value = NameReference.FromInstancedString(enumInfo[1]); operatingCollection.AddOrReplaceProp(ep); break; case @"StrProperty": var sp = new StrProperty(PropertyValue, propKeys.Last()); operatingCollection.AddOrReplaceProp(sp); break; default: throw new Exception(M3L.GetString(M3L.string_interp_mergefile_unsupportedPropertyType, PropertyType)); } return(true); }
private CPool(IOutputter outputter) : this(null, outputter) { properties.Add(ArrayProperty.Create("CharacterPool", 0)); properties.Add(StrProperty.Create("PoolFileName", "Unsaved Pool")); IsDirty = true; }
public static SerializedFields Parse(int length, BinaryReader reader) { var start = reader.BaseStream.Position; var result = new SerializedFields(); while (true) { var propertyName = reader.ReadLengthPrefixedString(); if (propertyName == "None") { break; } var fieldType = reader.ReadLengthPrefixedString(); var size = reader.ReadInt32(); var index = reader.ReadInt32(); int overhead; var before = reader.BaseStream.Position; switch (fieldType) { case ArrayProperty.TypeName: result.Add(ArrayProperty.Parse(propertyName, index, reader, size, out overhead)); break; case FloatProperty.TypeName: overhead = 1; result.Add(FloatProperty.Parse(propertyName, index, reader)); break; case IntProperty.TypeName: overhead = 1; result.Add(IntProperty.Parse(propertyName, index, reader)); break; case ByteProperty.TypeName: result.Add(ByteProperty.Parse(propertyName, index, reader, out overhead)); break; case EnumProperty.TypeName: result.Add(EnumProperty.Parse(propertyName, index, reader, out overhead)); break; case BoolProperty.TypeName: overhead = 2; result.Add(BoolProperty.Parse(propertyName, index, reader)); break; case StrProperty.TypeName: overhead = 1; result.Add(StrProperty.Parse(propertyName, index, reader)); break; case NameProperty.TypeName: overhead = 1; result.Add(NameProperty.Parse(propertyName, index, reader)); break; case ObjectProperty.TypeName: overhead = 1; result.Add(ObjectProperty.Parse(propertyName, index, reader)); break; case StructProperty.TypeName: result.Add(StructProperty.Parse(propertyName, index, reader, size, out overhead)); break; case MapProperty.TypeName: result.Add(MapProperty.Parse(propertyName, index, reader, size, out overhead)); break; case TextProperty.TypeName: overhead = 1; result.Add(TextProperty.Parse(propertyName, index, reader)); break; default: throw new NotImplementedException(fieldType); } var after = reader.BaseStream.Position; if (before + size + overhead != after) { throw new InvalidOperationException($"Expected {size} bytes read but got {after - before - overhead}"); } } var int1 = reader.ReadInt32(); Trace.Assert(int1 == 0); var remainingBytes = start + length - reader.BaseStream.Position; if (remainingBytes > 0) { result.TrailingData = reader.ReadBytes((int)remainingBytes); } //if (remainingBytes == 4) ////if(result.Fields.Count > 0) //{ // var int2 = reader.ReadInt32(); //} //else if (remainingBytes > 0 && result.Any(f => f is ArrayProperty && ((ArrayProperty)f).Type == StructProperty.TypeName)) //{ // var unk = reader.ReadBytes((int)remainingBytes); //} //else if (remainingBytes > 4) //{ // var int2 = reader.ReadInt32(); // var str2 = reader.ReadLengthPrefixedString(); // var str3 = reader.ReadLengthPrefixedString(); //} return(result); }
public static DotArkProperty ReadPropertyFromDisk(DotArkDeserializer d) { var ms = d.ms; //First, read a name and open it. ArkClassName name = ms.ReadArkClassname(d); //If this name is null, we've done something wrong. if (name == null) { throw new Exception("A property reading error occurred and got an unexpected NULL value; do not save"); } //If the name is None, we've read to the final property and we can stop. if (name.IsNone()) { return(null); } //Now, read the type ArkClassName type = ms.ReadArkClassname(d); //If the type is None or unreadable, something has gone wrong. if (type == null) { throw new Exception($"A property name was identified as {name.classname}, but the type failed to read."); } //Read in the index and size int size = ms.ReadInt(); int index = ms.ReadInt(); //Based on the type, deserialize this. DotArkProperty prop; switch (type.classname) { case "IntProperty": prop = new IntProperty(d, index, size); break; case "UInt32Property": prop = new UInt32Property(d, index, size); break; case "Int8Property": prop = new Int8Property(d, index, size); break; case "Int16Property": prop = new Int16Property(d, index, size); break; case "UInt16Property": prop = new UInt16Property(d, index, size); break; case "UInt64Property": prop = new UInt64Property(d, index, size); break; case "BoolProperty": prop = new BoolProperty(d, index, size); break; case "ByteProperty": prop = new ByteProperty(d, index, size); break; case "FloatProperty": prop = new FloatProperty(d, index, size); break; case "DoubleProperty": prop = new DoubleProperty(d, index, size); break; case "NameProperty": prop = new NameProperty(d, index, size); break; case "ObjectProperty": prop = new ObjectProperty(d, index, size); break; case "StrProperty": prop = new StrProperty(d, index, size); break; case "StructProperty": prop = new StructProperty(d, index, size); break; case "ArrayProperty": prop = DotArkArray.ReadArray(d, index, size); //UNFINISHED break; case "TextProperty": prop = new TextProperty(d, index, size); break; default: //Unknown throw new Exception($"Type {type.classname} was not a valid property type. Something failed to read."); } //Set additional values in the property and return it. prop.type = type; prop.name = name; prop.index = index; prop.size = size; return(prop); }
public static UProperty ReadProp(IOMemoryStream ms, UAssetFile f, string arrayType, bool isStruct) { //Read the name long start = ms.position; //Read the remainder of the properties string name; int u1; string type; int u2; int length; int index; if (arrayType == null) { //Not an array name = ms.ReadNameTableEntry(f); //Return null if this is "None". That means we're done reading if (name == "None") { return(null); } u1 = ms.ReadInt(); type = ms.ReadNameTableEntry(f); u2 = ms.ReadInt(); length = ms.ReadInt(); index = ms.ReadInt(); } else { name = null; u1 = 0; type = arrayType; u2 = 0; length = 0; index = 0; } long payloadStart = ms.position; //Create the object UProperty u; switch (type) { case "ArrayProperty": u = new ArrayProperty(ms, f); break; case "BoolProperty": u = new BoolProperty(ms, f); break; case "ByteProperty": u = new ByteProperty(ms, f); break; case "DoubleProperty": u = new DoubleProperty(ms, f); break; case "FloatProperty": u = new FloatProperty(ms, f); break; case "Int16Property": u = new Int16Property(ms, f); break; case "Int8Property": u = new Int8Property(ms, f); break; case "IntProperty": u = new IntProperty(ms, f); break; case "NameProperty": u = new NameProperty(ms, f); break; case "ObjectProperty": u = new ObjectProperty(ms, f); break; case "StrProperty": u = new StrProperty(ms, f); break; case "StructProperty": u = new StructProperty(ms, f); break; case "TextProperty": u = new TextProperty(ms, f); break; case "UInt16Property": u = new UInt16Property(ms, f); break; case "UInt32Property": u = new UInt32Property(ms, f); break; case "UInt64Property": u = new UInt64Property(ms, f); break; default: throw new Exception($"FAILED TO READ UPROPERTY: Type {type} was not a valid type. Name={name}, u1={u1}, u2={u2}, length={length}, index={index}, position={start}"); } //Set attributes u.name = name; u.unknown1 = u1; u.type = type; u.unknown2 = u2; u.length = length; u.index = index; u.start = start; u.payloadStart = payloadStart; u.isArray = arrayType != null; //Dump f.DebugDump("UProperty Reading", ConsoleColor.Green, "name", name, "u1", u1.ToString(), "type", type, "u2", u2.ToString(), "length", length.ToString(), "index", index.ToString(), "start", start.ToString(), "payloadStart", payloadStart.ToString()); //Read u.Read(ms, f); //Log string msg = u.WriteString(); f.Debug("UProperty Read " + type, msg, ConsoleColor.DarkGreen); return(u); }