From e551e58a7ddb25f27ee10021a1bb86d14c33d1bf Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Sat, 30 Dec 2023 02:51:02 +0100 Subject: [PATCH] Server: rename 'ServerPlayer_t' to 'CClientExtended' A more correct name + comments as to why this structure exists. --- r5dev/engine/client/client.cpp | 19 ++++++++--- r5dev/engine/client/client.h | 38 ++++++++++++++++++++++ r5dev/engine/net.cpp | 1 - r5dev/engine/net_chan.cpp | 18 +++++----- r5dev/engine/networkstringtable.cpp | 12 +++---- r5dev/engine/server/server.cpp | 3 +- r5dev/engine/server/server.h | 9 +++-- r5dev/engine/server/vengineserver_impl.cpp | 5 +-- r5dev/engine/server/vengineserver_impl.h | 28 ---------------- 9 files changed, 77 insertions(+), 56 deletions(-) diff --git a/r5dev/engine/client/client.cpp b/r5dev/engine/client/client.cpp index f07fec7b..4aef78e8 100644 --- a/r5dev/engine/client/client.cpp +++ b/r5dev/engine/client/client.cpp @@ -27,7 +27,7 @@ void CClient::Clear(void) { #ifndef CLIENT_DLL - g_ServerPlayer[GetUserID()].Reset(); // Reset ServerPlayer slot. + GetClientExtended()->Reset(); // Reset extended data. #endif // !CLIENT_DLL v_CClient_Clear(this); } @@ -41,6 +41,16 @@ void CClient::VClear(CClient* pClient) pClient->Clear(); } +//--------------------------------------------------------------------------------- +// Purpose: gets the extended client data +// Output : CClientExtended* - +//--------------------------------------------------------------------------------- +CClientExtended* CClient::GetClientExtended(void) const +{ + return m_pServer->GetClientExtended(m_nUserID); +} + + static const char JWT_PUBLIC_KEY[] = "-----BEGIN PUBLIC KEY-----\n" "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2/335exIZ6LE8pYi6e50\n" @@ -186,7 +196,7 @@ bool CClient::Connect(const char* szName, CNetChan* pNetChan, bool bFakePlayer, CUtlVector* conVars, char* szMessage, int nMessageSize) { #ifndef CLIENT_DLL - g_ServerPlayer[GetUserID()].Reset(); // Reset ServerPlayer slot. + GetClientExtended()->Reset(); // Reset extended data. #endif if (!v_CClient_Connect(this, szName, pNetChan, bFakePlayer, conVars, szMessage, nMessageSize)) @@ -362,8 +372,7 @@ bool CClient::VProcessStringCmd(CClient* pClient, NET_StringCmd* pMsg) if (!pClient_Adj->IsActive()) return true; - const int nUserID = pClient_Adj->GetUserID(); - ServerPlayer_t* const pSlot = &g_ServerPlayer[nUserID]; + CClientExtended* const pSlot = pClient_Adj->GetClientExtended(); const double flStartTime = Plat_FloatTime(); const int nCmdQuotaLimit = sv_quota_stringCmdsPerSecond->GetInt(); @@ -427,7 +436,7 @@ bool CClient::VProcessSetConVar(CClient* pClient, NET_SetConVar* pMsg) { #ifndef CLIENT_DLL CClient* const pAdj = AdjustShiftedThisPointer(pClient); - ServerPlayer_t* const pSlot = &g_ServerPlayer[pAdj->GetUserID()]; + CClientExtended* const pSlot = pAdj->GetClientExtended(); // This loop never exceeds 255 iterations, NET_SetConVar::ReadFromBuffer(...) // reads and inserts up to 255 entries in the vector (reads a byte for size). diff --git a/r5dev/engine/client/client.h b/r5dev/engine/client/client.h index 7372b452..5451edbd 100644 --- a/r5dev/engine/client/client.h +++ b/r5dev/engine/client/client.h @@ -21,6 +21,7 @@ enum Reputation_t //----------------------------------------------------------------------------- class CServer; class CClient; +class CClientExtended; struct Spike_t { @@ -73,6 +74,8 @@ public: inline CNetChan* GetNetChan(void) const { return m_NetChannel; } inline CServer* GetServer(void) const { return m_pServer; } + CClientExtended* GetClientExtended(void) const; + inline int GetCommandTick(void) const { return m_nCommandTick; } inline const char* GetServerName(void) const { return m_szServerName; } inline const char* GetClientName(void) const { return m_szClientName; } @@ -208,6 +211,41 @@ static_assert(sizeof(CClient) == 0x4A440); static_assert(sizeof(CClient) == 0x4A4C0); #endif +//----------------------------------------------------------------------------- +// Extended CClient class +//----------------------------------------------------------------------------- +// NOTE: since we interface directly with the engine, we cannot modify the +// client structure. In order to add new data to each client instance, we +// need to use this new class which we link directly to the corresponding +// client instance through its UserID. +//----------------------------------------------------------------------------- +class CClientExtended +{ +public: + CClientExtended(void) + { + Reset(); + } + inline void Reset(void) + { + m_flCurrentNetProcessTime = 0.0; + m_flLastNetProcessTime = 0.0; + m_flLastClockSyncTime = 0.0; + m_flStringCommandQuotaTimeStart = 0.0; + m_nStringCommandQuotaCount = NULL; + m_bRetryClockSync = false; + m_bInitialConVarsSet = false; + } + + double m_flCurrentNetProcessTime; + double m_flLastNetProcessTime; + double m_flLastClockSyncTime; + double m_flStringCommandQuotaTimeStart; + int m_nStringCommandQuotaCount; + bool m_bRetryClockSync; + bool m_bInitialConVarsSet; +}; + /* ==== CBASECLIENT ===================================================================================================================================================== */ inline CMemory p_CClient_Connect; inline bool(*v_CClient_Connect)(CClient* pClient, const char* szName, CNetChan* pNetChan, bool bFakePlayer, CUtlVector* conVars, char* szMessage, int nMessageSize); diff --git a/r5dev/engine/net.cpp b/r5dev/engine/net.cpp index 906b110e..424a5342 100644 --- a/r5dev/engine/net.cpp +++ b/r5dev/engine/net.cpp @@ -175,7 +175,6 @@ void NET_RemoveChannel(CClient* pClient, int nIndex, const char* szReason, uint8 pClient->GetNetChan()->Shutdown(szReason, bBadRep, bRemoveNow); // Shutdown NetChannel. pClient->Clear(); // Reset CClient slot. - g_ServerPlayer[nIndex].Reset(); // Reset ServerPlayer slot. #endif // !CLIENT_DLL } diff --git a/r5dev/engine/net_chan.cpp b/r5dev/engine/net_chan.cpp index 8edb836a..80062655 100644 --- a/r5dev/engine/net_chan.cpp +++ b/r5dev/engine/net_chan.cpp @@ -345,23 +345,23 @@ bool CNetChan::_ProcessMessages(CNetChan* pChan, bf_read* pBuf) if (!pChan->m_MessageHandler) // NetChannel removed? return bResult; - CClient* pClient = reinterpret_cast(pChan->m_MessageHandler); - ServerPlayer_t* pSlot = &g_ServerPlayer[pClient->GetUserID()]; + CClient* const pClient = reinterpret_cast(pChan->m_MessageHandler); + CClientExtended* const pExtended = pClient->GetClientExtended(); - if (flStartTime - pSlot->m_flLastNetProcessTime >= 1.0 || - pSlot->m_flLastNetProcessTime == -1.0) + if (flStartTime - pExtended->m_flLastNetProcessTime >= 1.0 || + pExtended->m_flLastNetProcessTime == -1.0) { - pSlot->m_flLastNetProcessTime = flStartTime; - pSlot->m_flCurrentNetProcessTime = 0.0; + pExtended->m_flLastNetProcessTime = flStartTime; + pExtended->m_flCurrentNetProcessTime = 0.0; } - pSlot->m_flCurrentNetProcessTime += + pExtended->m_flCurrentNetProcessTime += (Plat_FloatTime() * 1000) - (flStartTime * 1000); - if (pSlot->m_flCurrentNetProcessTime > + if (pExtended->m_flCurrentNetProcessTime > net_processTimeBudget->GetFloat()) { Warning(eDLL_T::SERVER, "Removing netchannel '%s' ('%s' exceeded frame budget by '%3.1f'ms!)\n", - pChan->GetName(), pChan->GetAddress(), (pSlot->m_flCurrentNetProcessTime - net_processTimeBudget->GetFloat())); + pChan->GetName(), pChan->GetAddress(), (pExtended->m_flCurrentNetProcessTime - net_processTimeBudget->GetFloat())); pClient->Disconnect(Reputation_t::REP_MARK_BAD, "#DISCONNECT_NETCHAN_OVERFLOW"); return false; diff --git a/r5dev/engine/networkstringtable.cpp b/r5dev/engine/networkstringtable.cpp index 789bdf5b..cb4a1e92 100644 --- a/r5dev/engine/networkstringtable.cpp +++ b/r5dev/engine/networkstringtable.cpp @@ -95,19 +95,19 @@ void CNetworkStringTableContainer::WriteUpdateMessage(CNetworkStringTableContain #ifndef CLIENT_DLL const double currentTime = Plat_FloatTime(); - ServerPlayer_t& clientExtended = g_ServerPlayer[pClient->GetUserID()]; + CClientExtended* const clientExtended = pClient->GetClientExtended(); int commandTick = -1; // -1 means we update statistics only; see 'CClientState::VProcessServerTick()'. // NOTE: if we send this message each tick, the client will start to // falter. Unlike other source games, we have to have some delay in // between each server tick message for this to work correctly. - if (clientExtended.m_bRetryClockSync || - (currentTime - clientExtended.m_flLastClockSyncTime) > sv_clockSyncInterval->GetFloat()) + if (clientExtended->m_bRetryClockSync || + (currentTime - clientExtended->m_flLastClockSyncTime) > sv_clockSyncInterval->GetFloat()) { // Sync the clocks on the client with that of the server's. commandTick = pClient->GetCommandTick(); - clientExtended.m_flLastClockSyncTime = currentTime; - clientExtended.m_bRetryClockSync = false; + clientExtended->m_flLastClockSyncTime = currentTime; + clientExtended->m_bRetryClockSync = false; } // If commandTick == statistics only while server opted out, do not @@ -132,7 +132,7 @@ void CNetworkStringTableContainer::WriteUpdateMessage(CNetworkStringTableContain else { Assert(0, "Snapshot buffer overflowed before string table update!"); - clientExtended.m_bRetryClockSync = true; // Retry on next snapshot for this client. + clientExtended->m_bRetryClockSync = true; // Retry on next snapshot for this client. } } #endif // !CLIENT_DLL diff --git a/r5dev/engine/server/server.cpp b/r5dev/engine/server/server.cpp index fba24376..60321ceb 100644 --- a/r5dev/engine/server/server.cpp +++ b/r5dev/engine/server/server.cpp @@ -222,4 +222,5 @@ void VServer::Detour(const bool bAttach) const /////////////////////////////////////////////////////////////////////////////// -CServer* g_pServer = nullptr; \ No newline at end of file +CServer* g_pServer = nullptr; +CClientExtended CServer::sm_ClientsExtended[MAX_PLAYERS]; diff --git a/r5dev/engine/server/server.h b/r5dev/engine/server/server.h index ddada952..64a95939 100644 --- a/r5dev/engine/server/server.h +++ b/r5dev/engine/server/server.h @@ -45,7 +45,8 @@ public: inline int GetMaxClients(void) const { return m_nMaxClients; } inline int64_t GetMaxTeams(void) const { return m_iMaxTeams; } - inline CClient* GetClient(int nIndex) { Assert(nIndex >= NULL && nIndex < MAX_PLAYERS); return &m_Clients[nIndex]; } + inline CClient* GetClient(const int nIndex) { Assert(nIndex >= NULL && nIndex < MAX_PLAYERS); return &m_Clients[nIndex]; } + inline CClientExtended* GetClientExtended(const int nIndex) { Assert(nIndex >= NULL && nIndex < MAX_PLAYERS); return &sm_ClientsExtended[nIndex]; } inline float GetTime(void) const { return m_nTickCount * m_flTickInterval; } inline float GetCPUUsage(void) const { return m_fCPUPercent; } @@ -58,7 +59,6 @@ public: static CClient* ConnectClient(CServer* pServer, user_creds_s* pChallenge); void BroadcastMessage(CNetMessage* const msg, const bool onlyActive, const bool reliable); - void UpdateClientClocks(void); static void RunFrame(CServer* pServer); static void FrameJob(double flFrameTime, bool bRunOverlays, bool bUpdateFrame); #endif // !CLIENT_DLL @@ -101,6 +101,11 @@ private: float m_fStartTime; float m_fLastCPUCheckTime; bool m_bTeams[MAX_TEAMS]; // Something with teams, unclear what this does; see '[r5apex_ds.exe + 0x30CE40]' + + // Maps directly to m_Clients, contains extended client data which we + // cannot add to the CClient class as it would otherwise mismatch the + // structure in the engine. + static CClientExtended sm_ClientsExtended[MAX_PLAYERS]; }; #if defined (GAMEDLL_S0) || defined (GAMEDLL_S1) // !TODO: check if struct size is correct for S1! diff --git a/r5dev/engine/server/vengineserver_impl.cpp b/r5dev/engine/server/vengineserver_impl.cpp index cb449af4..4e8a67f6 100644 --- a/r5dev/engine/server/vengineserver_impl.cpp +++ b/r5dev/engine/server/vengineserver_impl.cpp @@ -20,8 +20,5 @@ void HVEngineServer::Detour(const bool bAttach) const DetourSetup(&IVEngineServer__PersistenceAvailable, &CVEngineServer::PersistenceAvailable, bAttach); } -/////////////////////////////////////////////////////////////////////////////// -ServerPlayer_t g_ServerPlayer[MAX_PLAYERS]; - IVEngineServer* g_pEngineServerVFTable = nullptr; -CVEngineServer* g_pEngineServer = reinterpret_cast(&g_pEngineServerVFTable); \ No newline at end of file +CVEngineServer* g_pEngineServer = reinterpret_cast(&g_pEngineServerVFTable); diff --git a/r5dev/engine/server/vengineserver_impl.h b/r5dev/engine/server/vengineserver_impl.h index 66b97003..9a3ae5a4 100644 --- a/r5dev/engine/server/vengineserver_impl.h +++ b/r5dev/engine/server/vengineserver_impl.h @@ -10,34 +10,6 @@ inline bool* m_bIsDedicated = nullptr; /////////////////////////////////////////////////////////////////////////////// -struct ServerPlayer_t -{ - ServerPlayer_t(void) - { - Reset(); - } - inline void Reset(void) - { - m_flCurrentNetProcessTime = 0.0; - m_flLastNetProcessTime = 0.0; - m_flLastClockSyncTime = 0.0; - m_flStringCommandQuotaTimeStart = 0.0; - m_nStringCommandQuotaCount = NULL; - m_bRetryClockSync = false; - m_bInitialConVarsSet = false; - } - - double m_flCurrentNetProcessTime; - double m_flLastNetProcessTime; - double m_flLastClockSyncTime; - double m_flStringCommandQuotaTimeStart; - int m_nStringCommandQuotaCount; - bool m_bRetryClockSync; - bool m_bInitialConVarsSet; -}; - -extern ServerPlayer_t g_ServerPlayer[MAX_PLAYERS]; - class CVEngineServer : public IVEngineServer { public: