From 215f205508eb179430d40613ec50e40ada941a64 Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Fri, 6 May 2022 02:32:25 +0200 Subject: [PATCH] Improve CMDLCache::GetMaterialTable() This should also be backwards compatible now --- r5dev/datacache/mdlcache.cpp | 48 ++++++++++++++---------------------- r5dev/datacache/mdlcache.h | 41 +++++++++++++++--------------- r5dev/rtech/rtech_utils.h | 4 +-- r5dev/tier1/utldict.h | 5 ++-- 4 files changed, 45 insertions(+), 53 deletions(-) diff --git a/r5dev/datacache/mdlcache.cpp b/r5dev/datacache/mdlcache.cpp index e0e2607a..4803335f 100644 --- a/r5dev/datacache/mdlcache.cpp +++ b/r5dev/datacache/mdlcache.cpp @@ -31,8 +31,7 @@ studiohdr_t* CMDLCache::FindMDL(CMDLCache* cache, MDLHandle_t handle, void* a3) studiohdr_t* pStudioHdr; // rax EnterCriticalSection(reinterpret_cast(&*m_MDLMutex)); - auto mdlDict = CUtlDict(m_MDLDict.Deref().GetPtr()); - pStudioData = mdlDict.Find(static_cast(handle)); + pStudioData = m_MDLDict->Find(handle); LeaveCriticalSection(reinterpret_cast(&*m_MDLMutex)); if (!g_pMDLFallback->m_hErrorMDL || !g_pMDLFallback->m_hEmptyMDL) @@ -93,13 +92,11 @@ studiohdr_t* CMDLCache::FindMDL(CMDLCache* cache, MDLHandle_t handle, void* a3) //----------------------------------------------------------------------------- void CMDLCache::FindCachedMDL(CMDLCache* cache, studiodata_t* pStudioData, void* a3) { - __int64 v6; // rax - if (a3) { pStudioData->m_Mutex.WaitForLock(); *(_QWORD*)((int64_t)a3 + 0x880) = *(_QWORD*)&pStudioData->pad[0x24]; - v6 = *(_QWORD*)&pStudioData->pad[0x24]; + int64_t v6 = *(_QWORD*)&pStudioData->pad[0x24]; if (v6) *(_QWORD*)(v6 + 0x878) = (int64_t)a3; *(_QWORD*)&pStudioData->pad[0x24] = (int64_t)a3; @@ -212,7 +209,7 @@ studiohdr_t* CMDLCache::FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, st studiohdr_t* CMDLCache::GetStudioHDR(CMDLCache* pMDLCache, MDLHandle_t handle) { __int64 v2; // rbx - __int64 v3; // rbx + studiodata_t* pStudioData; // rbx __int64 v4; // rdx studiohdr_t* result = nullptr; // rax @@ -227,11 +224,11 @@ studiohdr_t* CMDLCache::GetStudioHDR(CMDLCache* pMDLCache, MDLHandle_t handle) v2 = handle; EnterCriticalSection(reinterpret_cast(&*m_MDLMutex)); - v3 = *(_QWORD*)(m_MDLDict.Deref().GetPtr() + 24 * v2 + 16); + pStudioData = m_MDLDict->Find(handle); LeaveCriticalSection(reinterpret_cast(&*m_MDLMutex)); - if (*(_QWORD*)(v3)) + if (*(_QWORD*)(pStudioData)) { - v4 = *(_QWORD*)(*(_QWORD*)(*(_QWORD*)v3 + 8i64) + 24i64); + v4 = *(_QWORD*)(*(_QWORD*)(*(_QWORD*)pStudioData + 8i64) + 24i64); if (v4) result = (studiohdr_t*)(v4 + 16); } @@ -244,14 +241,10 @@ studiohdr_t* CMDLCache::GetStudioHDR(CMDLCache* pMDLCache, MDLHandle_t handle) // handle - // Output : a pointer to the studiohwdata_t object //----------------------------------------------------------------------------- -studiohwdata_t* CMDLCache::GetStudioHardware(CMDLCache* cache, MDLHandle_t handle) +studiohwdata_t* CMDLCache::GetHardwareData(CMDLCache* cache, MDLHandle_t handle) { - studiodata_t* pStudioData; // rdi - void* pAnimData; // rbx - studiohwdata_t* result; // rax - EnterCriticalSection(reinterpret_cast(&*m_MDLMutex)); - pStudioData = *(studiodata_t**)(m_MDLDict.Deref().GetPtr() + 24 * static_cast(handle) + 16); + studiodata_t* pStudioData = m_MDLDict->Find(handle); LeaveCriticalSection(reinterpret_cast(&*m_MDLMutex)); if (!pStudioData) @@ -261,7 +254,7 @@ studiohwdata_t* CMDLCache::GetStudioHardware(CMDLCache* cache, MDLHandle_t handl Error(eDLL_T::ENGINE, "Studio hardware with handle \"%hu\" not found and \"%s\" couldn't be loaded.\n", handle, ERROR_MODEL); return nullptr; } - pStudioData = *(studiodata_t**)(m_MDLDict.Deref().GetPtr() + 24i64 * g_pMDLFallback->m_hErrorMDL + 16); + pStudioData = m_MDLDict->Find(g_pMDLFallback->m_hErrorMDL); } if (pStudioData->m_MDLCache) @@ -269,16 +262,16 @@ studiohwdata_t* CMDLCache::GetStudioHardware(CMDLCache* cache, MDLHandle_t handl if (reinterpret_cast(pStudioData->m_MDLCache) == 0xDEADFEEDDEADFEED) return nullptr; - pAnimData = (void*)*((_QWORD*)pStudioData->m_MDLCache + 1); + void* pAnimData = (void*)*((_QWORD*)pStudioData->m_MDLCache + 1); + AcquireSRWLockExclusive(reinterpret_cast(&*m_MDLLock)); v_CStudioHWDataRef__SetFlags(reinterpret_cast(pAnimData), 1i64); // !!! DECLARED INLINE IN < S3 !!! ReleaseSRWLockExclusive(reinterpret_cast(&*m_MDLLock)); } if ((pStudioData->m_nFlags & STUDIODATA_FLAGS_STUDIOMESH_LOADED)) - result = &pStudioData->m_pHardwareRef->m_HardwareData; + return &pStudioData->m_pHardwareRef->m_HardwareData; else - result = nullptr; - return result; + return nullptr; } //----------------------------------------------------------------------------- @@ -287,16 +280,13 @@ studiohwdata_t* CMDLCache::GetStudioHardware(CMDLCache* cache, MDLHandle_t handl // handle - // Output : a pointer to the CMaterialGlue object //----------------------------------------------------------------------------- -void* CMDLCache::GetStudioMaterialGlue(CMDLCache* cache, MDLHandle_t handle) +void* CMDLCache::GetMaterialTable(CMDLCache* cache, MDLHandle_t handle) { - __int64 v2; // rbx - __int64 v3; // rbx - - v2 = handle; EnterCriticalSection(reinterpret_cast(&*m_MDLMutex)); - v3 = *(_QWORD*)(m_MDLDict.Deref().GetPtr() + 24 * v2 + 16); + studiodata_t* pStudioData = m_MDLDict->Find(handle); LeaveCriticalSection(reinterpret_cast(&*m_MDLMutex)); - return (char*)v3 + 40; + + return &pStudioData->m_pMaterialTable; } void MDLCache_Attach() @@ -304,7 +294,7 @@ 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__GetStudioHardware, &CMDLCache::GetStudioHardware); + DetourAttach((LPVOID*)&v_CMDLCache__GetHardwareData, &CMDLCache::GetHardwareData); DetourAttach((LPVOID*)&v_CMDLCache__GetStudioHDR, &CMDLCache::GetStudioHDR); } @@ -313,6 +303,6 @@ 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__GetStudioHardware, &CMDLCache::GetStudioHardware); + DetourDetach((LPVOID*)&v_CMDLCache__GetHardwareData, &CMDLCache::GetHardwareData); DetourDetach((LPVOID*)&v_CMDLCache__GetStudioHDR, &CMDLCache::GetStudioHDR); } \ No newline at end of file diff --git a/r5dev/datacache/mdlcache.h b/r5dev/datacache/mdlcache.h index 0a7555d8..772c6806 100644 --- a/r5dev/datacache/mdlcache.h +++ b/r5dev/datacache/mdlcache.h @@ -4,6 +4,7 @@ #include "datacache/idatacache.h" #include "datacache/imdlcache.h" #include "tier0/threadtools.h" +#include "tier1/utldict.h" struct RStaticProp_t { @@ -44,7 +45,7 @@ struct studiodata_t #endif // !GAMEDLL_S3 void* Unk3; // ptr to flags and model string. CStudioHWDataRef* m_pHardwareRef; - void* Unk4; // contains material stuff (CMaterialGlue). + void* m_pMaterialTable; // contains a large table of CMaterialGlue objects. int Unk5; char pad[72]; CThreadFastMutex m_Mutex; @@ -61,8 +62,8 @@ public: static void FindCachedMDL(CMDLCache* cache, studiodata_t* pStudioData, void* a3); static studiohdr_t* FindUncachedMDL(CMDLCache* cache, MDLHandle_t handle, studiodata_t* pStudioData, void* a4); static studiohdr_t* GetStudioHDR(CMDLCache* cache, MDLHandle_t handle); - static studiohwdata_t* GetStudioHardware(CMDLCache* cache, MDLHandle_t handle); - static void* GetStudioMaterialGlue(CMDLCache* cache, MDLHandle_t handle); + static studiohwdata_t* GetHardwareData(CMDLCache* cache, MDLHandle_t handle); + static void* GetMaterialTable(CMDLCache* cache, MDLHandle_t handle); CMDLCache* m_pVTable; void* m_pStrCmp; // string compare func; @@ -83,13 +84,13 @@ inline auto v_CMDLCache__FindUncachedMDL = p_CMDLCache__FindUncachedMDL.RCast(); -inline CMemory p_CMDLCache__GetStudioHardware; -inline auto v_CMDLCache__GetStudioHardware = p_CMDLCache__GetStudioHardware.RCast(); +inline CMemory p_CMDLCache__GetHardwareData; +inline auto v_CMDLCache__GetHardwareData = p_CMDLCache__GetHardwareData.RCast(); inline CMemory p_CStudioHWDataRef__SetFlags; // Probably incorrect. inline auto v_CStudioHWDataRef__SetFlags = p_CStudioHWDataRef__SetFlags.RCast(); -inline CMemory m_MDLDict; +inline CUtlDict* m_MDLDict; inline LPCRITICAL_SECTION* m_MDLMutex = nullptr; inline PSRWLOCK* m_MDLLock = nullptr; inline CMDLCache* g_MDLCache = nullptr; @@ -102,16 +103,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 << "| FUN: CMDLCache::GetStudioHardware : 0x" << std::hex << std::uppercase << p_CMDLCache__GetStudioHardware.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 << "| 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::GetHardwareData : 0x" << std::hex << std::uppercase << p_CMDLCache__GetHardwareData.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(0) << " |" << std::endl; + std::cout << "| VAR: m_MDLLock : 0x" << std::hex << std::uppercase << m_MDLLock << std::setw(0) << " |" << std::endl; + std::cout << "| VAR: m_MDLDict : 0x" << std::hex << std::uppercase << m_MDLDict << std::setw(0) << " |" << 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 @@ -128,8 +129,8 @@ class HMDLCache : public IDetour p_CMDLCache__GetStudioHDR = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x40\x53\x48\x83\xEC\x20\x48\x8D\x0D\x00\x00\x00\x00\x0F\xB7\xDA\xFF\x15\x00\x00\x00\x00\x48\x8B\x05\x00\x00\x00\x00\x48\x8D\x14\x5B\x48\x8D\x0D\x00\x00\x00\x00\x48\x8B\x5C\xD0\x00\xFF\x15\x00\x00\x00\x00\x48\x8B\x03\x48\x8B\x48\x08"), "xxxxxxxxx????xxxxx????xxx????xxxxxxx????xxxx?xx????xxxxxxx"); v_CMDLCache__GetStudioHDR = p_CMDLCache__GetStudioHDR.RCast(); /*40 53 48 83 EC 20 48 8D 0D ? ? ? ? 0F B7 DA FF 15 ? ? ? ? 48 8B 05 ? ? ? ? 48 8D 14 5B 48 8D 0D ? ? ? ? 48 8B 5C D0 ? FF 15 ? ? ? ? 48 8B 03 48 8B 48 08*/ - p_CMDLCache__GetStudioHardware = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x48\x89\x5C\x24\x00\x57\x48\x83\xEC\x20\x48\x8D\x0D\x00\x00\x00\x00\x0F\xB7\xDA\xFF\x15\x00\x00\x00\x00\x48\x8B\x05\x00\x00\x00\x00\x48\x8D\x14\x5B\x48\x8D\x0D\x00\x00\x00\x00\x48\x8B\x7C\xD0\x00\xFF\x15\x00\x00\x00\x00\x48\x8B\x1F"), "xxxx?xxxxxxxx????xxxxx????xxx????xxxxxxx????xxxx?xx????xxx"); - v_CMDLCache__GetStudioHardware = p_CMDLCache__GetStudioHardware.RCast(); /*48 89 5C 24 ? 57 48 83 EC 20 48 8D 0D ? ? ? ? 0F B7 DA FF 15 ? ? ? ? 48 8B 05 ? ? ? ? 48 8D 14 5B 48 8D 0D ? ? ? ? 48 8B 7C D0 ? FF 15 ? ? ? ? 48 8B 1F*/ + p_CMDLCache__GetHardwareData = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x48\x89\x5C\x24\x00\x57\x48\x83\xEC\x20\x48\x8D\x0D\x00\x00\x00\x00\x0F\xB7\xDA\xFF\x15\x00\x00\x00\x00\x48\x8B\x05\x00\x00\x00\x00\x48\x8D\x14\x5B\x48\x8D\x0D\x00\x00\x00\x00\x48\x8B\x7C\xD0\x00\xFF\x15\x00\x00\x00\x00\x48\x8B\x1F"), "xxxx?xxxxxxxx????xxxxx????xxx????xxxxxxx????xxxx?xx????xxx"); + v_CMDLCache__GetHardwareData = p_CMDLCache__GetHardwareData.RCast(); /*48 89 5C 24 ? 57 48 83 EC 20 48 8D 0D ? ? ? ? 0F B7 DA FF 15 ? ? ? ? 48 8B 05 ? ? ? ? 48 8D 14 5B 48 8D 0D ? ? ? ? 48 8B 7C D0 ? FF 15 ? ? ? ? 48 8B 1F*/ p_CStudioHWDataRef__SetFlags = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x48\x83\xEC\x08\x4C\x8D\x14\x12"), "xxxxxxxx"); v_CStudioHWDataRef__SetFlags = p_CStudioHWDataRef__SetFlags.RCast(); /*48 83 EC 08 4C 8D 14 12*/ @@ -139,9 +140,9 @@ class HMDLCache : public IDetour m_MDLMutex = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x48\x83\xEC\x28\xBA\x00\x00\x00\x00\x48\x8D\x0D\x00\x00\x00\x00\xFF\x15\x00\x00\x00\x00\x0F\xB6\x05\x00\x00\x00\x00"), "xxxxx????xxx????xx????xxx????") .FindPatternSelf("48 8D 0D").ResolveRelativeAddressSelf(0x3, 0x7).RCast(); - m_MDLLock = p_CMDLCache__GetStudioHardware.Offset(0x35).FindPatternSelf("48 8D 0D").ResolveRelativeAddressSelf(0x3, 0x7).RCast(); + m_MDLLock = p_CMDLCache__GetHardwareData.Offset(0x35).FindPatternSelf("48 8D 0D").ResolveRelativeAddressSelf(0x3, 0x7).RCast(); - m_MDLDict = p_CMDLCache__FindMDL.FindPattern("48 8B 05").ResolveRelativeAddressSelf(0x3, 0x7); + m_MDLDict = p_CMDLCache__FindMDL.FindPattern("48 8B 05").ResolveRelativeAddressSelf(0x3, 0x7).RCast*>(); g_MDLCache = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x48\x8B\x0D\x00\x00\x00\x00\x44\x0F\xB7\x82\x00\x00\x00\x00\x48\x8B\x01\x48\xFF\xA0\x30\x01\x00\x00"), "xxx????xxxx????xxxxxxxxxx") .ResolveRelativeAddressSelf(0x3, 0x7).RCast(); diff --git a/r5dev/rtech/rtech_utils.h b/r5dev/rtech/rtech_utils.h index dcb86d44..6e2ed09a 100644 --- a/r5dev/rtech/rtech_utils.h +++ b/r5dev/rtech/rtech_utils.h @@ -181,8 +181,8 @@ class HPakFile : public IDetour { virtual void GetAdr(void) const { - std::cout << "| VAR: g_pLoadedPakInfo : 0x" << std::hex << std::uppercase << g_pLoadedPakInfo << std::setw(nPad) << " |" << std::endl; - std::cout << "| VAR: s_pLoadedPakCount : 0x" << std::hex << std::uppercase << s_pLoadedPakCount << std::setw(nPad) << " |" << std::endl; + std::cout << "| VAR: g_pLoadedPakInfo : 0x" << std::hex << std::uppercase << g_pLoadedPakInfo << std::setw(0) << " |" << std::endl; + std::cout << "| VAR: s_pLoadedPakCount : 0x" << std::hex << std::uppercase << s_pLoadedPakCount << std::setw(0) << " |" << std::endl; std::cout << "+----------------------------------------------------------------+" << std::endl; } virtual void GetFun(void) const { } diff --git a/r5dev/tier1/utldict.h b/r5dev/tier1/utldict.h index f61ee970..fc7595f0 100644 --- a/r5dev/tier1/utldict.h +++ b/r5dev/tier1/utldict.h @@ -12,15 +12,16 @@ template class CUtlDict { public: + CUtlDict() {}; CUtlDict(uintptr_t ptr) : m_Elements(ptr) {}; - T Find(__int64 entry); + T Find(I entry); private: uintptr_t m_Elements; }; template -T CUtlDict::Find(__int64 entry) +T CUtlDict::Find(I entry) { return *(T*)(m_Elements + 24 * entry + 16); } \ No newline at end of file