Skip to content

Commit

Permalink
Use a different method to get pending clients
Browse files Browse the repository at this point in the history
It's ugly but it ensures that we won't run into issues with clients sharing an IP
  • Loading branch information
xen-000 committed Feb 19, 2024
1 parent 808b06e commit ecfb06e
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 19 deletions.
15 changes: 10 additions & 5 deletions src/cs2fixes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -528,13 +528,18 @@ void CS2Fixes::AllPluginsLoaded()
Message( "AllPluginsLoaded\n" );
}

CServerSideClient *GetClientBySlot(CPlayerSlot slot)
CUtlVector<CServerSideClient *> *GetClientList()
{
if (!g_pNetworkGameServer)
return nullptr;

static int offset = g_GameConfig->GetOffset("CNetworkGameServer_ClientList");
CUtlVector<CServerSideClient *> *pClients = (CUtlVector<CServerSideClient *> *)(&g_pNetworkGameServer[offset]);
return (CUtlVector<CServerSideClient *> *)(&g_pNetworkGameServer[offset]);
}

CServerSideClient *GetClientBySlot(CPlayerSlot slot)
{
CUtlVector<CServerSideClient *> *pClients = GetClientList();

if (!pClients)
return nullptr;
Expand Down Expand Up @@ -599,18 +604,18 @@ bool CS2Fixes::Hook_ClientConnect( CPlayerSlot slot, const char *pszName, uint64
netadr_t *adr = pClient->GetRemoteAddress();
Message("Client %lli, %i.%i.%i.%i", xuid, adr->ip[0], adr->ip[1], adr->ip[2], adr->ip[3]);

// Store the client's ID and IP temporarily as they will get reconnected once the extra addon is sent
// Store the client's ID temporarily as they will get reconnected once the extra addon is sent
// This gets checked for in SendNetMessage so we don't repeatedly send the changelevel signon state
// The only caveat to this is that there's no way for us to verify if the client has actually downloaded the extra addon,
// since they're fully disconnected while downloading it
// since they're fully disconnected while downloading it, so the best we can do is use a timeout interval
int index;
ClientJoinInfo_t *pPendingClient = GetPendingClient(xuid, index);

if (!pPendingClient)
{
// Client joined for the first time or after a timeout
Msg(" will reconnect for addon\n");
AddPendingClient(xuid, *(uint32*)adr->ip);
AddPendingClient(xuid);
}
else if ((g_flUniversalTime - pPendingClient->signon_timestamp) < g_flRejoinTimeout)
{
Expand Down
3 changes: 1 addition & 2 deletions src/detours.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -458,8 +458,7 @@ void FASTCALL Detour_SendNetMessage(CNetChan *pNetChan, INetworkSerializable *pN
return SendNetMessage(pNetChan, pNetMessage, pData, a4);

netadr_t *adr = pNetChan->GetRemoteAddress();
uint32 ip32 = *(uint32*)adr->ip;
ClientJoinInfo_t *pPendingClient = GetPendingClient(ip32);
ClientJoinInfo_t *pPendingClient = GetPendingClient(pNetChan);

CUtlString str;
info->m_pBinding->ToString(pData, str);
Expand Down
32 changes: 23 additions & 9 deletions src/playermanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "entity/ccsplayercontroller.h"
#include "utils/entity.h"
#include "ctimer.h"
#include "serversideclient.h"
#include "ctime"

#define VPROF_ENABLED
Expand All @@ -37,34 +38,47 @@
extern IVEngineServer2 *g_pEngineServer2;
extern CGameEntitySystem *g_pEntitySystem;
extern CGlobalVars *gpGlobals;
extern INetworkGameServer *g_pNetworkGameServer;

extern CUtlVector<CServerSideClient *> *GetClientList();

CUtlVector<ClientJoinInfo_t> g_ClientsPendingAddon;

void AddPendingClient(uint64 steamid, uint32 ip32)
void AddPendingClient(uint64 steamid)
{
ClientJoinInfo_t PendingCLient {steamid, ip32, 0.f};
ClientJoinInfo_t PendingCLient {steamid, 0.f};
g_ClientsPendingAddon.AddToTail(PendingCLient);
}

ClientJoinInfo_t *GetPendingClient(uint32 ip32)
ClientJoinInfo_t *GetPendingClient(uint64 steamid, int &index)
{
index = 0;

FOR_EACH_VEC(g_ClientsPendingAddon, i)
{
if (g_ClientsPendingAddon[i].ip32 == ip32)
if (g_ClientsPendingAddon[i].steamid == steamid)
{
index = i;
return &g_ClientsPendingAddon[i];
}
}

return nullptr;
}

ClientJoinInfo_t *GetPendingClient(uint64 steamid, int &index)
ClientJoinInfo_t *GetPendingClient(CNetChan *pNetChan)
{
index = 0;
CUtlVector<CServerSideClient *> *pClients = GetClientList();

FOR_EACH_VEC(g_ClientsPendingAddon, index)
if (!pClients)
return nullptr;

FOR_EACH_VEC(*pClients, i)
{
if (g_ClientsPendingAddon[index].steamid == steamid)
return &g_ClientsPendingAddon[index];
CServerSideClient *pClient = pClients->Element(i);

if (pClient && pClient->GetNetChannel() == pNetChan)
return GetPendingClient(pClient->GetClientSteamID()->ConvertToUint64(), i); // just pass i here, it's discarded anyway
}

return nullptr;
Expand Down
7 changes: 4 additions & 3 deletions src/playermanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,16 @@
struct ClientJoinInfo_t
{
uint64 steamid;
uint32 ip32;
double signon_timestamp;
};

class CNetChan;

extern CUtlVector<ClientJoinInfo_t> g_ClientsPendingAddon;

void AddPendingClient(uint64 steamid, uint32 ip32);
ClientJoinInfo_t *GetPendingClient(uint32 ip32);
void AddPendingClient(uint64 steamid);
ClientJoinInfo_t *GetPendingClient(uint64 steamid, int &index);
ClientJoinInfo_t *GetPendingClient(CNetChan *pNetChan);

enum class ETargetType {
NONE,
Expand Down

0 comments on commit ecfb06e

Please sign in to comment.