From 4c33272e42463fa1d63ed0cf8bb233e57e6dc07d Mon Sep 17 00:00:00 2001 From: Boris Date: Fri, 2 Sep 2022 21:56:15 +0300 Subject: [PATCH] GOTV clients support Sending modified tables & class infos to support GOTV clients --- plugin/limit_extender.cpp | 54 +++++++++++++++++++++++++++++++++++++++ plugin/limit_extender.h | 18 +++++++++++++ plugin/particle_fix.cpp | 2 +- 3 files changed, 73 insertions(+), 1 deletion(-) diff --git a/plugin/limit_extender.cpp b/plugin/limit_extender.cpp index c7c9d6d..22e9bb9 100644 --- a/plugin/limit_extender.cpp +++ b/plugin/limit_extender.cpp @@ -20,17 +20,27 @@ #include "limit_extender.h" #include #include +#include // memdbgon must be the last include file in a .cpp file!!! #include +decltype(LimitExtender::m_pFullSendTables) LimitExtender::m_pFullSendTables; +decltype(LimitExtender::CBaseClient_SendSignonData) LimitExtender::CBaseClient_SendSignonData; + bool LimitExtender::Init(char* error, size_t maxlength) { #ifdef _WIN32 const uint8_t CreateNetworkStringTablesPattern[] = "\x8B\x0D\x2A\x2A\x2A\x2A\x6A\x01\x6A\x00\x6A\x00\x8B\x01\x68\x00\x04\x00\x00\x68"; const uint8_t SendTablePattern[] = "\x55\x8B\xEC\x83\xEC\x0C\x83\x3D\x2A\x2A\x2A\x2A\x00\x53\x56\x57\x8B\xFA\x8B\xD9\x74"; + const uint8_t CreateBaselinePattern[] = "\x55\x8B\xEC\x83\xEC\x5C\xB9\x2A\x2A\x2A\x2A\x53\x56\x57\xE8"; + const uint8_t CHLTVClient_SendSignonDataPattern[] = "\x55\x8B\xEC\x83\xEC\x44\x56\x8B\xF1\x8B\x86\xF8\x01\x00\x00"; + const uint8_t CBaseClient_SendSignonDataPattern[] = "\x55\x8B\xEC\x83\xE4\xF8\x83\xEC\x54\x53\x56\x57\x68"; #else const uint8_t CreateNetworkStringTablesPattern[] = "\x55\x89\xE5\x83\xEC\x28\xA1\x2A\x2A\x2A\x2A\x8B\x10\xC7\x44\x24\x14\x01\x00\x00\x00\xC7\x44\x24\x10\x00\x00\x00\x00\xC7\x44\x24\x0C\x00\x00\x00\x00\xC7\x44\x24\x08\x00\x04\x00\x00\xC7\x44\x24\x04\x2A\x2A\x2A\x2A\x89\x04\x24\xFF\x52\x08\xA3\x2A\x2A\x2A\x2A\xA1\x2A\x2A\x2A\x2A\x8B\x10"; const uint8_t SendTablePattern[] = "\x55\x89\xE5\x57\x56\x53\x83\xEC\x4C\xA1\x2A\x2A\x2A\x2A\x8B\x7D\x08\x85\xC0"; + const uint8_t CreateBaselinePattern[] = "\x55\x89\xE5\x57\x56\x53\x81\xEC\x8C\x40\x00\x00\xC7\x04\x24"; + const uint8_t CHLTVClient_SendSignonDataPattern[] = "\x55\x89\xE5\x83\xEC\x48\x89\x5D\xF8\x8B\x5D\x08\x89\x75\xFC\x8B\xB3\xE4\x01\x00\x00"; + const uint8_t CBaseClient_SendSignonDataPattern[] = "\x55\x89\xE5\x56\x53\x83\xEC\x50\x8B\x5D\x08\xC7\x04\x24"; #endif uintptr_t pCreateNetworkStringTables = g_PatternFinderServer.Find(CreateNetworkStringTablesPattern, sizeof(CreateNetworkStringTablesPattern) - 1); @@ -49,6 +59,30 @@ bool LimitExtender::Init(char* error, size_t maxlength) return false; } + uintptr_t pCreateBaseline = g_PatternFinderEngine.Find(CreateBaselinePattern, sizeof(CreateBaselinePattern) - 1); + if(!pCreateBaseline) + { + V_strncpy(error, "Failed to find SV_CreateBaseline.", maxlength); + + return false; + } + + void* pCHLTVClient_SendSignonData = g_PatternFinderEngine.Find(CHLTVClient_SendSignonDataPattern, sizeof(CHLTVClient_SendSignonDataPattern) - 1); + if(!pCHLTVClient_SendSignonData) + { + V_strncpy(error, "Failed to find CHLTVClient::SendSignonData.", maxlength); + + return false; + } + + CBaseClient_SendSignonData = g_PatternFinderEngine.Find(CBaseClient_SendSignonDataPattern, sizeof(CBaseClient_SendSignonDataPattern) - 1); + if(!CBaseClient_SendSignonData) + { + V_strncpy(error, "Failed to find CBaseClient::SendSignonData.", maxlength); + + return false; + } + // Maxentries parameter m_pMaxEntries = reinterpret_cast(pCreateNetworkStringTables + WIN_LINUX(0x2F, 0x63)); @@ -80,6 +114,11 @@ bool LimitExtender::Init(char* error, size_t maxlength) // Transfer modified table to clients m_pSendTables = g_pCVar->FindVar("sv_sendtables"); + // sv.m_FullSendTables + m_pFullSendTables = *reinterpret_cast(pCreateBaseline + WIN_LINUX(0xA5, 0x75)); + + m_pCHLTVClient_SendSignonData = new subhook::Hook(pCHLTVClient_SendSignonData, reinterpret_cast(CHLTVClient_SendSignonDataHook)); + return true; } @@ -98,6 +137,8 @@ void LimitExtender::Enable() // Disallow changing sv_sendtables m_pSendTables->InstallChangeCallback(SendTablesChangeCallback); + + m_pCHLTVClient_SendSignonData->Install(); } void LimitExtender::Shutdown() @@ -106,6 +147,11 @@ void LimitExtender::Shutdown() { m_pSendTables->RemoveChangeCallback(SendTablesChangeCallback); } + + if(m_pCHLTVClient_SendSignonData) + { + delete m_pCHLTVClient_SendSignonData; + } } void LimitExtender::SendTablesChangeCallback(IConVar* pVar, const char* pszOldValue, float flOldValue) @@ -114,4 +160,12 @@ void LimitExtender::SendTablesChangeCallback(IConVar* pVar, const char* pszOldVa { pVar->SetValue(1); } +} + +bool LimitExtender::CHLTVClient_SendSignonDataHook(CHLTVClient* _this) +{ + // Send tables & class infos + _this->GetNetChannel()->SendData(*m_pFullSendTables); + + return CBaseClient_SendSignonData(_this); } \ No newline at end of file diff --git a/plugin/limit_extender.h b/plugin/limit_extender.h index dbc48fd..dab09b9 100644 --- a/plugin/limit_extender.h +++ b/plugin/limit_extender.h @@ -21,7 +21,9 @@ #define _INCLUDE_LIMIT_EXTENDER_H_ #include "particle_fix.h" +#include "subhook.h" #include +#include class LimitExtender { @@ -31,12 +33,28 @@ class LimitExtender void Shutdown(); private: + class CBaseClient : public IGameEventListener2, public IClient + { + public: + virtual ~CBaseClient(); + }; + + class CHLTVClient : public CBaseClient + { + public: + virtual ~CHLTVClient(); + }; + static void SendTablesChangeCallback(IConVar* pVar, const char* pszOldValue, float flOldValue); + static bool WIN_LINUX(__thiscall, __cdecl) CHLTVClient_SendSignonDataHook(CHLTVClient* _this); uint32_t* m_pMaxEntries; int32_t* m_pBits; uint32_t* m_pSendTableCRC; ConVar* m_pSendTables; + static bf_write* m_pFullSendTables; + subhook::Hook* m_pCHLTVClient_SendSignonData; + static bool (WIN_LINUX(__thiscall, __cdecl) *CBaseClient_SendSignonData)(CBaseClient* _this); }; #endif // _INCLUDE_LIMIT_EXTENDER_H_ \ No newline at end of file diff --git a/plugin/particle_fix.cpp b/plugin/particle_fix.cpp index d96e5d2..f8bc143 100644 --- a/plugin/particle_fix.cpp +++ b/plugin/particle_fix.cpp @@ -99,5 +99,5 @@ void ParticleFix::LevelInit(char const* pszMapName) const char* ParticleFix::GetPluginDescription() { - return "ParticleFix (1.0.1) by Phoenix (˙·٠●Феникс●٠·˙)"; + return "ParticleFix (1.0.2) by Phoenix (˙·٠●Феникс●٠·˙)"; } \ No newline at end of file