public static RTTIMapContainer FromData(SaveState state) { int rttiEntryCount = state.ReadVariableLengthOffset(); var container = new RTTIMapContainer(); for (int i = 0; i < rttiEntryCount; i++) { string classType = state.ReadIndexedString(); int memberCount = state.ReadVariableLengthOffset(); var rttiList = new RTTI.VirtualRTTIList(classType, memberCount); for (int j = 0; j < memberCount; j++) { string type = state.ReadIndexedString(); string category = state.ReadIndexedString(); string name = state.ReadIndexedString(); rttiList.Add(type, category, name); } rttiList.ResolveMembersToFieldInfo(); container.Map.Add(rttiList); } return(container); }
public static WideStringTableContainer FromData(SaveState state) { int wideStringCount = state.ReadVariableLengthOffset(); var container = new WideStringTableContainer(); for (int i = 0; i < wideStringCount; i++) { int stringLength = state.ReadVariableLengthOffset() * sizeof(short); string str = Encoding.Unicode.GetString(state.Reader.ReadBytesStrict(stringLength)); container.Table.Add(str); } return(container); }
public static StringTableContainer FromData(SaveState state) { int stringTableCount = state.ReadVariableLengthOffset(); var reader = state.Reader; var container = new StringTableContainer(); for (int i = 0; i < stringTableCount; i++) { int blockCount = reader.ReadInt32(); if (blockCount < 0) { return(null); } int blockSize = reader.ReadInt32(); if (blockSize < 0) { return(null); } if ((blockCount * blockSize) > reader.StreamRemainder() || ((blockSize - 1) & blockSize) != 0) { return(null); } var table = new Table() { BitShiftMask = BitOperations.TrailingZeroCount(blockSize), BlockCount = blockCount, BlockSize = blockSize, Data = new byte[blockCount][], }; for (int j = 0; j < table.BlockCount; j++) { table.Data[j] = reader.ReadBytesStrict(table.BlockSize); } // No clue what this is int unknownCount = reader.ReadInt32(); if (unknownCount < 0 || (unknownCount * 8) > reader.StreamRemainder()) { return(null); } table.UnknownData = reader.ReadBytesStrict(unknownCount * 8); // Insert container.Tables.Add(table); } return(container); }
public void DeserializeStateObject(SaveState state) { int itemCount = state.ReadVariableLengthOffset(); for (int i = 0; i < itemCount; i++) { var newObj = state.DeserializeType <T>(); Add(newObj); } }
public static GUIDTableContainer FromData(SaveState state) { var container = new GUIDTableContainer(); // Why do they try to keep GUID allocations balanced across 256 tables? I don't see the point for (int i = 0; i < HardcodedTableCount; i++) { int guidCount = state.ReadVariableLengthOffset(); for (int j = 0; j < guidCount; j++) { container.Tables[i].Add(new BaseGGUUID().FromData(state.Reader)); } } return(container); }
public void ReadProfile() { FileHandle.Position = 0; using (var reader = new BinaryReader(FileHandle, Encoding.UTF8, true)) { uint magic = reader.ReadUInt32(); if (magic != HardcodedMagic) { throw new Exception(); } uint playerProfileSize = reader.ReadUInt32(); // sizeof(class PlayerProfile) = 0x1AF uint savedDataChunkSize = reader.ReadUInt32(); // Length of all data minus the header (0xC) var state = new SaveState(reader, 0, (uint)reader.BaseStream.Position, savedDataChunkSize); // Handle game version int gameVersion = state.ReadVariableLengthOffset(); string gameVersionString = state.ReadIndexedString(); if (gameVersion != HardcodedGameVersion) { throw new Exception("Unknown profile version"); } if (gameVersionString != HardcodedGameVersionString) { throw new Exception("Unknown profile version"); } // Read the root structure (PlayerProfile) Profile = state.DeserializeType <HZD.PlayerProfile>(); } }