private static bool ValidateStructure( GFF.StructureDefinition def, Type nativeType) { // i'm too lazy to write this code right now :) return(true); }
private void ImportTypeStructure(GFF.StructureDefinition def, object instance, long offset, ref long newOffset) { var type = instance.GetType(); if (ValidateStructure(def, type) == false) { throw new FormatException("structure validation failed"); } var reflected = GFF.ReflectedStructureType.For(type); foreach (var fieldDef in def.Fields) { var value = reflected.GetField(instance, fieldDef.Id); this.ImportTypeField(fieldDef, reflected.GetFieldType(fieldDef.Id), value, offset, ref newOffset); } }
private object ExportTypeStructure(GFF.StructureDefinition def, Type type, long offset) { if (ValidateStructure(def, type) == false) { throw new FormatException("structure validation failed"); } var instance = Activator.CreateInstance(type); var reflected = GFF.ReflectedStructureType.For(type); foreach (var fieldDef in def.Fields) { var value = this.ExportTypeField( fieldDef, reflected.GetFieldType(fieldDef.Id), offset); reflected.SetField(instance, fieldDef.Id, value); } return(instance); }
private void ImportStructure(GFF.StructureDefinition def, GenericKeyValue data, long offset, ref long newOffset, ImportState state) { foreach (var fieldDef in def.Fields) { if (fieldDef.Id == 16208) { } GenericKeyValue value; if (data.Values.ContainsKey(fieldDef.Id) == false) { //throw new InvalidOperationException(); value = new GenericKeyValue(fieldDef.Type, null); } else { value = data[fieldDef.Id]; } this.ImportField(fieldDef, value, offset, ref newOffset, state); } }
private GenericKeyValue ExportStructure(GFF.StructureDefinition def, long offset, ExportState state) { var kv = new GenericKeyValue(GFF.FieldType.Structure, null); kv.StructureId = def.Id; foreach (var fieldDef in def.Fields) { var value = this.ExportField(fieldDef, offset, state); if (value is GenericKeyValue) { kv[fieldDef.Id] = (GenericKeyValue)value; } else { kv[fieldDef.Id] = new GenericKeyValue(fieldDef.Type, value); } } return(kv); }
private void ImportTypeToStructures(Type root) { var structs = new List <GFF.StructureDefinition>(); var map = new Dictionary <Type, GFF.StructureDefinition>(); var types = new List <Type>(); var queue = new Queue <Type>(); queue.Enqueue(root); // discover non-native types we need to add while (queue.Count > 0) { var type = queue.Dequeue(); types.Add(type); foreach (var field in type.GetFields()) { var subtype = field.FieldType; if (GFF.Builtin.FromNativeType(subtype) != GFF.FieldType.Structure) { continue; } if (subtype.IsGenericType == true && subtype.GetGenericTypeDefinition() == typeof(List <>)) { subtype = subtype.GetGenericArguments()[0]; } if (types.Contains(subtype) == true || queue.Contains(subtype) == true) { continue; } queue.Enqueue(subtype); } } if (types.Count > 0xFFFF) { throw new InvalidOperationException(); } // now define them foreach (var type in types) { var structDef = new GFF.StructureDefinition(); var reflected = GFF.ReflectedStructureType.For(type); map.Add(type, structDef); structs.Add(structDef); structDef.Id = reflected.Id; uint offset = 0; foreach (var kvp in reflected.Fields) { var subtype = kvp.Value.Field.FieldType; var fieldDef = new GFF.FieldDefinition(); if (subtype.IsGenericType == true && subtype.GetGenericTypeDefinition() == typeof(List <>)) { subtype = subtype.GetGenericArguments()[0]; fieldDef.Flags |= GFF.FieldFlags.IsList; } else if (subtype.IsArray == true) { fieldDef.Flags |= GFF.FieldFlags.IsList; } fieldDef.Id = kvp.Key; fieldDef.Type = GFF.Builtin .FromNativeType(subtype, kvp.Value.Type); fieldDef.Offset = offset; fieldDef.NativeType = subtype; structDef.Fields.Add(fieldDef); if ((fieldDef.Flags & GFF.FieldFlags.IsList) != 0) { offset += 4; } else if (fieldDef.Type == GFF.FieldType.Structure) { throw new NotImplementedException(); } else { offset += GFF.Builtin.SizeOf(fieldDef.Type); } } structDef.DataSize = offset; } // update ids foreach (var type in types) { var structDef = map[type]; foreach (var fieldDef in structDef.Fields) { if (fieldDef.Type == GFF.FieldType.Structure) { var structRef = map[fieldDef.NativeType]; int index = structs.IndexOf(structRef); if (index < 0) { throw new InvalidOperationException(); } fieldDef.StructureReference = structRef; fieldDef.StructureId = (ushort)index; } } } this.Structures = structs; }
private TType ExportTypeStructure <TType>(GFF.StructureDefinition def, long offset) where TType : class, new() { return((TType)ExportTypeStructure(def, typeof(TType), offset)); }
public void Deserialize(Stream input) { input.Seek(0, SeekOrigin.Begin); var magic = input.ReadValueU32(Endian.Big); if (magic != 0x47464620) { throw new FormatException(); } var version = input.ReadValueU32(Endian.Big); if (version != 0x56342E30 && // 4.0 version != 0x56342E31) // 4.1 { throw new FormatException("unsupported version"); } this.FileVersion = (byte)(version - 0x56342E30); this.FilePlatform = input.ReadValueEnum <GFF.FilePlatform>(Endian.Big); this.FormatType = input.ReadValueEnum <GFF.FormatType>(Endian.Big); this.FormatVersion = input.ReadValueU32(Endian.Big); var endian = this.FilePlatform == GFF.FilePlatform.PC ? Endian.Little : Endian.Big; var structCount = input.ReadValueU32(endian); var stringCount = this.FileVersion < 1 ? 0 : input.ReadValueU32(endian); var stringOffset = this.FileVersion < 1 ? 0 : input.ReadValueU32(endian); var dataOffset = input.ReadValueU32(endian); if (this.FileVersion < 1) { stringOffset = dataOffset; } else { if (dataOffset < stringOffset) { throw new FormatException(); } } this.Structures.Clear(); for (uint i = 0; i < structCount; i++) { var structDef = new GFF.StructureDefinition(); //structDef.Id = input.ReadValueU32(endian); structDef.Id = input.ReadValueU32(Endian.Big); var fieldCount = input.ReadValueU32(endian); var fieldOffset = input.ReadValueU32(endian); structDef.DataSize = input.ReadValueU32(endian); long nextOffset = input.Position; structDef.Fields.Clear(); input.Seek(fieldOffset, SeekOrigin.Begin); for (uint j = 0; j < fieldCount; j++) { var fieldDef = new GFF.FieldDefinition(); fieldDef.Id = input.ReadValueS32(endian); var rawFlags = input.ReadValueU32(endian); fieldDef.Offset = input.ReadValueU32(endian); var type = (ushort)(rawFlags & 0xFFFF); var flags = (GFF.FieldFlags)((rawFlags >> 16) & 0xFFFF); if ((flags & GFF.FieldFlags.IsStructure) != 0) { flags &= ~GFF.FieldFlags.IsStructure; fieldDef.Type = GFF.FieldType.Structure; fieldDef.StructureId = type; } else { fieldDef.Type = (GFF.FieldType)type; } fieldDef.Flags = flags; structDef.Fields.Add(fieldDef); } this.Structures.Add(structDef); input.Seek(nextOffset, SeekOrigin.Begin); } if (this.FileVersion >= 1) { input.Seek(stringOffset, SeekOrigin.Begin); this.StringTable = new List <string>(); for (uint i = 0; i < stringCount; i++) { this.StringTable.Add(input.ReadStringZ(Encoding.UTF8)); } } input.Seek(dataOffset, SeekOrigin.Begin); this.Data = input.ReadToMemoryStream(input.Length - dataOffset); }
private void PrintStructure(GFF.StructureDefinition def, int level) { var queue = new Queue <GFF.StructureDefinition>(); if (Printed.Contains(def) == false) { Printed.Add(def); } PrintLine(level, "[GFF.StructureDefinition(0x{0:X8})] // {1}", def.Id, ParseId(def.Id)); PrintLine(level, "public class {0}", ParseId(def.Id)); PrintLine(level, "{{"); foreach (var fieldDef in def.Fields) { string type; if (fieldDef.Type == GFF.FieldType.Structure) { var subdef = this.Structures[fieldDef.StructureId]; type = ParseId(subdef.Id); if (queue.Contains(subdef) == false) { queue.Enqueue(subdef); } } else { type = fieldDef.Type.ToString(); } if (fieldDef.Type == GFF.FieldType.Color || fieldDef.Type == GFF.FieldType.Matrix4x4 || fieldDef.Type == GFF.FieldType.Quaternion || fieldDef.Type == GFF.FieldType.TalkString || fieldDef.Type == GFF.FieldType.Vector3 || fieldDef.Type == GFF.FieldType.Vector4) { type = "GFF.Builtins." + type; } if (fieldDef.Type == GFF.FieldType.UInt8 && fieldDef.IsList == true) { type = "byte[]"; } else if (fieldDef.IsList == true) { type = "List<" + type + ">"; } if (fieldDef.IsReference == true) { type = "*" + type; } PrintLine(level + 1, ""); PrintLine(level + 1, "[GFF.FieldDefinition({0})]", fieldDef.Id); PrintLine(level + 1, "public {0} Unknown{1};", type, fieldDef.Id); } if (queue.Count > 0) { while (queue.Count > 0) { PrintLine(level + 1, ""); PrintStructure(queue.Dequeue(), level + 1); } } PrintLine(level, "}}"); }
public void Deserialize(Stream input) { input.Seek(0, SeekOrigin.Begin); var magic = input.ReadValueU32(false); if (magic != 0x47464620) { throw new FormatException(); } var version = input.ReadValueU32(false); if (version != 0x56342E30 && // 4.0 version != 0x56342E31) // 4.1 { throw new FormatException("unsupported version"); } this.FileVersion = (byte)(version - 0x56342E30); this.FilePlatform = input.ReadValueEnum<GFF.FilePlatform>(false); this.FormatType = input.ReadValueEnum<GFF.FormatType>(false); this.FormatVersion = input.ReadValueU32(false); var littleEndian = this.FilePlatform == GFF.FilePlatform.PC; var structCount = input.ReadValueU32(littleEndian); var stringCount = this.FileVersion < 1 ? 0 : input.ReadValueU32(littleEndian); var stringOffset = this.FileVersion < 1 ? 0 : input.ReadValueU32(littleEndian); var dataOffset = input.ReadValueU32(littleEndian); if (this.FileVersion < 1) { stringOffset = dataOffset; } else { if (dataOffset < stringOffset) { throw new FormatException(); } } this.Structures.Clear(); for (uint i = 0; i < structCount; i++) { var structDef = new GFF.StructureDefinition(); //structDef.Id = input.ReadValueU32(littleEndian); structDef.Id = input.ReadValueU32(false); var fieldCount = input.ReadValueU32(littleEndian); var fieldOffset = input.ReadValueU32(littleEndian); structDef.DataSize = input.ReadValueU32(littleEndian); long nextOffset = input.Position; structDef.Fields.Clear(); input.Seek(fieldOffset, SeekOrigin.Begin); for (uint j = 0; j < fieldCount; j++) { var fieldDef = new GFF.FieldDefinition(); fieldDef.Id = input.ReadValueS32(littleEndian); var rawFlags = input.ReadValueU32(littleEndian); fieldDef.Offset = input.ReadValueU32(littleEndian); var type = (ushort)(rawFlags & 0xFFFF); var flags = (GFF.FieldFlags)((rawFlags >> 16) & 0xFFFF); if ((flags & GFF.FieldFlags.IsStructure) != 0) { flags &= ~GFF.FieldFlags.IsStructure; fieldDef.Type = GFF.FieldType.Structure; fieldDef.StructureId = type; } else { fieldDef.Type = (GFF.FieldType)type; } fieldDef.Flags = flags; structDef.Fields.Add(fieldDef); } this.Structures.Add(structDef); input.Seek(nextOffset, SeekOrigin.Begin); } if (this.FileVersion >= 1) { input.Seek(stringOffset, SeekOrigin.Begin); this.StringTable = new List<string>(); for (uint i = 0; i < stringCount; i++) { this.StringTable.Add(input.ReadStringZ(Encoding.UTF8)); } } input.Seek(dataOffset, SeekOrigin.Begin); this.Data = input.ReadToMemoryStream(input.Length - dataOffset); }