diff --git a/r5dev/engine/client/clientstate.cpp b/r5dev/engine/client/clientstate.cpp index 0e4dafe8..0dbc615a 100644 --- a/r5dev/engine/client/clientstate.cpp +++ b/r5dev/engine/client/clientstate.cpp @@ -113,7 +113,7 @@ bool CClientState::VProcessServerTick(CClientState* pClientState, SVC_ServerTick } else // Statistics only. { - char* pShifted = reinterpret_cast(pClientState) - 0x10; // Shifted due to compiled optimizations. + char* pShifted = reinterpret_cast(pClientState) - 0x10; // Shifted due to compiler optimizations. CClientState* pClient_Adj = reinterpret_cast(pShifted); CNetChan* pChan = pClient_Adj->m_NetChannel; diff --git a/r5dev/engine/networkstringtable.cpp b/r5dev/engine/networkstringtable.cpp index 52aa90ad..144b6aef 100644 --- a/r5dev/engine/networkstringtable.cpp +++ b/r5dev/engine/networkstringtable.cpp @@ -89,16 +89,24 @@ bool CNetworkStringTable::Lock(bool bLock) // nTickAck - // *pMsg - //----------------------------------------------------------------------------- -static uint8_t s_OldCPUPercentage; +#ifndef CLIENT_DLL +CFastTimer CNetworkStringTableContainer::sm_StatsTimer; +bool CNetworkStringTableContainer::sm_bStatsInitialized = false; +#endif // !CLIENT_DLL void CNetworkStringTableContainer::WriteUpdateMessage(CNetworkStringTableContainer* thisp, CClient* pClient, unsigned int nTickAck, bf_write* pMsg) { #ifndef CLIENT_DLL if (sv_stats->GetBool()) { - uint8_t nCPUPercentage = static_cast(g_pServer[MAX_PLAYERS].GetCPUUsage() * 100.0f); - if (s_OldCPUPercentage != nCPUPercentage) + if (!sm_bStatsInitialized) { - s_OldCPUPercentage = nCPUPercentage; + sm_bStatsInitialized = true; + sm_StatsTimer.Start(); + } + + if (sm_StatsTimer.GetDurationInProgress().GetSeconds() >= sv_statsUpdateRate->GetDouble()) + { + uint8_t nCPUPercentage = static_cast(g_pServer[MAX_PLAYERS].GetCPUUsage() * 100.0f); SVC_ServerTick serverTick(g_pServer->GetTick(), *host_frametime_unbounded, *host_frametime_stddeviation, nCPUPercentage); serverTick.m_nGroup = 0; @@ -107,6 +115,17 @@ void CNetworkStringTableContainer::WriteUpdateMessage(CNetworkStringTableContain // Send individually instead of writing into snapshot buffer to avoid overflow. pClient->SendNetMsg(&serverTick, false, true, false); + + // Re-run timer. + sm_StatsTimer.Start(); + } + } + else // Reset timer. + { + if (sm_bStatsInitialized) + { + sm_bStatsInitialized = false; + sm_StatsTimer.End(); } } #endif // !CLIENT_DLL diff --git a/r5dev/engine/networkstringtable.h b/r5dev/engine/networkstringtable.h index e5e9b153..fcae5658 100644 --- a/r5dev/engine/networkstringtable.h +++ b/r5dev/engine/networkstringtable.h @@ -7,6 +7,7 @@ #ifndef NETWORKSTRINGTABLE_H #define NETWORKSTRINGTABLE_H +#include "tier0/fasttimer.h" #include "tier1/utlvector.h" #include "tier1/bitbuf.h" #include "client/client.h" @@ -44,6 +45,10 @@ class CNetworkStringTableContainer : public INetworkStringTable { public: static void WriteUpdateMessage(CNetworkStringTableContainer* thisp, CClient* client, unsigned int tick_ack, bf_write* msg); +#ifndef CLIENT_DLL + static CFastTimer sm_StatsTimer; + static bool sm_bStatsInitialized; +#endif // !CLIENT_DLL private: bool m_bAllowCreation; // create guard diff --git a/r5dev/public/tier1/cvar.h b/r5dev/public/tier1/cvar.h index 6f87b0c2..41e44ad2 100644 --- a/r5dev/public/tier1/cvar.h +++ b/r5dev/public/tier1/cvar.h @@ -98,6 +98,7 @@ extern ConVar* sv_autoReloadRate; extern ConVar* sv_simulateBots; extern ConVar* sv_showhitboxes; extern ConVar* sv_stats; +extern ConVar* sv_statsUpdateRate; extern ConVar* sv_quota_stringCmdsPerSecond; diff --git a/r5dev/tier1/cvar.cpp b/r5dev/tier1/cvar.cpp index 0cb915c9..6150d8bd 100644 --- a/r5dev/tier1/cvar.cpp +++ b/r5dev/tier1/cvar.cpp @@ -92,6 +92,7 @@ ConVar* sv_autoReloadRate = nullptr; ConVar* sv_simulateBots = nullptr; ConVar* sv_showhitboxes = nullptr; ConVar* sv_stats = nullptr; +ConVar* sv_statsUpdateRate = nullptr; ConVar* sv_quota_stringCmdsPerSecond = nullptr; @@ -335,8 +336,9 @@ void ConVar::StaticInit(void) sv_pylonVisibility = ConVar::StaticCreate("sv_pylonVisibility", "0", FCVAR_RELEASE, "Determines the visibility to the Pylon master server.", false, 0.f, false, 0.f, nullptr, "0 = Offline, 1 = Hidden, 2 = Public."); sv_pylonRefreshRate = ConVar::StaticCreate("sv_pylonRefreshRate" , "5.0", FCVAR_RELEASE, "Pylon host refresh rate (seconds).", true, 2.f, true, 8.f, nullptr, nullptr); sv_banlistRefreshRate = ConVar::StaticCreate("sv_banlistRefreshRate", "1.0", FCVAR_RELEASE, "Banned list refresh rate (seconds).", true, 1.f, false, 0.f, nullptr, nullptr); - sv_statusRefreshRate = ConVar::StaticCreate("sv_statusRefreshRate" , "0.5", FCVAR_RELEASE, "Server status refresh rate (seconds).", false, 0.f, false, 0.f, nullptr, nullptr); - sv_autoReloadRate = ConVar::StaticCreate("sv_autoReloadRate" , "0" , FCVAR_RELEASE, "Time in seconds between each server auto-reload (disabled if null). ", true, 0.f, false, 0.f, nullptr, nullptr); + sv_statusRefreshRate = ConVar::StaticCreate("sv_statusRefreshRate" , "0.5", FCVAR_RELEASE, "Server status refresh rate (seconds).", true, 0.f, false, 0.f, nullptr, nullptr); + sv_statsUpdateRate = ConVar::StaticCreate("sv_statsUpdateRate" , "1.0", FCVAR_RELEASE, "Server statistics update rate (seconds).", true, 0.f, false, 0.f, nullptr, nullptr); + sv_autoReloadRate = ConVar::StaticCreate("sv_autoReloadRate" , "0" , FCVAR_RELEASE, "Time in seconds between each server auto-reload (disabled if null).", true, 0.f, false, 0.f, nullptr, nullptr); sv_simulateBots = ConVar::StaticCreate("sv_simulateBots", "1", FCVAR_RELEASE, "Simulate user commands for bots on the server.", true, 0.f, false, 0.f, nullptr, nullptr); sv_rcon_debug = ConVar::StaticCreate("sv_rcon_debug" , "0" , FCVAR_RELEASE, "Show rcon debug information ( !slower! ).", false, 0.f, false, 0.f, nullptr, nullptr); @@ -452,12 +454,12 @@ void ConVar::StaticInit(void) //------------------------------------------------------------------------- // RUI | #ifndef DEDICATED - rui_drawEnable = ConVar::StaticCreate("rui_drawEnable", "1", FCVAR_RELEASE, "Draws the RUI if set.", false, 0.f, false, 0.f, nullptr, " 1 = Draw, 0 = No Draw."); + rui_drawEnable = ConVar::StaticCreate("rui_drawEnable", "1", FCVAR_RELEASE, "Draws the RUI if set.", false, 0.f, false, 0.f, nullptr, "1 = Draw, 0 = No Draw."); #endif // !DEDICATED //------------------------------------------------------------------------- // MILES | #ifndef DEDICATED - miles_debug = ConVar::StaticCreate("miles_debug", "0", FCVAR_RELEASE, "Enables debug prints for the Miles Sound System.", false, 0.f, false, 0.f, nullptr, " 1 = Print, 0 = No Print"); + miles_debug = ConVar::StaticCreate("miles_debug", "0", FCVAR_RELEASE, "Enables debug prints for the Miles Sound System.", false, 0.f, false, 0.f, nullptr, "1 = Print, 0 = No Print"); #endif // !DEDICATED //------------------------------------------------------------------------- }