From c405c2393421728d3b980a5fd239bc6436b751a2 Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Fri, 22 Jul 2022 16:34:10 +0200 Subject: [PATCH] Implement memory allocation singleton wrappers * Pointer to g_pMemAllocSingleton * New wrapper for returning the singleton, and creating one if not yet initialized (game shares the same pointer, and is aware of its creation). --- r5dev/core/init.cpp | 1 + r5dev/engine/debugoverlay.cpp | 19 ++++---- r5dev/tier0/memstd.h | 68 +++++++++++++++++++++++++++ r5dev/tier0/tslist.cpp | 17 ------- r5dev/tier0/tslist.h | 29 +----------- r5dev/tier1/IConVar.cpp | 19 ++++++-- r5dev/tier1/cmd.cpp | 5 +- r5dev/vproj/clientsdk.vcxproj | 2 +- r5dev/vproj/clientsdk.vcxproj.filters | 6 +-- r5dev/vproj/dedicated.vcxproj | 2 +- r5dev/vproj/dedicated.vcxproj.filters | 6 +-- r5dev/vproj/gamesdk.vcxproj | 2 +- r5dev/vproj/gamesdk.vcxproj.filters | 6 +-- 13 files changed, 109 insertions(+), 73 deletions(-) create mode 100644 r5dev/tier0/memstd.h diff --git a/r5dev/core/init.cpp b/r5dev/core/init.cpp index a7e49164..b7482302 100644 --- a/r5dev/core/init.cpp +++ b/r5dev/core/init.cpp @@ -10,6 +10,7 @@ #include "tier0/jobthread.h" #include "tier0/threadtools.h" #include "tier0/tslist.h" +#include "tier0/memstd.h" #include "tier0/fasttimer.h" #include "tier0/cpu.h" #include "tier0/commandline.h" diff --git a/r5dev/engine/debugoverlay.cpp b/r5dev/engine/debugoverlay.cpp index 264f94ae..a84788ab 100644 --- a/r5dev/engine/debugoverlay.cpp +++ b/r5dev/engine/debugoverlay.cpp @@ -6,7 +6,7 @@ #include "core/stdafx.h" #include "common/pseudodefs.h" -#include "tier0/tslist.h" +#include "tier0/memstd.h" #include "tier0/basetypes.h" #include "tier1/cvar.h" #include "tier2/renderutils.h" @@ -102,7 +102,7 @@ void DestroyOverlay(OverlayBase_t* pOverlay) goto LABEL_MALLOC; LABEL_MALLOC: pOverlay->m_Type = OverlayType_t::OVERLAY_UNK1; - v_MemAlloc_Internal(pOverlay, pOverlaySize); + MemAllocSingleton()->Free(pOverlay); break; default: break; @@ -253,11 +253,6 @@ void DrawAIScriptNodes() for (int i = ai_script_nodes_draw_index->GetInt(); i < (*g_pAINetwork)->GetNumScriptNodes(); i++) { - if (i < 0) - { - return; - } - vTransforms.xmm[0] = _mm_set_ps((*g_pAINetwork)->m_ScriptNode[i].m_vOrigin.x - 50.f, 0.0f, 0.0f, 1.0f); vTransforms.xmm[1] = _mm_set_ps((*g_pAINetwork)->m_ScriptNode[i].m_vOrigin.y - 50.f, 0.0f, 1.0f, 0.0f); vTransforms.xmm[2] = _mm_set_ps((*g_pAINetwork)->m_ScriptNode[i].m_vOrigin.z - 50.f, 1.0f, 0.0f, 0.0f); @@ -386,6 +381,9 @@ static void DrawNavMeshPortals() } } +//------------------------------------------------------------------------------ +// Purpose : draw NavMesh polys +//------------------------------------------------------------------------------ void DrawNavMeshPolys() { const dtNavMesh* mesh = GetNavMeshForHull(navmesh_debug_type->GetInt()); @@ -452,7 +450,10 @@ void DrawNavMeshPolys() } } -static void DrawNavMeshPolyBoundaries() +//------------------------------------------------------------------------------ +// Purpose : draw NavMesh poly boundaries +//------------------------------------------------------------------------------ +void DrawNavMeshPolyBoundaries() { static const float thr = 0.01f * 0.01f; Color col{20, 140, 255, 255}; @@ -556,7 +557,7 @@ void DrawAllOverlays(bool bDraw) return; EnterCriticalSection(&*s_OverlayMutex); #ifndef CLIENT_DLL - if (ai_script_nodes_draw->GetBool()) + if (ai_script_nodes_draw->GetInt() > -1) DrawAIScriptNodes(); if (navmesh_draw_bvtree->GetInt() > -1) DrawNavMeshBVTree(); diff --git a/r5dev/tier0/memstd.h b/r5dev/tier0/memstd.h new file mode 100644 index 00000000..91949f15 --- /dev/null +++ b/r5dev/tier0/memstd.h @@ -0,0 +1,68 @@ +#ifndef MEMSTD_H +#define MEMSTD_H + +class IMemAlloc +{ +public: + template + T* Alloc(size_t nSize) + { + const int index = 1; + return CallVFunc(index, this, nSize); + } + template + void Free(T* pMem) + { + const int index = 4; + CallVFunc(index, this, pMem); + } +}; + +//----------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------- +class CStdMemAlloc : public IMemAlloc{}; + +inline CMemory p_CreateGlobalMemAlloc; +inline auto v_CreateGlobalMemAlloc = p_CreateGlobalMemAlloc.RCast(); + +inline CStdMemAlloc** g_pMemAllocSingleton = nullptr; + + +inline CStdMemAlloc* MemAllocSingleton() +{ + if (!(*g_pMemAllocSingleton)) + { + (*g_pMemAllocSingleton) = v_CreateGlobalMemAlloc(); + } + return (*g_pMemAllocSingleton); +} + +/////////////////////////////////////////////////////////////////////////////// +class VMemStd : public IDetour +{ + virtual void GetAdr(void) const + { + spdlog::debug("| FUN: CreateGlobalMemAlloc : {:#18x} |\n", p_CreateGlobalMemAlloc.GetPtr()); + spdlog::debug("| VAR: g_pMemAllocSingleton : {:#18x} |\n", reinterpret_cast(g_pMemAllocSingleton)); + spdlog::debug("+----------------------------------------------------------------+\n"); + } + virtual void GetFun(void) const + { + p_CreateGlobalMemAlloc = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x40\x53\x48\x83\xEC\x20\xBB\x00\x00\x00\x00\x33\xC0"), "xxxxxxx????xx"); + v_CreateGlobalMemAlloc = p_CreateGlobalMemAlloc.RCast(); /*40 53 48 83 EC 20 BB ?? ?? ?? ?? 33 C0*/ + } + virtual void GetVar(void) const + { + g_pMemAllocSingleton = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x48\x89\x5C\x24\x00\x57\x48\x81\xEC\x00\x00\x00\x00\x41\x8B\xD8"), + "xxxx?xxxx????xxx").OffsetSelf(0x5A).FindPatternSelf("48 8B", CMemory::Direction::DOWN, 100).ResolveRelativeAddressSelf(0x3, 0x7).RCast(); + } + virtual void GetCon(void) const { } + virtual void Attach(void) const { } + virtual void Detach(void) const { } +}; +/////////////////////////////////////////////////////////////////////////////// + +REGISTER(VMemStd); + +#endif // MEMSTD_H diff --git a/r5dev/tier0/tslist.cpp b/r5dev/tier0/tslist.cpp index fbbb4aec..e69de29b 100644 --- a/r5dev/tier0/tslist.cpp +++ b/r5dev/tier0/tslist.cpp @@ -1,17 +0,0 @@ -#include "core/stdafx.h" -#include "tier0/tslist.h" - -void* MemAlloc_Internal(void* pPool, size_t nSize) -{ - return v_MemAlloc_Internal(pPool, nSize); -} - -void TSList_Attach() -{ - DetourAttach((LPVOID*)&v_MemAlloc_Internal, &MemAlloc_Internal); -} - -void TSList_Detach() -{ - DetourDetach((LPVOID*)&v_MemAlloc_Internal, &MemAlloc_Internal); -} \ No newline at end of file diff --git a/r5dev/tier0/tslist.h b/r5dev/tier0/tslist.h index 92192bd7..259a72a2 100644 --- a/r5dev/tier0/tslist.h +++ b/r5dev/tier0/tslist.h @@ -1,15 +1,6 @@ #ifndef TSLIST_H #define TSLIST_H -inline CMemory p_MemAlloc_Internal; -inline auto v_MemAlloc_Internal = p_MemAlloc_Internal.RCast(); - -inline CMemory p_MemAlloc_Wrapper; -inline auto v_MemAlloc_Wrapper = p_MemAlloc_Wrapper.RCast(); - -inline CMemory p_CTSListBase_Wrapper; -inline auto CTSListBase_Wrapper = p_CTSListBase_Wrapper.RCast(); - inline CMemory g_pMallocPool; void TSList_Attach(); @@ -19,28 +10,10 @@ class VTSListBase : public IDetour { virtual void GetAdr(void) const { - spdlog::debug("| FUN: MemAlloc_Internal : {:#18x} |\n", p_MemAlloc_Internal.GetPtr()); - spdlog::debug("| FUN: MemAlloc_Wrapper : {:#18x} |\n", p_MemAlloc_Wrapper.GetPtr()); - spdlog::debug("| FUN: CTSListBase_Wrapper : {:#18x} |\n", p_CTSListBase_Wrapper.GetPtr()); spdlog::debug("| VAR: g_pMallocPool : {:#18x} |\n", g_pMallocPool.GetPtr()); spdlog::debug("+----------------------------------------------------------------+\n"); } - virtual void GetFun(void) const - { - p_MemAlloc_Internal = g_mGameDll.FindPatternSIMD(reinterpret_cast("\xE9\x00\x00\x00\x00\xCC\xCC\xCC\x40\x53\x48\x83\xEC\x20\x48\x8D\x05\x00\x00\x00\x00"), "x????xxxxxxxxxxxx????"); -#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) - p_MemAlloc_Wrapper = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x40\x53\x48\x83\xEC\x20\x48\x8B\x05\x00\x00\x00\x00\x48\x8B\xD9\x48\x85\xC0\x75\x0C\xE8\x16"), "xxxxxxxxx????xxxxxxxxxx"); -#elif defined (GAMEDLL_S2) - p_MemAlloc_Wrapper = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x40\x53\x48\x83\xEC\x20\x48\x8B\x05\x00\x00\x00\x00\x48\x8B\xD9\x48\x85\xC0\x75\x0C\xE8\x00\x00\x00\x00\x48\x89\x05\x00\x00\x00\x00\x4C\x8B\x00\x48\x8B\xD3\x48\x8B\xC8\x48\x83\xC4\x20\x5B\x49\xFF\x60\x08"), "xxxxxxxxx????xxxxxxxxx????xxx????xxxxxxxxxxxxxxxxxx"); -#elif defined (GAMEDLL_S3) - p_MemAlloc_Wrapper = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x40\x53\x48\x83\xEC\x20\x48\x8B\x05\x6B\x83\x25\x0D\x48\x8B\xD9"), "xxxxxxxxxxxxxxxx"); -#endif - p_CTSListBase_Wrapper = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x40\x53\x48\x83\xEC\x20\xBB\x00\x00\x00\x00\x33\xC0"), "xxxxxxx????xx"); - - CTSListBase_Wrapper = p_CTSListBase_Wrapper.RCast(); /*40 53 48 83 EC 20 BB ?? ?? ?? ?? 33 C0*/ - v_MemAlloc_Wrapper = p_MemAlloc_Wrapper.RCast(); /*40 53 48 83 EC 20 48 8B 05 6B 83 25 0D 48 8B D9*/ - v_MemAlloc_Internal = p_MemAlloc_Internal.RCast(); /*E9 ?? ?? ?? ?? CC CC CC 40 53 48 83 EC 20 48 8D 05 ?? ?? ?? ??*/ - } + virtual void GetFun(void) const { } virtual void GetVar(void) const { #if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) diff --git a/r5dev/tier1/IConVar.cpp b/r5dev/tier1/IConVar.cpp index 17d5df10..c96ee49b 100644 --- a/r5dev/tier1/IConVar.cpp +++ b/r5dev/tier1/IConVar.cpp @@ -6,6 +6,7 @@ #include "core/stdafx.h" #include "tier0/tslist.h" +#include "tier0/memstd.h" #include "tier1/IConVar.h" #include "tier1/cvar.h" #include "mathlib/bits.h" @@ -16,8 +17,8 @@ //----------------------------------------------------------------------------- ConVar::ConVar(const char* pszName, const char* pszDefaultValue, int nFlags, const char* pszHelpString, bool bMin, float fMin, bool bMax, float fMax, void* pCallback, const char* pszUsageString) { - ConVar* pNewConVar = reinterpret_cast(v_MemAlloc_Wrapper(sizeof(ConVar))); // Allocate new memory with StdMemAlloc else we crash. - memset(pNewConVar, '\0', sizeof(ConVar)); // Set all to null. + ConVar* pNewConVar = MemAllocSingleton()->Alloc(sizeof(ConVar)); // Allocate new memory with StdMemAlloc else we crash. + memset(pNewConVar, '\0', sizeof(ConVar)); // Set all to null. pNewConVar->m_pConCommandBaseVTable = g_pConVarVtable.RCast(); pNewConVar->m_pIConVarVTable = g_pIConVarVtable.RCast(); @@ -31,6 +32,11 @@ ConVar::ConVar(const char* pszName, const char* pszDefaultValue, int nFlags, con //----------------------------------------------------------------------------- ConVar::~ConVar(void) { + if (m_Value.m_pszString) + { + MemAllocSingleton()->Free(m_Value.m_pszString); + m_Value.m_pszString = NULL; + } } //----------------------------------------------------------------------------- @@ -204,6 +210,9 @@ void ConVar::InitShipped(void) const host_hasIrreversibleShutdown = g_pCVar->FindVar("host_hasIrreversibleShutdown"); net_usesocketsforloopback = g_pCVar->FindVar("net_usesocketsforloopback"); +#ifndef CLIENT_DLL + ai_script_nodes_draw->SetValue(-1); +#endif // !CLIENT_DLL mp_gamemode->SetCallback(&MP_GameMode_Changed_f); } @@ -745,15 +754,15 @@ void ConVar::ChangeStringValue(const char* pszTempVal, float flOldValue) { if (m_Value.m_pszString) { - delete[] m_Value.m_pszString; + MemAllocSingleton()->Free(m_Value.m_pszString); } - m_Value.m_pszString = new char[len]; + m_Value.m_pszString = MemAllocSingleton()->Alloc(len); m_Value.m_iStringLength = len; } else if (!m_Value.m_pszString) { - m_Value.m_pszString = new char[len]; + m_Value.m_pszString = MemAllocSingleton()->Alloc(len); m_Value.m_iStringLength = len; } memcpy(const_cast(m_Value.m_pszString), pszTempVal, len); diff --git a/r5dev/tier1/cmd.cpp b/r5dev/tier1/cmd.cpp index 26828c73..b9cab8ef 100644 --- a/r5dev/tier1/cmd.cpp +++ b/r5dev/tier1/cmd.cpp @@ -6,6 +6,7 @@ #include "core/stdafx.h" #include "tier0/tslist.h" +#include "tier0/memstd.h" #include "tier1/cmd.h" #include "tier1/cvar.h" #include "vstdlib/callback.h" @@ -97,8 +98,8 @@ bool CCommand::HasOnlyDigits(int nIndex) const //----------------------------------------------------------------------------- ConCommand::ConCommand(const char* pszName, const char* pszHelpString, int nFlags, void* pCallback, void* pCommandCompletionCallback) { - ConCommand* pCommand = reinterpret_cast(v_MemAlloc_Wrapper(sizeof(ConCommand))); // Allocate new memory with StdMemAlloc else we crash. - memset(pCommand, '\0', sizeof(ConCommand)); // Set all to null. + ConCommand* pCommand = MemAllocSingleton()->Alloc(sizeof(ConCommand)); + memset(pCommand, '\0', sizeof(ConCommand)); pCommand->m_pConCommandBaseVTable = g_pConCommandVtable.RCast(); pCommand->m_pszName = pszName; diff --git a/r5dev/vproj/clientsdk.vcxproj b/r5dev/vproj/clientsdk.vcxproj index 8dfb0bdd..bcd55ce0 100644 --- a/r5dev/vproj/clientsdk.vcxproj +++ b/r5dev/vproj/clientsdk.vcxproj @@ -105,7 +105,6 @@ - @@ -447,6 +446,7 @@ + diff --git a/r5dev/vproj/clientsdk.vcxproj.filters b/r5dev/vproj/clientsdk.vcxproj.filters index b32d81aa..15539df3 100644 --- a/r5dev/vproj/clientsdk.vcxproj.filters +++ b/r5dev/vproj/clientsdk.vcxproj.filters @@ -477,9 +477,6 @@ sdk\engine - - sdk\tier0 - sdk\engine\client @@ -1613,6 +1610,9 @@ sdk\public\include + + sdk\tier0 + diff --git a/r5dev/vproj/dedicated.vcxproj b/r5dev/vproj/dedicated.vcxproj index 466a808b..51f3ddb1 100644 --- a/r5dev/vproj/dedicated.vcxproj +++ b/r5dev/vproj/dedicated.vcxproj @@ -418,6 +418,7 @@ + @@ -539,7 +540,6 @@ - diff --git a/r5dev/vproj/dedicated.vcxproj.filters b/r5dev/vproj/dedicated.vcxproj.filters index facc5fde..20d95716 100644 --- a/r5dev/vproj/dedicated.vcxproj.filters +++ b/r5dev/vproj/dedicated.vcxproj.filters @@ -1170,6 +1170,9 @@ sdk\server + + sdk\tier0 + @@ -1394,9 +1397,6 @@ sdk\engine - - sdk\tier0 - sdk\engine\client diff --git a/r5dev/vproj/gamesdk.vcxproj b/r5dev/vproj/gamesdk.vcxproj index e567424b..c5cb08b2 100644 --- a/r5dev/vproj/gamesdk.vcxproj +++ b/r5dev/vproj/gamesdk.vcxproj @@ -114,7 +114,6 @@ - @@ -472,6 +471,7 @@ + diff --git a/r5dev/vproj/gamesdk.vcxproj.filters b/r5dev/vproj/gamesdk.vcxproj.filters index c5b41b6d..48f8597e 100644 --- a/r5dev/vproj/gamesdk.vcxproj.filters +++ b/r5dev/vproj/gamesdk.vcxproj.filters @@ -504,9 +504,6 @@ sdk\engine - - sdk\tier0 - sdk\engine\server @@ -1697,6 +1694,9 @@ sdk\public\include + + sdk\tier0 +