//public String __parentTypeIndex { get { return String.Format("{0:X4}", ParentTypeIndex); } } //public String __attributeCount { get { return String.Format("{0:X4}", AttributeCount); } } //public String __firstAttributeIndex { get { return String.Format("{0:X4}", FirstAttributeIndex); } } //public String __nodeType { get { return String.Format("{0:X4}", NodeType); } } public void Read(BinaryReader r, string name, DataForgeFile df) { var baseStruct = this; var properties = new List <PropertyDefinition>(); // TODO: Do we need to handle property overrides (original comment, investigate) // TODO: Include 1st call in while loop (same call inside)? var propertyDefinitions = Enumerable.Range(FirstAttributeIndex, AttributeCount) .Select(i => df.PropertyDefinitionTable[i]) .ToArray(); properties.InsertRange(0, propertyDefinitions); while (baseStruct.ParentTypeIndex != 0xFFFFFFFF) { baseStruct = df.StructDefinitionTable[Convert.ToInt32(baseStruct.ParentTypeIndex)]; var attributes = Enumerable.Range(baseStruct.FirstAttributeIndex, baseStruct.AttributeCount) .Select(i => df.PropertyDefinitionTable[i]) .ToArray(); properties.InsertRange(0, attributes); } //Console.WriteLine($"Reading Struct: {Name} (Prop: {properties.Count})"); foreach (var propertyDefinition in properties) { propertyDefinition.ConversionType = (ConversionType)((int)propertyDefinition.ConversionType & 0xFF); if (propertyDefinition.ConversionType == ConversionType.Attribute) { // ConversionType seems only used to differentiate between arrays and single values if (propertyDefinition.DataType == DataType.Class) { Console.WriteLine($"Class:"); var dataStruct = df.StructDefinitionTable[propertyDefinition.StructIndex]; dataStruct.Read(r, propertyDefinition.Name, df); } else if (propertyDefinition.DataType == DataType.StrongPointer) { Console.WriteLine($"Pointer:"); var structIndex = (ushort)r.ReadUInt32(); var recordIndex = (int)r.ReadUInt32(); //Console.WriteLine($"Require ClassMapping for struct {df.StructDefinitionTable[structIndex].Name}"); df.ClassMappings.Add(new ClassMapping { StructIndex = structIndex, RecordIndex = recordIndex }); } else { Console.WriteLine($"Simple:"); propertyDefinition.Read(r, df); } } else { // ConversionType seems only used to differentiate between arrays and single values var arrayCount = r.ReadUInt32(); var firstIndex = r.ReadUInt32(); Console.WriteLine($"Array of {propertyDefinition.DataType} ({arrayCount}, {firstIndex}):"); var elements = new List <object>(); for (var i = 0; i < arrayCount; i++) { switch (propertyDefinition.DataType) { case DataType.Boolean: elements.Add(df.BooleanValues[firstIndex + i]); break; case DataType.Double: elements.Add(df.DoubleValues[firstIndex + i]); break; case DataType.Enum: //TODO uint, value is retrieved from ValueMap elements.Add(df.EnumValues[firstIndex + i]); break; case DataType.Guid: elements.Add(df.GuidValues[firstIndex + i]); break; case DataType.Int16: elements.Add(df.Int16Values[firstIndex + i]); break; case DataType.Int32: elements.Add(df.Int32Values[firstIndex + i]); break; case DataType.Int64: elements.Add(df.Int64Values[firstIndex + i]); break; case DataType.SByte: elements.Add(df.Int8Values[firstIndex + i]); break; case DataType.Locale: elements.Add(df.LocaleValues[firstIndex + i]); break; case DataType.Reference: elements.Add(df.ReferenceValues[firstIndex + i]); break; case DataType.Single: elements.Add(df.SingleValues[firstIndex + i]); break; case DataType.String: elements.Add(df.StringValues[firstIndex + i]); break; case DataType.UInt16: elements.Add(df.UInt16Values[firstIndex + i]); break; case DataType.UInt32: elements.Add(df.UInt32Values[firstIndex + i]); break; case DataType.UInt64: elements.Add(df.UInt64Values[firstIndex + i]); break; case DataType.Byte: elements.Add(df.UInt8Values[firstIndex + i]); break; case DataType.Class: df.ClassMappings.Add(new ClassMapping { StructIndex = propertyDefinition.StructIndex, RecordIndex = (int)(firstIndex + i) }); break; case DataType.StrongPointer: df.StrongMappings.Add(new ClassMapping { StructIndex = propertyDefinition.StructIndex, RecordIndex = (int)(firstIndex + i) }); break; case DataType.WeakPointer: df.WeakMappings1.Add(new ClassMapping { StructIndex = propertyDefinition.StructIndex, RecordIndex = (int)(firstIndex + i) }); break; default: throw new NotImplementedException(); // var tempe = this.DocumentRoot.CreateElement(String.Format("{0}", node.DataType)); // var tempa = this.DocumentRoot.CreateAttribute("__child"); // tempa.Value = (firstIndex + i).ToString(); // tempe.Attributes.Append(tempa); // var tempb = this.DocumentRoot.CreateAttribute("__parent"); // tempb.Value = node.StructIndex.ToString(); // tempe.Attributes.Append(tempb); // child.AppendChild(tempe); // break; } } } } Properties = properties.ToArray(); }
public Struct Read(BinaryReader r, string name, DataForgeFile df) { var baseStruct = this; var propertyDefinitions = new List <PropertyDefinition>(); // TODO: Do we need to handle property overrides (original comment, investigate) // TODO: Include 1st call in while loop (same call inside)? propertyDefinitions.InsertRange(0, Enumerable.Range(FirstAttributeIndex, AttributeCount) .Select(i => df.PropertyDefinitionTable[i]) .ToArray()); while (baseStruct.ParentTypeIndex != 0xFFFFFFFF) { baseStruct = df.StructDefinitionTable[Convert.ToInt32(baseStruct.ParentTypeIndex)]; var attributes = Enumerable.Range(baseStruct.FirstAttributeIndex, baseStruct.AttributeCount) .Select(i => df.PropertyDefinitionTable[i]) .ToArray(); propertyDefinitions.InsertRange(0, attributes); } if (name == "MeleeAttackInfo") { } var properties = new List <Property>(); foreach (var propertyDefinition in propertyDefinitions) { propertyDefinition.ConversionType = (ConversionType)((int)propertyDefinition.ConversionType & 0xFF); if (propertyDefinition.ConversionType == ConversionType.Attribute) { // ConversionType seems only used to differentiate between arrays and single values if (propertyDefinition.DataType == DataType.Class) { var structDefinition = df.StructDefinitionTable[propertyDefinition.StructIndex]; var structData = structDefinition.Read(r, propertyDefinition.Name, df); properties.Add(new Property() { Name = structDefinition.Name, Type = DataType.Class, Value = structData }); } else if (propertyDefinition.DataType == DataType.StrongPointer) { var structIndex = (ushort)r.ReadUInt32(); var recordIndex = (int)r.ReadUInt32(); var property = new Property() { Name = propertyDefinition.Name, Type = DataType.StrongPointer, Value = "some reference" }; properties.Add(property); df.ClassMappings.Add(new ClassMapping { StructIndex = structIndex, RecordIndex = recordIndex, Property = property }); } else { properties.Add(propertyDefinition.Read(r, df)); } } else { // ConversionType seems only used to differentiate between arrays and single values var arrayCount = r.ReadUInt32(); var firstIndex = r.ReadUInt32(); var elements = new List <Property>(); var propName = propertyDefinition.Name; var propType = propertyDefinition.DataType; for (var i = 0; i < arrayCount; i++) { switch (propertyDefinition.DataType) { case DataType.Boolean: elements.Add(new Property { Name = propName, Type = propType, Value = df.BooleanValues[firstIndex + i] }); break; case DataType.Double: elements.Add(new Property { Name = propName, Type = propType, Value = df.DoubleValues[firstIndex + i] }); break; case DataType.Enum: //TODO uint, value is retrieved from ValueMap elements.Add(new Property { Name = propName, Type = propType, Value = df.EnumValues[firstIndex + i] }); break; case DataType.Guid: elements.Add(new Property { Name = propName, Type = propType, Value = df.GuidValues[firstIndex + i] }); break; case DataType.Int16: elements.Add(new Property { Name = propName, Type = propType, Value = df.Int16Values[firstIndex + i] }); break; case DataType.Int32: elements.Add(new Property { Name = propName, Type = propType, Value = df.Int32Values[firstIndex + i] }); break; case DataType.Int64: elements.Add(new Property { Name = propName, Type = propType, Value = df.Int64Values[firstIndex + i] }); break; case DataType.SByte: elements.Add(new Property { Name = propName, Type = propType, Value = df.Int8Values[firstIndex + i] }); break; case DataType.Locale: elements.Add(new Property { Name = propName, Type = propType, Value = df.LocaleValues[firstIndex + i] }); break; case DataType.Reference: elements.Add(new Property { Name = propName, Type = propType, Value = df.ReferenceValues[firstIndex + i] }); break; case DataType.Single: elements.Add(new Property { Name = propName, Type = propType, Value = df.SingleValues[firstIndex + i] }); break; case DataType.String: elements.Add(new Property { Name = propName, Type = propType, Value = df.StringValues[firstIndex + i] }); break; case DataType.UInt16: elements.Add(new Property { Name = propName, Type = propType, Value = df.UInt16Values[firstIndex + i] }); break; case DataType.UInt32: elements.Add(new Property { Name = propName, Type = propType, Value = df.UInt32Values[firstIndex + i] }); break; case DataType.UInt64: elements.Add(new Property { Name = propName, Type = propType, Value = df.UInt64Values[firstIndex + i] }); break; case DataType.Byte: elements.Add(new Property { Name = propName, Type = propType, Value = df.UInt8Values[firstIndex + i] }); break; case DataType.Class: var property = new Property { Name = propName, Type = propType, Value = "MAPPING PLACEHOLDER" }; elements.Add(property); df.ClassMappings.Add(new ClassMapping { StructIndex = propertyDefinition.StructIndex, RecordIndex = (int)(firstIndex + i), Property = property }); break; case DataType.StrongPointer: var property1 = new Property { Name = propName, Type = propType, Value = "MAPPING PLACEHOLDER" }; elements.Add(property1); df.StrongMappings.Add(new ClassMapping { StructIndex = propertyDefinition.StructIndex, RecordIndex = (int)(firstIndex + i), Property = property1 }); break; case DataType.WeakPointer: var property2 = new Property { Name = propName, Type = propType, Value = "MAPPING PLACEHOLDER" }; elements.Add(property2); df.WeakMappings1.Add(new ClassMapping { StructIndex = propertyDefinition.StructIndex, RecordIndex = (int)(firstIndex + i), Property = property2 }); break; default: throw new NotImplementedException(); } } var listProperty = new Property { Name = propertyDefinition.Name, Type = propertyDefinition.DataType, IsList = true, Value = elements }; properties.Add(listProperty); } } return(new Struct { Name = Name, Properties = properties.ToArray() }); }
public void Read(BinaryReader r, DataForgeFile df) { //Console.Write($"Reading Property: {Name} ({ConversionType}, {DataType}): "); switch (DataType) { case DataType.Reference: Unknown = r.ReadUInt32(); // ? Value = r.ReadGuid(); break; case DataType.Locale: var offset = r.ReadUInt32(); Value = df.ValueMap[offset]; break; case DataType.StrongPointer: r.ReadUInt32(); // ? {1:X8} Value = r.ReadUInt32(); break; case DataType.WeakPointer: var structIndex = r.ReadUInt32(); var itemIndex = r.ReadUInt32(); df.WeakMappings2.Add(new ClassMapping { StructIndex = (ushort)structIndex, RecordIndex = (int)itemIndex }); break; case DataType.String: var v = r.ReadUInt32(); Value = df.ValueMap[v]; break; case DataType.Boolean: Value = r.ReadByte(); break; case DataType.Single: Value = r.ReadSingle(); break; case DataType.Double: Value = r.ReadDouble(); break; case DataType.Guid: Value = r.ReadGuid(); break; case DataType.SByte: Value = r.ReadSByte(); break; case DataType.Int16: Value = r.ReadInt16(); break; case DataType.Int32: Value = r.ReadInt32(); break; case DataType.Int64: Value = r.ReadInt64(); break; case DataType.Byte: Value = r.ReadByte(); break; case DataType.UInt16: Value = r.ReadUInt16(); break; case DataType.UInt32: Value = r.ReadUInt32(); break; case DataType.UInt64: Value = r.ReadUInt64(); break; case DataType.Enum: var enumDefinition = df.EnumDefinitionTable[StructIndex]; // ? Value = df.ValueMap[r.ReadUInt32()]; break; default: throw new NotImplementedException(); } }
} // -> Property public Property Read(BinaryReader r, DataForgeFile df) { object value; switch (DataType) { case DataType.Reference: Unknown = r.ReadUInt32(); // ? value = r.ReadGuid(); return(new Property { Name = Name, Type = DataType, Value = value }); case DataType.Locale: var offset = r.ReadUInt32(); value = df.ValueMap[offset]; return(new Property { Name = Name, Type = DataType, Value = value }); case DataType.StrongPointer: r.ReadUInt32(); // ? {1:X8} value = r.ReadUInt32(); return(new Property { Name = Name, Type = DataType, Value = value }); case DataType.WeakPointer: var structIndex = r.ReadUInt32(); var itemIndex = r.ReadUInt32(); var property = new Property { Name = Name, Type = DataType, Value = "MAPPING PLACEHOLDER" }; df.WeakMappings2.Add(new ClassMapping { StructIndex = (ushort)structIndex, RecordIndex = (int)itemIndex, Property = property }); return(property); case DataType.String: var v = r.ReadUInt32(); value = df.ValueMap[v]; return(new Property { Name = Name, Type = DataType, Value = value }); case DataType.Boolean: value = r.ReadByte(); return(new Property { Name = Name, Type = DataType, Value = value }); case DataType.Single: value = r.ReadSingle(); return(new Property { Name = Name, Type = DataType, Value = value }); case DataType.Double: value = r.ReadDouble(); return(new Property { Name = Name, Type = DataType, Value = value }); case DataType.Guid: value = r.ReadGuid(); return(new Property { Name = Name, Type = DataType, Value = value }); case DataType.SByte: value = r.ReadSByte(); return(new Property { Name = Name, Type = DataType, Value = value }); case DataType.Int16: value = r.ReadInt16(); return(new Property { Name = Name, Type = DataType, Value = value }); case DataType.Int32: value = r.ReadInt32(); return(new Property { Name = Name, Type = DataType, Value = value }); case DataType.Int64: value = r.ReadInt64(); return(new Property { Name = Name, Type = DataType, Value = value }); case DataType.Byte: value = r.ReadByte(); return(new Property { Name = Name, Type = DataType, Value = value }); case DataType.UInt16: value = r.ReadUInt16(); return(new Property { Name = Name, Type = DataType, Value = value }); case DataType.UInt32: value = r.ReadUInt32(); return(new Property { Name = Name, Type = DataType, Value = value }); case DataType.UInt64: value = r.ReadUInt64(); return(new Property { Name = Name, Type = DataType, Value = value }); case DataType.Enum: var enumDefinition = df.EnumDefinitionTable[StructIndex]; // ? value = df.ValueMap[r.ReadUInt32()]; return(new Property { Name = Name, Type = DataType, Value = value }); default: throw new NotImplementedException(); } }