예제 #1
0
        public override void DeserializeStateObject(SaveState state)
        {
            Type         = Types.StreamingRef;
            ExternalFile = new BaseString(state.ReadIndexedString());
            GUID         = state.ReadIndexedGUID();

            // if not zero, calls something into the streaming manager
            byte unknown = state.Reader.ReadByte();
        }
예제 #2
0
        public void DeserializeStateObject(SaveState state)
        {
            int itemCount = state.ReadVariableLengthOffset();

            for (int i = 0; i < itemCount; i++)
            {
                var newObj = state.DeserializeType <T>();

                Add(newObj);
            }
        }
예제 #3
0
        public virtual void DeserializeStateObject(SaveState state)
        {
            ResolvedObject = state.ReadObjectHandle();

            if (ResolvedObject != null)
            {
                Type = Types.LocalCoreUUID;// Not entirely correct...
            }
            else
            {
                Type = Types.Null;
            }
        }
예제 #4
0
            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);
            }
예제 #5
0
            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>();
            }
        }
예제 #7
0
 public void SerializeStateObject(SaveState state) => throw new NotImplementedException();
예제 #8
0
 public void DeserializeStateObject(SaveState state)
 {
     Value = state.ReadIndexedString();
 }
        public SaveGameSystem(string savePath, FileMode mode = FileMode.Open)
        {
            if (mode == FileMode.Open)
            {
                var fileHandle = File.Open(savePath, mode, FileAccess.Read, FileShare.Read);

                using (var reader = new BinaryReader(fileHandle, Encoding.UTF8, true))
                {
                    // Offset 0x0
                    string gameVersionString = Encoding.ASCII.GetString(reader.ReadBytesStrict(32));
                    uint   gameVersion       = reader.ReadUInt32();
                    byte   saveVersion       = reader.ReadByte();
                    byte   saveFlags         = reader.ReadByte(); // { 0x80 = unknown, 0x1 = NG+, 0x2 = DLC entitlements }

                    ushort worldIdHash    = reader.ReadUInt16();  // CRC32-C xor'd - "World"
                    bool   isCoopGameMode = reader.ReadBooleanStrict();
                    _ = reader.ReadBytesStrict(3);

                    // Offset 0x2C
                    uint gameStateBlockLength = reader.ReadUInt32();
                    var  gameStateBlock       = reader.ReadBytesStrict(256);

                    if (gameStateBlockLength != 84)
                    {
                        throw new Exception();
                    }

                    // Offset 0x130
                    int unknown1 = reader.ReadInt32();                  // Sign extended
                    int saveType = reader.ReadInt32();                  // Sign extended { 1 = manual, 2 = quick, 4 = auto, 8 = NG+ start point }

                    var gameModuleGUID = new GGUUID().FromData(reader); // Field from `class GameModule`
                    var uniqueSaveGUID = new GGUUID().FromData(reader); // CoCreateGuid() on save
                    var gameLoadGUID   = new GGUUID().FromData(reader); // CoCreateGuid() on game start
                    var systemTypeGUID = new GGUUID().FromData(reader); // Possibly GUID for Win32System or physics

                    double playTimeInSeconds = reader.ReadDouble();
                    _ = reader.ReadBytesStrict(108);

                    // Offset 0x1EC
                    var  dataBlockMD5    = reader.ReadBytesStrict(16);
                    uint dataBlockLength = reader.ReadUInt32();

                    // Parse actual save data
                    State = new SaveState(reader, saveVersion, (uint)reader.BaseStream.Position, dataBlockLength);

                    var unknownData1   = State.Reader.ReadBytesStrict(24);
                    var unknownObject1 = State.ReadObjectHandle();
                    var unknownString1 = State.ReadIndexedString();// Likely entity RTTI name for the player's current mount. Instanced by AIManager.

                    var unknownData2   = State.Reader.ReadBytesStrict(24);
                    var unknownObject2 = State.ReadObjectHandle();

                    GlobalGameModule = RTTI.CreateObjectInstance <GameModule>();
                    GlobalStreamingStrategyManagerGame = RTTI.CreateObjectInstance <StreamingStrategyManagerGame>();
                    GlobalSceneManagerGame             = RTTI.CreateObjectInstance <SceneManagerGame>();

                    // GameModule info
                    {
                        byte unknownByte = State.Reader.ReadByte();

                        if (unknownByte != 0)
                        {
                            var unknownData = State.Reader.ReadBytesStrict(24);
                        }
                    }

                    GlobalStreamingStrategyManagerGame.ReadSave(State);
                    GlobalSceneManagerGame.ReadSave(State);
                    GlobalFactDatabase = State.DeserializeType <FactDatabase>();
                    GlobalGameModule.ReadSaveSystem(this);
                }
            }
            else if (mode == FileMode.Create || mode == FileMode.CreateNew)
            {
                throw new NotImplementedException("Writing archives is not supported at the moment");
            }
            else
            {
                throw new NotImplementedException("Archive file mode must be Open, Create, or CreateNew");
            }
        }
예제 #10
0
 public void DeserializeStateObject(SaveState state)
 {
     AssignFromOther(state.ReadIndexedGUID());
 }
예제 #11
0
 public virtual void DeserializeStateObject(SaveState state)
 {
     var resolvedObject = state.ReadObjectHandle();
 }