From a496254b9300fb083ae461643a26c88417c1530b Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Sat, 30 Apr 2022 03:30:16 +0200 Subject: [PATCH] Add mutex for CMDLCache methods Als fall back to old GatherProps when at least one model is replaced with mdl/error.rmdl as the new GatherProps function does not support this yet. --- r5dev/core/init.cpp | 1 + r5dev/datacache/mdlcache.cpp | 33 ++++++++++++----- r5dev/datacache/mdlcache.h | 21 ++++++----- r5dev/tier0/threadtools.h | 52 +++++++++++++++++++++++++++ r5dev/tier1/IConVar.cpp | 1 + r5dev/tier1/cvar.cpp | 1 + r5dev/tier1/cvar.h | 1 + r5dev/vproj/clientsdk.vcxproj | 1 + r5dev/vproj/clientsdk.vcxproj.filters | 3 ++ r5dev/vproj/dedicated.vcxproj | 1 + r5dev/vproj/dedicated.vcxproj.filters | 3 ++ r5dev/vproj/gamesdk.vcxproj | 1 + r5dev/vproj/gamesdk.vcxproj.filters | 3 ++ 13 files changed, 102 insertions(+), 20 deletions(-) create mode 100644 r5dev/tier0/threadtools.h diff --git a/r5dev/core/init.cpp b/r5dev/core/init.cpp index f802089a..cc613700 100644 --- a/r5dev/core/init.cpp +++ b/r5dev/core/init.cpp @@ -7,6 +7,7 @@ #include "core/stdafx.h" #include "core/init.h" #include "tier0/jobthread.h" +#include "tier0/threadtools.h" #include "tier0/tslist.h" #include "tier0/fasttimer.h" #include "tier0/cpu.h" diff --git a/r5dev/datacache/mdlcache.cpp b/r5dev/datacache/mdlcache.cpp index 22ddcbb6..4f1aa034 100644 --- a/r5dev/datacache/mdlcache.cpp +++ b/r5dev/datacache/mdlcache.cpp @@ -6,6 +6,8 @@ //=====================================================================================// #include "core/stdafx.h" +#include "tier0/threadtools.h" +#include "tier1/cvar.h" #include "datacache/mdlcache.h" #include "datacache/imdlcache.h" #include "engine/sys_utils.h" @@ -87,9 +89,22 @@ studiohdr_t* CMDLCache::FindMDL(CMDLCache* pMDLCache, MDLHandle_t handle, void* // *a2 - // *a3 - //----------------------------------------------------------------------------- -void CMDLCache::FindCachedMDL(CMDLCache* pMDLCache, void* a2, void* a3) +void CMDLCache::FindCachedMDL(CMDLCache* cache, void* a2, void* a3) { - v_CMDLCache__FindCachedMDL(pMDLCache, a2, a3); + __int64 v6; // rax + + if (a3) + { + CThreadFastMutex::WaitForLock((CThreadFastMutex*)a2 + 128); + *(_QWORD*)((int64_t)a3 + 2176) = *(_QWORD*)((int64_t)a2 + 88); + v6 = *(_QWORD*)((int64_t)a2 + 88); + if (v6) + *(_QWORD*)(v6 + 2168) = (int64_t)a3; + *(_QWORD*)((int64_t)a2 + 88) = (int64_t)a3; + *(_QWORD*)((int64_t)a3 + 2160) = (int64_t)cache; + *(_WORD*)((int64_t)a3 + 2184) = *(_WORD*)((int64_t)a2 + 20); + CThreadFastMutex::ReleaseWaiter((CThreadFastMutex*)a2 + 128); + } } //----------------------------------------------------------------------------- @@ -97,7 +112,7 @@ void CMDLCache::FindCachedMDL(CMDLCache* pMDLCache, void* a2, void* a3) // Input : *this - // handle - // *a3 - -// *a4 +// *a4 - // Output : a pointer to the studiohdr_t object //----------------------------------------------------------------------------- studiohdr_t* CMDLCache::FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, void* a3, void* a4) @@ -113,7 +128,7 @@ studiohdr_t* CMDLCache::FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, vo studiohdr_t* v17; // rdi studiohdr_t** v18; // rax - //CThreadFastMutexSlow::WaitForLock(a3 + 0x80); + CThreadFastMutex::WaitForLock((CThreadFastMutex*)a3 + 0x80); EnterCriticalSection(reinterpret_cast(&*m_MDLMutex)); void* modelCache = cache->m_pModelCacheSection; v8 = (const char*)(*(_QWORD*)((int64)modelCache + 24 * static_cast(handle) + 8)); @@ -152,8 +167,10 @@ studiohdr_t* CMDLCache::FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, vo else Error(eDLL_T::ENGINE, "Model \"%s\" not found and \"%s\" couldn't be loaded.\n", v8, ERROR_MODEL); g_vBadMDLHandles.push_back(handle); + } v17 = g_pMDLFallback->m_pErrorHDR; + old_gather_props->SetValue(true); // mdl/error.rmdl fallback is not supported (yet) in the new GatherProps solution! } } else @@ -161,7 +178,7 @@ studiohdr_t* CMDLCache::FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, vo v_CMDLCache__FindCachedMDL(cache, a3, a4); v17 = **(studiohdr_t***)a3; } - //CThreadFastMutexSlow::ReleaseWaiter(a3 + 128); + CThreadFastMutex::ReleaseWaiter((CThreadFastMutex*)a3 + 128); return v17; } @@ -169,8 +186,6 @@ studiohdr_t* CMDLCache::FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, vo // Purpose: gets the studiohdr from cache pool by handle // Input : *this - // handle - -// *a3 - -// *a4 // Output : a pointer to the studiohdr_t object //----------------------------------------------------------------------------- studiohdr_t* CMDLCache::GetStudioHDR(CMDLCache* pMDLCache, MDLHandle_t handle) @@ -206,8 +221,6 @@ studiohdr_t* CMDLCache::GetStudioHDR(CMDLCache* pMDLCache, MDLHandle_t handle) // Purpose: gets the studio hardware data reference from cache pool by handle // Input : *this - // handle - -// *a3 - -// *a4 // Output : a pointer to the CStudioHWDataRef object //----------------------------------------------------------------------------- CStudioHWDataRef* CMDLCache::GetStudioHardwareRef(CMDLCache* cache, MDLHandle_t handle) @@ -249,6 +262,7 @@ CStudioHWDataRef* CMDLCache::GetStudioHardwareRef(CMDLCache* cache, MDLHandle_t void MDLCache_Attach() { DetourAttach((LPVOID*)&v_CMDLCache__FindMDL, &CMDLCache::FindMDL); + DetourAttach((LPVOID*)&v_CMDLCache__FindCachedMDL, &CMDLCache::FindCachedMDL); DetourAttach((LPVOID*)&v_CMDLCache__FindUncachedMDL, &CMDLCache::FindUncachedMDL); DetourAttach((LPVOID*)&v_CMDLCache__GetStudioHardwareRef, &CMDLCache::GetStudioHardwareRef); DetourAttach((LPVOID*)&v_CMDLCache__GetStudioHDR, &CMDLCache::GetStudioHDR); @@ -257,6 +271,7 @@ void MDLCache_Attach() void MDLCache_Detach() { DetourDetach((LPVOID*)&v_CMDLCache__FindMDL, &CMDLCache::FindMDL); + DetourDetach((LPVOID*)&v_CMDLCache__FindCachedMDL, &CMDLCache::FindCachedMDL); DetourDetach((LPVOID*)&v_CMDLCache__FindUncachedMDL, &CMDLCache::FindUncachedMDL); DetourDetach((LPVOID*)&v_CMDLCache__GetStudioHardwareRef, &CMDLCache::GetStudioHardwareRef); DetourDetach((LPVOID*)&v_CMDLCache__GetStudioHDR, &CMDLCache::GetStudioHDR); diff --git a/r5dev/datacache/mdlcache.h b/r5dev/datacache/mdlcache.h index 5a7c66a9..23895126 100644 --- a/r5dev/datacache/mdlcache.h +++ b/r5dev/datacache/mdlcache.h @@ -53,9 +53,6 @@ public: // TODO.. }; -extern studiohdr_t* pErrorStudioHDR; -extern MDLHandle_t hErrorMDL; - inline CMemory p_CMDLCache__FindMDL; inline auto v_CMDLCache__FindMDL = p_CMDLCache__FindMDL.RCast(); @@ -87,14 +84,16 @@ class HMDLCache : public IDetour { virtual void GetAdr(void) const { - std::cout << "| FUN: CMDLCache::FindMDL : 0x" << std::hex << std::uppercase << p_CMDLCache__FindMDL.GetPtr() << std::setw(nPad) << " |" << std::endl; - std::cout << "| FUN: CMDLCache::FindCachedMDL : 0x" << std::hex << std::uppercase << p_CMDLCache__FindCachedMDL.GetPtr() << std::setw(nPad) << " |" << std::endl; - std::cout << "| FUN: CMDLCache::FindUncachedMDL : 0x" << std::hex << std::uppercase << p_CMDLCache__FindUncachedMDL.GetPtr() << std::setw(nPad) << " |" << std::endl; - std::cout << "| FUN: CMDLCache::GetStudioHdr : 0x" << std::hex << std::uppercase << p_CMDLCache__GetStudioHDR.GetPtr() << std::setw(nPad) << " |" << std::endl; - std::cout << "| VAR: m_MDLMutex : 0x" << std::hex << std::uppercase << m_MDLMutex << std::setw(nPad) << " |" << std::endl; - std::cout << "| VAR: m_MDLLock : 0x" << std::hex << std::uppercase << m_MDLLock << std::setw(nPad) << " |" << std::endl; - std::cout << "| VAR: m_MDLDict : 0x" << std::hex << std::uppercase << m_MDLDict.GetPtr() << std::setw(nPad) << " |" << std::endl; - std::cout << "| VAR: g_MDLCache : 0x" << std::hex << std::uppercase << g_MDLCache << std::setw(0) << " |" << std::endl; + std::cout << "| FUN: CMDLCache::FindMDL : 0x" << std::hex << std::uppercase << p_CMDLCache__FindMDL.GetPtr() << std::setw(nPad) << " |" << std::endl; + std::cout << "| FUN: CMDLCache::FindCachedMDL : 0x" << std::hex << std::uppercase << p_CMDLCache__FindCachedMDL.GetPtr() << std::setw(nPad) << " |" << std::endl; + std::cout << "| FUN: CMDLCache::FindUncachedMDL : 0x" << std::hex << std::uppercase << p_CMDLCache__FindUncachedMDL.GetPtr() << std::setw(nPad) << " |" << std::endl; + std::cout << "| FUN: CMDLCache::GetStudioHDR : 0x" << std::hex << std::uppercase << p_CMDLCache__GetStudioHDR.GetPtr() << std::setw(nPad) << " |" << std::endl; + std::cout << "| FUN: CMDLCache::GetStudioHardwareRef : 0x" << std::hex << std::uppercase << p_CMDLCache__GetStudioHardwareRef.GetPtr() << std::setw(nPad) << " |" << std::endl; + std::cout << "| FUN: CStudioHWDataRef::SetFlags : 0x" << std::hex << std::uppercase << p_CStudioHWDataRef__SetFlags.GetPtr() << std::setw(nPad) << " |" << std::endl; + std::cout << "| VAR: m_MDLMutex : 0x" << std::hex << std::uppercase << m_MDLMutex << std::setw(nPad) << " |" << std::endl; + std::cout << "| VAR: m_MDLLock : 0x" << std::hex << std::uppercase << m_MDLLock << std::setw(nPad) << " |" << std::endl; + std::cout << "| VAR: m_MDLDict : 0x" << std::hex << std::uppercase << m_MDLDict.GetPtr() << std::setw(nPad) << " |" << std::endl; + std::cout << "| VAR: g_MDLCache : 0x" << std::hex << std::uppercase << g_MDLCache << std::setw(0) << " |" << std::endl; std::cout << "+----------------------------------------------------------------+" << std::endl; } virtual void GetFun(void) const diff --git a/r5dev/tier0/threadtools.h b/r5dev/tier0/threadtools.h new file mode 100644 index 00000000..cdf160b2 --- /dev/null +++ b/r5dev/tier0/threadtools.h @@ -0,0 +1,52 @@ +#ifndef THREADTOOLS_H +#define THREADTOOLS_H +//============================================================================= + +inline CMemory p_MutexInternal_WaitForLock; +inline auto v_MutexInternal_WaitForLock = p_MutexInternal_WaitForLock.RCast(); + +inline CMemory p_MutexInternal_ReleaseWaiter; +inline auto v_MutexInternal_ReleaseWaiter = p_MutexInternal_ReleaseWaiter.RCast(); + +/////////////////////////////////////////////////////////////////////////////// +class CThreadFastMutex +{ +public: + static int WaitForLock(CThreadFastMutex* mutex) + { + return v_MutexInternal_WaitForLock(mutex); + } + static int ReleaseWaiter(CThreadFastMutex* mutex) + { + return v_MutexInternal_ReleaseWaiter(mutex); + } +}; + +/////////////////////////////////////////////////////////////////////////////// +class HThreadTools : public IDetour +{ + virtual void GetAdr(void) const + { + std::cout << "| FUN: CThreadFastMutex::WaitForLock : 0x" << std::hex << std::uppercase << p_MutexInternal_WaitForLock.GetPtr() << std::setw(nPad) << " |" << std::endl; + std::cout << "| FUN: CThreadFastMutex::ReleaseWaiter : 0x" << std::hex << std::uppercase << p_MutexInternal_ReleaseWaiter.GetPtr() << std::setw(nPad) << " |" << std::endl; + std::cout << "+----------------------------------------------------------------+" << std::endl; + } + virtual void GetFun(void) const + { + p_MutexInternal_WaitForLock = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x48\x89\x5C\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xEC\x20\x48\x8B\xD9\xFF\x15\x00\x00\x00\x00"), "xxxx?xxxx?xxxxxxxxxx????"); + p_MutexInternal_ReleaseWaiter = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x40\x53\x48\x83\xEC\x20\x8B\x41\x04\x48\x8B\xD9\x83\xE8\x01"), "xxxxxxxxxxxxxxx"); + + v_MutexInternal_WaitForLock = p_MutexInternal_WaitForLock.RCast(); /*48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC 20 48 8B D9 FF 15 ?? ?? ?? ??*/ + v_MutexInternal_ReleaseWaiter = p_MutexInternal_ReleaseWaiter.RCast(); /*40 53 48 83 EC 20 8B 41 04 48 8B D9 83 E8 01*/ + + } + virtual void GetVar(void) const { } + virtual void GetCon(void) const { } + virtual void Attach(void) const { } + virtual void Detach(void) const { } +}; +/////////////////////////////////////////////////////////////////////////////// + +REGISTER(HThreadTools); + +#endif // THREADTOOLS_H diff --git a/r5dev/tier1/IConVar.cpp b/r5dev/tier1/IConVar.cpp index 933349b5..7cc808b3 100644 --- a/r5dev/tier1/IConVar.cpp +++ b/r5dev/tier1/IConVar.cpp @@ -168,6 +168,7 @@ void ConVar::Init(void) const void ConVar::InitShipped(void) const { single_frame_shutdown_for_reload = g_pCVar->FindVar("single_frame_shutdown_for_reload"); + old_gather_props = g_pCVar->FindVar("old_gather_props"); mp_gamemode = g_pCVar->FindVar("mp_gamemode"); hostname = g_pCVar->FindVar("hostname"); hostport = g_pCVar->FindVar("hostport"); diff --git a/r5dev/tier1/cvar.cpp b/r5dev/tier1/cvar.cpp index d7e888cc..1f487b0a 100644 --- a/r5dev/tier1/cvar.cpp +++ b/r5dev/tier1/cvar.cpp @@ -6,6 +6,7 @@ //----------------------------------------------------------------------------- // ENGINE | ConVar* single_frame_shutdown_for_reload = nullptr; +ConVar* old_gather_props = nullptr; ConVar* hostname = nullptr; ConVar* hostport = nullptr; diff --git a/r5dev/tier1/cvar.h b/r5dev/tier1/cvar.h index 53274a53..36c531e8 100644 --- a/r5dev/tier1/cvar.h +++ b/r5dev/tier1/cvar.h @@ -4,6 +4,7 @@ //------------------------------------------------------------------------- // ENGINE | extern ConVar* single_frame_shutdown_for_reload; +extern ConVar* old_gather_props; extern ConVar* hostname; extern ConVar* hostport; diff --git a/r5dev/vproj/clientsdk.vcxproj b/r5dev/vproj/clientsdk.vcxproj index c848afb8..026171c6 100644 --- a/r5dev/vproj/clientsdk.vcxproj +++ b/r5dev/vproj/clientsdk.vcxproj @@ -357,6 +357,7 @@ + diff --git a/r5dev/vproj/clientsdk.vcxproj.filters b/r5dev/vproj/clientsdk.vcxproj.filters index 73363ac5..eb103946 100644 --- a/r5dev/vproj/clientsdk.vcxproj.filters +++ b/r5dev/vproj/clientsdk.vcxproj.filters @@ -1265,6 +1265,9 @@ sdk\public\include + + sdk\tier0 + diff --git a/r5dev/vproj/dedicated.vcxproj b/r5dev/vproj/dedicated.vcxproj index e45dfa50..33ad96c8 100644 --- a/r5dev/vproj/dedicated.vcxproj +++ b/r5dev/vproj/dedicated.vcxproj @@ -350,6 +350,7 @@ + diff --git a/r5dev/vproj/dedicated.vcxproj.filters b/r5dev/vproj/dedicated.vcxproj.filters index 6529d52b..cb8e575a 100644 --- a/r5dev/vproj/dedicated.vcxproj.filters +++ b/r5dev/vproj/dedicated.vcxproj.filters @@ -897,6 +897,9 @@ sdk\public\include + + sdk\tier0 + diff --git a/r5dev/vproj/gamesdk.vcxproj b/r5dev/vproj/gamesdk.vcxproj index e546184c..b0e8f7f4 100644 --- a/r5dev/vproj/gamesdk.vcxproj +++ b/r5dev/vproj/gamesdk.vcxproj @@ -375,6 +375,7 @@ + diff --git a/r5dev/vproj/gamesdk.vcxproj.filters b/r5dev/vproj/gamesdk.vcxproj.filters index bf4ffa9a..29339a14 100644 --- a/r5dev/vproj/gamesdk.vcxproj.filters +++ b/r5dev/vproj/gamesdk.vcxproj.filters @@ -1325,6 +1325,9 @@ sdk\public\include + + sdk\tier0 +