Skip to content

Commit a8bec38

Browse files
committed
Switch to SourceHook for SendNetMessage
1 parent 405f64d commit a8bec38

File tree

2 files changed

+25
-57
lines changed

2 files changed

+25
-57
lines changed

src/multiaddonmanager.cpp

Lines changed: 23 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -92,25 +92,26 @@ std::string VectorToString(CUtlVector<std::string> &vector)
9292
return result;
9393
}
9494

95-
typedef void (FASTCALL *SendNetMessage_t)(INetChannel *pNetChan, CNetMessage *pData, int a4);
9695
typedef void* (FASTCALL *HostStateRequest_t)(void *a1, void **pRequest);
97-
98-
void FASTCALL Hook_SendNetMessage(INetChannel *pNetChan, CNetMessage *pData, int a4);
9996
void* FASTCALL Hook_HostStateRequest(void *a1, void **pRequest);
100-
101-
SendNetMessage_t g_pfnSendNetMessage = nullptr;
10297
HostStateRequest_t g_pfnHostStateRequest = nullptr;
103-
104-
funchook_t *g_pSendNetMessageHook = nullptr;
10598
funchook_t *g_pHostStateRequestHook = nullptr;
10699

100+
int g_iSendNetMessage;
101+
107102
class GameSessionConfiguration_t { };
108103

109104
SH_DECL_HOOK0_void(IServerGameDLL, GameServerSteamAPIActivated, SH_NOATTRIB, 0);
110105
SH_DECL_HOOK3_void(INetworkServerService, StartupServer, SH_NOATTRIB, 0, const GameSessionConfiguration_t &, ISource2WorldSession *, const char *);
111106
SH_DECL_HOOK6(IServerGameClients, ClientConnect, SH_NOATTRIB, 0, bool, CPlayerSlot, const char*, uint64, const char *, bool, CBufferString *);
112107
SH_DECL_HOOK3_void(IServerGameDLL, GameFrame, SH_NOATTRIB, 0, bool, bool, bool);
113108

109+
#ifdef PLATFORM_WINDOWS
110+
SH_DECL_MANUALHOOK2(SendNetMessage, 15, 0, 0, bool, CNetMessage *, NetChannelBufType_t);
111+
#else
112+
SH_DECL_MANUALHOOK2(SendNetMessage, 16, 0, 0, bool, CNetMessage *, NetChannelBufType_t);
113+
#endif
114+
114115
MultiAddonManager g_MultiAddonManager;
115116
INetworkGameServer *g_pNetworkGameServer = nullptr;
116117
CSteamGameServerAPIContext g_SteamAPI;
@@ -135,33 +136,17 @@ bool MultiAddonManager::Load(PluginId id, ISmmAPI *ismm, char *error, size_t max
135136
// Required to get the IMetamodListener events
136137
g_SMAPI->AddListener( this, this );
137138

138-
CModule *pEngineModule = new CModule(ROOTBIN, "engine2");
139-
CModule *pNetworkSystemModule = new CModule(ROOTBIN, "networksystem");
139+
CModule engineModule(ROOTBIN, "engine2");
140140

141141
#ifdef PLATFORM_WINDOWS
142-
const byte SendNetMessage_Sig[] = "\x48\x89\x5C\x24\x10\x48\x89\x6C\x24\x18\x56\x57\x41\x56\x48\x83\xEC\x40\x48\x8D\xA9\xD8\x75\x00\x00";
143142
const byte HostStateRequest_Sig[] = "\x48\x89\x74\x24\x10\x57\x48\x83\xEC\x30\x33\xF6\x48\x8B\xFA";
144143
#else
145-
const byte SendNetMessage_Sig[] = "\x55\x48\x89\xE5\x41\x57\x41\x56\x4C\x8D\xB7\x2A\x2A\x2A\x2A\x41\x55\x49\x89\xF5";
146144
const byte HostStateRequest_Sig[] = "\x55\x48\x89\xE5\x41\x56\x41\x55\x41\x54\x49\x89\xF4\x53\x48\x83\x7F\x30\x00";
147145
#endif
148146

149147
int sig_error;
150148

151-
g_pfnSendNetMessage = (SendNetMessage_t)pNetworkSystemModule->FindSignature(SendNetMessage_Sig, sizeof(SendNetMessage_Sig) - 1, sig_error);
152-
153-
if (!g_pfnSendNetMessage)
154-
{
155-
V_snprintf(error, maxlen, "Could not find the signature for SendNetMessage\n");
156-
Panic("%s", error);
157-
return false;
158-
}
159-
else if (sig_error == SIG_FOUND_MULTIPLE)
160-
{
161-
Panic("Signature for SendNetMessage occurs multiple times! Using first match but this might end up crashing!\n");
162-
}
163-
164-
g_pfnHostStateRequest = (HostStateRequest_t)pEngineModule->FindSignature(HostStateRequest_Sig, sizeof(HostStateRequest_Sig) - 1, sig_error);
149+
g_pfnHostStateRequest = (HostStateRequest_t)engineModule.FindSignature(HostStateRequest_Sig, sizeof(HostStateRequest_Sig) - 1, sig_error);
165150

166151
if (!g_pfnHostStateRequest)
167152
{
@@ -174,13 +159,6 @@ bool MultiAddonManager::Load(PluginId id, ISmmAPI *ismm, char *error, size_t max
174159
Panic("Signature for HostStateRequest occurs multiple times! Using first match but this might end up crashing!\n");
175160
}
176161

177-
delete pEngineModule;
178-
delete pNetworkSystemModule;
179-
180-
g_pSendNetMessageHook = funchook_create();
181-
funchook_prepare(g_pSendNetMessageHook, (void**)&g_pfnSendNetMessage, (void*)Hook_SendNetMessage);
182-
funchook_install(g_pSendNetMessageHook, 0);
183-
184162
g_pHostStateRequestHook = funchook_create();
185163
funchook_prepare(g_pHostStateRequestHook, (void **)&g_pfnHostStateRequest, (void*)Hook_HostStateRequest);
186164
funchook_install(g_pHostStateRequestHook, 0);
@@ -190,6 +168,9 @@ bool MultiAddonManager::Load(PluginId id, ISmmAPI *ismm, char *error, size_t max
190168
SH_ADD_HOOK(IServerGameClients, ClientConnect, g_pSource2GameClients, SH_MEMBER(this, &MultiAddonManager::Hook_ClientConnect), false);
191169
SH_ADD_HOOK(IServerGameDLL, GameFrame, g_pSource2Server, SH_MEMBER(this, &MultiAddonManager::Hook_GameFrame), true);
192170

171+
void *pServerSideClientVTable = engineModule.FindVirtualTable("CServerSideClient");
172+
g_iSendNetMessage = SH_ADD_MANUALDVPHOOK(SendNetMessage, pServerSideClientVTable, SH_MEMBER(&g_MultiAddonManager, &MultiAddonManager::Hook_SendNetMessage), false);
173+
193174
if (late)
194175
{
195176
g_pNetworkGameServer = g_pNetworkServerService->GetIGameServer();
@@ -215,12 +196,7 @@ bool MultiAddonManager::Unload(char *error, size_t maxlen)
215196
SH_REMOVE_HOOK(INetworkServerService, StartupServer, g_pNetworkServerService, SH_MEMBER(this, &MultiAddonManager::Hook_StartupServer), true);
216197
SH_REMOVE_HOOK(IServerGameClients, ClientConnect, g_pSource2GameClients, SH_MEMBER(this, &MultiAddonManager::Hook_ClientConnect), false);
217198
SH_REMOVE_HOOK(IServerGameDLL, GameFrame, g_pSource2Server, SH_MEMBER(this, &MultiAddonManager::Hook_GameFrame), true);
218-
219-
if (g_pSendNetMessageHook)
220-
{
221-
funchook_uninstall(g_pSendNetMessageHook, 0);
222-
funchook_destroy(g_pSendNetMessageHook);
223-
}
199+
SH_REMOVE_HOOK_ID(g_iSendNetMessage);
224200

225201
if (g_pHostStateRequestHook)
226202
{
@@ -623,22 +599,10 @@ ClientJoinInfo_t *GetPendingClient(uint64 steamid, int &index)
623599
return nullptr;
624600
}
625601

626-
ClientJoinInfo_t *GetPendingClient(INetChannel *pNetChan)
602+
ClientJoinInfo_t *GetPendingClient(uint64 steamid)
627603
{
628-
CUtlVector<CServerSideClient *> *pClients = GetClientList();
629-
630-
if (!pClients)
631-
return nullptr;
632-
633-
FOR_EACH_VEC(*pClients, i)
634-
{
635-
CServerSideClient *pClient = pClients->Element(i);
636-
637-
if (pClient && pClient->GetNetChannel() == pNetChan)
638-
return GetPendingClient(pClient->GetClientSteamID()->ConvertToUint64(), i); // just pass i here, it's discarded anyway
639-
}
640-
641-
return nullptr;
604+
int index;
605+
return GetPendingClient(steamid, index);
642606
}
643607

644608
void MultiAddonManager::Hook_StartupServer(const GameSessionConfiguration_t &config, ISource2WorldSession *session, const char *mapname)
@@ -659,13 +623,13 @@ void MultiAddonManager::Hook_StartupServer(const GameSessionConfiguration_t &con
659623
RefreshAddons();
660624
}
661625

662-
void FASTCALL Hook_SendNetMessage(INetChannel *pNetChan, CNetMessage *pData, int a4)
626+
bool MultiAddonManager::Hook_SendNetMessage(CNetMessage *pData, NetChannelBufType_t bufType)
663627
{
664628
NetMessageInfo_t *info = pData->GetNetMessage()->GetNetMessageInfo();
665629

666630
// 7 for signon messages
667631
if (info->m_MessageId != 7 || g_MultiAddonManager.m_ExtraAddons.Count() == 0 || !CommandLine()->HasParm("-dedicated"))
668-
return g_pfnSendNetMessage(pNetChan, pData, a4);
632+
RETURN_META_VALUE(MRES_IGNORED, true);
669633

670634
auto pMsg = pData->ToPB<CNETMsg_SignonState>();
671635

@@ -678,7 +642,9 @@ void FASTCALL Hook_SendNetMessage(INetChannel *pNetChan, CNetMessage *pData, int
678642
if (pMsg->signon_state() == SIGNONSTATE_CHANGELEVEL)
679643
pMsg->set_addons(sMap.empty() ? g_MultiAddonManager.m_ExtraAddons[0].c_str() : sMap.c_str()); // If we're on a default map send the first addon
680644

681-
ClientJoinInfo_t *pPendingClient = GetPendingClient(pNetChan);
645+
CServerSideClient *pClient = META_IFACEPTR(CServerSideClient);
646+
647+
ClientJoinInfo_t *pPendingClient = GetPendingClient(pClient->GetClientSteamID()->ConvertToUint64());
682648

683649
if (pPendingClient)
684650
{
@@ -692,7 +658,7 @@ void FASTCALL Hook_SendNetMessage(INetChannel *pNetChan, CNetMessage *pData, int
692658
pPendingClient->signon_timestamp = Plat_FloatTime();
693659
}
694660

695-
g_pfnSendNetMessage(pNetChan, pData, a4);
661+
RETURN_META_VALUE(MRES_HANDLED, true);
696662
}
697663

698664
void* FASTCALL Hook_HostStateRequest(void *a1, void **pRequest)

src/multiaddonmanager.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <sh_vector.h>
2525
#include "utlqueue.h"
2626
#include "utlvector.h"
27+
#include "networksystem/inetworkserializer.h"
2728
#include "steam/steam_api_common.h"
2829
#include "steam/isteamugc.h"
2930
#include "imultiaddonmanager.h"
@@ -75,6 +76,7 @@ class MultiAddonManager : public ISmmPlugin, public IMetamodListener
7576
public: //hooks
7677
void Hook_GameServerSteamAPIActivated();
7778
void Hook_StartupServer(const GameSessionConfiguration_t &config, ISource2WorldSession *, const char *);
79+
bool Hook_SendNetMessage(CNetMessage *pData, NetChannelBufType_t bufType);
7880
bool Hook_ClientConnect(CPlayerSlot slot, const char *pszName, uint64 xuid, const char *pszNetworkID, bool unk1, CBufferString *pRejectReason);
7981
void Hook_GameFrame(bool simulating, bool bFirstTick, bool bLastTick);
8082

0 commit comments

Comments
 (0)