diff --git a/include/RE/B/BGSSaveLoadManager.h b/include/RE/B/BGSSaveLoadManager.h index b5ae176e9..1b8e42b0e 100644 --- a/include/RE/B/BGSSaveLoadManager.h +++ b/include/RE/B/BGSSaveLoadManager.h @@ -24,9 +24,12 @@ namespace RE { kAutosave = 0x0, kSave = 0x1, - kQuicksave = 0x2 + kQuicksave = 0x2, + kCustom = 0x3 }; + bool PopulateFileEntryData(); + // members BSFixedString fileName; // 00 BSFixedString characterName; // 08 @@ -50,7 +53,7 @@ namespace RE bool unk66; // 66 std::uint8_t unk67; // 67 std::uint8_t unk68; // 68 - bool unk69; // 69 + bool modded; // 69 std::uint16_t pad6A; // 6A std::uint32_t characterID; // 6C stl::enumeration saveType; // 70 @@ -89,6 +92,17 @@ namespace RE }; static_assert(sizeof(Thread) == 0xC0); + struct SaveEntry + { + std::uint32_t characterID; // 00 + std::uint32_t isModded; // 04 + std::uint32_t manualSaveCount; // 08 + std::uint32_t autoSaveCount; // 0C + BSTHashMap autoSaves; // 18 + BSFixedString lastQuicksave; // 40 + }; + static_assert(sizeof(SaveEntry) == 0x48); + ~BGSSaveLoadManager() override; // 00 // override (BSTEventSink) @@ -102,97 +116,69 @@ namespace RE static BGSSaveLoadManager* GetSingleton(); + void GenerateCharacterID(); void Save(const char* a_fileName); void Load(const char* a_fileName); void Load(const char* a_fileName, bool a_checkForMods); - bool PopulateSaveList(); - bool LoadMostRecentSaveGame(); + bool PopulateSaveList(); // members - BSTHashMap playerIDNameMap; // 078 - std::uint64_t unk0A0; // 0A0 - std::uint32_t unk0A8; // 0A8 - std::uint32_t unk0AC; // 0AC - std::uint32_t unk0B0; // 0B0 - std::uint32_t unk0B4; // 0B4 - std::uint64_t unk0B8; // 0B8 - std::uint64_t unk0C0; // 0C0 - std::uint64_t unk0C8; // 0C8 - std::uint64_t currentPlayerID; // 0D0 - std::uint64_t displayPlayerID; // 0D8 - std::uint32_t unk0E0; // 0E0 - std::uint32_t unk0E4; // 0E4 - BSTArray unk0E8; // 0E8 - - BSTArray saveGameList; // 100 - std::uint8_t unk118; // 118 - std::uint8_t unk119; // 119 - std::uint16_t unk11A; // 11A - std::uint32_t unk11C; // 11C - std::uint16_t unk120; // 120 - std::uint16_t unk122; // 122 - std::uint32_t unk124; // 124 - std::uint32_t tickCount; // 128 - std::uint32_t unk12C; // 12C - std::uint8_t unk130; // 130 - std::uint8_t unk131; // 131 - std::uint16_t unk132; // 132 - std::uint32_t unk134; // 134 - std::uint64_t unk138; // 138 - std::uint64_t unk140; // 140 - std::uint64_t unk148; // 148 - std::uint64_t unk150; // 150 - std::uint64_t unk158; // 158 - std::uint64_t unk160; // 160 - std::uint64_t unk168; // 168 - std::uint64_t unk170; // 170 - std::uint64_t unk178; // 178 - std::uint64_t unk180; // 180 - std::uint64_t unk188; // 188 - std::uint64_t unk190; // 190 - std::uint64_t unk198; // 198 - std::uint64_t unk1A0; // 1A0 - std::uint64_t unk1A8; // 1A8 - std::uint64_t unk1B0; // 1B0 - std::uint64_t unk1B8; // 1B8 - std::uint64_t unk1C0; // 1C0 - std::uint64_t unk1C8; // 1C8 - std::uint64_t unk1D0; // 1D0 - std::uint64_t unk1D8; // 1D8 - std::uint64_t unk1E0; // 1E0 - std::uint64_t unk1E8; // 1E8 - std::uint64_t unk1F0; // 1F0 - std::uint64_t unk1F8; // 1F8 - - std::uint64_t unk200; // 200 - std::uint64_t unk208; // 208 - std::uint64_t unk210; // 210 - std::uint64_t unk218; // 218 - std::uint64_t unk220; // 220 - std::uint64_t unk228; // 228 - std::uint64_t unk230; // 230 - std::uint64_t unk238; // 238 - std::uint64_t unk240; // 240 - std::uint64_t unk248; // 248 - std::uint32_t unk250; // 250 - std::uint32_t unk254; // 254 - std::uint64_t unk258; // 258 - std::uint16_t unk260; // 260 - std::uint16_t unk262; // 262 - std::uint32_t unk264; // 264 - std::uint64_t unk268; // 268 - std::uint32_t unk270; // 270 - std::uint32_t unk274; // 274 - std::uint64_t unk278; // 278 - std::uint64_t unk280; // 280 - std::uint32_t unk288; // 288 - std::uint32_t unk28C; // 28C - std::uint64_t unk290; // 290 - std::uint64_t unk298; // 298 - std::uint32_t unk2A0; // 2A0 - std::uint32_t unk2A4; // 2A4 - std::uint64_t unk2A8; // 2A8 + BSTHashMap characterIDNameMap; // 078 + std::uint64_t unk0A0; // 0A0 + std::uint32_t unk0A8; // 0A8 + std::uint32_t unk0AC; // 0AC + std::uint32_t unk0B0; // 0B0 + std::uint32_t unk0B4; // 0B4 + std::uint64_t unk0B8; // 0B8 + std::uint64_t unk0C0; // 0C0 + std::uint64_t unk0C8; // 0C8 + std::uint32_t currentCharacterID; // 0D0 + std::uint32_t currentCharacterModded; // 0D4 + std::uint32_t displayCharacterID; // 0D8 + std::uint32_t displayCharacterModded; // 0DC + std::uint32_t unk0E0; // 0E0 + std::uint32_t unk0E4; // 0E4 + BSTArray loadedEntries; // 0E8 + + BSTArray saveGameList; // 100 + std::uint8_t unk118; // 118 + std::uint8_t pad119; // 119 + std::uint16_t pad11A; // 11A + std::uint32_t saveCount; // 11C + std::uint8_t unk120; // 120 + std::uint8_t pad121; // 121 + std::uint16_t pad122; // 122 + std::uint32_t pad124; // 124 + std::uint64_t tickCount; // 128 + std::uint8_t unk130; // 130 + std::uint8_t pad131; // 131 + std::uint16_t pad132; // 132 + std::uint32_t pad134; // 134 + const char lastFileFullName[0x104]; // 138 + std::uint32_t pad23C; // 23C + BSFixedString lastFileName; // 240 + std::uint16_t lastFileNameLength; // 248 + std::uint16_t maxFileNameLength; // 24A + std::uint32_t unk24C; // 24C + std::int32_t unk250; // 250 + std::uint32_t pad254; // 254 + std::uint64_t unk258; // 258 + std::uint16_t unk260; // 260 + std::uint16_t unk262; // 262 + std::uint32_t unk264; // 264 + std::uint64_t unk268; // 268 + std::uint32_t unk270; // 270 + std::uint32_t unk274; // 274 + std::uint64_t unk278; // 278 + std::uint64_t unk280; // 280 + std::uint32_t unk288; // 288 + std::uint32_t unk28C; // 28C + std::uint64_t unk290; // 290 + std::uint64_t unk298; // 298 + std::uint32_t unk2A0; // 2A0 + std::uint32_t unk2A4; // 2A4 + std::uint64_t unk2A8; // 2A8 #ifdef SKYRIM_SUPPORT_AE std::uint16_t unk2B0; // 2B0 std::uint16_t unk2B2; // 2B2 diff --git a/include/RE/B/BSSaveDataSystemUtility.h b/include/RE/B/BSSaveDataSystemUtility.h index 78bff50f8..7b0f38d89 100644 --- a/include/RE/B/BSSaveDataSystemUtility.h +++ b/include/RE/B/BSSaveDataSystemUtility.h @@ -1,5 +1,6 @@ #pragma once +#include "RE/B/BSFixedString.h" #include "RE/B/BSString.h" #include "RE/B/BSTEvent.h" @@ -20,57 +21,44 @@ namespace RE inline static constexpr auto RTTI = RTTI_BSSaveDataSystemUtility__Entry; inline static constexpr auto VTABLE = VTABLE_BSSaveDataSystemUtility__Entry; - virtual void Unk_00(void); // 00 + virtual void Read(const char* a_path); // 00 + + enum class SaveType : std::uint32_t + { + kAutosave = 0x0, + kSave = 0x1, + kQuicksave = 0x2, + kCustom = 0x3 + }; // members - std::uint64_t unk008; // 008 - std::uint64_t unk010; // 010 - std::uint64_t unk018; // 018 - std::uint64_t unk020; // 020 - std::uint64_t unk028; // 028 - std::uint64_t unk030; // 030 - std::uint64_t unk038; // 038 - std::uint64_t unk040; // 040 - std::uint64_t unk048; // 048 - std::uint64_t unk050; // 050 - std::uint64_t unk058; // 058 - std::uint64_t unk060; // 060 - std::uint64_t unk068; // 068 - std::uint64_t unk070; // 070 - std::uint64_t unk078; // 078 - std::uint64_t unk080; // 080 - std::uint64_t unk088; // 088 - std::uint64_t unk090; // 090 - std::uint64_t unk098; // 098 - std::uint64_t unk0A0; // 0A0 - std::uint64_t unk0A8; // 0A8 - std::uint64_t unk0B0; // 0B0 - std::uint64_t unk0B8; // 0B8 - std::uint64_t unk0C0; // 0C0 - std::uint64_t unk0C8; // 0C8 - std::uint64_t unk0D0; // 0D0 - std::uint64_t unk0D8; // 0D8 - std::uint64_t unk0E0; // 0E0 - std::uint64_t unk0E8; // 0E8 - std::uint64_t unk0F0; // 0F0 - std::uint64_t unk0F8; // 0F8 - std::uint64_t unk100; // 100 - std::uint64_t unk108; // 108 - std::uint64_t unk110; // 110 - std::uint64_t unk118; // 118 - std::uint64_t unk120; // 120 - std::uint64_t unk128; // 128 - BSString unk130; // 130 - BSString unk140; // 140 - BSString unk150; // 150 - std::uint64_t unk160; // 160 - std::uint64_t unk168; // 168 - std::uint64_t unk170; // 170 - std::uint64_t unk178; // 178 - std::uint64_t unk180; // 180 - std::uint64_t unk188; // 188 - std::uint64_t unk190; // 190 + const char fileName[0x104]; // 008 + std::uint32_t pad0C; // 00C + BSString fileNamePtr; // 110 + std::uint64_t unk120; // 120 + std::uint32_t unk128; // 128 + std::uint32_t pad12C; // 12C + BSString locationName; // 130 + BSString unk140; // 140 + BSString characterName; // 150 + std::uint64_t unk160; // 160 + std::uint32_t unk168; // 168 + std::uint32_t pad16C; // 16C + std::uint64_t unk170; // 170 + std::uint32_t unk178; // 178 + std::uint32_t saveNumber; // 17C + std::uint32_t characterID; // 180 + std::uint32_t unk184; // 184 + bool fileNameValid; // 188 + bool modded; // 189 + std::uint8_t unk18A; // 18A + std::uint8_t pad18B; // 18B + std::uint32_t pad18C; // 18C + BSFixedString saveTypeName; // 190 + stl::enumeration saveType; // 198 + std::uint32_t pad19C; // 19C }; + static_assert(sizeof(Entry) == 0x1A0); virtual ~BSSaveDataSystemUtility(); // 00 @@ -94,14 +82,19 @@ namespace RE virtual void Unk_11(void); // 11 - { return; } // members - std::uint32_t unk060; // 060 - std::uint32_t profileHash; // 064 - std::uint64_t unk068; // 068 - Entry entry; // 070 - std::uint64_t unk208; // 208 - std::uint64_t unk210; // 210 - std::uint64_t unk218; // 218 - std::uint64_t unk220; // 220 + std::uint8_t unk060; // 060 + std::uint8_t pad061; // 061 + std::uint16_t pad062; // 062 + std::uint32_t currentCharacterID; // 064 + std::uint8_t unk068; // 068 + std::uint8_t pad069; // 069 + std::uint16_t pad06A; // 06A + std::uint32_t pad06C; // 06C + Entry entry; // 070 + std::uint32_t unk210; // 210 + std::uint32_t pad214; // 214 + std::uint64_t unk218; // 218 + std::uint64_t unk220; // 220 }; static_assert(sizeof(BSSaveDataSystemUtility) == 0x228); } diff --git a/src/RE/B/BGSSaveLoadManager.cpp b/src/RE/B/BGSSaveLoadManager.cpp index 4855ab964..5c97167e3 100644 --- a/src/RE/B/BGSSaveLoadManager.cpp +++ b/src/RE/B/BGSSaveLoadManager.cpp @@ -8,6 +8,20 @@ namespace RE return *singleton; } + bool BGSSaveLoadFileEntry::PopulateFileEntryData() + { + using func_t = decltype(&BGSSaveLoadFileEntry::PopulateFileEntryData); + REL::Relocation func{ RELOCATION_ID(34627, 35547) }; + return func(this); + } + + void BGSSaveLoadManager::GenerateCharacterID() + { + using func_t = decltype(&BGSSaveLoadManager::GenerateCharacterID); + REL::Relocation func{ RELOCATION_ID(34847, 35757) }; + return func(this); + } + void BGSSaveLoadManager::Save(const char* a_fileName) { Save_Impl(2, 0, a_fileName);