From 1dcd0b884ec31519b11a8b38d78008dcf5d98fc7 Mon Sep 17 00:00:00 2001 From: EricPlayZ Date: Fri, 3 May 2024 22:19:16 +0300 Subject: [PATCH] - Added "Player Immunity" slider (Player) - Fixed issue with Unlimited Immunity not working whenever somebody hits you - Changed version to v1.2.0 (because it's a big update :D) --- EGameTools/EGameTools.vcxproj | 2 + EGameTools/EGameTools.vcxproj.filters | 6 +++ EGameTools/source/changelog.h | 3 +- EGameTools/source/core.cpp | 2 + EGameTools/source/core.h | 4 +- .../game/GamePH/PlayerInfectionModule.cpp | 40 ++++++++++++++++++ .../game/GamePH/PlayerInfectionModule.h | 22 ++++++++++ EGameTools/source/game/GamePH/game_hooks.cpp | 41 +++++++++++++++---- EGameTools/source/menu/misc.cpp | 2 +- EGameTools/source/menu/player.cpp | 28 +++++++++++++ EGameTools/source/menu/player.h | 2 + EGameTools/source/offsets.h | 2 + EGameTools/source/utils/hook.h | 4 +- 13 files changed, 143 insertions(+), 15 deletions(-) create mode 100644 EGameTools/source/game/GamePH/PlayerInfectionModule.cpp create mode 100644 EGameTools/source/game/GamePH/PlayerInfectionModule.h diff --git a/EGameTools/EGameTools.vcxproj b/EGameTools/EGameTools.vcxproj index c76b45c..945cb69 100644 --- a/EGameTools/EGameTools.vcxproj +++ b/EGameTools/EGameTools.vcxproj @@ -43,6 +43,7 @@ + @@ -141,6 +142,7 @@ + diff --git a/EGameTools/EGameTools.vcxproj.filters b/EGameTools/EGameTools.vcxproj.filters index 3f18cca..ab4db9b 100644 --- a/EGameTools/EGameTools.vcxproj.filters +++ b/EGameTools/EGameTools.vcxproj.filters @@ -194,6 +194,9 @@ game\Engine + + game\GamePH + @@ -411,6 +414,9 @@ game\Engine + + game\GamePH + diff --git a/EGameTools/source/changelog.h b/EGameTools/source/changelog.h index 02255a6..7c50afd 100644 --- a/EGameTools/source/changelog.h +++ b/EGameTools/source/changelog.h @@ -50,8 +50,9 @@ Thank you everyone for the support <3)" }, - Fixed really fast player speed when executing a slow motion kill, dodging or ground pounding at 1.00x game speed (will still happen at any other game speed unfortunately) - Added function hooking timeout for easier debugging - Fetch game version using Windows' API instead of using the game's function)" }, - { "v1.1.4", + { "v1.2.0", R"(- Added compatibility with v1.16.1 hotfix update +- Added "Player Immunity" slider (Player) - Added "Unlimited Immunity" (Player) - Added "Increase Data PAKs Limit" (Misc; requires game restart to apply) - you can now add more than 8 data PAKs, e.g. data8.pak, data9.pak, data10.pak, etc, up to 200 PAKs in total - Added "Disable Data PAKs CRC Check" (Misc; requires game restart to apply) - stops the game from detecting data PAKs, which allows you to use data PAK mods in multiplayer as well diff --git a/EGameTools/source/core.cpp b/EGameTools/source/core.cpp index 04901ac..963bc19 100644 --- a/EGameTools/source/core.cpp +++ b/EGameTools/source/core.cpp @@ -3,6 +3,7 @@ #include "core.h" #include "game\GamePH\LevelDI.h" #include "game\GamePH\PlayerHealthModule.h" +#include "game\GamePH\PlayerInfectionModule.h" #include "game\GamePH\PlayerVariables.h" #include "game\GamePH\gameph_misc.h" #include "menu\menu.h" @@ -169,6 +170,7 @@ namespace Core { menuTab.second->Update(); GamePH::PlayerHealthModule::UpdateClassAddr(); + GamePH::PlayerInfectionModule::UpdateClassAddr(); } /*static bool WriteMiniDump(PEXCEPTION_POINTERS pExceptionPointers) { HANDLE hFile = CreateFileA("EGameTools-dump.dmp", GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr); diff --git a/EGameTools/source/core.h b/EGameTools/source/core.h index b5df627..6481ac2 100644 --- a/EGameTools/source/core.h +++ b/EGameTools/source/core.h @@ -16,8 +16,8 @@ #define VK_MWHEELUP 0x101 #endif -constexpr const char* MOD_VERSION_STR = "v1.1.4"; -constexpr DWORD MOD_VERSION = 10104; +constexpr const char* MOD_VERSION_STR = "v1.2.0"; +constexpr DWORD MOD_VERSION = 10200; constexpr DWORD GAME_VER_COMPAT = 11601; struct Key { diff --git a/EGameTools/source/game/GamePH/PlayerInfectionModule.cpp b/EGameTools/source/game/GamePH/PlayerInfectionModule.cpp new file mode 100644 index 0000000..0d2799a --- /dev/null +++ b/EGameTools/source/game/GamePH/PlayerInfectionModule.cpp @@ -0,0 +1,40 @@ +#include +#include "LevelDI.h" +#include "PlayerInfectionModule.h" + +namespace GamePH { + static PlayerInfectionModule* pPlayerInfectionModule = nullptr; + std::vector PlayerInfectionModule::playerInfectionModulePtrList{}; + + PlayerInfectionModule* PlayerInfectionModule::Get() { + __try { + if (!pPlayerInfectionModule) + return nullptr; + if (!*reinterpret_cast(pPlayerInfectionModule)) + return nullptr; + + return pPlayerInfectionModule; + } __except (EXCEPTION_EXECUTE_HANDLER) { + pPlayerInfectionModule = nullptr; + playerInfectionModulePtrList.clear(); + return nullptr; + } + } + void PlayerInfectionModule::Set(LPVOID instance) { pPlayerInfectionModule = reinterpret_cast(instance); } + + void PlayerInfectionModule::UpdateClassAddr() { + LevelDI* iLevel = LevelDI::Get(); + if (!iLevel) + return; + if (PlayerInfectionModule::Get() && PlayerInfectionModule::Get()->pPlayerDI_PH == iLevel->pPlayerDI_PH) + return; + + for (auto& pPlayerInfectionModule : PlayerInfectionModule::playerInfectionModulePtrList) { + if (pPlayerInfectionModule->pPlayerDI_PH == iLevel->pPlayerDI_PH) { + PlayerInfectionModule::Set(pPlayerInfectionModule); + PlayerInfectionModule::playerInfectionModulePtrList.clear(); + PlayerInfectionModule::playerInfectionModulePtrList.emplace_back(pPlayerInfectionModule); + } + } + } +} \ No newline at end of file diff --git a/EGameTools/source/game/GamePH/PlayerInfectionModule.h b/EGameTools/source/game/GamePH/PlayerInfectionModule.h new file mode 100644 index 0000000..a6c40b1 --- /dev/null +++ b/EGameTools/source/game/GamePH/PlayerInfectionModule.h @@ -0,0 +1,22 @@ +#pragma once +#include "..\buffer.h" + +namespace GamePH { + class PlayerDI_PH; + + class PlayerInfectionModule { + public: + union { + buffer<0x8, PlayerDI_PH*> pPlayerDI_PH; + buffer<0x20, float> maxImmunity; + buffer<0x2C, float> immunity; + }; + + static std::vector playerInfectionModulePtrList; + + static PlayerInfectionModule* Get(); + static void Set(LPVOID instance); + + static void UpdateClassAddr(); + }; +} \ No newline at end of file diff --git a/EGameTools/source/game/GamePH/game_hooks.cpp b/EGameTools/source/game/GamePH/game_hooks.cpp index 0ed2deb..c555a93 100644 --- a/EGameTools/source/game/GamePH/game_hooks.cpp +++ b/EGameTools/source/game/GamePH/game_hooks.cpp @@ -9,6 +9,7 @@ #include "GameDI_PH2.h" #include "LevelDI.h" #include "PlayerHealthModule.h" +#include "PlayerInfectionModule.h" #include "gen_TPPModel.h" namespace GamePH { @@ -24,6 +25,17 @@ namespace GamePH { } #pragma endregion +#pragma region CreatePlayerInfectionModule + static DWORD64 detourCreatePlayerInfectionModule(DWORD64 playerInfectionModule); + static Utils::Hook::MHook CreatePlayerInfectionModuleHook{ "CreatePlayerInfectionModule", &Offsets::Get_CreatePlayerInfectionModule, &detourCreatePlayerInfectionModule }; + + static DWORD64 detourCreatePlayerInfectionModule(DWORD64 playerInfectionModule) { + PlayerInfectionModule::playerInfectionModulePtrList.emplace_back(reinterpret_cast(playerInfectionModule)); + + return CreatePlayerInfectionModuleHook.pOriginal(playerInfectionModule); + } +#pragma endregion + #pragma region LifeSetHealth static void detourLifeSetHealth(float* pLifeHealth, float health); static Utils::Hook::MHook LifeSetHealthHook{ "LifeSetHealth", &Offsets::Get_LifeSetHealth, &detourLifeSetHealth }; @@ -219,15 +231,15 @@ namespace GamePH { static float detourCompareAndUpdateFloat(float result, float a1, float a2) { if (funcHandlePlayerImmunityRunning) { - static float immunityTimerBeforeFreeze = -1.0f; + LevelDI* iLevel = LevelDI::Get(); + if (!iLevel || !iLevel->IsLoaded()) + return CompareAndUpdateFloatHook.pOriginal(result, a1, a2); + GamePH::PlayerInfectionModule* playerInfectionModule = GamePH::PlayerInfectionModule::Get(); + if (!playerInfectionModule) + return CompareAndUpdateFloatHook.pOriginal(result, a1, a2); - if (Menu::Player::unlimitedImmunity.GetValue()) { - if (Utils::Values::are_samef(immunityTimerBeforeFreeze, -1.0f)) - immunityTimerBeforeFreeze = result > a2 ? a2 : result; - return immunityTimerBeforeFreeze; - } - - immunityTimerBeforeFreeze = -1.0f; + if (Menu::Player::unlimitedImmunity.GetValue()) + return playerInfectionModule->immunity; } return CompareAndUpdateFloatHook.pOriginal(result, a1, a2); @@ -245,9 +257,20 @@ namespace GamePH { } #pragma endregion +#pragma region HandlePlayerImmunity2 + static void detourHandlePlayerImmunity2(LPVOID pInstance, DWORD64 a2, bool a3); + static Utils::Hook::MHook HandlePlayerImmunity2Hook{ "HandlePlayerImmunity2", &Offsets::Get_HandlePlayerImmunity2, &detourHandlePlayerImmunity2 }; + + static void detourHandlePlayerImmunity2(LPVOID pInstance, DWORD64 a2, bool a3) { + funcHandlePlayerImmunityRunning = true; + HandlePlayerImmunity2Hook.pOriginal(pInstance, a2, a3); + funcHandlePlayerImmunityRunning = false; + } +#pragma endregion + #pragma region ByteHooks static unsigned char SaveGameCRCBoolCheckBytes[3] = { 0xB3, 0x01, 0x90 }; // mov bl, 01 - Utils::Hook::BytesHook SaveGameCRCBoolCheckHook{ "SaveGameCRCBoolCheck", &Offsets::Get_SaveGameCRCBoolCheck, SaveGameCRCBoolCheckBytes, sizeof(SaveGameCRCBoolCheckBytes), &Menu::Misc::disableSavegameCRCCheck }; // and bl, dil + Utils::Hook::ByteHook SaveGameCRCBoolCheckHook{ "SaveGameCRCBoolCheck", &Offsets::Get_SaveGameCRCBoolCheck, SaveGameCRCBoolCheckBytes, sizeof(SaveGameCRCBoolCheckBytes), &Menu::Misc::disableSavegameCRCCheck }; // and bl, dil #pragma endregion } } \ No newline at end of file diff --git a/EGameTools/source/menu/misc.cpp b/EGameTools/source/menu/misc.cpp index c71fa26..0f8f096 100644 --- a/EGameTools/source/menu/misc.cpp +++ b/EGameTools/source/menu/misc.cpp @@ -4,7 +4,7 @@ #include "misc.h" namespace GamePH::Hooks { - extern Utils::Hook::BytesHook SaveGameCRCBoolCheckHook; + extern Utils::Hook::ByteHook SaveGameCRCBoolCheckHook; } namespace Menu { diff --git a/EGameTools/source/menu/player.cpp b/EGameTools/source/menu/player.cpp index 2f618d3..0e59454 100644 --- a/EGameTools/source/menu/player.cpp +++ b/EGameTools/source/menu/player.cpp @@ -4,6 +4,7 @@ #include "..\game\GamePH\FreeCamera.h" #include "..\game\GamePH\LevelDI.h" #include "..\game\GamePH\PlayerHealthModule.h" +#include "..\game\GamePH\PlayerInfectionModule.h" #include "..\game\GamePH\PlayerVariables.h" #include "..\game\GamePH\gameph_misc.h" #include "camera.h" @@ -6432,6 +6433,8 @@ namespace Menu { float playerHealth = 80.0f; float playerMaxHealth = 80.0f; + float playerImmunity = 80.0f; + float playerMaxImmunity = 80.0f; KeyBindOption godMode{ VK_F6 }; KeyBindOption unlimitedImmunity{ VK_NONE }; KeyBindOption freezePlayer{ VK_F7 }; @@ -6552,6 +6555,21 @@ namespace Menu { playerHealth = playerHealthModule->health; } + static void PlayerImmunityUpdate() { + GamePH::PlayerInfectionModule* playerInfectionModule = GamePH::PlayerInfectionModule::Get(); + if (!playerInfectionModule) + return; + + playerMaxImmunity = playerInfectionModule->maxImmunity * 100.0f; + + if (menuToggle.GetValue()) + return; + GamePH::LevelDI* iLevel = GamePH::LevelDI::Get(); + if (!iLevel || !iLevel->IsLoaded()) + return; + + playerImmunity = playerInfectionModule->immunity * 100.0f; + } static void UpdatePlayerVars() { if (!GamePH::PlayerVariables::gotPlayerVars) return; @@ -6571,6 +6589,7 @@ namespace Menu { PlayerPositionUpdate(); PlayerVarsUpdate(); PlayerHealthUpdate(); + PlayerImmunityUpdate(); UpdateDisabledOptions(); UpdatePlayerVars(); } @@ -6867,6 +6886,15 @@ namespace Menu { playerHealth = playerHealthModule->health; ImGui::EndDisabled(); } + GamePH::PlayerInfectionModule* playerInfectionModule = GamePH::PlayerInfectionModule::Get(); + ImGui::BeginDisabled(!playerInfectionModule); + { + if (ImGui::SliderFloat("Player Immunity", &playerImmunity, 0.0f, playerMaxImmunity, "%.2f") && playerInfectionModule) + playerInfectionModule->immunity = playerImmunity / 100.0f; + else if (playerInfectionModule) + playerImmunity = playerInfectionModule->immunity * 100.0f; + ImGui::EndDisabled(); + } ImGui::CheckboxHotkey("God Mode", &godMode); ImGui::SameLine(); ImGui::CheckboxHotkey("Unlimited Immunity", &unlimitedImmunity); diff --git a/EGameTools/source/menu/player.h b/EGameTools/source/menu/player.h index 25cce50..bb5a52c 100644 --- a/EGameTools/source/menu/player.h +++ b/EGameTools/source/menu/player.h @@ -6,6 +6,8 @@ namespace Menu { namespace Player { extern float playerHealth; extern float playerMaxHealth; + extern float playerImmunity; + extern float playerMaxImmunity; extern KeyBindOption godMode; extern KeyBindOption unlimitedImmunity; extern KeyBindOption freezePlayer; diff --git a/EGameTools/source/offsets.h b/EGameTools/source/offsets.h index a86a4ec..0bddeed 100644 --- a/EGameTools/source/offsets.h +++ b/EGameTools/source/offsets.h @@ -56,6 +56,7 @@ struct Offsets { AddOffset(AllowCameraMovement, "gamedll_ph_x64_rwdi.dll", "89 91 ?? ?? ?? ?? C3 CC CC CC CC CC CC CC CC CC 48 8B C4 55 56", Utils::SigScan::PatternType::Address, LPVOID) //AddOffset(GetViewCamera, "engine_x64_rwdi.dll", "E8 [?? ?? ?? ?? 48 85 C0 74 28 48 8B C8", PatternType::RelativePointer, LPVOID) AddOffset(CreatePlayerHealthModule, "gamedll_ph_x64_rwdi.dll", "48 89 5C 24 ?? 55 56 57 41 54 41 55 41 56 41 57 48 8D 6C 24 ?? 48 81 EC ?? ?? ?? ?? 4C 8B F1 E8 ?? ?? ?? ?? 48 8D 05", Utils::SigScan::PatternType::Address, LPVOID) + AddOffset(CreatePlayerInfectionModule, "gamedll_ph_x64_rwdi.dll", "48 89 5C 24 ?? 57 48 83 EC ?? 48 8B D9 E8 ?? ?? ?? ?? 33 FF 66 C7 44 24 ?? ?? ?? 48 8D 05 ?? ?? ?? ?? 48 89 03", Utils::SigScan::PatternType::Address, LPVOID) AddOffset(LifeSetHealth, "gamedll_ph_x64_rwdi.dll", "F3 0F 11 49 ?? F3 0F 11 49 ?? F3 0F 11 49 ?? C3", Utils::SigScan::PatternType::Address, LPVOID) AddOffset(TogglePhotoMode1, "gamedll_ph_x64_rwdi.dll", "48 83 EC ?? 38 91 ?? ?? ?? ?? 0F 84", Utils::SigScan::PatternType::Address, LPVOID) AddOffset(TogglePhotoMode2, "gamedll_ph_x64_rwdi.dll", "48 89 5C 24 ?? 57 48 83 EC ?? 48 8B D9 41 0F B6 F8 48 8B 0D", Utils::SigScan::PatternType::Address, LPVOID) @@ -71,6 +72,7 @@ struct Offsets { AddOffset(PlayerHealthModuleKillPlayer, "gamedll_ph_x64_rwdi.dll", "40 53 48 83 EC ?? 48 8B 01 48 8B D9 FF 90 ?? ?? ?? ?? 84 C0 74 ?? 48 8B 4B ?? 48 81 C1 ?? ?? ?? ?? 48 8B 01 FF 50", Utils::SigScan::PatternType::Address, LPVOID) AddOffset(CompareAndUpdateFloat, "gamedll_ph_x64_rwdi.dll", "0F 2F C1 73 ?? 0F 28 C1 C3", Utils::SigScan::PatternType::Address, LPVOID) AddOffset(HandlePlayerImmunity, "gamedll_ph_x64_rwdi.dll", "48 8B C4 53 56 57 41 56 41 57", Utils::SigScan::PatternType::Address, LPVOID) + AddOffset(HandlePlayerImmunity2, "gamedll_ph_x64_rwdi.dll", "40 55 56 41 56 41 57 48 8D 6C 24 ?? 48 81 EC ?? ?? ?? ?? 48 8B F1 45 0F B6 F0", Utils::SigScan::PatternType::Address, LPVOID) //AddOffset(HandleFallHeight, "gamedll_ph_x64_rwdi.dll", "48 89 5C 24 ?? 57 48 83 EC ?? 0F B6 FA 48 8B D9 0F B6 91", Utils::SigScan::PatternType::Address, LPVOID) //AddOffset(HandlePlayerFall, "gamedll_ph_x64_rwdi.dll", "48 89 5C 24 ?? 57 48 83 EC ?? 0F 29 74 24 ?? 48 8B FA 0F 28 F2", Utils::SigScan::PatternType::Address, LPVOID) //AddOffset(GetTimeWeatherSystem, "engine_x64_rwdi.dll", "E8 [?? ?? ?? ?? 33 D2 48 8B C8 E8 ?? ?? ?? ?? 49 8D 4F 38", PatternType::RelativePointer, LPVOID) diff --git a/EGameTools/source/utils/hook.h b/EGameTools/source/utils/hook.h index 0746532..6816a97 100644 --- a/EGameTools/source/utils/hook.h +++ b/EGameTools/source/utils/hook.h @@ -33,9 +33,9 @@ namespace Utils { const std::string_view name; }; template - class BytesHook : HookBase { + class ByteHook : HookBase { public: - BytesHook(const std::string_view& name, GetTargetOffsetRetType(*pGetOffsetFunc)(), unsigned char* patchBytes, size_t bytesAmount, Option* optionRef = nullptr) : HookBase(name), pGetOffsetFunc(pGetOffsetFunc), patchBytes(patchBytes), bytesAmount(bytesAmount), optionRef(optionRef) {} + ByteHook(const std::string_view& name, GetTargetOffsetRetType(*pGetOffsetFunc)(), unsigned char* patchBytes, size_t bytesAmount, Option* optionRef = nullptr) : HookBase(name), pGetOffsetFunc(pGetOffsetFunc), patchBytes(patchBytes), bytesAmount(bytesAmount), optionRef(optionRef) {} bool HookLoop() override { if (hooked || (optionRef && !optionRef->GetValue()))