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);
            }
Exemple #4
0
        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>();
            }
        }