diff --git a/src/App/Stats/StatService.cpp b/src/App/Stats/StatService.cpp index d686345..bbf5848 100644 --- a/src/App/Stats/StatService.cpp +++ b/src/App/Stats/StatService.cpp @@ -46,20 +46,49 @@ void App::StatService::OnInitializeStats(void* aSystem) statRecords->EmplaceBack(); } - statTypeEnum->AddOption(statRecords->size, enumName); + const auto enumValue = statRecords->size; + + statTypeEnum->AddOption(enumValue, enumName); statRecords->PushBack(recordId); if (!s_statTypesModified) { s_statTypesModified = true; - Hook(&OnGetStatFlags); Hook(&OnGetStatRange); + Hook(&OnGetStatFlags); + Hook(&OnCheckStatFlag); + } + + { + const auto record = tweakManager.GetRecord(recordId); + const auto recordSize = record->GetType()->GetSize(); + const auto enumPropAddr = reinterpret_cast(record.instance) + recordSize - 8; + *reinterpret_cast(enumPropAddr) = enumValue; } } } } } +uint64_t* App::StatService::OnGetStatRange(void* aSystem, uint64_t* aRange, uint32_t aStat) +{ + if (aStat != InvalidStat) + { + auto& statParams = Raw::StatsDataSystem::StatParams::Ref(aSystem); + auto& statLock = Raw::StatsDataSystem::StatLock::Ref(aSystem); + + std::shared_lock _(statLock); + if (aStat < statParams.size) + { + *aRange = statParams[aStat].range; + return aRange; + } + } + + *aRange = 0; + return aRange; +} + uint32_t App::StatService::OnGetStatFlags(void* aSystem, uint32_t aStat) { if (aStat != InvalidStat) @@ -77,7 +106,7 @@ uint32_t App::StatService::OnGetStatFlags(void* aSystem, uint32_t aStat) return 0; } -uint64_t* App::StatService::OnGetStatRange(void* aSystem, uint64_t* aRange, uint32_t aStat) +bool App::StatService::OnCheckStatFlag(void* aSystem, uint32_t aStat, uint32_t aFlag) { if (aStat != InvalidStat) { @@ -87,11 +116,9 @@ uint64_t* App::StatService::OnGetStatRange(void* aSystem, uint64_t* aRange, uint std::shared_lock _(statLock); if (aStat < statParams.size) { - *aRange = statParams[aStat].range; - return aRange; + return statParams[aStat].flags & aFlag; } } - *aRange = 0; - return aRange; + return false; } diff --git a/src/App/Stats/StatService.hpp b/src/App/Stats/StatService.hpp index dab70ae..bfd0d9e 100644 --- a/src/App/Stats/StatService.hpp +++ b/src/App/Stats/StatService.hpp @@ -16,7 +16,8 @@ class StatService void OnBootstrap() override; static void OnInitializeStats(void* aSystem); - static uint32_t OnGetStatFlags(void* aSystem, uint32_t aStat); static uint64_t* OnGetStatRange(void* aSystem, uint64_t* aRange, uint32_t aStat); + static uint32_t OnGetStatFlags(void* aSystem, uint32_t aStat); + static bool OnCheckStatFlag(void* aSystem, uint32_t aStat, uint32_t aFlag); }; } diff --git a/src/App/Version.rc b/src/App/Version.rc index 3bc2ba2..27a7bcf 100644 --- a/src/App/Version.rc +++ b/src/App/Version.rc @@ -1,9 +1,9 @@ #define VER_PRODUCTVERSION 1,2,0,0 -#define VER_FILEVERSION 1,2,0,2308042025 +#define VER_FILEVERSION 1,2,0,2308051122 #define VER_PRODUCTNAME_STR "TweakXL\0" #define VER_PRODUCTVERSION_STR "1.2.0\0" -#define VER_FILEVERSION_STR "1.2.0.2308042025\0" +#define VER_FILEVERSION_STR "1.2.0.2308051122\0" 1 VERSIONINFO FILEVERSION VER_FILEVERSION diff --git a/src/Red/Addresses.hpp b/src/Red/Addresses.hpp index 9d22e17..9102653 100644 --- a/src/Red/Addresses.hpp +++ b/src/Red/Addresses.hpp @@ -1,6 +1,6 @@ #pragma once -// Generated by cp77ida.py on 2023-08-04 for Cyberpunk 2077 v.1.63 +// Generated by cp77ida.py on 2023-08-05 for Cyberpunk 2077 v.1.63 // DO NOT MODIFY. USE tools\ida\scan.py TO GENERATE THIS FILE. #include @@ -13,8 +13,9 @@ constexpr uintptr_t Main = 0x1401A0550 - ImageBase; // 40 53 48 81 EC ? ? ? ? FF constexpr uintptr_t StatsDataSystem_InitializeRecords = 0x141A26120 - ImageBase; // 48 89 5C 24 ? 55 56 57 41 54 41 55 41 56 41 57 48 83 EC ? 48 8B F9 E8 ? ? ? ? 48 BA, expected: 1, index: 0 constexpr uintptr_t StatsDataSystem_InitializeParams = 0x141A262C0 - ImageBase; // 48 8B C4 41 54 41 56 48 81 EC ? ? ? ? 8B 91 ? ? ? ? 4C 8D B1 ? ? ? ? 45 33 E4 48 89 58 ? 48 89 78, expected: 1, index: 0 -constexpr uintptr_t StatsDataSystem_GetStatFlags = 0x141A24810 - ImageBase; // 48 89 74 24 ? 57 48 83 EC ? 8B FA 48 8B F1 81 FA ? ? ? ? 73 ? 48 81 C1 ? ? ? ? 48 89 5C 24, expected: 1, index: 0 constexpr uintptr_t StatsDataSystem_GetStatRange = 0x141A24880 - ImageBase; // 48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC ? 41 8B F0 48 8B FA 48 8B E9 41 81 F8 ? ? ? ? 73, expected: 1, index: 0 +constexpr uintptr_t StatsDataSystem_GetStatFlags = 0x141A24810 - ImageBase; // 48 89 74 24 ? 57 48 83 EC ? 8B FA 48 8B F1 81 FA ? ? ? ? 73 ? 48 81 C1 ? ? ? ? 48 89 5C 24, expected: 1, index: 0 +constexpr uintptr_t StatsDataSystem_CheckStatFlag = 0x141A24C10 - ImageBase; // 48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC ? 8B FA 41 8B F0 48 8B E9 81 FA ? ? ? ? 73 ? 48 81 C1, expected: 1, index: 0 constexpr uintptr_t TweakDB_Load = 0x140BE6B50 - ImageBase; // 48 89 5C 24 18 55 57 41 56 48 8B EC 48 83 EC 70 48 8B D9 45 33 F6 48 8D, expected: 1, index: 0 constexpr uintptr_t TweakDB_CreateRecord = 0x140FD4930 - ImageBase; // 48 89 5C 24 08 ? 89 ? 24 18 57 48 83 EC 30 8B C2, expected: 1, index: 0 diff --git a/src/Red/StatsDataSystem.hpp b/src/Red/StatsDataSystem.hpp index 979e200..75f7be3 100644 --- a/src/Red/StatsDataSystem.hpp +++ b/src/Red/StatsDataSystem.hpp @@ -35,11 +35,15 @@ constexpr auto InitializeParams = Core::RawFunc< /* addr = */ Red::Addresses::StatsDataSystem_InitializeParams, /* type = */ void (*)(void* aSystem)>(); +constexpr auto GetStatRange = Core::RawFunc< + /* addr = */ Red::Addresses::StatsDataSystem_GetStatRange, + /* type = */ uint64_t* (*)(void* aSystem, uint64_t*, uint32_t aStat)>(); + constexpr auto GetStatFlags = Core::RawFunc< /* addr = */ Red::Addresses::StatsDataSystem_GetStatFlags, /* type = */ uint32_t (*)(void* aSystem, uint32_t aStat)>(); -constexpr auto GetStatRange = Core::RawFunc< - /* addr = */ Red::Addresses::StatsDataSystem_GetStatRange, - /* type = */ uint64_t* (*)(void* aSystem, uint64_t*, uint32_t aStat)>(); +constexpr auto CheckStatFlag = Core::RawFunc< + /* addr = */ Red::Addresses::StatsDataSystem_CheckStatFlag, + /* type = */ bool (*)(void* aSystem, uint32_t aStat, uint32_t aFlag)>(); } diff --git a/src/Red/TweakDB/Reflection.cpp b/src/Red/TweakDB/Reflection.cpp index 776f008..4176171 100644 --- a/src/Red/TweakDB/Reflection.cpp +++ b/src/Red/TweakDB/Reflection.cpp @@ -98,7 +98,7 @@ Core::SharedPtr Red::TweakDBReflection::CollectRecordInf auto propInfo = Red::MakeInstance(); propInfo->name = Red::CName(propName.c_str()); - propInfo->dataOffset = baseOffset + DataOffsetSize * recordInfo->props.size(); + propInfo->dataOffset = baseOffset + (recordInfo->props.size() * DataOffsetSize); // Case: Foreign Key Array => TweakDBID[] if (!func->returnType) diff --git a/tools/ida/scan.py b/tools/ida/scan.py index 50e11a3..59b8027 100644 --- a/tools/ida/scan.py +++ b/tools/ida/scan.py @@ -25,10 +25,12 @@ def patterns(): pattern="48 89 5C 24 ? 55 56 57 41 54 41 55 41 56 41 57 48 83 EC ? 48 8B F9 E8 ? ? ? ? 48 BA"), Item(name="InitializeParams", pattern="48 8B C4 41 54 41 56 48 81 EC ? ? ? ? 8B 91 ? ? ? ? 4C 8D B1 ? ? ? ? 45 33 E4 48 89 58 ? 48 89 78"), - Item(name="GetStatFlags", - pattern="48 89 74 24 ? 57 48 83 EC ? 8B FA 48 8B F1 81 FA ? ? ? ? 73 ? 48 81 C1 ? ? ? ? 48 89 5C 24"), Item(name="GetStatRange", pattern="48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC ? 41 8B F0 48 8B FA 48 8B E9 41 81 F8 ? ? ? ? 73"), + Item(name="GetStatFlags", + pattern="48 89 74 24 ? 57 48 83 EC ? 8B FA 48 8B F1 81 FA ? ? ? ? 73 ? 48 81 C1 ? ? ? ? 48 89 5C 24"), + Item(name="CheckStatFlag", + pattern="48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC ? 8B FA 41 8B F0 48 8B E9 81 FA ? ? ? ? 73 ? 48 81 C1"), ]), ]), ]