Skip to content

Commit 126dd36

Browse files
committed
Don't use SourceHook for SendNetMessage
It seems that sometimes SendNetMessage is called on a different thread (like when sending spawngroup) and SourceHook DOES NOT like this. So I'm reverting to funchook (with vtable offset) for now until SH is made thread-safe, if ever.
1 parent 6336808 commit 126dd36

File tree

2 files changed

+22
-14
lines changed

2 files changed

+22
-14
lines changed

src/multiaddonmanager.cpp

+22-13
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,16 @@ std::string VectorToString(CUtlVector<std::string> &vector)
9292
return result;
9393
}
9494

95-
typedef void* (FASTCALL *HostStateRequest_t)(void *a1, void **pRequest);
96-
void* FASTCALL Hook_HostStateRequest(void *a1, void **pRequest);
95+
typedef bool (FASTCALL *SendNetMessage_t)(CServerSideClient *, CNetMessage*, NetChannelBufType_t);
96+
typedef void *(FASTCALL *HostStateRequest_t)(void*, void**);
97+
98+
bool FASTCALL Hook_SendNetMessage(CServerSideClient *pClient, CNetMessage *pData, NetChannelBufType_t bufType);
99+
void *FASTCALL Hook_HostStateRequest(void *a1, void **pRequest);
100+
101+
SendNetMessage_t g_pfnSendNetMessage = nullptr;
97102
HostStateRequest_t g_pfnHostStateRequest = nullptr;
103+
104+
funchook_t *g_pSendNetMessageHook = nullptr;
98105
funchook_t *g_pHostStateRequestHook = nullptr;
99106

100107
int g_iSendNetMessage;
@@ -107,9 +114,9 @@ SH_DECL_HOOK6(IServerGameClients, ClientConnect, SH_NOATTRIB, 0, bool, CPlayerSl
107114
SH_DECL_HOOK3_void(IServerGameDLL, GameFrame, SH_NOATTRIB, 0, bool, bool, bool);
108115

109116
#ifdef PLATFORM_WINDOWS
110-
SH_DECL_MANUALHOOK2(SendNetMessage, 15, 0, 0, bool, CNetMessage *, NetChannelBufType_t);
117+
constexpr int g_iSendNetMessageOffset = 15;
111118
#else
112-
SH_DECL_MANUALHOOK2(SendNetMessage, 16, 0, 0, bool, CNetMessage *, NetChannelBufType_t);
119+
constexpr int g_iSendNetMessageOffset = 16;
113120
#endif
114121

115122
struct ClientJoinInfo_t
@@ -171,17 +178,21 @@ bool MultiAddonManager::Load(PluginId id, ISmmAPI *ismm, char *error, size_t max
171178
}
172179

173180
g_pHostStateRequestHook = funchook_create();
174-
funchook_prepare(g_pHostStateRequestHook, (void **)&g_pfnHostStateRequest, (void*)Hook_HostStateRequest);
181+
funchook_prepare(g_pHostStateRequestHook, (void**)&g_pfnHostStateRequest, (void*)Hook_HostStateRequest);
175182
funchook_install(g_pHostStateRequestHook, 0);
176183

184+
void **pServerSideClientVTable = (void **)engineModule.FindVirtualTable("CServerSideClient");
185+
g_pfnSendNetMessage = (SendNetMessage_t)pServerSideClientVTable[g_iSendNetMessageOffset];
186+
187+
g_pSendNetMessageHook = funchook_create();
188+
funchook_prepare(g_pSendNetMessageHook, (void**)&g_pfnSendNetMessage, (void*)Hook_SendNetMessage);
189+
funchook_install(g_pSendNetMessageHook, 0);
190+
177191
SH_ADD_HOOK(IServerGameDLL, GameServerSteamAPIActivated, g_pSource2Server, SH_MEMBER(this, &MultiAddonManager::Hook_GameServerSteamAPIActivated), false);
178192
SH_ADD_HOOK(INetworkServerService, StartupServer, g_pNetworkServerService, SH_MEMBER(this, &MultiAddonManager::Hook_StartupServer), true);
179193
SH_ADD_HOOK(IServerGameClients, ClientConnect, g_pSource2GameClients, SH_MEMBER(this, &MultiAddonManager::Hook_ClientConnect), false);
180194
SH_ADD_HOOK(IServerGameDLL, GameFrame, g_pSource2Server, SH_MEMBER(this, &MultiAddonManager::Hook_GameFrame), true);
181195

182-
void *pServerSideClientVTable = engineModule.FindVirtualTable("CServerSideClient");
183-
g_iSendNetMessage = SH_ADD_MANUALDVPHOOK(SendNetMessage, pServerSideClientVTable, SH_MEMBER(&g_MultiAddonManager, &MultiAddonManager::Hook_SendNetMessage), false);
184-
185196
if (late)
186197
{
187198
g_pNetworkGameServer = g_pNetworkServerService->GetIGameServer();
@@ -634,13 +645,13 @@ void MultiAddonManager::Hook_StartupServer(const GameSessionConfiguration_t &con
634645
RefreshAddons();
635646
}
636647

637-
bool MultiAddonManager::Hook_SendNetMessage(CNetMessage *pData, NetChannelBufType_t bufType)
648+
bool FASTCALL Hook_SendNetMessage(CServerSideClient *pClient, CNetMessage *pData, NetChannelBufType_t bufType)
638649
{
639650
NetMessageInfo_t *info = pData->GetNetMessage()->GetNetMessageInfo();
640651

641652
// 7 for signon messages
642653
if (info->m_MessageId != net_SignonState || g_MultiAddonManager.m_ExtraAddons.Count() == 0 || !CommandLine()->HasParm("-dedicated"))
643-
RETURN_META_VALUE(MRES_IGNORED, true);
654+
return g_pfnSendNetMessage(pClient, pData, bufType);
644655

645656
auto pMsg = pData->ToPB<CNETMsg_SignonState>();
646657

@@ -653,8 +664,6 @@ bool MultiAddonManager::Hook_SendNetMessage(CNetMessage *pData, NetChannelBufTyp
653664
if (pMsg->signon_state() == SIGNONSTATE_CHANGELEVEL)
654665
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
655666

656-
CServerSideClient *pClient = META_IFACEPTR(CServerSideClient);
657-
658667
ClientJoinInfo_t *pPendingClient = GetPendingClient(pClient->GetClientSteamID()->ConvertToUint64());
659668

660669
if (pPendingClient)
@@ -669,7 +678,7 @@ bool MultiAddonManager::Hook_SendNetMessage(CNetMessage *pData, NetChannelBufTyp
669678
pPendingClient->signon_timestamp = Plat_FloatTime();
670679
}
671680

672-
RETURN_META_VALUE(MRES_HANDLED, true);
681+
return g_pfnSendNetMessage(pClient, pData, bufType);
673682
}
674683

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

src/multiaddonmanager.h

-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ class MultiAddonManager : public ISmmPlugin, public IMetamodListener
7676
public: //hooks
7777
void Hook_GameServerSteamAPIActivated();
7878
void Hook_StartupServer(const GameSessionConfiguration_t &config, ISource2WorldSession *, const char *);
79-
bool Hook_SendNetMessage(CNetMessage *pData, NetChannelBufType_t bufType);
8079
bool Hook_ClientConnect(CPlayerSlot slot, const char *pszName, uint64 xuid, const char *pszNetworkID, bool unk1, CBufferString *pRejectReason);
8180
void Hook_GameFrame(bool simulating, bool bFirstTick, bool bLastTick);
8281

0 commit comments

Comments
 (0)