diff --git a/r5dev/common/opcodes.cpp b/r5dev/common/opcodes.cpp index 0adb9823..3004066f 100644 --- a/r5dev/common/opcodes.cpp +++ b/r5dev/common/opcodes.cpp @@ -18,6 +18,7 @@ #include "game/server/ai_networkmanager.h" #include "game/server/fairfight_impl.h" #include "rtech/rtech_game.h" +#include "rtech/rui/rui.h" #include "client/client.h" #include "client/cdll_engine_int.h" #include "materialsystem/cmaterialsystem.h" @@ -60,6 +61,7 @@ void Dedicated_Init() // CCLIENTSTATE //------------------------------------------------------------------------- { + /*MOV EAX, 0*/ CClientState__RunFrame.Patch({ 0xB8, 0x00, 0x00, 0x00, 0x00, 0xC3 }); // FUN --> RET | Always return false for pending client snapshots (inline CClientState call in '_Host_RunFrame()') } @@ -158,6 +160,13 @@ void Dedicated_Init() /*MOV EAX, 0*/ CVGui__RunFrame.Patch({ 0xB8, 0x00, 0x00, 0x00, 0x00, 0xC3 }); // FUN --> RET | 'CVGui::RunFrame()' gets called on DLL shutdown. } + //------------------------------------------------------------------------- + // CRUI + //------------------------------------------------------------------------- + { + /*MOV EAX, 0*/ + p_RuiLoadAsset.Patch({ 0xB8, 0x00, 0x00, 0x00, 0x00, 0xC3 }); // FUN --> RET | Return early in RuiLoadAsset() to prevent error while attempting to load RUI assets after applying player settings. + } //------------------------------------------------------------------------- // CENGINEVGUI diff --git a/r5dev/common/opcodes.h b/r5dev/common/opcodes.h index 0899b9c0..2917c90f 100644 --- a/r5dev/common/opcodes.h +++ b/r5dev/common/opcodes.h @@ -81,7 +81,6 @@ inline CMemory CWin32Surface_initStaticData; inline CMemory KeyboardLayout_Init; #endif - //------------------------------------------------------------------------- // .RDATA //------------------------------------------------------------------------- diff --git a/r5dev/core/init.cpp b/r5dev/core/init.cpp index f0b0c8a5..04066540 100644 --- a/r5dev/core/init.cpp +++ b/r5dev/core/init.cpp @@ -53,10 +53,9 @@ #include "squirrel/sqvm.h" #include "studiorender/studiorendercontext.h" #include "rtech/rtech_game.h" +#include "rtech/rtech_utils.h" #include "rtech/stryder/stryder.h" -#ifndef DEDICATED #include "rtech/rui/rui.h" -#endif // !DEDICATED #include "engine/baseclient.h" #include "engine/baseclientstate.h" #ifndef CLIENT_DLL diff --git a/r5dev/engine/cmodel_bsp.cpp b/r5dev/engine/cmodel_bsp.cpp index dc087a8a..a4bb4b57 100644 --- a/r5dev/engine/cmodel_bsp.cpp +++ b/r5dev/engine/cmodel_bsp.cpp @@ -40,7 +40,7 @@ void MOD_PreloadPak(const string& svSetFile) if (it.value().is_string()) { string svToLoad = it.value().get() + ".rpak"; - uint32_t nPakId = CPakFile_AsyncLoad((void*)svToLoad.c_str(), g_pMallocPool.GetPtr(), 4, 0); + uint32_t nPakId = g_pakLoadApi->AsyncLoad(svToLoad.c_str(), g_pMallocPool.GetPtr(), 4, 0); if (nPakId == -1) { diff --git a/r5dev/engine/host_cmd.h b/r5dev/engine/host_cmd.h index 607334a3..f56edbd3 100644 --- a/r5dev/engine/host_cmd.h +++ b/r5dev/engine/host_cmd.h @@ -20,7 +20,6 @@ inline auto Host_NewGame = p_Host_NewGame.RCast(); -inline CMemory g_pMallocPool; inline CMemory g_pEngineParmsBuffer; extern EngineParms_t* g_pEngineParms; @@ -34,7 +33,6 @@ class HHostCmd : public IDetour std::cout << "| FUN: Host_NewGame : 0x" << std::hex << std::uppercase << p_Host_NewGame.GetPtr() << std::setw(nPad) << " |" << std::endl; std::cout << "| FUN: Host_ChangeLevel : 0x" << std::hex << std::uppercase << p_Host_ChangeLevel.GetPtr() << std::setw(nPad) << " |" << std::endl; std::cout << "| VAR: g_pEngineParms : 0x" << std::hex << std::uppercase << g_pEngineParmsBuffer.GetPtr() << std::setw(nPad) << " |" << std::endl; - std::cout << "| VAR: g_pMallocPool : 0x" << std::hex << std::uppercase << g_pMallocPool.GetPtr() << std::setw(nPad) << " |" << std::endl; std::cout << "+----------------------------------------------------------------+" << std::endl; } virtual void GetFun(void) const @@ -55,10 +53,8 @@ class HHostCmd : public IDetour virtual void GetVar(void) const { #if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) - g_pMallocPool = p_Host_Init.Offset(0x600).FindPatternSelf("48 8D 15 ?? ?? ?? 01", CMemory::Direction::DOWN, 100).ResolveRelativeAddressSelf(0x3, 0x7); g_pEngineParmsBuffer = p_CModAppSystemGroup_Main.Offset(0x0).FindPatternSelf("48 8B", CMemory::Direction::DOWN, 100).ResolveRelativeAddress(0x3, 0x7); #elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3) - g_pMallocPool = p_Host_Init.Offset(0x130).FindPatternSelf("48 8D 15 ?? ?? ?? 01", CMemory::Direction::DOWN, 100).ResolveRelativeAddressSelf(0x3, 0x7); g_pEngineParmsBuffer = p_CModAppSystemGroup_Main.Offset(0x0).FindPatternSelf("4C 8B", CMemory::Direction::DOWN, 100).ResolveRelativeAddress(0x3, 0x7); #endif g_pEngineParms = g_pEngineParmsBuffer.RCast(); diff --git a/r5dev/launcher/IApplication.h b/r5dev/launcher/IApplication.h index 86e0f7fd..2fd592fd 100644 --- a/r5dev/launcher/IApplication.h +++ b/r5dev/launcher/IApplication.h @@ -76,12 +76,15 @@ class HApplication : public IDetour #if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) p_CModAppSystemGroup_Main = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x48\x83\xEC\x28\x80\xB9\x00\x00\x00\x00\x00\x48\x8B\x15\x00\x00\x00\x00"), "xxxxxx?????xxx????"); p_CModAppSystemGroup_Create = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x48\x8B\xC4\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x83\xEC\x60\x48\xC7\x40\x00\x00\x00\x00\x00\x48\x89\x58\x08"), "xxxxxxxxxxxxxxxxxxx?????xxxx"); + + p_CSourceAppSystemGroup__Create = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x48\x89\x5C\x24\x00\x48\x89\x6C\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xEC\x20\x48\x8B\xF9\xE8\x00\x00\x00\x00\x33\xC9"), "xxxx?xxxx?xxxx?xxxxxxxxx????xx"); #elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3) p_CModAppSystemGroup_Main = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x40\x53\x48\x83\xEC\x20\x80\xB9\x00\x00\x00\x00\x00\xBB\x00\x00\x00\x00"), "xxxxxxxx?????x????"); p_CModAppSystemGroup_Create = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x48\x8B\xC4\x55\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8B\xEC\x48\x83\xEC\x60"), "xxxxxxxxxxxxxxxxxxx"); + + p_CSourceAppSystemGroup__Create = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x48\x89\x5C\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xEC\x20\x48\x8B\xF9\xE8\x00\x00\x00\x00\x33\xC9"), "xxxx?xxxx?xxxxxxxxx????xx"); #endif p_CSourceAppSystemGroup__PreInit = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x48\x89\x74\x24\x00\x55\x48\x8D\xAC\x24\x00\x00\x00\x00\x48\x81\xEC\x00\x00\x00\x00\x48\x8B\x05\x00\x00\x00\x00"), "xxxx?xxxxx????xxx????xxx????"); - p_CSourceAppSystemGroup__Create = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x48\x89\x5C\x24\x00\x48\x89\x6C\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xEC\x20\x48\x8B\xF9\xE8\x00\x00\x00\x00\x33\xC9"), "xxxx?xxxx?xxxx?xxxxxxxxx????xx"); CModAppSystemGroup_Main = p_CModAppSystemGroup_Main.RCast(); /*40 53 48 83 EC 20 80 B9 ?? ?? ?? ?? ?? BB ?? ?? ?? ??*/ CModAppSystemGroup_Create = p_CModAppSystemGroup_Create.RCast(); /*48 8B C4 55 41 54 41 55 41 56 41 57 48 8B EC 48 83 EC 60*/ diff --git a/r5dev/launcher/launcher.cpp b/r5dev/launcher/launcher.cpp index d9773513..b0ff5709 100644 --- a/r5dev/launcher/launcher.cpp +++ b/r5dev/launcher/launcher.cpp @@ -29,7 +29,7 @@ int HWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int int LauncherMain(HINSTANCE hInstance) { int results = v_LauncherMain(hInstance); - printf("LauncherMain returned %s\n", ExitCodeToString(results)); + spdlog::info("LauncherMain: {:s}\n", ExitCodeToString(results)); return results; } diff --git a/r5dev/rtech/rtech_game.cpp b/r5dev/rtech/rtech_game.cpp index 2b409271..ae2b9005 100644 --- a/r5dev/rtech/rtech_game.cpp +++ b/r5dev/rtech/rtech_game.cpp @@ -8,59 +8,66 @@ #include "engine/sys_utils.h" #include "rtech/rtech_game.h" -std::vector g_LoadedPakHandle{ }; - -//----------------------------------------------------------------------------- -// Purpose: unloads asset files from the memory pool -//----------------------------------------------------------------------------- -void HPakFile_UnloadAsset(int64_t a1, int64_t a2) // This ain't related to RTech, its a CSTDMem function. -{ -#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) - int64_t pAsset = a1; -#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3) - int64_t pAsset = a2; -#endif - // Return early if address is out of scope. - if (pAsset <= 0x0000000000 || pAsset >= 0xFFFFFFFFFF) - { - return; - } -#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) - return CPakFile_UnloadAsset(a1); -#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3) - return CPakFile_UnloadAsset(a1, a2); -#endif -} +vector g_LoadedPakHandle{ }; //----------------------------------------------------------------------------- // Purpose: load user-requested pak files on-demand +// Input : *szPakFileName - +// *pMalloc - +// nIdx - +// bUnk - +// Output : pak file handle on success, -1 (INVALID_PAK_HANDLE) on failure //----------------------------------------------------------------------------- -void HPakFile_AsyncLoad(string svPakFileName) +RPakHandle_t CPakFile::AsyncLoad(const char* szPakFileName, uintptr_t pMalloc, int nIdx, bool bUnk) { - string svPakFilePathMod = "paks\\Win32\\" + svPakFileName; - string svPakFilePathBase = "paks\\Win64\\" + svPakFileName; + RPakHandle_t pakHandle = -1; +#ifdef DEDICATED + // Extraneous files (useless on the dedicated server). + if (strcmp(szPakFileName, "ui.rpak") == 0) + { + static const char* szReplacement = "common_empty.rpak"; + // Returning -1 (invalid handle) triggers engine error, call is inline. + // Replacing the ui.rpak file here with a stub to avoid having to patch. + Warning(eDLL_T::RTECH, "Replacing '%s' with '%s'\n", szPakFileName, szReplacement); + return pakHandle = CPakFile_AsyncLoad(szReplacement, pMalloc, nIdx, bUnk); + } + else if (strstr(szPakFileName, "ui") + || strstr(szPakFileName, "loadscreen") + || strstr(szPakFileName, "subtitles")) + { + return pakHandle; + } +#endif // DEDICATED + + string svPakFilePathMod = "paks\\Win32\\" + string(szPakFileName); + string svPakFilePathBase = "paks\\Win64\\" + string(szPakFileName); if (FileExists(svPakFilePathMod.c_str()) || FileExists(svPakFilePathBase.c_str())) { - int nPakId = CPakFile_AsyncLoad((void*)svPakFileName.c_str(), g_pMallocPool.GetPtr(), NULL, NULL); + pakHandle = CPakFile_AsyncLoad(szPakFileName, pMalloc, nIdx, bUnk); - if (nPakId == 0xFFFFFFFF) + if (pakHandle == -1) { - Error(eDLL_T::RTECH, "RTech_AsyncLoad: Failed read '%s' results '%u'\n", svPakFileName.c_str(), nPakId); + Error(eDLL_T::RTECH, "%s: Failed read '%s' results '%u'\n", __FUNCTION__, szPakFileName, pakHandle); } } else { - Error(eDLL_T::RTECH, "RTech_AsyncLoad: Failed. File '%s' doesn't exist\n", svPakFileName.c_str()); + Error(eDLL_T::RTECH, "%s: Failed. File '%s' doesn't exist\n", __FUNCTION__, szPakFileName); } + + return pakHandle; } void RTech_Game_Attach() { - //DetourAttach((LPVOID*)&RTech_UnloadAsset, &HRTech_UnloadAsset); + DetourAttach((LPVOID*)&CPakFile_AsyncLoad, &CPakFile::AsyncLoad); } void RTech_Game_Detach() { - //DetourDetach((LPVOID*)&RTech_UnloadAsset, &HRTech_UnloadAsset); + DetourDetach((LPVOID*)&CPakFile_AsyncLoad, &CPakFile::AsyncLoad); } + +// Symbols taken from R2 dll's. +CPakFile* g_pakLoadApi = new CPakFile(); diff --git a/r5dev/rtech/rtech_game.h b/r5dev/rtech/rtech_game.h index dc5df8d0..5b7d8d6c 100644 --- a/r5dev/rtech/rtech_game.h +++ b/r5dev/rtech/rtech_game.h @@ -1,6 +1,7 @@ #pragma once +#include "tier0/tslist.h" -typedef unsigned int RPakHandle_t; +typedef int RPakHandle_t; enum class ePakStatus : int { @@ -24,13 +25,7 @@ enum class ePakStatus : int /* ==== RTECH_GAME ====================================================================================================================================================== */ #if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) -inline CMemory p_CPakFile_UnloadAsset; -inline auto CPakFile_UnloadAsset = p_CPakFile_UnloadAsset.RCast(); - #elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3) -inline CMemory p_CPakFile_UnloadAsset; -inline auto CPakFile_UnloadAsset = p_CPakFile_UnloadAsset.RCast(); - inline CMemory p_CPakFile_LoadPak; inline auto CPakFile_LoadPak = p_CPakFile_LoadPak.RCast(); @@ -38,13 +33,17 @@ inline CMemory p_CPakFile_LoadMapPak; inline auto CPakFile_LoadMapPak = p_CPakFile_LoadMapPak.RCast(); #endif inline CMemory p_CPakFile_AsyncLoad; -inline auto CPakFile_AsyncLoad = p_CPakFile_AsyncLoad.RCast(); +inline auto CPakFile_AsyncLoad = p_CPakFile_AsyncLoad.RCast(); inline CMemory p_CPakFile_UnloadPak; inline auto CPakFile_UnloadPak = p_CPakFile_UnloadPak.RCast(); -void HPakFile_UnloadAsset(int64_t a1, int64_t a2); -void HPakFile_AsyncLoad(string svPakFileName); +class CPakFile +{ +public: + static RPakHandle_t AsyncLoad(const char* szPakFileName, uintptr_t pMalloc = g_pMallocPool.GetPtr(), int nIdx = NULL, bool bUnk = false); +}; +extern CPakFile* g_pakLoadApi; void RTech_Game_Attach(); void RTech_Game_Detach(); @@ -55,7 +54,6 @@ class HRTechGame : public IDetour { virtual void GetAdr(void) const { - std::cout << "| FUN: CPakFile::UnloadAsset : 0x" << std::hex << std::uppercase << p_CPakFile_UnloadAsset.GetPtr() << std::setw(nPad) << " |" << std::endl; std::cout << "| FUN: CPakFile::AsyncLoad : 0x" << std::hex << std::uppercase << p_CPakFile_AsyncLoad.GetPtr() << std::setw(nPad) << " |" << std::endl; #if defined (GAMEDLL_S2) || defined (GAMEDLL_S3) std::cout << "| FUN: CPakFile::LoadPak : 0x" << std::hex << std::uppercase << p_CPakFile_LoadPak.GetPtr() << std::setw(nPad) << " |" << std::endl; @@ -67,12 +65,7 @@ class HRTechGame : public IDetour virtual void GetFun(void) const { #if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) - p_CPakFile_UnloadAsset = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x48\x83\xEC\x28\x48\x85\xC9\x0F\x84\x00\x00\x00\x00\x48\x8B\x05\x00\x00\x00\x00"), "xxxxxxxxx????xxx????"); - CPakFile_UnloadAsset = p_CPakFile_UnloadAsset.RCast(); /*48 83 EC 28 48 85 C9 0F 84 ? ? ? ? 48 8B 05 ? ? ? ? */ #elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3) - p_CPakFile_UnloadAsset = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x48\x83\xEC\x28\x48\x85\xD2\x74\x40\x48\x8B\x05\x00\x00\x00\x00"), "xxxxxxxxxxxx????"); - CPakFile_UnloadAsset = p_CPakFile_UnloadAsset.RCast(); /*48 83 EC 28 48 85 D2 74 40 48 8B 05 ? ? ? ?*/ - p_CPakFile_LoadPak = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x48\x89\x4C\x24\x00\x56\x41\x55"), "xxxx?xxx"); /*48 89 4C 24 ? 56 41 55*/ CPakFile_LoadPak = p_CPakFile_LoadPak.RCast(); @@ -81,10 +74,10 @@ class HRTechGame : public IDetour #endif #if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) || defined (GAMEDLL_S2) p_CPakFile_AsyncLoad = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x40\x53\x48\x83\xEC\x40\x48\x89\x6C\x24\x00\x41\x8B\xE8"), "xxxxxxxxxx?xxx"); - CPakFile_AsyncLoad = p_CPakFile_AsyncLoad.RCast(); /*40 53 48 83 EC 40 48 89 6C 24 ? 41 8B E8*/ + CPakFile_AsyncLoad = p_CPakFile_AsyncLoad.RCast(); /*40 53 48 83 EC 40 48 89 6C 24 ? 41 8B E8*/ #elif defined (GAMEDLL_S3) p_CPakFile_AsyncLoad = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x40\x53\x48\x83\xEC\x40\x48\x89\x6C\x24\x00\x41\x0F\xB6\xE9"), "xxxxxxxxxx?xxxx"); - CPakFile_AsyncLoad = p_CPakFile_AsyncLoad.RCast(); /*40 53 48 83 EC 40 48 89 6C 24 ? 41 0F B6 E9*/ + CPakFile_AsyncLoad = p_CPakFile_AsyncLoad.RCast(); /*40 53 48 83 EC 40 48 89 6C 24 ? 41 0F B6 E9*/ #endif p_CPakFile_UnloadPak = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x48\x89\x5C\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xEC\x30\x8B\xC1"), "xxxx?xxxx?xxxxxxx"); CPakFile_UnloadPak = p_CPakFile_UnloadPak.RCast(); /*48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC 30 8B C1*/ diff --git a/r5dev/rtech/rui/rui.h b/r5dev/rtech/rui/rui.h index bc99db54..5e05f280 100644 --- a/r5dev/rtech/rui/rui.h +++ b/r5dev/rtech/rui/rui.h @@ -1,11 +1,11 @@ #pragma once -#ifndef DEDICATED - /* ==== RUI ====================================================================================================================================================== */ inline CMemory p_RuiDraw; inline auto v_RuiDraw = p_RuiDraw.RCast(); +inline CMemory p_RuiLoadAsset; +inline auto v_RuiLoadAsset = p_RuiLoadAsset.RCast(); void Rui_Attach(); void Rui_Detach(); @@ -15,13 +15,17 @@ class HRui : public IDetour { virtual void GetAdr(void) const { - std::cout << "| FUN: RuiDraw : 0x" << std::hex << std::uppercase << p_RuiDraw.GetPtr() << std::setw(nPad) << " |" << std::endl; + std::cout << "| FUN: RuiDraw : 0x" << std::hex << std::uppercase << p_RuiDraw.GetPtr() << std::setw(nPad) << " |" << std::endl; + std::cout << "| FUN: RuiLoadAsset : 0x" << std::hex << std::uppercase << p_RuiLoadAsset.GetPtr() << std::setw(nPad) << " |" << std::endl; std::cout << "+----------------------------------------------------------------+" << std::endl; } virtual void GetFun(void) const { p_RuiDraw = g_mGameDll.FindPatternSIMD(reinterpret_cast("\x40\x53\x48\x83\xEC\x40\x4C\x8B\x5A\x18"), "xxxxxxxxxx"); v_RuiDraw = p_RuiDraw.RCast(); /* 40 53 48 83 EC 40 4C 8B 5A 18 */ + + p_RuiLoadAsset = g_mGameDll.FindPatternSIMD(reinterpret_cast("\xE8\x00\x00\x00\x00\xEB\x03\x49\x8B\xC6\x48\x89\x86\x00\x00\x00\x00\x8B\x86\x00\x00\x00\x00"), "x????xxxxxxxx????xx????").FollowNearCallSelf(); + v_RuiLoadAsset = p_RuiLoadAsset.RCast(); /*E8 ?? ?? ?? ?? EB 03 49 8B C6 48 89 86 ?? ?? ?? ?? 8B 86 ?? ?? ?? ??*/ } virtual void GetVar(void) const { } virtual void GetCon(void) const { } @@ -31,5 +35,3 @@ class HRui : public IDetour /////////////////////////////////////////////////////////////////////////////// REGISTER(HRui); - -#endif // !DEDICATED \ No newline at end of file diff --git a/r5dev/tier0/tslist.h b/r5dev/tier0/tslist.h index 4f0c06e0..b395d539 100644 --- a/r5dev/tier0/tslist.h +++ b/r5dev/tier0/tslist.h @@ -10,6 +10,8 @@ inline auto MemAlloc_Wrapper = p_MemAlloc_Wrapper.RCast(); inline CMemory p_CTSListBase_Wrapper; inline auto CTSListBase_Wrapper = p_CTSListBase_Wrapper.RCast(); +inline CMemory g_pMallocPool; + /////////////////////////////////////////////////////////////////////////////// class HTSListBase : public IDetour { @@ -18,6 +20,7 @@ class HTSListBase : public IDetour std::cout << "| FUN: MemAlloc_Internal : 0x" << std::hex << std::uppercase << p_MemAlloc_Internal.GetPtr() << std::setw(nPad) << " |" << std::endl; std::cout << "| FUN: MemAlloc_Wrapper : 0x" << std::hex << std::uppercase << p_MemAlloc_Wrapper.GetPtr() << std::setw(nPad) << " |" << std::endl; std::cout << "| FUN: CTSListBase_Wrapper : 0x" << std::hex << std::uppercase << p_CTSListBase_Wrapper.GetPtr() << std::setw(nPad) << " |" << std::endl; + std::cout << "| VAR: g_pMallocPool : 0x" << std::hex << std::uppercase << g_pMallocPool.GetPtr() << std::setw(nPad) << " |" << std::endl; std::cout << "+----------------------------------------------------------------+" << std::endl; } virtual void GetFun(void) const @@ -32,11 +35,22 @@ class HTSListBase : public IDetour #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*/ + CTSListBase_Wrapper = p_CTSListBase_Wrapper.RCast(); /*40 53 48 83 EC 20 BB ?? ?? ?? ?? 33 C0*/ MemAlloc_Wrapper = p_MemAlloc_Wrapper.RCast(); /*40 53 48 83 EC 20 48 8B 05 6B 83 25 0D 48 8B D9*/ - malloc_internal = p_MemAlloc_Internal.RCast(); /*E9 ? ? ? ? CC CC CC 40 53 48 83 EC 20 48 8D 05 ? ? ? ?*/ + malloc_internal = p_MemAlloc_Internal.RCast(); /*E9 ?? ?? ?? ?? CC CC CC 40 53 48 83 EC 20 48 8D 05 ?? ?? ?? ??*/ + } + virtual void GetVar(void) const + { +#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) + g_pMallocPool = g_mGameDll.FindPatternSIMD(reinterpret_cast( + "\x48\x89\x5C\x24\x00\x48\x89\x6C\x24\x00\x48\x89\x74\x24\x00\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x81\xEC\x00\x00\x00\x00\x48\x8B\xD9\xFF\x15\x00\x00\x00\x00"), + "xxxx?xxxx?xxxx?xxxxxxxxxxxx????xxxxx????").Offset(0x600).FindPatternSelf("48 8D 15 ?? ?? ?? 01", CMemory::Direction::DOWN, 100).ResolveRelativeAddressSelf(0x3, 0x7); +#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3) + g_pMallocPool = g_mGameDll.FindPatternSIMD(reinterpret_cast( + "\x48\x89\x5C\x24\x00\x48\x89\x74\x24\x00\x48\x89\x7C\x24\x00\x55\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8D\xAC\x24\x00\x00\x00\x00\xB8\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x48\x2B\xE0\x48\x8B\xD9"), + "xxxx?xxxx?xxxx?xxxxxxxxxxxxx????x????x????xxxxxx").Offset(0x130).FindPatternSelf("48 8D 15 ?? ?? ?? 01", CMemory::Direction::DOWN, 100).ResolveRelativeAddressSelf(0x3, 0x7); +#endif } - virtual void GetVar(void) const { } virtual void GetCon(void) const { } virtual void Attach(void) const { } virtual void Detach(void) const { } diff --git a/r5dev/vproj/dedicated.vcxproj b/r5dev/vproj/dedicated.vcxproj index 5de23abd..b380c39f 100644 --- a/r5dev/vproj/dedicated.vcxproj +++ b/r5dev/vproj/dedicated.vcxproj @@ -199,6 +199,7 @@ + diff --git a/r5dev/vproj/dedicated.vcxproj.filters b/r5dev/vproj/dedicated.vcxproj.filters index 5889f115..61b903c3 100644 --- a/r5dev/vproj/dedicated.vcxproj.filters +++ b/r5dev/vproj/dedicated.vcxproj.filters @@ -142,6 +142,9 @@ {f6e1bcba-3548-4849-918d-9adea1603b0b} + + {cc54d9ba-f73a-48af-af6a-3b2064710e61} + @@ -867,6 +870,9 @@ sdk\tier0 + + sdk\rtech\rui + diff --git a/r5dev/vstdlib/completion.cpp b/r5dev/vstdlib/completion.cpp index efe689d6..a69d09cf 100644 --- a/r5dev/vstdlib/completion.cpp +++ b/r5dev/vstdlib/completion.cpp @@ -392,7 +392,7 @@ _Pak_RequestLoad_f_CompletionFunc */ void _Pak_RequestLoad_f_CompletionFunc(const CCommand& args) { - HPakFile_AsyncLoad(args.Arg(1)); + g_pakLoadApi->AsyncLoad(args.Arg(1)); } /* diff --git a/r5dev/windows/system.cpp b/r5dev/windows/system.cpp index aacb907b..283f8ab4 100644 --- a/r5dev/windows/system.cpp +++ b/r5dev/windows/system.cpp @@ -2,20 +2,49 @@ #include "windows/system.h" /////////////////////////////////////////////////////////////////////////////// -typedef BOOL(WINAPI* IGetVersionExA)(_Inout_ LPOSVERSIONINFOA lpVersionInformation); -static IGetVersionExA g_oGetVersionExA = nullptr; +typedef BOOL(WINAPI* IGetVersionExA)( + _Inout_ LPOSVERSIONINFOA lpVersionInformation); +typedef BOOL(WINAPI* IPeekMessage)( + _Out_ LPMSG lpMsg, + _In_opt_ HWND hWnd, + _In_ UINT wMsgFilterMin, + _In_ UINT wMsgFilterMax, + _In_ UINT wRemoveMsg); +static IGetVersionExA VGetVersionExA = nullptr; +static IPeekMessage VPeekMessageA = nullptr; +static IPeekMessage VPeekMessageW = nullptr; //############################################################################# // SYSTEM HOOKS //############################################################################# -BOOL WINAPI HGetVersionExA(_Inout_ LPOSVERSIONINFOA lpVersionInformation) +BOOL +WINAPI +HGetVersionExA( + _Inout_ LPOSVERSIONINFOA lpVersionInformation) { #ifdef DEDICATED // Return false for dedicated to skip 'SetProcessDpiAwareness' in 'CEngineAPI:OnStartup()'. return NULL; #else - return g_oGetVersionExA(lpVersionInformation); + return VGetVersionExA(lpVersionInformation); +#endif // DEDICATED +} + +BOOL +WINAPI +HPeekMessage( + _Out_ LPMSG lpMsg, + _In_opt_ HWND hWnd, + _In_ UINT wMsgFilterMin, + _In_ UINT wMsgFilterMax, + _In_ UINT wRemoveMsg) +{ +#ifdef DEDICATED + // Return false for dedicated to reduce unneccesary overhead when calling 'PeekMessageA/W()' every frame. + return NULL; +#else + return VPeekMessageA(lpMsg, hWnd, wMsgFilterMin, wMsgFilterMax, wRemoveMsg); #endif // DEDICATED } @@ -25,32 +54,43 @@ BOOL WINAPI HGetVersionExA(_Inout_ LPOSVERSIONINFOA lpVersionInformation) void WinSys_Init() { - g_oGetVersionExA = (IGetVersionExA)DetourFindFunction("KERNEL32.dll", "GetVersionExA"); + VGetVersionExA = (IGetVersionExA)DetourFindFunction("KERNEL32.dll", "GetVersionExA"); + VPeekMessageA = (IPeekMessage)DetourFindFunction("USER32.dll", "PeekMessageA"); + VPeekMessageW = (IPeekMessage)DetourFindFunction("USER32.dll", "PeekMessageW"); } void WinSys_Attach() { +#ifdef DEDICATED WinSys_Init(); + /////////////////////////////////////////////////////////////////////////// DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); /////////////////////////////////////////////////////////////////////////// - DetourAttach(&(LPVOID&)g_oGetVersionExA, (PBYTE)HGetVersionExA); + DetourAttach(&(LPVOID&)VGetVersionExA, (PBYTE)HGetVersionExA); + DetourAttach(&(LPVOID&)VPeekMessageA, (PBYTE)HPeekMessage); + //DetourAttach(&(LPVOID&)VPeekMessageW, (PBYTE)HPeekMessage); /////////////////////////////////////////////////////////////////////////// DetourTransactionCommit(); +#endif // DEDICATED } void WinSys_Detach() { +#ifdef DEDICATED /////////////////////////////////////////////////////////////////////////// DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); /////////////////////////////////////////////////////////////////////////// - DetourDetach(&(LPVOID&)g_oGetVersionExA, (PBYTE)HGetVersionExA); + DetourDetach(&(LPVOID&)VGetVersionExA, (PBYTE)HGetVersionExA); + DetourDetach(&(LPVOID&)VPeekMessageA, (PBYTE)HPeekMessage); + //DetourDetach(&(LPVOID&)VPeekMessageW, (PBYTE)HPeekMessage); /////////////////////////////////////////////////////////////////////////// DetourTransactionCommit(); +#endif // DEDICATED }