diff --git a/r5dev/client/cdll_engine_int.cpp b/r5dev/client/cdll_engine_int.cpp index 33db3ec7..bbc772cd 100644 --- a/r5dev/client/cdll_engine_int.cpp +++ b/r5dev/client/cdll_engine_int.cpp @@ -29,7 +29,7 @@ void __fastcall HFrameStageNotify(CHLClient* rcx, ClientFrameStage_t frameStage) g_pConVar->ClearHostNames(); #endif // GAMEDLL_S3 CKeyValueSystem_Init(); - +#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) || defined (GAMEDLL_S2) // !TEMP UNTIL CHOSTSTATE IS BUILD AGNOSTIC! // if (!g_pCmdLine->CheckParm("-devsdk")) { IVEngineClient_CommandExecute(NULL, "exec \"autoexec_server.cfg\""); @@ -55,42 +55,14 @@ void __fastcall HFrameStageNotify(CHLClient* rcx, ClientFrameStage_t frameStage) } g_pCVar->FindVar("net_usesocketsforloopback")->SetValue(1); g_pRConClient->Init(); - +#endif // GAMEDLL_S0 || GAMEDLL_S1 || GAMEDLL_S2 bInitialized = true; } break; } case ClientFrameStage_t::FRAME_NET_UPDATE_POSTDATAUPDATE_END: { - if (g_pBanSystem->IsRefuseListValid()) - { - for (int i = 0; i < g_pBanSystem->vsvrefuseList.size(); i++) // Loop through vector. - { - for (int c = 0; c < MAX_PLAYERS; c++) // Loop through all possible client instances. - { - CClient* client = g_pClient->GetClientInstance(c); // Get client instance. - if (!client) - { - continue; - } - - if (!client->GetNetChan()) // Netchan valid? - { - continue; - } - - int clientID = g_pClient->m_iUserID + 1; // Get UserID + 1. - if (clientID != g_pBanSystem->vsvrefuseList[i].second) // See if they match. - { - continue; - } - - NET_DisconnectClient(g_pClient, c, g_pBanSystem->vsvrefuseList[i].first.c_str(), 0, 1); - g_pBanSystem->DeleteConnectionRefuse(clientID); - break; - } - } - } + g_pBanSystem->BanListCheck(); PatchNetVarConVar(); break; } diff --git a/r5dev/client/cdll_engine_int.h b/r5dev/client/cdll_engine_int.h index a1540b55..ce9f0fd9 100644 --- a/r5dev/client/cdll_engine_int.h +++ b/r5dev/client/cdll_engine_int.h @@ -55,7 +55,7 @@ namespace void* (*CHLClient_PostInit)() = (void* (*)())p_CHLClient_PostInit.GetPtr(); /*48 83 EC 28 48 83 3D ? ? ? ? ? 48 8D 05 ? ? ? ?*/ #endif - bool* scr_drawloading = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x80\x3D\x00\x00\x00\x00\x00\x74\x14\x66\x0F\x6E\x05\x00\x00\x00\x00", "xx?????xxxxxx????").ResolveRelativeAddress(0x2, 0x7).RCast(); + bool* cl_time_use_host_tickcount = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x80\x3D\x00\x00\x00\x00\x00\x74\x14\x66\x0F\x6E\x05\x00\x00\x00\x00", "xx?????xxxxxx????").ResolveRelativeAddress(0x2, 0x7).RCast(); } /////////////////////////////////////////////////////////////////////////////// @@ -72,7 +72,7 @@ class HDll_Engine_Int : public IDetour { std::cout << "| FUN: CHLClient::FrameStageNotify : 0x" << std::hex << std::uppercase << p_CHLClient_FrameStageNotify.GetPtr() << std::setw(npad) << " |" << std::endl; std::cout << "| FUN: CHLClient::PostInit : 0x" << std::hex << std::uppercase << p_CHLClient_PostInit.GetPtr() << std::setw(npad) << " |" << std::endl; - std::cout << "| VAR: scr_drawloading : 0x" << std::hex << std::uppercase << scr_drawloading << std::setw(0) << " |" << std::endl; + std::cout << "| VAR: cl_time_use_host_tickcount : 0x" << std::hex << std::uppercase << cl_time_use_host_tickcount << std::setw(0) << " |" << std::endl; std::cout << "+----------------------------------------------------------------+" << std::endl; } }; diff --git a/r5dev/common/opcodes.cpp b/r5dev/common/opcodes.cpp index e1980dd1..848174c1 100644 --- a/r5dev/common/opcodes.cpp +++ b/r5dev/common/opcodes.cpp @@ -4,7 +4,11 @@ #include "core/stdafx.h" #include "common/opcodes.h" +#include "engine/cmodel_bsp.h" #include "engine/host_cmd.h" +#include "engine/gl_screen.h" +#include "engine/modelloader.h" +#include "engine/sv_main.h" #include "materialsystem/materialsystem.h" #include "bsplib/bsplib.h" #include "ebisusdk/EbisuSDK.h" diff --git a/r5dev/common/opcodes.h b/r5dev/common/opcodes.h index fdbc9152..87bf9c1d 100644 --- a/r5dev/common/opcodes.h +++ b/r5dev/common/opcodes.h @@ -78,39 +78,6 @@ namespace ADDRESS CStudioRenderContext__LoadMaterials = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x8B\xC4\x4C\x89\x40\x18\x55\x56\x41\x55", "xxxxxxxxxxx"); #endif// 0x140456B50 // 48 8B C4 4C 89 40 18 55 56 41 55 // - //------------------------------------------------------------------------- - // CMODELLOADER - //------------------------------------------------------------------------- -#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) - ADDRESS CModelLoader__FindModel = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x40\x55\x41\x55\x41\x56\x48\x8D\xAC\x24\x00\x00\x00\x00", "xxxxxxxxxx????"); - // 0x1402A1F10 // 40 55 41 55 41 56 48 8D AC 24 ? ? ? ? // - - ADDRESS CModelLoader__LoadModel = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x40\x53\x57\x41\x56\x48\x81\xEC\x00\x00\x00\x00\x48\x8B\xFA", "xxxxxxxx????xxx"); - // 0x1402A23B0 // 40 53 57 41 56 48 81 EC ? ? ? ? 48 8B FA // - - ADDRESS CModelLoader__Studio_LoadModel = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x5C\x24\x00\x55\x56\x57\x41\x54\x41\x56\x48\x8D\xAC\x24\x00\x00\x00\x00", "xxxx?xxxxxxxxxxx????"); - // 0x140252F10 // 48 89 5C 24 ? 55 56 57 41 54 41 57 48 81 EC ? ? ? ? // -#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3) - ADDRESS CModelLoader__FindModel = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x40\x55\x41\x57\x48\x83\xEC\x48\x80\x3A\x2A", "xxxxxxxxxxx"); - // 0x140253530 // 40 55 41 57 48 83 EC 48 80 3A 2A // - - ADDRESS CModelLoader__LoadModel = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x40\x53\x57\x41\x57\x48\x81\xEC\x00\x00\x00\x00\x48\x8B\x05\x00\x00\x00\x00", "xxxxxxxx????xxx????"); - // 0x140253810 // 40 53 57 41 57 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? // - - ADDRESS CModelLoader__Studio_LoadModel = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x5C\x24\x00\x55\x56\x57\x41\x54\x41\x57\x48\x81\xEC\x00\x00\x00\x00", "xxxx?xxxxxxxxxx????"); - // 0x140252F10 // 48 89 5C 24 ? 55 56 57 41 54 41 57 48 81 EC ? ? ? ? // -#endif - - //------------------------------------------------------------------------- - // CGAMESERVER - //------------------------------------------------------------------------- -#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) - ADDRESS CGameServer__SpawnServer = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x40\x53\x55\x56\x57\x41\x55\x41\x56\x41\x57\x48\x81\xEC\x00\x00\x00\x00", "xxxxxxxxxxxxxx????"); -#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3) - ADDRESS CGameServer__SpawnServer = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x8B\xC4\x53\x55\x56\x57\x41\x54\x41\x55\x41\x57", "xxxxxxxxxxxxx"); - // 0x140312D80 // 48 8B C4 53 55 56 57 41 54 41 55 41 57 // -#endif - //------------------------------------------------------------------------- // CVGUI //------------------------------------------------------------------------- @@ -131,15 +98,6 @@ namespace ADDRESS CEngineVGui__ActivateGameUI = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x40\x53\x48\x83\xEC\x20\xF6\x81\x00\x00\x00\x00\x00\x48\x8B\xD9\x74\x08", "xxxxxxxx?????xxxxx"); // - //------------------------------------------------------------------------- - // RUNTIME: BSP_LUMP - //------------------------------------------------------------------------- - ADDRESS CollisionBSPData_LoadAllLumps = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x54\x24\x00\x48\x89\x4C\x24\x00\x55\x53\x56\x57\x41\x54\x41\x55\x41\x57", "xxxx?xxxx?xxxxxxxxxx"); // BSP. - // 0x1402546F0 // 48 89 54 24 ? 48 89 4C 24 ? 55 53 56 57 41 54 41 55 41 57 // - - ADDRESS CollisionBSPData_LinkPhysics = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x5C\x24\x00\x48\x89\x6C\x24\x00\x57\x48\x81\xEC\x00\x00\x00\x00\x48\x8B\xF9\x33\xED", "xxxx?xxxx?xxxx????xxxxx"); // case 1: only gets called on changelevel, needs more research, function gets called by CModelLoader virtual function. - // 0x140256480 // 48 89 5C 24 ? 48 89 6C 24 ? 57 48 81 EC ? ? ? ? 48 8B F9 33 ED // - //------------------------------------------------------------------------- // RUNTIME: FAIRFIGHT //------------------------------------------------------------------------- @@ -194,16 +152,6 @@ namespace ADDRESS _Host_RunFrame = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x8B\xC4\x48\x89\x58\x18\x48\x89\x70\x20\xF3\x0F\x11\x48\x00", "xxxxxxxxxxxxxxx?"); // _Host_RunFrame() with inlined CFrameTimer::MarkFrame()? // 0x140231C00 // 48 8B C4 48 89 58 18 48 89 70 20 F3 0F 11 48 ? // - //------------------------------------------------------------------------- - // RUNTIME: GL_SCREEN - //------------------------------------------------------------------------- -#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) - ADDRESS SCR_BeginLoadingPlaque = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x5C\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xEC\x30\x0F\x29\x74\x24\x00\x48\x8B\xF9", "xxxx?xxxx?xxxxxxxxx?xxx"); - // 0x14022A4A0 // 48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC 30 0F 29 74 24 ? 48 8B F9 // -#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3) - ADDRESS SCR_BeginLoadingPlaque = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x83\xEC\x38\x0F\x29\x74\x24\x00\x48\x89\x5C\x24\x00", "xxxxxxxx?xxxx?"); - // 0x14022A4A0 // 48 83 EC 38 0F 29 74 24 ? 48 89 5C 24 ? // -#endif //------------------------------------------------------------------------- // RUNTIME: CL_CLEARSTATE //------------------------------------------------------------------------- @@ -236,18 +184,9 @@ class HOpcodes : public IDetour std::cout << "+----------------------------------------------------------------+" << std::endl; std::cout << "| FUN: CShaderSystem::Init : 0x" << std::hex << std::uppercase << CShaderSystem__Init.GetPtr() << std::setw(npad) << " |" << std::endl; std::cout << "+----------------------------------------------------------------+" << std::endl; - std::cout << "| FUN: CollisionBSPData_LoadAllLumps : 0x" << std::hex << std::uppercase << CollisionBSPData_LoadAllLumps.GetPtr() << std::setw(npad) << " |" << std::endl; - std::cout << "| FUN: CollisionBSPData_LinkPhysics : 0x" << std::hex << std::uppercase << CollisionBSPData_LinkPhysics.GetPtr() << std::setw(npad) << " |" << std::endl; - std::cout << "+----------------------------------------------------------------+" << std::endl; std::cout << "| FUN: CStudioRenderContext::LoadModel : 0x" << std::hex << std::uppercase << CStudioRenderContext__LoadModel.GetPtr() << std::setw(npad) << " |" << std::endl; std::cout << "| FUN: CStudioRenderContext::LoadMaterials : 0x" << std::hex << std::uppercase << CStudioRenderContext__LoadMaterials.GetPtr() << std::setw(npad) << " |" << std::endl; std::cout << "+----------------------------------------------------------------+" << std::endl; - std::cout << "| FUN: CModelLoader::FindModel : 0x" << std::hex << std::uppercase << CModelLoader__FindModel.GetPtr() << std::setw(npad) << " |" << std::endl; - std::cout << "| FUN: CModelLoader::LoadModel : 0x" << std::hex << std::uppercase << CModelLoader__LoadModel.GetPtr() << std::setw(npad) << " |" << std::endl; - std::cout << "| FUN: CModelLoader::Studio_LoadModel : 0x" << std::hex << std::uppercase << CModelLoader__Studio_LoadModel.GetPtr() << std::setw(npad) << " |" << std::endl; - std::cout << "+----------------------------------------------------------------+" << std::endl; - std::cout << "| FUN: CGameServer::SpawnServer : 0x" << std::hex << std::uppercase << CGameServer__SpawnServer.GetPtr() << std::setw(npad) << " |" << std::endl; - std::cout << "+----------------------------------------------------------------+" << std::endl; std::cout << "| FUN: CVGui::RunFrame : 0x" << std::hex << std::uppercase << CVGui__RunFrame.GetPtr() << std::setw(npad) << " |" << std::endl; std::cout << "+----------------------------------------------------------------+" << std::endl; std::cout << "| FUN: CEngineVGui::Shutdown : 0x" << std::hex << std::uppercase << CEngineVGui__Shutdown.GetPtr() << std::setw(npad) << " |" << std::endl; @@ -264,8 +203,6 @@ class HOpcodes : public IDetour std::cout << "| FUN: Host_Disconnect : 0x" << std::hex << std::uppercase << Host_Disconnect.GetPtr() << std::setw(npad) << " |" << std::endl; std::cout << "| FUN: _Host_RunFrame : 0x" << std::hex << std::uppercase << _Host_RunFrame.GetPtr() << std::setw(npad) << " |" << std::endl; std::cout << "+----------------------------------------------------------------+" << std::endl; - std::cout << "| FUN: SCR_BeginLoadingPlaque : 0x" << std::hex << std::uppercase << SCR_BeginLoadingPlaque.GetPtr() << std::setw(npad) << " |" << std::endl; - std::cout << "+----------------------------------------------------------------+" << std::endl; std::cout << "| CON: g_pClientVPKDir : 0x" << std::hex << std::uppercase << g_pClientVPKDir.GetPtr() << std::setw(npad) << " |" << std::endl; std::cout << "| CON: g_pClientBSP : 0x" << std::hex << std::uppercase << g_pClientBSP.GetPtr() << std::setw(npad) << " |" << std::endl; std::cout << "| CON: g_pClientCommonBSP : 0x" << std::hex << std::uppercase << g_pClientCommonBSP.GetPtr() << std::setw(npad) << " |" << std::endl; diff --git a/r5dev/core/init.cpp b/r5dev/core/init.cpp index 9ec94195..01010f5e 100644 --- a/r5dev/core/init.cpp +++ b/r5dev/core/init.cpp @@ -26,7 +26,8 @@ #include "bsplib/bsplib.h" #ifndef DEDICATED #include "materialsystem/materialsystem.h" -#include "vgui/CEngineVGui.h" +#include "vgui/vgui_baseui_interface.h" +#include "vgui/vgui_debugpanel.h" #include "vgui/vgui_fpspanel.h" #include "vguimatsurface/MatSystemSurface.h" #include "client/cdll_engine_int.h" @@ -41,8 +42,11 @@ #include "rtech/rtech_game.h" #include "rtech/stryder.h" #include "engine/baseclient.h" +#include "engine/common.h" +#include "engine/cmodel_bsp.h" #include "engine/host_cmd.h" #include "engine/host_state.h" +#include "engine/modelloader.h" #include "engine/net.h" #include "engine/net_chan.h" #include "engine/sv_main.h" @@ -51,6 +55,7 @@ #include "engine/sys_engine.h" #include "engine/sys_utils.h" #ifndef DEDICATED +#include "engine/gl_screen.h" #include "engine/debugoverlay.h" #include "inputsystem/inputsystem.h" #include "windows/id3dx.h" @@ -103,9 +108,10 @@ void Systems_Init() CServer_Attach(); // S1 and S2 CServer functions require work. #endif // GAMEDLL_S3 -#ifdef DEDICATED - CHostState_Attach(); // Dedicated only for now until backwards compatible with S1. -#endif // DEDICATED +// !TEMP UNTIL CHOSTSTATE IS BUILD AGNOSTIC! // +#if defined (DEDICATED) || defined (GAMEDLL_S3) + CHostState_Attach(); +#endif // DEDICATED || GAMEDLL_S3 CNetChan_Attach(); ConCommand_Attach(); @@ -182,9 +188,10 @@ void Systems_Shutdown() CServer_Detach(); // S1 and S2 CServer functions require work. #endif // GAMEDLL_S3 -#ifdef DEDICATED +// !TEMP UNTIL CHOSTSTATE IS BUILD AGNOSTIC! // +#if defined (DEDICATED) || defined (GAMEDLL_S3) CHostState_Detach(); // Dedicated only for now until backwards compatible with S1. -#endif // DEDICATED +#endif // DEDICATED || GAMEDLL_S3 CNetChan_Detach(); ConCommand_Detach(); diff --git a/r5dev/dedicated.vcxproj b/r5dev/dedicated.vcxproj index 41f59e58..7b48a89b 100644 --- a/r5dev/dedicated.vcxproj +++ b/r5dev/dedicated.vcxproj @@ -196,8 +196,11 @@ + + + @@ -217,6 +220,7 @@ + @@ -396,6 +400,7 @@ + @@ -413,6 +418,7 @@ + NotUsing diff --git a/r5dev/dedicated.vcxproj.filters b/r5dev/dedicated.vcxproj.filters index cff77e39..7bb90486 100644 --- a/r5dev/dedicated.vcxproj.filters +++ b/r5dev/dedicated.vcxproj.filters @@ -717,6 +717,18 @@ sdk\launcher + + sdk\engine + + + sdk\engine + + + sdk\engine + + + sdk\networksystem + @@ -962,6 +974,12 @@ sdk\launcher + + sdk\engine + + + sdk\networksystem + diff --git a/r5dev/engine/baseclientstate.cpp b/r5dev/engine/baseclientstate.cpp index 5b9c443c..34c89ced 100644 --- a/r5dev/engine/baseclientstate.cpp +++ b/r5dev/engine/baseclientstate.cpp @@ -1,6 +1,6 @@ //===========================================================================// // -// Purpose: +// Purpose: Implementation of the CBaseClient class. // //===========================================================================// @@ -18,13 +18,13 @@ bool CBaseClientState::IsPaused() return *m_bPaused; } -// Technically doesn't belong here. //------------------------------------------------------------------------------ // Purpose: gets the client time +// Technically doesn't belong here //------------------------------------------------------------------------------ float CBaseClientState::GetClientTime() { - if (*scr_drawloading) + if (*cl_time_use_host_tickcount) { return (float)(int)*host_tickcount * (float)*client_debugdraw_int_unk; } diff --git a/r5dev/engine/cmodel_bsp.h b/r5dev/engine/cmodel_bsp.h new file mode 100644 index 00000000..a929eaa3 --- /dev/null +++ b/r5dev/engine/cmodel_bsp.h @@ -0,0 +1,25 @@ +#pragma once + +// !TODO: BUILD AGNOSTIC! // +namespace +{ + ADDRESS CollisionBSPData_LoadAllLumps = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x54\x24\x00\x48\x89\x4C\x24\x00\x55\x53\x56\x57\x41\x54\x41\x55\x41\x57", "xxxx?xxxx?xxxxxxxxxx"); // BSP. + // 0x1402546F0 // 48 89 54 24 ? 48 89 4C 24 ? 55 53 56 57 41 54 41 55 41 57 // + + ADDRESS CollisionBSPData_LinkPhysics = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x5C\x24\x00\x48\x89\x6C\x24\x00\x57\x48\x81\xEC\x00\x00\x00\x00\x48\x8B\xF9\x33\xED", "xxxx?xxxx?xxxx????xxxxx"); // case 1: only gets called on changelevel, needs more research, function gets called by CModelLoader virtual function. + // 0x140256480 // 48 89 5C 24 ? 48 89 6C 24 ? 57 48 81 EC ? ? ? ? 48 8B F9 33 ED // +} + +/////////////////////////////////////////////////////////////////////////////// +class HModel_BSP : public IDetour +{ + virtual void debugp() + { + std::cout << "| FUN: CollisionBSPData_LoadAllLumps : 0x" << std::hex << std::uppercase << CollisionBSPData_LoadAllLumps.GetPtr() << std::setw(npad) << " |" << std::endl; + std::cout << "| FUN: CollisionBSPData_LinkPhysics : 0x" << std::hex << std::uppercase << CollisionBSPData_LinkPhysics.GetPtr() << std::setw(npad) << " |" << std::endl; + std::cout << "+----------------------------------------------------------------+" << std::endl; + } +}; +/////////////////////////////////////////////////////////////////////////////// + +REGISTER(HModel_BSP); diff --git a/r5dev/engine/common.cpp b/r5dev/engine/common.cpp new file mode 100644 index 00000000..7732ca3d --- /dev/null +++ b/r5dev/engine/common.cpp @@ -0,0 +1,19 @@ +//=====================================================================================// +// +// Purpose: +// +//=====================================================================================// + +#include +#include + +/* +============================== +COM_ExplainDisconnection + +============================== +*/ +void* HCOM_ExplainDisconnection(void* unused, const char* fmt, ...) +{ + // !TODO: rebuild. +} diff --git a/r5dev/engine/common.h b/r5dev/engine/common.h new file mode 100644 index 00000000..b933ca76 --- /dev/null +++ b/r5dev/engine/common.h @@ -0,0 +1,21 @@ +#pragma once + +namespace +{ + /* ==== COMMON ========================================================================================================================================================== */ + ADDRESS p_COM_ExplainDisconnection = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x8B\xC4\x48\x89\x50\x10\x4C\x89\x40\x18\x4C\x89\x48\x20\x48\x81\xEC\x00\x00\x00\x00", "xxxxxxxxxxxxxxxxxx????"); + void* (*COM_ExplainDisconnection)(void* unused, const char* fmt, ...) = (void* (*)(void*, const char*, ...))p_COM_ExplainDisconnection.GetPtr(); /*48 8B C4 48 89 50 10 4C 89 40 18 4C 89 48 20 48 81 EC ? ? ? ?*/ +} + +/////////////////////////////////////////////////////////////////////////////// +class HCommon : public IDetour +{ + virtual void debugp() + { + std::cout << "| FUN: COM_ExplainDisconnection : 0x" << std::hex << std::uppercase << p_COM_ExplainDisconnection.GetPtr() << std::setw(npad) << " |" << std::endl; + std::cout << "+----------------------------------------------------------------+" << std::endl; + } +}; +/////////////////////////////////////////////////////////////////////////////// + +REGISTER(HCommon); diff --git a/r5dev/engine/gl_screen.cpp b/r5dev/engine/gl_screen.cpp new file mode 100644 index 00000000..bfc3485f --- /dev/null +++ b/r5dev/engine/gl_screen.cpp @@ -0,0 +1,29 @@ +//=====================================================================================// +// +// Purpose: Master for refresh, status bar, console, chat, notify, etc. +// +// $NoKeywords: $ +//=====================================================================================// + +#include +#include +#include +#include + +//----------------------------------------------------------------------------- +// Purpose: finished loading +//----------------------------------------------------------------------------- +void SCR_EndLoadingPlaque(void) +{ + if (*scr_drawloading) + { + *scr_engineevent_loadingstarted = 0; + using HideLoadingPlaqueFn = void(*)(void*); + (*reinterpret_cast(g_pEngineVGui))[36](g_pEngineVGui); // (*((void(__fastcall**)(void**))g_CEngineVGui + 36))(&g_CEngineVGui);// HideLoadingPlaque + } + else if (*gfExtendedError) + { + using ShowErrorMessageFn = void(*)(void*); + (*reinterpret_cast(g_pEngineVGui))[35](g_pEngineVGui); // (*((void(__fastcall**)(void**))g_CEngineVGui + 35))(&g_CEngineVGui);// ShowErrorMessage + } +} diff --git a/r5dev/engine/gl_screen.h b/r5dev/engine/gl_screen.h new file mode 100644 index 00000000..5d2ad462 --- /dev/null +++ b/r5dev/engine/gl_screen.h @@ -0,0 +1,43 @@ +#pragma once + +/////////////////////////////////////////////////////////////////////////////// +namespace +{ +#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) + ADDRESS SCR_BeginLoadingPlaque = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x5C\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xEC\x30\x0F\x29\x74\x24\x00\x48\x8B\xF9", "xxxx?xxxx?xxxxxxxxx?xxx"); + // 0x14022A4A0 // 48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC 30 0F 29 74 24 ? 48 8B F9 // +#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3) + ADDRESS SCR_BeginLoadingPlaque = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x83\xEC\x38\x0F\x29\x74\x24\x00\x48\x89\x5C\x24\x00", "xxxxxxxx?xxxx?"); + // 0x14022A4A0 // 48 83 EC 38 0F 29 74 24 ? 48 89 5C 24 ? // +#endif +} + +/////////////////////////////////////////////////////////////////////////////// +namespace +{ + bool* scr_drawloading = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x0F\xB6\x05\x00\x00\x00\x00\xC3\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\x48\x83\xEC\x28", "xxx????xxxxxxxxxxxxx") + .ResolveRelativeAddressSelf(0x3, 0x7).RCast(); +#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) + char* scr_engineevent_loadingstarted = SCR_BeginLoadingPlaque.Offset(0x130).FindPatternSelf("C6 05 ?? ?? ?? ?? 01", ADDRESS::Direction::DOWN).ResolveRelativeAddress(0x2, 0x7).RCast(); +#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3) + bool* scr_engineevent_loadingstarted = SCR_BeginLoadingPlaque.Offset(0x60).FindPatternSelf("C6 05 ?? ?? ?? ?? 01", ADDRESS::Direction::DOWN).ResolveRelativeAddress(0x2, 0x7).RCast(); +#endif +} + +void SCR_EndLoadingPlaque(void); + +/////////////////////////////////////////////////////////////////////////////// +class HGL_Screen : public IDetour +{ + virtual void debugp() + { + std::cout << "| VAR: SCR_BeginLoadingPlaque : 0x" << std::hex << std::uppercase << SCR_BeginLoadingPlaque.GetPtr() << std::setw(npad) << " |" << std::endl; + std::cout << "+----------------------------------------------------------------+" << std::endl; + std::cout << "| VAR: scr_drawloading : 0x" << std::hex << std::uppercase << scr_drawloading << std::setw(0) << " |" << std::endl; + std::cout << "| VAR: scr_engineevent_loadingstarted : 0x" << std::hex << std::uppercase << scr_engineevent_loadingstarted << std::setw(0) << " |" << std::endl; + std::cout << "+----------------------------------------------------------------+" << std::endl; + } +}; +/////////////////////////////////////////////////////////////////////////////// + +REGISTER(HGL_Screen); diff --git a/r5dev/engine/host_cmd.h b/r5dev/engine/host_cmd.h index 6001c222..e4101b30 100644 --- a/r5dev/engine/host_cmd.h +++ b/r5dev/engine/host_cmd.h @@ -1,5 +1,5 @@ #pragma once - +#include "launcher/IApplication.h" struct EngineParms_t { char* baseDirectory; @@ -22,17 +22,16 @@ namespace #endif ADDRESS p_malloc_internal = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\xE9\x00\x00\x00\x00\xCC\xCC\xCC\x40\x53\x48\x83\xEC\x20\x48\x8D\x05\x00\x00\x00\x00", "x????xxxxxxxxxxxx????"); void* (*malloc_internal)(void* pPool, int64_t size) = (void* (*)(void*, int64_t))p_malloc_internal.GetPtr(); /*E9 ? ? ? ? CC CC CC 40 53 48 83 EC 20 48 8D 05 ? ? ? ?*/ - - // TODO: Verify for other seasons beside 3. - static ADDRESS g_pEngineParmsBuffer = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x4C\x8B\x05\x00\x00\x00\x00\xB2\x01", "xxx????xx").ResolveRelativeAddressSelf(0x3, 0x7); } namespace { #if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) ADDRESS g_pMallocPool = p_Host_Init.Offset(0x600).FindPatternSelf("48 8D 15 ?? ?? ?? 01", ADDRESS::Direction::DOWN, 100).ResolveRelativeAddressSelf(0x3, 0x7); + static ADDRESS g_pEngineParmsBuffer = p_IAppSystem_Main.Offset(0x0).FindPatternSelf("48 8B", ADDRESS::Direction::DOWN, 100).ResolveRelativeAddress(0x3, 0x7); #elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3) ADDRESS g_pMallocPool = p_Host_Init.Offset(0x130).FindPatternSelf("48 8D 15 ?? ?? ?? 01", ADDRESS::Direction::DOWN, 100).ResolveRelativeAddressSelf(0x3, 0x7); + static ADDRESS g_pEngineParmsBuffer = p_IAppSystem_Main.Offset(0x0).FindPatternSelf("4C 8B", ADDRESS::Direction::DOWN, 100).ResolveRelativeAddress(0x3, 0x7); #endif } diff --git a/r5dev/engine/host_state.cpp b/r5dev/engine/host_state.cpp index a9bf438b..670692a0 100644 --- a/r5dev/engine/host_state.cpp +++ b/r5dev/engine/host_state.cpp @@ -5,196 +5,37 @@ //=============================================================================// #include "core/stdafx.h" +#include "tier0/cmd.h" #include "tier0/cvar.h" #include "tier0/commandline.h" #include "tier1/NetAdr2.h" #include "tier2/socketcreator.h" -#include "engine/sys_utils.h" -#include "engine/host_state.h" -#include "engine/net_chan.h" -#include "client/IVEngineClient.h" -#include "networksystem/r5net.h" -#include "squirrel/sqinit.h" -#include "public/include/bansystem.h" -#include "engine/sys_engine.h" #ifdef DEDICATED #include "engine/sv_rcon.h" #else // #include "engine/cl_rcon.h" #endif // DEDICATED - -//----------------------------------------------------------------------------- -// Purpose: Send keep alive request to Pylon Master Server. -// NOTE: When Pylon update reaches indev remove this and implement properly. -//----------------------------------------------------------------------------- -void KeepAliveToPylon() -{ - if (g_pHostState->m_bActiveGame && sv_pylonvisibility->GetBool()) // Check for active game. - { - std::string m_szHostToken = std::string(); - std::string m_szHostRequestMessage = std::string(); - DevMsg(eDLL_T::CLIENT, "Sending PostServerHost request\n"); - bool result = g_pR5net->PostServerHost(m_szHostRequestMessage, m_szHostToken, - ServerListing{ - g_pCVar->FindVar("hostname")->GetString(), - std::string(g_pHostState->m_levelName), - "", - g_pCVar->FindVar("hostport")->GetString(), - g_pCVar->FindVar("mp_gamemode")->GetString(), - false, - std::to_string(*g_nServerRemoteChecksum), - std::string(), - g_szNetKey.c_str() - } - ); - } -} - -//----------------------------------------------------------------------------- -// Purpose: Check refuse list and kill netchan connection. -//----------------------------------------------------------------------------- -void BanListCheck() -{ - if (g_pBanSystem->IsRefuseListValid()) - { - for (int i = 0; i < g_pBanSystem->vsvrefuseList.size(); i++) // Loop through vector. - { - for (int c = 0; c < MAX_PLAYERS; c++) // Loop through all possible client instances. - { - CClient* client = g_pClient->GetClientInstance(c); // Get client instance. - if (!client) - { - continue; - } - - if (!client->GetNetChan()) // Netchan valid? - { - continue; - } - - if (g_pClient->m_iOriginID != g_pBanSystem->vsvrefuseList[i].second) // See if nucleus id matches entry. - { - continue; - } - - std::string finalIpAddress = std::string(); - ADDRESS ipAddressField = ADDRESS(((std::uintptr_t)client->GetNetChan()) + 0x1AC0); // Get client ip from netchan. - if (ipAddressField && ipAddressField.GetValue() != 0x0) - { - std::stringstream ss; - ss << std::to_string(ipAddressField.GetValue()) << "." - << std::to_string(ipAddressField.Offset(0x1).GetValue()) << "." - << std::to_string(ipAddressField.Offset(0x2).GetValue()) << "." - << std::to_string(ipAddressField.Offset(0x3).GetValue()); - - finalIpAddress = ss.str(); - } - - DevMsg(eDLL_T::SERVER, "\n"); - DevMsg(eDLL_T::SERVER, "______________________________________________________________\n"); - DevMsg(eDLL_T::SERVER, "] PYLON NOTICE -----------------------------------------------\n"); - DevMsg(eDLL_T::SERVER, "] OriginID : | '%lld' IS GETTING DISCONNECTED.\n", g_pClient->m_iOriginID); - if (finalIpAddress.empty()) - DevMsg(eDLL_T::SERVER, "] IP-ADDR : | CLIENT MODIFIED PACKET.\n"); - else - DevMsg(eDLL_T::SERVER, "] IP-ADDR : | '%s'\n", finalIpAddress.c_str()); - DevMsg(eDLL_T::SERVER, "--------------------------------------------------------------\n"); - DevMsg(eDLL_T::SERVER, "\n"); - - g_pBanSystem->AddEntry(finalIpAddress, g_pClient->m_iOriginID); // Add local entry to reserve a non needed request. - g_pBanSystem->Save(); // Save list. - NET_DisconnectClient(g_pClient, c, g_pBanSystem->vsvrefuseList[i].first.c_str(), 0, 1); // Disconnect client. - } - } - } -} +#include "engine/sys_engine.h" +#include "engine/sys_utils.h" +#include "engine/host_state.h" +#include "engine/net_chan.h" +#include "engine/gl_screen.h" +#ifndef DEDICATED +#include "vgui/vgui_baseui_interface.h" +#endif // DEDICATED +#include "client/IVEngineClient.h" +#include "networksystem/pylon.h" +#include "public/include/bansystem.h" //----------------------------------------------------------------------------- // Purpose: state machine's main processing loop //----------------------------------------------------------------------------- -void HCHostState_FrameUpdate(void* rcx, void* rdx, float time) +void CHostState::FrameUpdate(void* rcx, void* rdx, float time) { - static auto setjmpFn = ADDRESS(0x141205460).RCast(); - static auto host_abortserver = ADDRESS(0x14B37C700).RCast(); - static auto CHostState_InitFn = ADDRESS(0x14023E7D0).RCast(); - static auto g_ServerAbortServer = ADDRESS(0x14B37CA22).RCast(); - static auto State_RunFn = ADDRESS(0x14023E870).RCast(); - static auto Cbuf_ExecuteFn = ADDRESS(0x14020D5C0).RCast(); - static auto g_ServerGameClients = ADDRESS(0x14B383428).RCast(); - static auto SV_InitGameDLLFn = ADDRESS(0x140308B90).RCast(); - static auto g_CModelLoader = ADDRESS(0x14173B210).RCast(); - static auto CModelLoader_Map_IsValidFn = ADDRESS(0x1402562F0).RCast(); - static auto Host_NewGameFn = ADDRESS(0x140238DA0).RCast(); - static auto Host_Game_ShutdownFn = ADDRESS(0x14023EDA0).RCast(); - static auto src_drawloading = ADDRESS(0x14B37D96B).RCast(); - static auto scr_engineevent_loadingstarted = ADDRESS(0x1666ED024).RCast(); - static auto gfExtendedError = ADDRESS(0x14B383391).RCast(); - static auto g_CEngineVGui = ADDRESS(0x141741310).RCast(); - static auto g_ServerDLL = ADDRESS(0x141732048).RCast(); - static auto Host_ChangelevelFn = ADDRESS(0x1402387B0).RCast(); - static auto CL_EndMovieFn = ADDRESS(0x1402C03D0).RCast(); - static auto SendOfflineRequestToStryderFn = ADDRESS(0x14033D380).RCast(); - static bool bInitialized = false; if (!bInitialized) { - if (!g_pCmdLine->CheckParm("-devsdk")) - { - IVEngineClient_CommandExecute(NULL, "exec \"autoexec_server.cfg\""); - IVEngineClient_CommandExecute(NULL, "exec \"rcon_server.cfg\""); -#ifndef DEDICATED - IVEngineClient_CommandExecute(NULL, "exec \"autoexec_client.cfg\""); - IVEngineClient_CommandExecute(NULL, "exec \"rcon_client.cfg\""); -#endif // !DEDICATED - IVEngineClient_CommandExecute(NULL, "exec \"autoexec.cfg\""); - } - else // Development configs. - { - IVEngineClient_CommandExecute(NULL, "exec \"autoexec_server_dev.cfg\""); - IVEngineClient_CommandExecute(NULL, "exec \"rcon_server_dev.cfg\""); -#ifndef DEDICATED - IVEngineClient_CommandExecute(NULL, "exec \"autoexec_client_dev.cfg\""); - IVEngineClient_CommandExecute(NULL, "exec \"rcon_client_dev.cfg\""); -#endif // !DEDICATED - IVEngineClient_CommandExecute(NULL, "exec \"autoexec_dev.cfg\""); - } - - g_pConVar->ClearHostNames(); -#ifdef DEDICATED - g_pRConServer->Init(); -#else // - g_pRConClient->Init(); -#endif // DEDICATED - - *(bool*)m_bRestrictServerCommands = true; // Restrict commands. - ConCommandBase* disconnect = (ConCommandBase*)g_pCVar->FindCommand("disconnect"); - disconnect->AddFlags(FCVAR_SERVER_CAN_EXECUTE); // Make sure server is not restricted to this. - - static std::thread PylonThread([]() // Pylon request thread. - { - while (true) - { - KeepAliveToPylon(); - std::this_thread::sleep_for(std::chrono::milliseconds(5000)); - } - }); - - static std::thread BanlistThread([]() - { - while (true) - { - BanListCheck(); - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - } - }); - - if (net_userandomkey->GetBool()) - { - HNET_GenerateKey(); - } - - g_pCVar->FindVar("net_usesocketsforloopback")->SetValue(1); - + g_pHostState->Setup(); bInitialized = true; } #ifdef DEDICATED @@ -216,125 +57,26 @@ void HCHostState_FrameUpdate(void* rcx, void* rdx, float time) do { - Cbuf_ExecuteFn(); + Cbuf_Execute(); oldState = g_pHostState->m_iCurrentState; switch (g_pHostState->m_iCurrentState) { case HostStates_t::HS_NEW_GAME: { - DevMsg(eDLL_T::ENGINE, "CHostState::FrameUpdate | CASE:HS_NEW_GAME | Loading level: '%s'\n", g_pHostState->m_levelName); + DevMsg(eDLL_T::ENGINE, "Loading level: '%s'\n", g_pHostState->m_levelName); - // Inlined CHostState::State_NewGame - g_pHostState->m_bSplitScreenConnect = false; - if (!g_ServerGameClients) // Init Game if it ain't valid. - { - SV_InitGameDLLFn(); - } - - if (!CModelLoader_Map_IsValidFn(g_CModelLoader, g_pHostState->m_levelName) // Check if map is valid and if we can start a new game. - || !Host_NewGameFn(g_pHostState->m_levelName, nullptr, g_pHostState->m_bBackgroundLevel, g_pHostState->m_bSplitScreenConnect, nullptr) || !g_ServerGameClients) - { - DevMsg(eDLL_T::ENGINE, "CHostState::FrameUpdate | CASE:HS_NEW_GAME | Error: Map not valid.\n"); - // Inlined SCR_EndLoadingPlaque - if (*src_drawloading) - { - *scr_engineevent_loadingstarted = 0; - using HideLoadingPlaqueFn = void(*)(void*); - (*reinterpret_cast(g_CEngineVGui))[36](g_CEngineVGui); // (*((void(__fastcall**)(void**))g_CEngineVGui + 36))(&g_CEngineVGui);// HideLoadingPlaque - } - else if (*gfExtendedError) - { - using ShowErrorMessageFn = void(*)(void*); - (*reinterpret_cast(g_CEngineVGui))[35](g_CEngineVGui); // (*((void(__fastcall**)(void**))g_CEngineVGui + 35))(&g_CEngineVGui);// ShowErrorMessage - } - // End Inline SCR_EndLoadingPlaque - - // Inlined CHostState::GameShutdown - if (g_pHostState->m_bActiveGame) - { - using GameShutdownFn = void(*)(void*); - (*reinterpret_cast(g_ServerDLL))[9](g_ServerDLL); // (*(void(__fastcall**)(void*))(*(_QWORD*)g_ServerDLL + 72i64))(g_ServerDLL);// GameShutdown - g_pHostState->m_bActiveGame = 0; - } - // End Inline CHostState::GameShutdown - } - - // Seems useless so nope. - // if (g_CHLClient) - // (*(void(__fastcall**)(__int64, _QWORD))(*(_QWORD*)g_CHLClient + 1000i64))(g_CHLClient, 0i64); - - g_pHostState->m_iCurrentState = HostStates_t::HS_RUN; // Set current state to run. - - // If our next state isn't a shutdown or its a forced shutdown then set next state to run. - if (g_pHostState->m_iNextState != HostStates_t::HS_SHUTDOWN || !g_pCVar->FindVar("host_hasIrreversibleShutdown")->GetBool()) - { - g_pHostState->m_iNextState = HostStates_t::HS_RUN; - } - - // End Inline CHostState::State_NewGame + g_pHostState->State_NewGame(); break; } case HostStates_t::HS_CHANGE_LEVEL_SP: { - g_pHostState->m_flShortFrameTime = 1.5; // Set frame time. - - DevMsg(eDLL_T::ENGINE, "CHostState::FrameUpdate | CASE:HS_CHANGE_LEVEL_SP | Changing singleplayer level to: '%s'\n", g_pHostState->m_levelName); - - if (CModelLoader_Map_IsValidFn(g_CModelLoader, g_pHostState->m_levelName)) // Check if map is valid and if we can start a new game. - { - Host_ChangelevelFn(true, g_pHostState->m_levelName, g_pHostState->m_mapGroupName); // Call change level as singleplayer level. - } - else - { - DevMsg(eDLL_T::ENGINE, "CHostState::FrameUpdate | CASE:HS_CHANGE_LEVEL_SP | Error: Unable to find map: '%s'\n", g_pHostState->m_levelName); - } - - // Seems useless so nope. - // if (g_CHLClient) - // (*(void(__fastcall**)(__int64, _QWORD))(*(_QWORD*)g_CHLClient + 1000i64))(g_CHLClient, 0i64); - - g_pHostState->m_iCurrentState = HostStates_t::HS_RUN; // Set current state to run. - - // If our next state isn't a shutdown or its a forced shutdown then set next state to run. - if (g_pHostState->m_iNextState != HostStates_t::HS_SHUTDOWN || !g_pCVar->FindVar("host_hasIrreversibleShutdown")->GetBool()) - { - g_pHostState->m_iNextState = HostStates_t::HS_RUN; - } - + g_pHostState->State_ChangeLevelSP(); break; } case HostStates_t::HS_CHANGE_LEVEL_MP: { - g_pHostState->m_flShortFrameTime = 0.5; // Set frame time. - using LevelShutdownFn = void(__thiscall*)(void*); - (*reinterpret_cast(*g_ServerDLL))[8](g_ServerDLL); // (*(void (__fastcall **)(void *))(*(_QWORD *)server_dll_var + 64i64))(server_dll_var);// LevelShutdown - - DevMsg(eDLL_T::ENGINE, "CHostState::FrameUpdate | CASE:HS_CHANGE_LEVEL_MP | Changing multiplayer level to: '%s'\n", g_pHostState->m_levelName); - - if (CModelLoader_Map_IsValidFn(g_CModelLoader, g_pHostState->m_levelName)) // Check if map is valid and if we can start a new game. - { - using EnabledProgressBarForNextLoadFn = void(*)(void*); - (*reinterpret_cast(g_CEngineVGui))[31](g_CEngineVGui); // (*((void(__fastcall**)(void**))g_CEngineVGUI + 31))(&g_CEngineVGUI);// EnabledProgressBarForNextLoad - Host_ChangelevelFn(false, g_pHostState->m_levelName, g_pHostState->m_mapGroupName); // Call change level as multiplayer level. - } - else - { - DevMsg(eDLL_T::ENGINE, "CHostState::FrameUpdate | CASE:HS_CHANGE_LEVEL_MP | Error: Unable to find map: '%s'\n", g_pHostState->m_levelName); - } - - // Seems useless so nope. - // // if (g_CHLClient) - // (*(void(__fastcall**)(__int64, _QWORD))(*(_QWORD*)g_CHLClient + 1000i64))(g_CHLClient, 0i64); - - g_pHostState->m_iCurrentState = HostStates_t::HS_RUN; // Set current state to run. - - // If our next state isn't a shutdown or its a forced shutdown then set next state to run. - if (g_pHostState->m_iNextState != HostStates_t::HS_SHUTDOWN || !g_pCVar->FindVar("host_hasIrreversibleShutdown")->GetBool()) - { - g_pHostState->m_iNextState = HostStates_t::HS_RUN; - } - + g_pHostState->State_ChangeLevelMP(); break; } case HostStates_t::HS_RUN: @@ -344,22 +86,26 @@ void HCHostState_FrameUpdate(void* rcx, void* rdx, float time) } case HostStates_t::HS_GAME_SHUTDOWN: { - DevMsg(eDLL_T::ENGINE, "CHostState::FrameUpdate | CASE:HS_GAME_SHUTDOWN | Shutdown game\n"); + DevMsg(eDLL_T::ENGINE, "Shutdown game\n"); Host_Game_ShutdownFn(g_pHostState); break; } case HostStates_t::HS_RESTART: { - DevMsg(eDLL_T::ENGINE, "CHostState::FrameUpdate | CASE:HS_RESTART | Restarting client\n"); + DevMsg(eDLL_T::ENGINE, "Restarting statemachine\n"); +#ifndef DEDICATED CL_EndMovieFn(); +#endif // !DEDICATED SendOfflineRequestToStryderFn(); // We have hostnames nulled anyway. g_pEngine->SetNextState(EngineState_t::DLL_RESTART); break; } case HostStates_t::HS_SHUTDOWN: { - DevMsg(eDLL_T::ENGINE, "CHostState::FrameUpdate | CASE:HS_SHUTDOWN | Shutdown client\n"); + DevMsg(eDLL_T::ENGINE, "Shutdown statemachine\n"); +#ifndef DEDICATED CL_EndMovieFn(); +#endif // !DEDICATED SendOfflineRequestToStryderFn(); // We have hostnames nulled anyway. g_pEngine->SetNextState(EngineState_t::DLL_CLOSE); break; @@ -377,14 +123,188 @@ void HCHostState_FrameUpdate(void* rcx, void* rdx, float time) } } +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHostState::Setup(void) const +{ + g_pHostState->LoadConfig(); + g_pConVar->ClearHostNames(); +#ifdef DEDICATED + g_pRConServer->Init(); +#else // + g_pRConClient->Init(); +#endif // DEDICATED + + *(bool*)m_bRestrictServerCommands = true; // Restrict commands. + ConCommandBase* disconnect = (ConCommandBase*)g_pCVar->FindCommand("disconnect"); + disconnect->AddFlags(FCVAR_SERVER_CAN_EXECUTE); // Make sure server is not restricted to this. + + static std::thread PylonThread([]() // Pylon request thread. + { + while (true) + { + KeepAliveToPylon(); + std::this_thread::sleep_for(std::chrono::milliseconds(5000)); + } + }); + + static std::thread BanlistThread([]() + { + while (true) + { + g_pBanSystem->BanListCheck(); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + } + }); + + if (net_userandomkey->GetBool()) + { + HNET_GenerateKey(); + } + + g_pCVar->FindVar("net_usesocketsforloopback")->SetValue(1); +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHostState::LoadConfig(void) const +{ + if (!g_pCmdLine->CheckParm("-devsdk")) + { + IVEngineClient_CommandExecute(NULL, "exec \"autoexec_server.cfg\""); + IVEngineClient_CommandExecute(NULL, "exec \"rcon_server.cfg\""); +#ifndef DEDICATED + IVEngineClient_CommandExecute(NULL, "exec \"autoexec_client.cfg\""); + IVEngineClient_CommandExecute(NULL, "exec \"rcon_client.cfg\""); +#endif // !DEDICATED + IVEngineClient_CommandExecute(NULL, "exec \"autoexec.cfg\""); + } + else // Development configs. + { + IVEngineClient_CommandExecute(NULL, "exec \"autoexec_server_dev.cfg\""); + IVEngineClient_CommandExecute(NULL, "exec \"rcon_server_dev.cfg\""); +#ifndef DEDICATED + IVEngineClient_CommandExecute(NULL, "exec \"autoexec_client_dev.cfg\""); + IVEngineClient_CommandExecute(NULL, "exec \"rcon_client_dev.cfg\""); +#endif // !DEDICATED + IVEngineClient_CommandExecute(NULL, "exec \"autoexec_dev.cfg\""); + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHostState::State_NewGame(void) +{ + m_bSplitScreenConnect = false; + if (!g_ServerGameClients) // Init Game if it ain't valid. + { + SV_InitGameDLLFn(); + } + + if (!CModelLoader_Map_IsValidFn(g_CModelLoader, m_levelName) // Check if map is valid and if we can start a new game. + || !Host_NewGameFn(m_levelName, nullptr, m_bBackgroundLevel, m_bSplitScreenConnect, nullptr) || !g_ServerGameClients) + { + DevMsg(eDLL_T::ENGINE, "Error: Map not valid\n"); +#ifndef DEDICATED + SCR_EndLoadingPlaque(); +#endif // !DEDICATED + GameShutDown(); + } + + m_iCurrentState = HostStates_t::HS_RUN; // Set current state to run. + + // If our next state isn't a shutdown or its a forced shutdown then set next state to run. + if (m_iNextState != HostStates_t::HS_SHUTDOWN || !g_pCVar->FindVar("host_hasIrreversibleShutdown")->GetBool()) + { + m_iNextState = HostStates_t::HS_RUN; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHostState::GameShutDown(void) +{ + if (m_bActiveGame) + { + using GameShutdownFn = void(*)(void*); + (*reinterpret_cast(g_ServerDLL))[9](g_ServerDLL); // (*(void(__fastcall**)(void*))(*(_QWORD*)g_ServerDLL + 72i64))(g_ServerDLL);// GameShutdown + m_bActiveGame = 0; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHostState::State_ChangeLevelSP(void) +{ + DevMsg(eDLL_T::ENGINE, "Changing singleplayer level to: '%s'\n", m_levelName); + m_flShortFrameTime = 1.5; // Set frame time. + + if (CModelLoader_Map_IsValidFn(g_CModelLoader, m_levelName)) // Check if map is valid and if we can start a new game. + { + Host_ChangelevelFn(true, m_levelName, m_mapGroupName); // Call change level as singleplayer level. + } + else + { + DevMsg(eDLL_T::ENGINE, "Error: Unable to find map: '%s'\n", m_levelName); + } + + m_iCurrentState = HostStates_t::HS_RUN; // Set current state to run. + + // If our next state isn't a shutdown or its a forced shutdown then set next state to run. + if (m_iNextState != HostStates_t::HS_SHUTDOWN || !g_pCVar->FindVar("host_hasIrreversibleShutdown")->GetBool()) + { + m_iNextState = HostStates_t::HS_RUN; + } +} + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CHostState::State_ChangeLevelMP(void) +{ + DevMsg(eDLL_T::ENGINE, "Changing multiplayer level to: '%s'\n", m_levelName); + m_flShortFrameTime = 0.5; // Set frame time. + + using LevelShutdownFn = void(__thiscall*)(void*); + (*reinterpret_cast(*g_ServerDLL))[8](g_ServerDLL); // (*(void (__fastcall **)(void *))(*(_QWORD *)server_dll_var + 64i64))(server_dll_var);// LevelShutdown + + if (CModelLoader_Map_IsValidFn(g_CModelLoader, m_levelName)) // Check if map is valid and if we can start a new game. + { +#ifndef DEDICATED + using EnabledProgressBarForNextLoadFn = void(*)(void*); + (*reinterpret_cast(g_pEngineVGui))[31](g_pEngineVGui); // (*((void(__fastcall**)(void**))g_CEngineVGUI + 31))(&g_CEngineVGUI);// EnabledProgressBarForNextLoad +#endif // !DEDICATED + Host_ChangelevelFn(false, m_levelName, m_mapGroupName); // Call change level as multiplayer level. + } + else + { + DevMsg(eDLL_T::ENGINE, "Error: Unable to find map: '%s'\n", m_levelName); + } + + m_iCurrentState = HostStates_t::HS_RUN; // Set current state to run. + + // If our next state isn't a shutdown or its a forced shutdown then set next state to run. + if (m_iNextState != HostStates_t::HS_SHUTDOWN || !g_pCVar->FindVar("host_hasIrreversibleShutdown")->GetBool()) + { + m_iNextState = HostStates_t::HS_RUN; + } +} + +/////////////////////////////////////////////////////////////////////////////// void CHostState_Attach() { - DetourAttach((LPVOID*)&CHostState_FrameUpdate, &HCHostState_FrameUpdate); + DetourAttach((LPVOID*)&CHostState_FrameUpdate, &CHostState::FrameUpdate); } void CHostState_Detach() { - DetourDetach((LPVOID*)&CHostState_FrameUpdate, &HCHostState_FrameUpdate); + DetourDetach((LPVOID*)&CHostState_FrameUpdate, &CHostState::FrameUpdate); } +/////////////////////////////////////////////////////////////////////////////// CHostState* g_pHostState = reinterpret_cast(p_CHostState_FrameUpdate.FindPatternSelf("48 8D ?? ?? ?? ?? 01", ADDRESS::Direction::DOWN, 100).ResolveRelativeAddressSelf(0x3, 0x7).GetPtr());; diff --git a/r5dev/engine/host_state.h b/r5dev/engine/host_state.h index a16cb06f..535a5194 100644 --- a/r5dev/engine/host_state.h +++ b/r5dev/engine/host_state.h @@ -16,21 +16,33 @@ enum class HostStates_t : int class CHostState { public: - HostStates_t m_iCurrentState; //0x0000 - HostStates_t m_iNextState; //0x0004 - Vector3 m_vecLocation; //0x0008 - QAngle m_angLocation; //0x0014 - char m_levelName[64]; //0x0020 - char m_mapGroupName[256]; //0x0060 - char m_landMarkName[256]; //0x0160 - float m_flShortFrameTime; //0x0260 - bool m_bActiveGame; //0x0264 - bool m_bRememberLocation; //0x0265 - bool m_bBackgroundLevel; //0x0266 - bool m_bWaitingForConnection; //0x0267 - bool m_bSplitScreenConnect; //0x0268 - bool m_bGameHasShutDownAndFlushedMemory; //0x0269 - bool m_bWorkshopMapDownloadPending; //0x026A + static void FrameUpdate(void* rcx, void* rdx, float time); + + void Setup(void) const; + void LoadConfig(void) const; + + void State_NewGame(void); + void GameShutDown(void); + + void State_ChangeLevelSP(void); + void State_ChangeLevelMP(void); + +public: + HostStates_t m_iCurrentState; //0x0000 + HostStates_t m_iNextState; //0x0004 + Vector3 m_vecLocation; //0x0008 + QAngle m_angLocation; //0x0014 + char m_levelName[64]; //0x0020 + char m_mapGroupName[256]; //0x0060 + char m_landMarkName[256]; //0x0160 + float m_flShortFrameTime; //0x0260 + bool m_bActiveGame; //0x0264 + bool m_bRememberLocation; //0x0265 + bool m_bBackgroundLevel; //0x0266 + bool m_bWaitingForConnection; //0x0267 + bool m_bSplitScreenConnect; //0x0268 + bool m_bGameHasShutDownAndFlushedMemory; //0x0269 + bool m_bWorkshopMapDownloadPending; //0x026A }; namespace @@ -40,9 +52,26 @@ namespace void (*CHostState_FrameUpdate)(void* rcx, void* rdx, float time) = (void(*)(void*, void*, float))p_CHostState_FrameUpdate.GetPtr(); /*48 89 5C 24 08 48 89 6C 24 20 F3 0F 11 54 24 18*/ } -/////////////////////////////////////////////////////////////////////////////// -void HCHostState_FrameUpdate(void* rcx, void* rdx, float time); +namespace // !TEMP +{ + static auto setjmpFn = ADDRESS(0x141205460).RCast(); + static auto host_abortserver = ADDRESS(0x14B37C700).RCast(); + static auto CHostState_InitFn = ADDRESS(0x14023E7D0).RCast(); + static auto g_ServerAbortServer = ADDRESS(0x14B37CA22).RCast(); + static auto State_RunFn = ADDRESS(0x14023E870).RCast(); + static auto g_ServerGameClients = ADDRESS(0x14B383428).RCast(); + static auto SV_InitGameDLLFn = ADDRESS(0x140308B90).RCast(); + static auto g_CModelLoader = ADDRESS(0x14173B210).RCast(); + static auto CModelLoader_Map_IsValidFn = ADDRESS(0x1402562F0).RCast(); + static auto Host_NewGameFn = ADDRESS(0x140238DA0).RCast(); + static auto Host_Game_ShutdownFn = ADDRESS(0x14023EDA0).RCast(); + static auto g_ServerDLL = ADDRESS(0x141732048).RCast(); + static auto Host_ChangelevelFn = ADDRESS(0x1402387B0).RCast(); + static auto CL_EndMovieFn = ADDRESS(0x1402C03D0).RCast(); + static auto SendOfflineRequestToStryderFn = ADDRESS(0x14033D380).RCast(); +} +/////////////////////////////////////////////////////////////////////////////// void CHostState_Attach(); void CHostState_Detach(); diff --git a/r5dev/engine/modelloader.h b/r5dev/engine/modelloader.h new file mode 100644 index 00000000..9cfcd834 --- /dev/null +++ b/r5dev/engine/modelloader.h @@ -0,0 +1,39 @@ +#pragma once + +namespace +{ +#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) + ADDRESS CModelLoader__FindModel = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x40\x55\x41\x55\x41\x56\x48\x8D\xAC\x24\x00\x00\x00\x00", "xxxxxxxxxx????"); + // 0x1402A1F10 // 40 55 41 55 41 56 48 8D AC 24 ? ? ? ? // + + ADDRESS CModelLoader__LoadModel = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x40\x53\x57\x41\x56\x48\x81\xEC\x00\x00\x00\x00\x48\x8B\xFA", "xxxxxxxx????xxx"); + // 0x1402A23B0 // 40 53 57 41 56 48 81 EC ? ? ? ? 48 8B FA // + + ADDRESS CModelLoader__Studio_LoadModel = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x5C\x24\x00\x55\x56\x57\x41\x54\x41\x56\x48\x8D\xAC\x24\x00\x00\x00\x00", "xxxx?xxxxxxxxxxx????"); + // 0x140252F10 // 48 89 5C 24 ? 55 56 57 41 54 41 57 48 81 EC ? ? ? ? // +#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3) + ADDRESS CModelLoader__FindModel = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x40\x55\x41\x57\x48\x83\xEC\x48\x80\x3A\x2A", "xxxxxxxxxxx"); + // 0x140253530 // 40 55 41 57 48 83 EC 48 80 3A 2A // + + ADDRESS CModelLoader__LoadModel = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x40\x53\x57\x41\x57\x48\x81\xEC\x00\x00\x00\x00\x48\x8B\x05\x00\x00\x00\x00", "xxxxxxxx????xxx????"); + // 0x140253810 // 40 53 57 41 57 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? // + + ADDRESS CModelLoader__Studio_LoadModel = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x5C\x24\x00\x55\x56\x57\x41\x54\x41\x57\x48\x81\xEC\x00\x00\x00\x00", "xxxx?xxxxxxxxxx????"); + // 0x140252F10 // 48 89 5C 24 ? 55 56 57 41 54 41 57 48 81 EC ? ? ? ? // +#endif +} + +/////////////////////////////////////////////////////////////////////////////// +class HModelLoader : public IDetour +{ + virtual void debugp() + { + std::cout << "| FUN: CModelLoader::FindModel : 0x" << std::hex << std::uppercase << CModelLoader__FindModel.GetPtr() << std::setw(npad) << " |" << std::endl; + std::cout << "| FUN: CModelLoader::LoadModel : 0x" << std::hex << std::uppercase << CModelLoader__LoadModel.GetPtr() << std::setw(npad) << " |" << std::endl; + std::cout << "| FUN: CModelLoader::Studio_LoadModel : 0x" << std::hex << std::uppercase << CModelLoader__Studio_LoadModel.GetPtr() << std::setw(npad) << " |" << std::endl; + std::cout << "+----------------------------------------------------------------+" << std::endl; + } +}; +/////////////////////////////////////////////////////////////////////////////// + +REGISTER(HModelLoader); diff --git a/r5dev/engine/net_chan.cpp b/r5dev/engine/net_chan.cpp index c801c5a7..cd34ffca 100644 --- a/r5dev/engine/net_chan.cpp +++ b/r5dev/engine/net_chan.cpp @@ -26,9 +26,9 @@ //----------------------------------------------------------------------------- void HNET_ShutDown(void* thisptr, const char* szReason, std::uint8_t a1, char a2) { -#ifndef GAMEDLL_S1 // TODO +#if !defined (GAMEDLL_S0) || !defined (GAMEDLL_S1) // !TEMP UNTIL CHOSTSTATE IS BUILD AGNOSTIC! // DownloadPlaylists_f_CompletionFunc(); // Re-load playlist from disk after getting disconnected from the server. -#endif +#endif // !GAMEDLL_S0 || GAMEDLL_S1 NET_Shutdown(thisptr, szReason, a1, a2); } diff --git a/r5dev/engine/sv_main.h b/r5dev/engine/sv_main.h index ee27c5fc..657eac03 100644 --- a/r5dev/engine/sv_main.h +++ b/r5dev/engine/sv_main.h @@ -7,6 +7,13 @@ namespace /* ==== SV_MAIN ======================================================================================================================================================= */ ADDRESS p_SV_ShutdownGameDLL = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x83\xEC\x28\x80\x3D\x00\x00\x00\x00\x00\x0F\x84\x00\x00\x00\x00\x48\x8B\x0D\x00\x00\x00\x00\x48\x89\x5C\x24\x00", "xxxxxx?????xx????xxx????xxxx?"); void (*SV_ShutdownGameDLL)() = (void(*)())p_SV_ShutdownGameDLL.GetPtr(); /*48 83 EC 28 80 3D ? ? ? ? ? 0F 84 ? ? ? ? 48 8B 0D ? ? ? ? 48 89 5C 24 ?*/ + +#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) + ADDRESS CGameServer__SpawnServer = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x40\x53\x55\x56\x57\x41\x55\x41\x56\x41\x57\x48\x81\xEC\x00\x00\x00\x00", "xxxxxxxxxxxxxx????"); +#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3) + ADDRESS CGameServer__SpawnServer = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x8B\xC4\x53\x55\x56\x57\x41\x54\x41\x55\x41\x57", "xxxxxxxxxxxxx"); + // 0x140312D80 // 48 8B C4 53 55 56 57 41 54 41 55 41 57 // +#endif } /////////////////////////////////////////////////////////////////////////////// @@ -18,7 +25,8 @@ class HSV_MAIN : public IDetour { virtual void debugp() { - std::cout << "| FUN: SV_ShutdownGameDLL : 0x" << std::hex << std::uppercase << p_SV_ShutdownGameDLL.GetPtr() << std::setw(npad) << " |" << std::endl; + std::cout << "| FUN: SV_ShutdownGameDLL : 0x" << std::hex << std::uppercase << p_SV_ShutdownGameDLL.GetPtr() << std::setw(npad) << " |" << std::endl; + std::cout << "| FUN: CGameServer::SpawnServer : 0x" << std::hex << std::uppercase << CGameServer__SpawnServer.GetPtr() << std::setw(npad) << " |" << std::endl; std::cout << "+----------------------------------------------------------------+" << std::endl; } }; diff --git a/r5dev/engine/sys_dll.h b/r5dev/engine/sys_dll.h index eaa4df4d..4dee578c 100644 --- a/r5dev/engine/sys_dll.h +++ b/r5dev/engine/sys_dll.h @@ -1,10 +1,13 @@ #pragma once +#include "engine/common.h" namespace { /* ==== UTILITY ========================================================================================================================================================= */ ADDRESS p_Sys_Error_Internal = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x5C\x24\x08\x48\x89\x74\x24\x10\x57\x48\x81\xEC\x30\x08\x00\x00\x48\x8B\xDA\x48\x8B\xF9\xE8\x00\x00\x00\xFF\x33\xF6\x48", "xxxxxxxxxxxxxxxxxxxxxxxxx???xxxx"); int (*Sys_Error_Internal)(char* fmt, va_list args) = (int (*)(char*, va_list))p_Sys_Error_Internal.GetPtr(); /*48 89 5C 24 08 48 89 74 24 10 57 48 81 EC 30 08 00 00 48 8B DA 48 8B F9 E8 ?? ?? ?? FF 33 F6 48*/ + + bool* gfExtendedError = p_COM_ExplainDisconnection.Offset(0x0).FindPatternSelf("C6 05", ADDRESS::Direction::DOWN, 300).ResolveRelativeAddressSelf(0x2, 0x7).RCast(); } /////////////////////////////////////////////////////////////////////////////// @@ -19,6 +22,7 @@ class HSys_Dll : public IDetour virtual void debugp() { std::cout << "| FUN: Sys_Error_Internal : 0x" << std::hex << std::uppercase << p_Sys_Error_Internal.GetPtr() << std::setw(npad) << " |" << std::endl; + std::cout << "| VAR: gfExtendedError : 0x" << std::hex << std::uppercase << gfExtendedError << std::setw(0) << " |" << std::endl; std::cout << "+----------------------------------------------------------------+" << std::endl; } }; diff --git a/r5dev/engine/sys_dll2.h b/r5dev/engine/sys_dll2.h index 3cc68cf7..c0ffb94d 100644 --- a/r5dev/engine/sys_dll2.h +++ b/r5dev/engine/sys_dll2.h @@ -12,19 +12,26 @@ namespace ADDRESS p_CEngineAPI_Connect = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x83\xEC\x28\x48\x8B\x05\x00\x00\x00\x00\x48\x8D\x0D\x00\x00\x00\x00\x48\x85\xC0\x48\x89\x15", "xxxxxxx????xxx????xxxxxx"); bool (*CEngineAPI_Connect)(CEngineAPI* thisptr, CreateInterfaceFn factory) = (bool (*)(CEngineAPI*, CreateInterfaceFn))p_CEngineAPI_Connect.GetPtr(); /*48 83 EC 28 48 8B 05 ? ? ? ? 48 8D 0D ? ? ? ? 48 85 C0 48 89 15 ? ? ? ?*/ - // TODO: Verify for other seasons beside 3. - ADDRESS p_CEngineAPI_MainLoop = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\xE8\x00\x00\x00\x00\x48\x8B\x15\x00\x00\x00\x00\x84\xC0\xB9\x00\x00\x00\x00", "x????xxx????xxx????").FollowNearCallSelf(); - bool (*CEngineAPI_MainLoop)() = (bool(*)())p_CEngineAPI_MainLoop.GetPtr(); /*E8 ? ? ? ? 48 8B 15 ? ? ? ? 84 C0 B9 ? ? ? ?*/ #if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) ADDRESS p_PakFile_Init = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x5C\x24\x00\x48\x89\x6C\x24\x00\x44\x88\x44\x24\x00\x56\x57\x41\x54\x41\x56\x41\x57\x48\x83\xEC\x20", "xxxx?xxxx?xxxx?xxxxxxxxxxxx"); int (*PakFile_Init)(char* buffer, char* source, char vpk_file) = (int (*)(char*, char*, char))p_PakFile_Init.GetPtr(); /*48 89 5C 24 ?? 48 89 6C 24 ?? 44 88 44 24 ?? 56 57 41 54 41 56 41 57 48 83 EC 20*/ - ADDRESS g_pMapVPKCache = p_PakFile_Init.FindPatternSelf("4C 8D 35 ?? ?? ?? ?? 44", ADDRESS::Direction::DOWN, 250).OffsetSelf(0x3).ResolveRelativeAddressSelf().GetPtr(); + ADDRESS p_CEngineAPI_MainLoop = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x5C\x24\x00\x55\x48\x81\xEC\x00\x00\x00\x00\x45\x33\xC9", "xxxx?xxxx????xxx"); + void* (*CEngineAPI_MainLoop)() = (void* (*)())p_CEngineAPI_MainLoop.GetPtr(); /*48 89 5C 24 ? 55 48 81 EC ? ? ? ? 45 33 C9*/ #elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3) ADDRESS p_PakFile_Init = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x44\x88\x44\x24\x00\x53\x55\x56\x57", "xxxx?xxxx"); void (*PakFile_Init)(char* buffer, char* source, char vpk_file) = (void (*)(char*, char*, char))p_PakFile_Init.GetPtr(); /*44 88 44 24 ?? 53 55 56 57*/ - // TODO: Fix exception during search. + ADDRESS p_CEngineAPI_MainLoop = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\xE8\x00\x00\x00\x00\x48\x8B\x15\x00\x00\x00\x00\x84\xC0\xB9\x00\x00\x00\x00", "x????xxx????xxx????").FollowNearCallSelf(); + bool (*CEngineAPI_MainLoop)() = (bool(*)())p_CEngineAPI_MainLoop.GetPtr(); /*E8 ? ? ? ? 48 8B 15 ? ? ? ? 84 C0 B9 ? ? ? ?*/ +#endif +} + +namespace +{ +#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) + ADDRESS g_pMapVPKCache = p_PakFile_Init.FindPatternSelf("4C 8D 35 ?? ?? ?? ?? 44", ADDRESS::Direction::DOWN, 250).OffsetSelf(0x3).ResolveRelativeAddressSelf().GetPtr(); +#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3) ADDRESS g_pMapVPKCache = p_PakFile_Init.FindPatternSelf("48 8D 1D ?? ?? ?? ?? 4C", ADDRESS::Direction::DOWN, 250).OffsetSelf(0x3).ResolveRelativeAddressSelf().GetPtr(); #endif } diff --git a/r5dev/engine/sys_engine.h b/r5dev/engine/sys_engine.h index 4d67855d..d4cdb71a 100644 --- a/r5dev/engine/sys_engine.h +++ b/r5dev/engine/sys_engine.h @@ -1,5 +1,5 @@ #pragma once - +#include //----------------------------------------------------------------------------- // Forward declarations //----------------------------------------------------------------------------- @@ -62,10 +62,10 @@ public: namespace { /* ==== CENGINE ======================================================================================================================================================= */ -#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) // Verify for s0 and s1 - static ADDRESS g_pEngineBuffer = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x8D\x0D\x00\x00\x00\x00\x74\x2A\x4C\x8B\x05\x00\x00\x00\x00", "xxx????xxxxx????").ResolveRelativeAddressSelf(0x3, 0x7); -#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3) // Verify for s2 - static ADDRESS g_pEngineBuffer = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x8D\x0D\x00\x00\x00\x00\x74\x2A\x4C\x8B\x05\x00\x00\x00\x00", "xxx????xxxxx????").ResolveRelativeAddressSelf(0x3, 0x7); +#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) + static ADDRESS g_pEngineBuffer = p_IAppSystem_Main.Offset(0x0).FindPatternSelf("48 8D ?? ?? ?? ?? 01", ADDRESS::Direction::DOWN, 300).ResolveRelativeAddressSelf(0x3, 0x7); +#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3) + static ADDRESS g_pEngineBuffer = p_IAppSystem_Main.Offset(0x0).FindPatternSelf("48 8B ?? ?? ?? ?? 01", ADDRESS::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x3, 0x7); #endif } diff --git a/r5dev/engine/sys_utils.cpp b/r5dev/engine/sys_utils.cpp index ca7c64d8..2ebdf5cc 100644 --- a/r5dev/engine/sys_utils.cpp +++ b/r5dev/engine/sys_utils.cpp @@ -1,11 +1,12 @@ #include "core/stdafx.h" #include "core/logdef.h" #include "tier0/commandline.h" +#include "engine/common.h" #include "engine/sys_utils.h" #ifdef DEDICATED #include "engine/sv_rcon.h" #else -#include "vgui/CEngineVGui.h" +#include "vgui/vgui_debugpanel.h" #include "gameui/IConsole.h" #endif // !DEDICATED diff --git a/r5dev/gamesdk.vcxproj b/r5dev/gamesdk.vcxproj index 378e84c0..aa0daac8 100644 --- a/r5dev/gamesdk.vcxproj +++ b/r5dev/gamesdk.vcxproj @@ -36,6 +36,8 @@ + + @@ -54,6 +56,7 @@ + NotUsing @@ -214,7 +217,8 @@ - + + @@ -246,9 +250,13 @@ + + + + @@ -272,6 +280,7 @@ + @@ -440,7 +449,8 @@ - + + diff --git a/r5dev/gamesdk.vcxproj.filters b/r5dev/gamesdk.vcxproj.filters index ca708ad1..e17c55db 100644 --- a/r5dev/gamesdk.vcxproj.filters +++ b/r5dev/gamesdk.vcxproj.filters @@ -255,7 +255,7 @@ sdk\vgui - + sdk\vgui @@ -447,6 +447,18 @@ thirdparty\protobuf + + sdk\engine + + + sdk\engine + + + sdk\vgui + + + sdk\networksystem + @@ -878,7 +890,7 @@ sdk\vgui - + sdk\vgui @@ -1124,6 +1136,24 @@ thirdparty\protobuf + + sdk\engine + + + sdk\engine + + + sdk\vgui + + + sdk\engine + + + sdk\engine + + + sdk\networksystem + diff --git a/r5dev/launcher/IApplication.h b/r5dev/launcher/IApplication.h index f974fd48..6df078fe 100644 --- a/r5dev/launcher/IApplication.h +++ b/r5dev/launcher/IApplication.h @@ -15,7 +15,7 @@ namespace /* ==== CAPPSYSTEMGROUP ================================================================================================================================================= */ #if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) ADDRESS p_IAppSystem_Main = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x83\xEC\x28\x80\xB9\x00\x00\x00\x00\x00\x48\x8B\x15\x00\x00\x00\x00", "xxxxxx?????xxx????"); - void* (*IAppSystem_Main)(void* a1, void* a2) = (void* (*)(void*, void*))p_IAppSystem_Main.GetPtr(); /*48 83 EC 28 80 B9 ?? ?? ?? ?? ?? 48 8B 15 ?? ?? ?? ?? */ + void* (*IAppSystem_Main)(void* a1, void* a2) = (void* (*)(void*, void*))p_IAppSystem_Main.GetPtr(); /*48 83 EC 28 80 B9 ?? ?? ?? ?? ?? 48 8B 15 ?? ?? ?? ??*/ ADDRESS p_IAppSystem_Create = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\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"); bool (*IAppSystem_Create)(void* a1) = (bool(*)(void*))p_IAppSystem_Create.GetPtr(); /*48 8B C4 57 41 54 41 55 41 56 41 57 48 83 EC 60 48 C7 40 ?? ?? ?? ?? ?? 48 89 58 08*/ diff --git a/r5dev/networksystem/pylon.cpp b/r5dev/networksystem/pylon.cpp new file mode 100644 index 00000000..e89a7276 --- /dev/null +++ b/r5dev/networksystem/pylon.cpp @@ -0,0 +1,42 @@ +//=====================================================================================// +// +// Purpose: Implementation of the pylon server backend. +// +// $NoKeywords: $ +//=====================================================================================// + +#include +#include +#include +#include +#include +#include +#include +#include + +//----------------------------------------------------------------------------- +// Purpose: Send keep alive request to Pylon Master Server. +// NOTE: When Pylon update reaches indev remove this and implement properly. +//----------------------------------------------------------------------------- +void KeepAliveToPylon() +{ + if (g_pHostState->m_bActiveGame && sv_pylonvisibility->GetBool()) // Check for active game. + { + std::string m_szHostToken = std::string(); + std::string m_szHostRequestMessage = std::string(); + DevMsg(eDLL_T::SERVER, "Sending PostServerHost request\n"); + bool result = g_pR5net->PostServerHost(m_szHostRequestMessage, m_szHostToken, + ServerListing{ + g_pCVar->FindVar("hostname")->GetString(), + std::string(g_pHostState->m_levelName), + "", + g_pCVar->FindVar("hostport")->GetString(), + g_pCVar->FindVar("mp_gamemode")->GetString(), + false, + std::to_string(*g_nServerRemoteChecksum), + std::string(), + g_szNetKey.c_str() + } + ); + } +} \ No newline at end of file diff --git a/r5dev/networksystem/pylon.h b/r5dev/networksystem/pylon.h new file mode 100644 index 00000000..548a2ecc --- /dev/null +++ b/r5dev/networksystem/pylon.h @@ -0,0 +1,3 @@ +#pragma once + +void KeepAliveToPylon(); \ No newline at end of file diff --git a/r5dev/public/bansystem.cpp b/r5dev/public/bansystem.cpp index e5012cdb..0ff3428f 100644 --- a/r5dev/public/bansystem.cpp +++ b/r5dev/public/bansystem.cpp @@ -1,11 +1,27 @@ +//=====================================================================================// +// +// Purpose: Implementation of the CBanSystem class. +// +// $NoKeywords: $ +//=====================================================================================// + #include "core/stdafx.h" +#include "client/client.h" +#include "engine/net_chan.h" +#include "engine/sys_utils.h" #include "public/include/bansystem.h" -CBanSystem::CBanSystem() +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +CBanSystem::CBanSystem(void) { Load(); } +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- void CBanSystem::operator[](std::pair pair) { AddEntry(pair.first, pair.second); @@ -14,7 +30,7 @@ void CBanSystem::operator[](std::pair pair) //----------------------------------------------------------------------------- // Purpose: loads and parses the banlist //----------------------------------------------------------------------------- -void CBanSystem::Load() +void CBanSystem::Load(void) { std::filesystem::path path = std::filesystem::current_path() /= "banlist.config"; // Get current path + banlist.config @@ -44,7 +60,6 @@ void CBanSystem::Load() continue; } - std::int64_t nOriginID = jsEntry["originID"].get(); // Get originID field from entry. std::string svIpAddress = jsEntry["ipAddress"].get(); // Get ipAddress field from entry. @@ -56,7 +71,7 @@ void CBanSystem::Load() //----------------------------------------------------------------------------- // Purpose: saves the banlist //----------------------------------------------------------------------------- -void CBanSystem::Save() +void CBanSystem::Save(void) const { nlohmann::json jsOut; @@ -144,7 +159,7 @@ void CBanSystem::DeleteConnectionRefuse(std::int64_t nOriginID) // nOriginID - // Output : true if banned, false if not banned //----------------------------------------------------------------------------- -bool CBanSystem::IsBanned(std::string svIpAddress, std::int64_t nOriginID) +bool CBanSystem::IsBanned(std::string svIpAddress, std::int64_t nOriginID) const { for (int i = 0; i < vsvBanList.size(); i++) { @@ -175,10 +190,69 @@ bool CBanSystem::IsBanned(std::string svIpAddress, std::int64_t nOriginID) return false; } +//----------------------------------------------------------------------------- +// Purpose: Check refuse list and kill netchan connection. +//----------------------------------------------------------------------------- +void CBanSystem::BanListCheck(void) +{ + if (IsRefuseListValid()) + { + for (int i = 0; i < vsvrefuseList.size(); i++) // Loop through vector. + { + for (int c = 0; c < MAX_PLAYERS; c++) // Loop through all possible client instances. + { + CClient* client = g_pClient->GetClientInstance(c); // Get client instance. + if (!client) + { + continue; + } + + if (!client->GetNetChan()) // Netchan valid? + { + continue; + } + + if (g_pClient->m_iOriginID != vsvrefuseList[i].second) // See if nucleus id matches entry. + { + continue; + } + + std::string finalIpAddress = std::string(); + ADDRESS ipAddressField = ADDRESS(((std::uintptr_t)client->GetNetChan()) + 0x1AC0); // Get client ip from netchan. + if (ipAddressField && ipAddressField.GetValue() != 0x0) + { + std::stringstream ss; + ss << std::to_string(ipAddressField.GetValue()) << "." + << std::to_string(ipAddressField.Offset(0x1).GetValue()) << "." + << std::to_string(ipAddressField.Offset(0x2).GetValue()) << "." + << std::to_string(ipAddressField.Offset(0x3).GetValue()); + + finalIpAddress = ss.str(); + } + + DevMsg(eDLL_T::SERVER, "\n"); + DevMsg(eDLL_T::SERVER, "______________________________________________________________\n"); + DevMsg(eDLL_T::SERVER, "] PYLON_NOTICE -----------------------------------------------\n"); + DevMsg(eDLL_T::SERVER, "] OriginID : | '%lld' IS GETTING DISCONNECTED.\n", g_pClient->m_iOriginID); + if (finalIpAddress.empty()) + DevMsg(eDLL_T::SERVER, "] IP-ADDR : | CLIENT MODIFIED PACKET.\n"); + else + DevMsg(eDLL_T::SERVER, "] IP-ADDR : | '%s'\n", finalIpAddress.c_str()); + DevMsg(eDLL_T::SERVER, "--------------------------------------------------------------\n"); + DevMsg(eDLL_T::SERVER, "\n"); + + AddEntry(finalIpAddress, g_pClient->m_iOriginID); // Add local entry to reserve a non needed request. + Save(); // Save list. + NET_DisconnectClient(g_pClient, c, vsvrefuseList[i].first.c_str(), 0, 1); // Disconnect client. + } + } + } +} + //----------------------------------------------------------------------------- // Purpose: checks if refuselist is valid //----------------------------------------------------------------------------- -bool CBanSystem::IsRefuseListValid() +bool CBanSystem::IsRefuseListValid(void) const { return !vsvrefuseList.empty(); } @@ -186,7 +260,7 @@ bool CBanSystem::IsRefuseListValid() //----------------------------------------------------------------------------- // Purpose: checks if banlist is valid //----------------------------------------------------------------------------- -bool CBanSystem::IsBanListValid() +bool CBanSystem::IsBanListValid(void) const { return !vsvBanList.empty(); } diff --git a/r5dev/public/include/bansystem.h b/r5dev/public/include/bansystem.h index 1e8e595e..ce07735f 100644 --- a/r5dev/public/include/bansystem.h +++ b/r5dev/public/include/bansystem.h @@ -4,20 +4,25 @@ class CBanSystem { public: - CBanSystem(); + CBanSystem(void); void operator[](std::pair pair); - void Load(); - void Save(); + void Load(void); + void Save(void) const; + void AddEntry(std::string svIpAddress, std::int64_t nOriginID); void DeleteEntry(std::string svIpAddress, std::int64_t nOriginID); + void AddConnectionRefuse(std::string svError, std::int64_t nOriginID); void DeleteConnectionRefuse(std::int64_t nUserID); - bool IsBanned(std::string svIpAddress, std::int64_t nOriginID); - bool IsRefuseListValid(); - bool IsBanListValid(); - std::vector> vsvrefuseList = {};; + bool IsBanned(std::string svIpAddress, std::int64_t nOriginID) const; + bool IsRefuseListValid(void) const; + bool IsBanListValid(void) const; + + void BanListCheck(void); + private: + std::vector> vsvrefuseList = {};; std::vector> vsvBanList = {}; }; diff --git a/r5dev/squirrel/sqvm.cpp b/r5dev/squirrel/sqvm.cpp index 1ee4ac80..dc339d42 100644 --- a/r5dev/squirrel/sqvm.cpp +++ b/r5dev/squirrel/sqvm.cpp @@ -13,7 +13,7 @@ #ifdef DEDICATED #include "engine/sv_rcon.h" #endif // DEDICATED -#include "vgui/CEngineVGui.h" +#include "vgui/vgui_debugpanel.h" #include "gameui/IConsole.h" #include "squirrel/sqvm.h" #include "squirrel/sqinit.h" diff --git a/r5dev/tier0/cmd.h b/r5dev/tier0/cmd.h index 2f8e8aec..e620b991 100644 --- a/r5dev/tier0/cmd.h +++ b/r5dev/tier0/cmd.h @@ -1,5 +1,31 @@ #pragma once +//----------------------------------------------------------------------------- +// Purpose: Command buffer context +//----------------------------------------------------------------------------- +typedef enum +{ + CBUF_FIRST_PLAYER = 0, + CBUF_LAST_PLAYER = MAX_SPLITSCREEN_CLIENTS - 1, + CBUF_SERVER = CBUF_LAST_PLAYER + 1, + + CBUF_COUNT, +} ECommandTarget_t; + +//----------------------------------------------------------------------------- +// Sources of console commands +//----------------------------------------------------------------------------- +enum class cmd_source_t : int +{ + kCommandSrcCode, + kCommandSrcClientCmd, + kCommandSrcUserInput, + kCommandSrcNetClient, + kCommandSrcNetServer, + kCommandSrcDemoFile, + kCommandSrcInvalid = -1 +}; + //----------------------------------------------------------------------------- // Purpose: Command tokenizer //----------------------------------------------------------------------------- @@ -73,6 +99,13 @@ private: namespace { + /* ==== COMMAND_BUFFER ================================================================================================================================================== */ + ADDRESS p_Cbuf_AddText = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x44\x89\x4C\x24\x00\x48\x89\x4C\x24\x00\x55\x56\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x81\xEC\x00\x00\x00\x00\x48\x8D\x6C\x24\x00\x48\x89\x9D\x00\x00\x00\x00\x4C\x8B", "xxxx?xxxx?xxxxxxxxxxxxxx????xxxx?xxx????xx"); + bool (*Cbuf_AddText)(ECommandTarget_t eTarget, const char* pText, cmd_source_t cmdSource, int nTickDelay) = (bool (*)(ECommandTarget_t, const char*, cmd_source_t, int))p_Cbuf_AddText.GetPtr(); /*44 89 4C 24 ? 48 89 4C 24 ? 55 56 57 41 54 41 55 41 56 41 57 48 81 EC ? ? ? ? 48 8D 6C 24 ? 48 89 9D ? ? ? ? 4C 8B*/ + + ADDRESS p_Cbuf_Execute = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x5C\x24\x00\x48\x89\x6C\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xEC\x20\xFF\x15\x00\x00\x00\x00", "xxxx?xxxx?xxxx?xxxxxxx????"); + void (*Cbuf_Execute)(void) = (void (*)(void))p_Cbuf_Execute.GetPtr(); /*48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC 20 FF 15 ? ? ? ?*/ + /* ==== CONCOMMAND ====================================================================================================================================================== */ ADDRESS p_ConCommandBase_IsFlagSet = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x85\x51\x38\x0F\x95\xC0\xC3", "xxxxxxx"); bool (*ConCommandBase_IsFlagSet)(ConCommandBase* cmd, int flag) = (bool (*)(ConCommandBase*, int))p_ConCommandBase_IsFlagSet.GetPtr(); /*85 51 38 0F 95 C0 C3*/ @@ -103,7 +136,10 @@ class HConCommand : public IDetour { virtual void debugp() { - std::cout << "| FUN: ConCommandBase::IsFlagSet : 0x" << std::hex << std::uppercase << p_ConCommandBase_IsFlagSet.GetPtr() << std::setw(npad) << " |" << std::endl; + std::cout << "| FUN: Cbuf_AddText : 0x" << std::hex << std::uppercase << p_Cbuf_AddText.GetPtr() << std::setw(npad) << " |" << std::endl; + std::cout << "| FUN: Cbuf_Execute : 0x" << std::hex << std::uppercase << p_Cbuf_Execute.GetPtr() << std::setw(npad) << " |" << std::endl; + std::cout << "+----------------------------------------------------------------+" << std::endl; + std::cout << "| FUN: ConCommandBase::IsFlagSet : 0x" << std::hex << std::uppercase << p_ConCommandBase_IsFlagSet.GetPtr() << std::setw(npad) << " |" << std::endl; std::cout << "| FUN: ConCommand::CMaterialSystemCmdInit : 0x" << std::hex << std::uppercase << p_ConCommand_CMaterialSystemCmdInit.GetPtr() << std::setw(npad) << " |" << std::endl; std::cout << "| FUN: ConCommand::NullSub : 0x" << std::hex << std::uppercase << p_ConCommand_NullSub.GetPtr() << std::setw(npad) << " |" << std::endl; std::cout << "| FUN: ConCommand::CallbackCompletion : 0x" << std::hex << std::uppercase << p_ConCommand_CallbackCompletion.GetPtr() << std::setw(npad) << " |" << std::endl; diff --git a/r5dev/vgui/CEngineVGui.h b/r5dev/vgui/CEngineVGui.h deleted file mode 100644 index d435447f..00000000 --- a/r5dev/vgui/CEngineVGui.h +++ /dev/null @@ -1,89 +0,0 @@ -#pragma once -#include "core/stdafx.h" -#include "mathlib/color.h" - -enum class LogType_t : int -{ - SCRIPT_SERVER, - SCRIPT_CLIENT, - SCRIPT_UI, - NATIVE_SERVER, - NATIVE_CLIENT, - NATIVE_UI, - NATIVE_ENGINE, - NATIVE_FS, - NATIVE_RTECH, - NATIVE_MS, - NETCON_S, - WARNING_C, - ERROR_C, - NONE -}; - -struct Log -{ - Log(const std::string Message, const int Ticks, const LogType_t Type) - { - this->Message = Message; - this->Ticks = Ticks; - this->Type = Type; - } - std::string Message = ""; - int Ticks = 1024; - LogType_t Type = LogType_t::NONE; -}; - -class CLogSystem -{ -public: - void Update(void); - void AddLog(LogType_t type, std::string text); - void DrawLog(void); - void DrawSimStats(void) const; - void DrawGPUStats(void) const; - -private: - Color GetLogColorForType(LogType_t type); - std::vector m_vLogs{}; - int fontHeight = 16; -}; - -namespace -{ - /* ==== CENGINEVGUI ===================================================================================================================================================== */ -#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) - ADDRESS p_CEngineVGui_Paint = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x89\x54\x24\x10\x55\x56\x41\x55\x48\x81\xEC\x00\x00\x00\x00", "xxxxxxxxxxx????"); - int (*CEngineVGui_Paint)(void* thisptr, int mode) = (int (*)(void*, int))p_CEngineVGui_Paint.GetPtr(); /*41 55 41 56 48 83 EC 78 44 8B EA*/ - - ADDRESS p_CEngineVGui_Unknown = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x4C\x8B\x81\x00\x00\x00\x00\x48\x8D\x05\x00\x00\x00\x00\x4C\x3B\xC0\x74\x1F", "xxx????xxx????xxxxx"); - void** (*CEngineVGui_Unknown)(std::int64_t a1) = (void** (*)(std::int64_t))p_CEngineVGui_Unknown.GetPtr(); /*4C 8B 81 ?? ?? ?? ?? 48 8D 05 ?? ?? ?? ?? 4C 3B C0 74 1F*/ -#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3) - ADDRESS p_CEngineVGui_Paint = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x41\x55\x41\x56\x48\x83\xEC\x78\x44\x8B\xEA", "xxxxxxxxxxx"); - int (*CEngineVGui_Paint)(void* thisptr, int mode) = (int (*)(void*, int))p_CEngineVGui_Paint.GetPtr(); /*41 55 41 56 48 83 EC 78 44 8B EA*/ - - ADDRESS p_CEngineVGui_Unknown = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x40\x53\x48\x83\xEC\x20\x48\x8D\x05\x00\x00\x00\x00\x48\x8B\xD9\x48\x39\x81\x00\x00\x00\x00\x74\x29", "xxxxxxxxx????xxxxxx????xx"); - void** (*CEngineVGui_Unknown)(std::int64_t a1) = (void** (*)(std::int64_t))p_CEngineVGui_Unknown.GetPtr(); /*40 53 48 83 EC 20 48 8D 05 ?? ?? ?? ?? 48 8B D9 48 39 81 ?? ?? ?? ?? 74 29*/ -#endif -} - -/////////////////////////////////////////////////////////////////////////////// -int HCEngineVGui_Paint(void* thisptr, int mode); -void CEngineVGui_Attach(); -void CEngineVGui_Detach(); - -/////////////////////////////////////////////////////////////////////////////// -extern CLogSystem g_pLogSystem; - -/////////////////////////////////////////////////////////////////////////////// -class HEngineVGui : public IDetour -{ - virtual void debugp() - { - std::cout << "| FUN: CEngineVGui::Paint : 0x" << std::hex << std::uppercase << p_CEngineVGui_Paint.GetPtr() << std::setw(npad) << " |" << std::endl; - std::cout << "| FUN: CEngineVGui::Unknown : 0x" << std::hex << std::uppercase << p_CEngineVGui_Unknown.GetPtr() << std::setw(npad) << " |" << std::endl; - std::cout << "+----------------------------------------------------------------+" << std::endl; - } -}; -/////////////////////////////////////////////////////////////////////////////// - -REGISTER(HEngineVGui); diff --git a/r5dev/vgui/vgui_baseui_interface.cpp b/r5dev/vgui/vgui_baseui_interface.cpp new file mode 100644 index 00000000..20387528 --- /dev/null +++ b/r5dev/vgui/vgui_baseui_interface.cpp @@ -0,0 +1,46 @@ +//===========================================================================// +// +// Purpose: Implements all the functions exported by the GameUI dll. +// +// $NoKeywords: $ +//===========================================================================// + +#include +#include +#include + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +int HCEngineVGui_Paint(void* thisptr, PaintMode_t mode) +{ + int result = CEngineVGui_Paint(thisptr, mode); + + static void* pCMatSystemSurface = ADDRESS(0x14D40B3B0).RCast(); + static auto fnRenderStart = ADDRESS(0x14053EFC0).RCast(); + static auto fnRenderEnd = ADDRESS(0x14053F1B0).RCast(); + + if (mode == PaintMode_t::PAINT_UIPANELS || mode == PaintMode_t::PAINT_INGAMEPANELS) // Render in-main menu and in-game. + { + fnRenderStart(pCMatSystemSurface); + + g_pLogSystem.Update(); + + fnRenderEnd(); + } + + return result; +} + +/////////////////////////////////////////////////////////////////////////////// +void CEngineVGui_Attach() +{ + //DetourAttach((LPVOID*)&CEngineVGui_Paint, &HCEngineVGui_Paint); +} + +void CEngineVGui_Detach() +{ + //DetourDetach((LPVOID*)&CEngineVGui_Paint, &HCEngineVGui_Paint); +} + +/////////////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/r5dev/vgui/vgui_baseui_interface.h b/r5dev/vgui/vgui_baseui_interface.h new file mode 100644 index 00000000..056a4645 --- /dev/null +++ b/r5dev/vgui/vgui_baseui_interface.h @@ -0,0 +1,42 @@ +#pragma once +#include + +enum class PaintMode_t +{ + PAINT_UIPANELS = (1 << 0), + PAINT_INGAMEPANELS = (1 << 1), +}; + +namespace +{ + /* ==== CENGINEVGUI ===================================================================================================================================================== */ +#if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) + ADDRESS p_CEngineVGui_Paint = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x89\x54\x24\x10\x55\x56\x41\x55\x48\x81\xEC\x00\x00\x00\x00", "xxxxxxxxxxx????"); + int (*CEngineVGui_Paint)(void* thisptr, PaintMode_t mode) = (int (*)(void*, PaintMode_t))p_CEngineVGui_Paint.GetPtr(); /*41 55 41 56 48 83 EC 78 44 8B EA*/ + + ADDRESS p_CEngineVGui_Unknown = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x4C\x8B\x81\x00\x00\x00\x00\x48\x8D\x05\x00\x00\x00\x00\x4C\x3B\xC0\x74\x1F", "xxx????xxx????xxxxx"); + void** (*CEngineVGui_Unknown)(void* thisptr) = (void** (*)(void*))p_CEngineVGui_Unknown.GetPtr(); /*4C 8B 81 ?? ?? ?? ?? 48 8D 05 ?? ?? ?? ?? 4C 3B C0 74 1F*/ +#elif defined (GAMEDLL_S2) || defined (GAMEDLL_S3) + ADDRESS p_CEngineVGui_Paint = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x41\x55\x41\x56\x48\x83\xEC\x78\x44\x8B\xEA", "xxxxxxxxxxx"); + int (*CEngineVGui_Paint)(void* thisptr, PaintMode_t mode) = (int (*)(void*, PaintMode_t))p_CEngineVGui_Paint.GetPtr(); /*41 55 41 56 48 83 EC 78 44 8B EA*/ + + ADDRESS p_CEngineVGui_Unknown = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x40\x53\x48\x83\xEC\x20\x48\x8D\x05\x00\x00\x00\x00\x48\x8B\xD9\x48\x39\x81\x00\x00\x00\x00\x74\x29", "xxxxxxxxx????xxxxxx????xx"); + void** (*CEngineVGui_Unknown)(void* thisptr) = (void** (*)(void*))p_CEngineVGui_Unknown.GetPtr(); /*40 53 48 83 EC 20 48 8D 05 ?? ?? ?? ?? 48 8B D9 48 39 81 ?? ?? ?? ?? 74 29*/ +#endif + void* g_pEngineVGui = CGameServer__SpawnServer.Offset(0x18).FindPatternSelf("48 ?? ?? ?? ?? ?? 01", ADDRESS::Direction::DOWN, 150).ResolveRelativeAddressSelf(0x3, 0x7).RCast(); +} + +/////////////////////////////////////////////////////////////////////////////// +class HEngineVGui : public IDetour +{ + virtual void debugp() + { + std::cout << "| FUN: CEngineVGui::Paint : 0x" << std::hex << std::uppercase << p_CEngineVGui_Paint.GetPtr() << std::setw(npad) << " |" << std::endl; + std::cout << "| FUN: CEngineVGui::Unknown : 0x" << std::hex << std::uppercase << p_CEngineVGui_Unknown.GetPtr() << std::setw(npad) << " |" << std::endl; + std::cout << "| VAR: g_pEngineVGui : 0x" << std::hex << std::uppercase << g_pEngineVGui << std::setw(0) << " |" << std::endl; + std::cout << "+----------------------------------------------------------------+" << std::endl; + } +}; +/////////////////////////////////////////////////////////////////////////////// + +REGISTER(HEngineVGui); \ No newline at end of file diff --git a/r5dev/vgui/CEngineVGui.cpp b/r5dev/vgui/vgui_debugpanel.cpp similarity index 64% rename from r5dev/vgui/CEngineVGui.cpp rename to r5dev/vgui/vgui_debugpanel.cpp index 4f0854b8..0da5a248 100644 --- a/r5dev/vgui/CEngineVGui.cpp +++ b/r5dev/vgui/vgui_debugpanel.cpp @@ -1,35 +1,19 @@ -#include "core/stdafx.h" -#include "tier0/cvar.h" -#include "mathlib/color.h" -#include "vgui/CEngineVGui.h" -#include "vguimatsurface/MatSystemSurface.h" -#include "materialsystem/materialsystem.h" -#include "engine/debugoverlay.h" -#include "engine/baseclientstate.h" -#include "server/server.h" +//===========================================================================// +// +// Purpose: Implements the debug panels. +// +// $NoKeywords: $ +//===========================================================================// -//----------------------------------------------------------------------------- -// Purpose: -//----------------------------------------------------------------------------- -int HCEngineVGui_Paint(void* thisptr, int mode) -{ - int result = CEngineVGui_Paint(thisptr, mode); - - static void* pCMatSystemSurface = ADDRESS(0x14D40B3B0).RCast(); - static auto fnRenderStart = ADDRESS(0x14053EFC0).RCast(); - static auto fnRenderEnd = ADDRESS(0x14053F1B0).RCast(); - - if (mode == 1 || mode == 2) // Render in-main menu and in-game. - { - fnRenderStart(pCMatSystemSurface); - - g_pLogSystem.Update(); - - fnRenderEnd(); - } - - return result; -} +#include +#include +#include +#include +#include +#include +#include +#include +#include //----------------------------------------------------------------------------- // Purpose: @@ -61,7 +45,7 @@ void CLogSystem::AddLog(LogType_t type, std::string svMessage) { if (svMessage.length() > 0) { - m_vLogs.push_back(Log{ svMessage, 1024, type }); + m_vLogs.push_back(LogMsg_t{ svMessage, 1024, type }); } } @@ -73,18 +57,18 @@ void CLogSystem::DrawLog(void) if (m_vLogs.empty()) { return; } for (int i = 0; i < m_vLogs.size(); ++i) { - if (m_vLogs[i].Ticks >= 0) + if (m_vLogs[i].m_nTicks >= 0) { if (i < cl_consoleoverlay_lines->GetInt()) { - float fadepct = fminf(static_cast(m_vLogs[i].Ticks) / 255.f, 4.f); // TODO [ AMOS ]: register a ConVar for this! + float fadepct = fminf(static_cast(m_vLogs[i].m_nTicks) / 255.f, 4.f); // TODO [ AMOS ]: register a ConVar for this! float ptc = static_cast(ceilf(fadepct * 100.f)); int alpha = static_cast(ptc); - int y = (cl_consoleoverlay_offset_y->GetInt() + (fontHeight * i)); + int y = (cl_consoleoverlay_offset_y->GetInt() + (m_nFontHeight * i)); int x = cl_consoleoverlay_offset_x->GetInt(); - Color c = GetLogColorForType(m_vLogs[i].Type); - CMatSystemSurface_DrawColoredText(g_pMatSystemSurface, 0x13, fontHeight, x, y, c.r(), c.g(), c.b(), alpha, m_vLogs[i].Message.c_str()); + Color c = GetLogColorForType(m_vLogs[i].m_type); + CMatSystemSurface_DrawColoredText(g_pMatSystemSurface, 0x13, m_nFontHeight, x, y, c.r(), c.g(), c.b(), alpha, m_vLogs[i].m_svMessage.c_str()); } else { @@ -92,7 +76,7 @@ void CLogSystem::DrawLog(void) continue; } - m_vLogs[i].Ticks--; + m_vLogs[i].m_nTicks--; } else { @@ -111,7 +95,7 @@ void CLogSystem::DrawSimStats(void) const snprintf((char*)szLogbuf, 4096, "Server Frame: (%d) Client Frame: (%d) Render Frame: (%d)\n", *sv_m_nTickCount, *cl_host_tickcount, *render_tickcount); - CMatSystemSurface_DrawColoredText(g_pMatSystemSurface, 0x13, fontHeight, cl_simstats_offset_x->GetInt(), cl_simstats_offset_y->GetInt(), c.r(), c.g(), c.b(), c.a(), (char*)szLogbuf); + CMatSystemSurface_DrawColoredText(g_pMatSystemSurface, 0x13, m_nFontHeight, cl_simstats_offset_x->GetInt(), cl_simstats_offset_y->GetInt(), c.r(), c.g(), c.b(), c.a(), (char*)szLogbuf); } //----------------------------------------------------------------------------- @@ -124,13 +108,13 @@ void CLogSystem::DrawGPUStats(void) const snprintf((char*)szLogbuf, 4096, "%8d/%8d/%8dkiB unusable/unfree/total GPU Streaming Texture memory\n", *unusable_streaming_tex_memory / 1024, *unfree_streaming_tex_memory / 1024, *unusable_streaming_tex_memory / 1024); - CMatSystemSurface_DrawColoredText(g_pMatSystemSurface, 0x13, fontHeight, cl_gpustats_offset_x->GetInt(), cl_gpustats_offset_y->GetInt(), c.r(), c.g(), c.b(), c.a(), (char*)szLogbuf); + CMatSystemSurface_DrawColoredText(g_pMatSystemSurface, 0x13, m_nFontHeight, cl_gpustats_offset_x->GetInt(), cl_gpustats_offset_y->GetInt(), c.r(), c.g(), c.b(), c.a(), (char*)szLogbuf); } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- -Color CLogSystem::GetLogColorForType(LogType_t type) +Color CLogSystem::GetLogColorForType(LogType_t type) const { switch (type) { @@ -165,16 +149,5 @@ Color CLogSystem::GetLogColorForType(LogType_t type) } } -/////////////////////////////////////////////////////////////////////////////// -void CEngineVGui_Attach() -{ - //DetourAttach((LPVOID*)&CEngineVGui_Paint, &HCEngineVGui_Paint); -} - -void CEngineVGui_Detach() -{ - //DetourDetach((LPVOID*)&CEngineVGui_Paint, &HCEngineVGui_Paint); -} - /////////////////////////////////////////////////////////////////////////////// CLogSystem g_pLogSystem; diff --git a/r5dev/vgui/vgui_debugpanel.h b/r5dev/vgui/vgui_debugpanel.h new file mode 100644 index 00000000..21823acf --- /dev/null +++ b/r5dev/vgui/vgui_debugpanel.h @@ -0,0 +1,57 @@ +#pragma once +#include "core/stdafx.h" +#include "mathlib/color.h" + +enum class LogType_t : int +{ + SCRIPT_SERVER, + SCRIPT_CLIENT, + SCRIPT_UI, + NATIVE_SERVER, + NATIVE_CLIENT, + NATIVE_UI, + NATIVE_ENGINE, + NATIVE_FS, + NATIVE_RTECH, + NATIVE_MS, + NETCON_S, + WARNING_C, + ERROR_C, + NONE +}; + +struct LogMsg_t +{ + LogMsg_t(const std::string svMessage, const int nTicks, const LogType_t type) + { + this->m_svMessage = svMessage; + this->m_nTicks = nTicks; + this->m_type = type; + } + std::string m_svMessage = ""; + int m_nTicks = 1024; + LogType_t m_type = LogType_t::NONE; +}; + +class CLogSystem +{ +public: + void Update(void); + void AddLog(LogType_t type, std::string svText); + void DrawLog(void); + void DrawSimStats(void) const; + void DrawGPUStats(void) const; + +private: + Color GetLogColorForType(LogType_t type) const; + std::vector m_vLogs{}; + int m_nFontHeight = 16; +}; + +/////////////////////////////////////////////////////////////////////////////// +int HCEngineVGui_Paint(void* thisptr, int nMode); +void CEngineVGui_Attach(); +void CEngineVGui_Detach(); + +/////////////////////////////////////////////////////////////////////////////// +extern CLogSystem g_pLogSystem; diff --git a/r5dev/vgui/vgui_fpspanel.cpp b/r5dev/vgui/vgui_fpspanel.cpp index 26a0a8fb..1edab289 100644 --- a/r5dev/vgui/vgui_fpspanel.cpp +++ b/r5dev/vgui/vgui_fpspanel.cpp @@ -1,14 +1,25 @@ +//===========================================================================// +// +// Purpose: Framerate indicator panel. +// +// $NoKeywords: $ +//===========================================================================// + #include "core/stdafx.h" #include "tier0/cvar.h" #include "vgui/vgui_fpspanel.h" -#include "vgui/CEngineVGui.h" +#include "vgui/vgui_debugpanel.h" +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- ConVar* HCFPSPanel_Paint(void* thisptr) { g_pLogSystem.Update(); return CFPSPanel_Paint(thisptr); } +/////////////////////////////////////////////////////////////////////////////// void CFPSPanel_Attach() { DetourAttach((LPVOID*)&CFPSPanel_Paint, &HCFPSPanel_Paint);