removed PlayerObjProperties class (it is the same as PlayerDI_PH), better multi-threading safety

This commit is contained in:
EricPlayZ
2024-11-03 19:27:40 +02:00
parent 8b4e3c4b75
commit c163301344
13 changed files with 81 additions and 74 deletions

View File

@ -45,7 +45,6 @@
<ClCompile Include="source\game\GamePH\PlayerDI_PH.cpp" />
<ClCompile Include="source\game\GamePH\PlayerHealthModule.cpp" />
<ClCompile Include="source\game\GamePH\PlayerInfectionModule.cpp" />
<ClCompile Include="source\game\GamePH\PlayerObjProperties.cpp" />
<ClCompile Include="source\game\GamePH\PlayerState.cpp" />
<ClCompile Include="source\game\GamePH\PlayerVariables.cpp" />
<ClCompile Include="source\game\GamePH\SessionCooperativeDI.cpp" />
@ -158,7 +157,6 @@
<ClInclude Include="source\game\GamePH\PlayerDI_PH.h" />
<ClInclude Include="source\game\GamePH\PlayerHealthModule.h" />
<ClInclude Include="source\game\GamePH\PlayerInfectionModule.h" />
<ClInclude Include="source\game\GamePH\PlayerObjProperties.h" />
<ClInclude Include="source\game\GamePH\PlayerState.h" />
<ClInclude Include="source\game\GamePH\PlayerVariables.h" />
<ClInclude Include="source\game\GamePH\SessionCooperativeDI.h" />

View File

@ -38,6 +38,7 @@
#include <unordered_map>
#include <unordered_set>
#include <semaphore>
#include <atomic>
#include <dxgi.h>
#include <dxgi1_4.h>

View File

@ -38,7 +38,9 @@ namespace Core {
#pragma endregion
// Core
bool exiting = false;
std::atomic<bool> exiting = false;
static std::vector<std::thread> threads{};
static HANDLE keepAliveEvent{};
int rendererAPI = 0;
DWORD gameVer = 0;
@ -232,36 +234,52 @@ namespace Core {
spdlog::warn("Initializing config");
Config::InitConfig();
std::thread(Config::ConfigLoop).detach();
threads.emplace_back(Config::ConfigLoop);
CreateSymlinkForLoadingFiles();
for (auto& hook : *Utils::Hook::HookBase::GetInstances()) {
std::thread([&hook]() {
threads.emplace_back([&hook]() {
maxHookThreads.acquire();
spdlog::warn("Hooking \"{}\"", hook->name.data());
if (hook->HookLoop())
if (hook->isHooking) {
spdlog::warn("Hooking \"{}\"", hook->name.data());
while (hook->isHooking)
Sleep(10);
if (hook->isHooked)
spdlog::info("Hooked \"{}\"!", hook->name.data());
} else if (hook->isHooked)
spdlog::info("Hooked \"{}\"!", hook->name.data());
else {
spdlog::warn("Hooking \"{}\"", hook->name.data());
if (hook->HookLoop())
spdlog::info("Hooked \"{}\"!", hook->name.data());
}
maxHookThreads.release();
}).detach();
}
spdlog::warn("Sorting Player Variables");
std::thread([]() {
threads.emplace_back([]() {
GamePH::PlayerVariables::SortPlayerVars();
spdlog::info("Player Variables sorted");
}).detach();
spdlog::warn("Hooking DX11/DX12 renderer");
std::thread([]() {
threads.emplace_back([]() {
LoopHookRenderer();
spdlog::info("Hooked \"DX11/DX12 renderer\"!");
}).detach();
const HANDLE proc = GetCurrentProcess();
WaitForSingleObject(proc, INFINITE);
keepAliveEvent = CreateEventA(nullptr, TRUE, FALSE, nullptr);
WaitForSingleObject(keepAliveEvent, INFINITE);
for (auto& thread : threads) {
if (thread.joinable())
thread.join();
}
return TRUE;
}
@ -278,5 +296,7 @@ namespace Core {
MH_DisableHook(MH_ALL_HOOKS);
MH_Uninitialize();
spdlog::info("Unhooked everything");
SetEvent(keepAliveEvent);
}
}

View File

@ -3,6 +3,7 @@
#include <imgui.h>
#include <ranges>
#include <set>
#include <atomic>
#include "..\utils\values.h"
#ifndef VK_NONE
@ -225,7 +226,7 @@ private:
};
namespace Core {
extern bool exiting;
extern std::atomic<bool> exiting;
extern int rendererAPI;
extern DWORD gameVer;

View File

@ -1,15 +1,15 @@
#include <pch.h>
#include "..\GamePH\PlayerObjProperties.h"
#include "..\GamePH\PlayerDI_PH.h"
#include "CoPhysicsProperty.h"
namespace Engine {
CoPhysicsProperty* CoPhysicsProperty::Get() {
__try {
GamePH::PlayerObjProperties* pPlayerObjProperties = GamePH::PlayerObjProperties::Get();
if (!pPlayerObjProperties)
GamePH::PlayerDI_PH* pPlayerDI_PH = GamePH::PlayerDI_PH::Get();
if (!pPlayerDI_PH)
return nullptr;
CoPhysicsProperty* ptr = pPlayerObjProperties->pCoPhysicsProperty;
CoPhysicsProperty* ptr = pPlayerDI_PH->pCoPhysicsProperty;
if (!Utils::Memory::IsValidPtrMod(ptr, "engine_x64_rwdi.dll"))
return nullptr;

View File

@ -2,7 +2,7 @@
#include "..\Engine\CLevel.h"
#include "..\offsets.h"
#include "LevelDI.h"
#include "PlayerObjProperties.h"
#include "PlayerDI_PH.h"
namespace GamePH {
bool LevelDI::IsLoading() {
@ -20,7 +20,7 @@ namespace GamePH {
static Utils::Time::Timer loadTimer{ 7500 };
static bool isStillLoading = false;
if (IsLoading() || !GamePH::PlayerObjProperties::Get()) {
if (IsLoading() || !GamePH::PlayerDI_PH::Get()) {
isStillLoading = true;
return false;
}

View File

@ -3,10 +3,15 @@
#include "InventoryItem.h"
#include "InventoryContainerDI.h"
namespace Engine {
class CoPhysicsProperty;
}
namespace GamePH {
class PlayerDI_PH {
public:
union {
buffer<0xF0, Engine::CoPhysicsProperty*> pCoPhysicsProperty;
buffer<0x35E9, bool> enableTPPModel1;
buffer<0x35EA, bool> enableTPPModel2;
};

View File

@ -1,20 +0,0 @@
#include <pch.h>
#include "..\offsets.h"
#include "PlayerObjProperties.h"
namespace GamePH {
PlayerObjProperties* PlayerObjProperties::Get() {
__try {
if (!Offsets::Get_g_PlayerObjProperties())
return nullptr;
PlayerObjProperties* ptr = *reinterpret_cast<PlayerObjProperties**>(Offsets::Get_g_PlayerObjProperties());
if (!Utils::Memory::IsValidPtrMod(ptr, "gamedll_ph_x64_rwdi.dll"))
return nullptr;
return ptr;
} __except (EXCEPTION_EXECUTE_HANDLER) {
return nullptr;
}
}
}

View File

@ -1,19 +0,0 @@
#pragma once
#include "..\buffer.h"
namespace Engine {
class CoPhysicsProperty;
}
namespace GamePH {
class PlayerObjProperties {
public:
union {
buffer<0xF0, Engine::CoPhysicsProperty*> pCoPhysicsProperty;
//buffer<0x2E80, bool> isOutOfBounds;
//buffer<0x2E84, float> outOfBoundsTimer;
};
static PlayerObjProperties* Get();
};
}

View File

@ -6,7 +6,7 @@
#include "..\game\GamePH\GameDI_PH.h"
#include "..\game\GamePH\LevelDI.h"
#include "..\game\GamePH\PlayerVariables.h"
#include "..\game\GamePH\PlayerObjProperties.h"
#include "..\game\GamePH\PlayerDI_PH.h"
#include "..\game\GamePH\gameph_misc.h"
#include "..\offsets.h"
#include "camera.h"
@ -149,8 +149,8 @@ namespace Menu {
if (!iLevel || !iLevel->IsLoaded())
return;
GamePH::PlayerObjProperties* playerObjProperties = GamePH::PlayerObjProperties::Get();
if (playerObjProperties) {
GamePH::PlayerDI_PH* pPlayerDI_PH = GamePH::PlayerDI_PH::Get();
if (pPlayerDI_PH) {
if (Menu::Camera::freeCam.GetValue() && !iLevel->IsTimerFrozen())
GamePH::ShowTPPModel(true);
else if (Menu::Camera::freeCam.GetValue() && iLevel->IsTimerFrozen() && !photoMode.GetValue())

View File

@ -10,7 +10,6 @@
#include "..\game\GamePH\LogicalPlayer.h"
#include "..\game\GamePH\PlayerDI_PH.h"
#include "..\game\GamePH\PlayerHealthModule.h"
#include "..\game\GamePH\PlayerObjProperties.h"
#include "..\game\GamePH\PlayerState.h"
#include "..\game\GamePH\PlayerVariables.h"
#include "..\game\GamePH\SessionCooperativeDI.h"
@ -41,7 +40,6 @@ namespace Menu {
{ "LogicalPlayer", reinterpret_cast<LPVOID(*)()>(&GamePH::LogicalPlayer::Get) },
{ "PlayerDI_PH", reinterpret_cast<LPVOID(*)()>(&GamePH::PlayerDI_PH::Get) },
{ "PlayerHealthModule", reinterpret_cast<LPVOID(*)()>(&GamePH::PlayerHealthModule::Get) },
{ "PlayerObjProperties", reinterpret_cast<LPVOID(*)()>(&GamePH::PlayerObjProperties::Get) },
{ "PlayerState", reinterpret_cast<LPVOID(*)()>(&GamePH::PlayerState::Get) },
{ "PlayerVariables", reinterpret_cast<LPVOID(*)()>(&GamePH::PlayerVariables::Get) },
{ "SessionCooperativeDI", reinterpret_cast<LPVOID(*)()>(&GamePH::SessionCooperativeDI::Get) },

View File

@ -71,7 +71,7 @@ struct Offsets {
AddStaticOffset(allowVelocityMod_offset, 0x5C)
AddStaticOffset(disableHeadCorrection_offset, 0x108)
AddOffset(CLobbySteam, "engine_x64_rwdi.dll", "48 8B 05 [?? ?? ?? ?? 48 85 C0 74 ?? 48 83 C0", Utils::SigScan::PatternType::RelativePointer, LPVOID)
AddOffset(g_PlayerObjProperties, "gamedll_ph_x64_rwdi.dll", "48 89 0D [?? ?? ?? ?? E8 ?? ?? ?? ?? 48 85 C0", Utils::SigScan::PatternType::RelativePointer, LPVOID)
//AddOffset(g_PlayerDI_PH, "gamedll_ph_x64_rwdi.dll", "48 89 0D [?? ?? ?? ?? E8 ?? ?? ?? ?? 48 85 C0", Utils::SigScan::PatternType::RelativePointer, LPVOID) // also PlayerObjProperties
AddOffset(g_DayNightCycle, "gamedll_ph_x64_rwdi.dll", "48 8B 0D [?? ?? ?? ?? 48 85 C9 74 ?? E8 ?? ?? ?? ?? 84 C0 74 ?? B0 ?? 48 83 C4 ?? C3 32 C0", Utils::SigScan::PatternType::RelativePointer, LPVOID)
//AddOffset(g_CameraFPPDI, "gamedll_ph_x64_rwdi.dll", "48 89 05 [?? ?? ?? ?? 40 84 FF", PatternType::RelativePointer, DWORD64*)
AddOffset(g_FreeCamera, "gamedll_ph_x64_rwdi.dll", "48 89 05 [?? ?? ?? ?? 48 89 4C 24", Utils::SigScan::PatternType::RelativePointer, DWORD64*)

View File

@ -1,6 +1,7 @@
#pragma once
#include <functional>
#include <set>
#include <atomic>
#include "..\MinHook\MinHook.h"
namespace Utils {
@ -30,7 +31,9 @@ namespace Utils {
virtual bool HookLoop() { return false; };
const std::string_view name;
const std::string_view name{};
std::atomic<bool> isHooking = false;
std::atomic<bool> isHooked = false;
};
template <typename GetTargetOffsetRetType>
class ByteHook : HookBase {
@ -38,13 +41,18 @@ namespace Utils {
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()))
if (isHooked || (optionRef && !optionRef->GetValue()))
return true;
if (isHooking)
return true;
isHooking = true;
timeSpentHooking = Utils::Time::Timer(120000);
while (true) {
if (timeSpentHooking.DidTimePass()) {
spdlog::error("Failed hooking \"{}\" after 120 seconds", name);
isHooking = false;
return false;
}
if (!pGetOffsetFunc || !pGetOffsetFunc())
@ -60,7 +68,8 @@ namespace Utils {
}
memcpy_s(pGetOffsetFunc(), bytesAmount, patchBytes, bytesAmount);
VirtualProtect(pGetOffsetFunc(), bytesAmount, originalProtection, &oldProtection);
hooked = true;
isHooked = true;
isHooking = false;
return true;
Sleep(10);
@ -68,7 +77,7 @@ namespace Utils {
}
void Enable() {
if (hooked)
if (isHooked)
return;
DWORD originalProtection = 0;
@ -81,10 +90,10 @@ namespace Utils {
}
memcpy_s(pGetOffsetFunc(), bytesAmount, patchBytes, bytesAmount);
VirtualProtect(pGetOffsetFunc(), bytesAmount, originalProtection, &oldProtection);
hooked = true;
isHooked = true;
}
void Disable() {
if (!hooked)
if (!isHooked)
return;
DWORD originalProtection = 0;
@ -93,11 +102,11 @@ namespace Utils {
VirtualProtect(pGetOffsetFunc(), bytesAmount, PAGE_EXECUTE_READWRITE, &originalProtection);
memcpy_s(pGetOffsetFunc(), bytesAmount, origBytes, bytesAmount);
VirtualProtect(pGetOffsetFunc(), bytesAmount, originalProtection, &oldProtection);
hooked = false;
isHooked = false;
}
void Toggle() {
if (!optionRef) {
hooked ? Disable() : Enable();
isHooked ? Disable() : Enable();
return;
}
@ -111,8 +120,6 @@ namespace Utils {
unsigned char* patchBytes = nullptr;
size_t bytesAmount = 0;
bool hooked = false;
Utils::Time::Timer timeSpentHooking{ 120000 };
};
template <typename GetTargetOffsetRetType, typename OrigType>
@ -123,11 +130,16 @@ namespace Utils {
bool HookLoop() override {
if (pOriginal)
return true;
if (isHooking)
return true;
isHooking = true;
timeSpentHooking = Utils::Time::Timer(120000);
while (true) {
if (timeSpentHooking.DidTimePass()) {
spdlog::error("Failed hooking function \"{}\" after 120 seconds", name);
isHooking = false;
return false;
}
if (!pGetOffsetFunc)
@ -137,6 +149,8 @@ namespace Utils {
pTarget = reinterpret_cast<OrigType>(pGetOffsetFunc());
else if (!pOriginal && MH_CreateHook(pTarget, pDetour, reinterpret_cast<LPVOID*>(&pOriginal)) == MH_OK) {
MH_EnableHook(pTarget);
isHooked = true;
isHooking = false;
return true;
}
@ -160,11 +174,16 @@ namespace Utils {
bool HookLoop() override {
if (pOriginal)
return true;
if (isHooking)
return true;
isHooking = true;
timeSpentHooking = Utils::Time::Timer(120000);
while (true) {
if (timeSpentHooking.DidTimePass()) {
spdlog::error("Failed hooking function \"{}\" after 120 seconds", name);
isHooking = false;
return false;
}
if (!pGetOffsetFunc)
@ -174,7 +193,11 @@ namespace Utils {
pInstance = pGetOffsetFunc();
else if (!pOriginal) {
HookVT(pInstance, pDetour, reinterpret_cast<LPVOID*>(&pOriginal), offset);
return true;
if (pOriginal) {
isHooked = true;
isHooking = false;
return true;
}
}
Sleep(10);