//////////////////////////////////////////////////////////////// // // CEffectTemplateImpl::GetTicksSinceLastBeingUsed // // // //////////////////////////////////////////////////////////////// int CEffectTemplateImpl::GetTicksSinceLastUsed ( void ) { if ( !m_CloneList.empty () ) return 0; // Used right now CTickCount delta = CTickCount::Now ( true ) - m_TickCountLastUsed; return static_cast < int > ( delta.ToLongLong () ); }
/////////////////////////////////////////////////////////////// // // CPerfStatDebugInfoImpl::DoPulse // // // /////////////////////////////////////////////////////////////// void CPerfStatDebugInfoImpl::DoPulse ( void ) { // Check if time to auto deactivate if ( m_bActive ) { CTickCount timeSinceLastGetStats = CTickCount::Now () - m_LastGetStatsTime; if ( timeSinceLastGetStats.ToLongLong () > 10000 ) m_bActive = false; } }
/////////////////////////////////////////////////////////////// // // CDatabaseJobQueueImpl::UpdateDebugData // // Update info relevant to debugging database jobs // /////////////////////////////////////////////////////////////// void CDatabaseJobQueueImpl::UpdateDebugData ( void ) { // Update once every 10 seconds if ( m_JobCountElpasedTime.Get () < 10000 ) return; shared.m_Mutex.Lock (); // Log to console if connection count is creeping up if ( shared.m_HandleConnectionMap.size() > m_uiConnectionCountWarnThresh ) { m_uiConnectionCountWarnThresh = shared.m_HandleConnectionMap.size() * 2; CLogger::LogPrintf( "Notice: There are now %d database connections\n", shared.m_HandleConnectionMap.size() ); } // Log to console if job count is creeping up m_uiJobCount10sMin = std::min < uint > ( m_uiJobCount10sMin, m_ActiveJobHandles.size () ); if ( m_uiJobCount10sMin > m_uiJobCountWarnThresh ) { m_uiJobCountWarnThresh = m_uiJobCount10sMin * 2; CLogger::LogPrintf ( "Notice: %d database query handles active in the last 10 seconds\n", m_uiJobCount10sMin ); } m_JobCountElpasedTime.Reset (); m_uiJobCount10sMin = m_ActiveJobHandles.size (); CTickCount timeNow = CTickCount::Now ( true ); // Log old uncollected queries for ( CJobQueueType::iterator iter = shared.m_ResultQueue.begin () ; iter != shared.m_ResultQueue.end () ; iter++ ) { CDbJobData* pJobData = *iter; if ( !pJobData->result.bLoggedWarning ) { CTickCount age = timeNow - pJobData->result.timeReady; if ( age.ToLongLong () > 1000 * 60 * 5 ) { shared.m_Mutex.Unlock (); g_pGame->GetScriptDebugging()->LogWarning( pJobData->m_LuaDebugInfo, "Database result uncollected after 5 minutes. [Query: %s]", *pJobData->GetCommandStringForLog() ); shared.m_Mutex.Lock (); pJobData->result.bLoggedWarning = true; break; } } } shared.m_Mutex.Unlock (); }
void LuaTimerManager::GetTimers( CTickCount time, LuaMain *main ) { // We expect a table on the stack CTickCount curTime = CTickCount::Now(); std::list <LuaTimer*>::const_iterator iter = m_list.begin(); unsigned int n = 0; for ( ; iter != m_list.end(); ++iter ) { // If the time left is less than the time specified, or the time specifed is 0 if ( time.ToLongLong() != 0 && ( (*iter)->GetStartTime () + (*iter)->GetDelay () ) - curTime > time ) continue; lua_State *L = main->GetVirtualMachine(); lua_pushnumber( L, ++n ); (*iter)->PushStack( L ); lua_settable( L, -3 ); } }
void CLuaTimerManager::GetTimers ( CTickCount llTime, lua_State* luaVM ) { assert ( luaVM ); CTickCount llCurrentTime = CTickCount::Now (); // Add all the timers to the table unsigned int uiIndex = 0; list < CLuaTimer* > ::const_iterator iter = m_TimerList.begin (); for ( ; iter != m_TimerList.end () ; iter++ ) { // If the time left is less than the time specified, or the time specifed is 0 CTickCount llTimeLeft = ( (*iter)->GetStartTime () + (*iter)->GetDelay () ) - llCurrentTime; if ( llTime.ToLongLong () == 0 || llTimeLeft <= llTime ) { // Add it to the table lua_pushnumber ( luaVM, ++uiIndex ); lua_pushtimer ( luaVM, *iter ); lua_settable ( luaVM, -3 ); } } }
/////////////////////////////////////////////////////////////// // // CPerfStatBandwidthReductionImpl::GetStats // // // /////////////////////////////////////////////////////////////// void CPerfStatBandwidthReductionImpl::GetStats ( CPerfStatResult* pResult, const std::map < SString, int >& strOptionMap, const SString& strFilter ) { // Calculate current rates SStatData stats1Sec = m_Stats5Sec; for ( uint i = 0 ; i < ZONE_MAX ; i++ ) { CPerfStatManager::ToPerSecond ( stats1Sec.puresync.llSentPacketsByZone [ i ], m_DeltaTickCount.ToLongLong () ); CPerfStatManager::ToPerSecond ( stats1Sec.puresync.llSentBytesByZone [ i ], m_DeltaTickCount.ToLongLong () ); CPerfStatManager::ToPerSecond ( stats1Sec.puresync.llSkippedPacketsByZone [ i ], m_DeltaTickCount.ToLongLong () ); CPerfStatManager::ToPerSecond ( stats1Sec.puresync.llSkippedBytesByZone [ i ], m_DeltaTickCount.ToLongLong () ); } CPerfStatManager::ToPerSecond ( stats1Sec.lightsync.llLightSyncPacketsSent, m_DeltaTickCount.ToLongLong () ); CPerfStatManager::ToPerSecond ( stats1Sec.lightsync.llLightSyncBytesSent, m_DeltaTickCount.ToLongLong () ); CPerfStatManager::ToPerSecond ( stats1Sec.lightsync.llSyncPacketsSkipped, m_DeltaTickCount.ToLongLong () ); CPerfStatManager::ToPerSecond ( stats1Sec.lightsync.llSyncBytesSkipped, m_DeltaTickCount.ToLongLong () ); // // Set option flags // bool bHelp = MapContains ( strOptionMap, "h" ); // // Process help // if ( bHelp ) { pResult->AddColumn ( "Bandwidth reduction help" ); pResult->AddRow ()[0] ="Option h - This help"; return; } // Add columns pResult->AddColumn ( "Zone" ); pResult->AddColumn ( "Current rate - pure/light sync.Bytes/sec sent" ); pResult->AddColumn ( "Current rate - pure/light sync.Bytes/sec skipped" ); pResult->AddColumn ( "Current rate - pure/light sync.Msgs/sec sent" ); pResult->AddColumn ( "Current rate - pure/light sync.Msgs/sec skipped" ); pResult->AddColumn ( "Total - pure/light sync.Bytes sent" ); pResult->AddColumn ( "Total - pure/light sync.Bytes skipped" ); pResult->AddColumn ( "Total - pure/light sync.Messages sent" ); pResult->AddColumn ( "Total - pure/light sync.Messages skipped" ); SFixedArray < long long, 8 > llTotals = { { 0, 0, 0, 0, 0, 0, 0, 0 } }; SFixedArray < const char*, 4 > szDesc = { { "Very near/in FOV", "Near/close FOV", "Near/out FOV", "Far" } }; // Add puresync skipping zones for ( uint i = 0 ; i < ZONE_MAX ; i++ ) { SString* row = pResult->AddRow (); int c = 0; row[c++] = SString ( "%d) %s", i, szDesc[i] ); row[c++] = CPerfStatManager::GetScaledByteString ( stats1Sec.puresync.llSentBytesByZone[i] ); row[c++] = CPerfStatManager::GetScaledByteString ( stats1Sec.puresync.llSkippedBytesByZone[i] ); row[c++] = SString ( "%lld", stats1Sec.puresync.llSentPacketsByZone[i] ); row[c++] = SString ( "%lld", stats1Sec.puresync.llSkippedPacketsByZone[i] ); row[c++] = CPerfStatManager::GetScaledByteString ( m_StatsTotal.puresync.llSentBytesByZone[i] ); row[c++] = CPerfStatManager::GetScaledByteString ( m_StatsTotal.puresync.llSkippedBytesByZone[i] ); row[c++] = SString ( "%lld", m_StatsTotal.puresync.llSentPacketsByZone[i] ); row[c++] = SString ( "%lld", m_StatsTotal.puresync.llSkippedPacketsByZone[i] ); llTotals[0] += stats1Sec.puresync.llSentBytesByZone[i]; llTotals[1] += stats1Sec.puresync.llSkippedBytesByZone[i]; llTotals[2] += stats1Sec.puresync.llSentPacketsByZone[i]; llTotals[3] += stats1Sec.puresync.llSkippedPacketsByZone[i]; llTotals[4] += m_StatsTotal.puresync.llSentBytesByZone[i]; llTotals[5] += m_StatsTotal.puresync.llSkippedBytesByZone[i]; llTotals[6] += m_StatsTotal.puresync.llSentPacketsByZone[i]; llTotals[7] += m_StatsTotal.puresync.llSkippedPacketsByZone[i]; } // Add lightsync row { SString* row = pResult->AddRow (); int c = 0; row[c++] = "Light sync"; row[c++] = CPerfStatManager::GetScaledByteString ( stats1Sec.lightsync.llLightSyncBytesSent ); row[c++] = CPerfStatManager::GetScaledByteString ( stats1Sec.lightsync.llSyncBytesSkipped ); row[c++] = SString ( "%lld", stats1Sec.lightsync.llLightSyncPacketsSent ); row[c++] = SString ( "%lld", stats1Sec.lightsync.llSyncPacketsSkipped ); row[c++] = CPerfStatManager::GetScaledByteString ( m_StatsTotal.lightsync.llLightSyncBytesSent ); row[c++] = CPerfStatManager::GetScaledByteString ( m_StatsTotal.lightsync.llSyncBytesSkipped ); row[c++] = SString ( "%lld", m_StatsTotal.lightsync.llLightSyncPacketsSent ); row[c++] = SString ( "%lld", m_StatsTotal.lightsync.llSyncPacketsSkipped ); llTotals[0] += stats1Sec.lightsync.llLightSyncBytesSent; llTotals[1] += stats1Sec.lightsync.llSyncBytesSkipped; llTotals[2] += stats1Sec.lightsync.llLightSyncPacketsSent; llTotals[3] += stats1Sec.lightsync.llSyncPacketsSkipped; llTotals[4] += m_StatsTotal.lightsync.llLightSyncBytesSent; llTotals[5] += m_StatsTotal.lightsync.llSyncBytesSkipped; llTotals[6] += m_StatsTotal.lightsync.llLightSyncPacketsSent; llTotals[7] += m_StatsTotal.lightsync.llSyncPacketsSkipped; } // Add total { pResult->AddRow (); pResult->AddRow (); SString* row = pResult->AddRow (); int c = 0; row[c++] = "Total"; row[c++] = CPerfStatManager::GetScaledByteString ( llTotals[0] ); row[c++] = CPerfStatManager::GetScaledByteString ( llTotals[1] ); row[c++] = SString ( "%lld", llTotals[2] ); row[c++] = SString ( "%lld", llTotals[3] ); row[c++] = CPerfStatManager::GetScaledByteString ( llTotals[4] ); row[c++] = CPerfStatManager::GetScaledByteString ( llTotals[5] ); row[c++] = SString ( "%lld", llTotals[6] ); row[c++] = SString ( "%lld", llTotals[7] ); } // Add reduction { pResult->AddRow (); SString* row = pResult->AddRow (); double dBytesSent5Sec = static_cast < double > ( llTotals[0] ); double dBytesSkipped5Sec = static_cast < double > ( llTotals[1] ); double dPacketsSent5Sec = static_cast < double > ( llTotals[2] ); double dPacketsSkipped5Sec = static_cast < double > ( llTotals[3] ); double dBytesSentAll = static_cast < double > ( llTotals[4] ); double dBytesSkippedAll = static_cast < double > ( llTotals[5] ); double dPacketsSentAll = static_cast < double > ( llTotals[6] ); double dPacketsSkippedAll = static_cast < double > ( llTotals[7] ); double dBytesPercent5Sec = 100 * dBytesSkipped5Sec / Max ( 1.0, dBytesSent5Sec + dBytesSkipped5Sec ); double dPacketsPercent5Sec = 100 * dPacketsSkipped5Sec / Max ( 1.0, dPacketsSent5Sec + dPacketsSkipped5Sec ); double dBytesPercentAll = 100 * dBytesSkippedAll / Max ( 1.0, dBytesSentAll + dBytesSkippedAll ); double dPacketsPercentAll = 100 * dPacketsSkippedAll / Max ( 1.0, dPacketsSentAll + dPacketsSkippedAll ); int c = 0; row[c++] = "Reduction percent"; row[c++] = SString ( "%0.0f%%", -dBytesPercent5Sec ); row[c++] = ""; row[c++] = SString ( "%0.0f%%", -dPacketsPercent5Sec ); row[c++] = ""; row[c++] = SString ( "%0.0f%%", -dBytesPercentAll ); row[c++] = ""; row[c++] = SString ( "%0.0f%%", -dPacketsPercentAll ); row[c++] = ""; pResult->AddRow (); pResult->AddRow (); } }
/////////////////////////////////////////////////////////////// // // CPerfStatServerInfoImpl::GetStats // // // /////////////////////////////////////////////////////////////// void CPerfStatServerInfoImpl::GetStats ( CPerfStatResult* pResult, const std::map < SString, int >& strOptionMap, const SString& strFilter ) { // // Set option flags // bool bHelp = MapContains ( strOptionMap, "h" ); bool bIncludeDebugInfo = MapContains ( strOptionMap, "d" ); // // Process help // if ( bHelp ) { pResult->AddColumn ( "Server info help" ); pResult->AddRow ()[0] ="Option h - This help"; pResult->AddRow ()[0] ="Option d - Include debug info"; return; } // Calculate current rates long long llIncomingBytesPS = CPerfStatManager::GetPerSecond ( m_llDeltaGameBytesRecv, m_DeltaTickCount.ToLongLong () ); long long llIncomingBytesPSBlocked = CPerfStatManager::GetPerSecond ( m_llDeltaGameBytesRecvBlocked, m_DeltaTickCount.ToLongLong () ); long long llOutgoingBytesPS = CPerfStatManager::GetPerSecond ( m_llDeltaGameBytesSent, m_DeltaTickCount.ToLongLong () ); long long llOutgoingBytesResentPS = CPerfStatManager::GetPerSecond ( m_llDeltaGameBytesResent, m_DeltaTickCount.ToLongLong () ); SString strIncomingPacketsPS = CPerfStatManager::GetPerSecondString ( m_llDeltaGamePacketsRecv, m_DeltaTickCount.ToDouble () ); SString strIncomingPacketsPSBlocked = CPerfStatManager::GetPerSecondString ( m_llDeltaGamePacketsRecvBlocked, m_DeltaTickCount.ToDouble () ); SString strOutgoingPacketsPS = CPerfStatManager::GetPerSecondString ( m_llDeltaGamePacketsSent, m_DeltaTickCount.ToDouble () ); SString strOutgoingMessagesResentPS = CPerfStatManager::GetPerSecondString ( m_llDeltaGameMessagesResent, m_DeltaTickCount.ToDouble () ); // Estimate total network usage long long llIncomingPacketsPS = CPerfStatManager::GetPerSecond ( m_llDeltaGamePacketsRecv, m_DeltaTickCount.ToLongLong () ); long long llIncomingPacketsPSBlocked = CPerfStatManager::GetPerSecond ( m_llDeltaGamePacketsRecvBlocked, m_DeltaTickCount.ToLongLong () ); long long llOutgoingPacketsPS = CPerfStatManager::GetPerSecond ( m_llDeltaGamePacketsSent, m_DeltaTickCount.ToLongLong () ); long long llNetworkUsageBytesPS = ( llIncomingPacketsPS + llOutgoingPacketsPS ) * UDP_PACKET_OVERHEAD + llIncomingBytesPS + llOutgoingBytesPS; long long llNetworkUsageBytesPSInclBlocked = ( llIncomingPacketsPS + llIncomingPacketsPSBlocked + llOutgoingPacketsPS ) * UDP_PACKET_OVERHEAD + llIncomingBytesPS + llIncomingBytesPSBlocked + llOutgoingBytesPS; // Calculate uptime time_t tUptime = time ( NULL ) - m_tStartTime; time_t tDays = tUptime / ( 60 * 60 * 24 ); tUptime = tUptime % ( 60 * 60 * 24 ); time_t tHours = tUptime / ( 60 * 60 ); tUptime = tUptime % ( 60 * 60 ); time_t tMinutes = tUptime / ( 60 ); SString strNone; CMainConfig* pConfig = g_pGame->GetConfig (); m_InfoList.clear (); m_StatusList.clear (); m_OptionsList.clear (); // Fill info lists m_InfoList.push_back ( StringPair ( "Platform", CStaticFunctionDefinitions::GetOperatingSystemName () ) ); m_InfoList.push_back ( StringPair ( "Version", CStaticFunctionDefinitions::GetVersionSortable () ) ); m_InfoList.push_back ( StringPair ( "Date", GetLocalTimeString ( true ) ) ); m_InfoList.push_back ( StringPair ( "Uptime", SString ( "%d Days %d Hours %02d Mins", (int)tDays, (int)tHours, (int)tMinutes ) ) ); m_InfoList.push_back ( StringPair ( "Memory", GetProcessMemoryUsage() ) ); if ( !pConfig->GetThreadNetEnabled () ) m_StatusList.push_back ( StringPair ( "Server FPS", SString ( "%d", g_pGame->GetServerFPS () ) ) ); else m_StatusList.push_back ( StringPair ( "Server FPS sync (logic)", SString ( "%3d (%d)", g_pGame->GetSyncFPS (), g_pGame->GetServerFPS () ) ) ); m_StatusList.push_back ( StringPair ( "Players", SString ( "%d / %d", g_pGame->GetPlayerManager ()->Count (), pConfig->GetMaxPlayers () ) ) ); m_StatusList.push_back ( StringPair ( "Bytes/sec incoming", CPerfStatManager::GetScaledByteString ( llIncomingBytesPS ) ) ); m_StatusList.push_back ( StringPair ( "Bytes/sec outgoing", CPerfStatManager::GetScaledByteString ( llOutgoingBytesPS ) ) ); m_StatusList.push_back ( StringPair ( "Packets/sec incoming", strIncomingPacketsPS ) ); m_StatusList.push_back ( StringPair ( "Packets/sec outgoing", strOutgoingPacketsPS ) ); m_StatusList.push_back ( StringPair ( "Packet loss outgoing", CPerfStatManager::GetPercentString ( llOutgoingBytesResentPS, llOutgoingBytesPS ) ) ); m_StatusList.push_back ( StringPair ( "Approx network usage", CPerfStatManager::GetScaledBitString ( llNetworkUsageBytesPS * 8LL ) + "/s" ) ); if ( pConfig->GetThreadNetEnabled () ) { m_StatusList.push_back ( StringPair ( "Msg queue incoming", SString ( "%d", CNetBufferWatchDog::ms_uiInResultQueueSize ) ) ); if ( bIncludeDebugInfo ) m_StatusList.push_back ( StringPair ( " finished incoming", SString ( "%d", CNetBufferWatchDog::ms_uiFinishedListSize ) ) ); m_StatusList.push_back ( StringPair ( "Msg queue outgoing", SString ( "%d", CNetBufferWatchDog::ms_uiOutCommandQueueSize ) ) ); if ( bIncludeDebugInfo ) m_StatusList.push_back ( StringPair ( " finished outgoing", SString ( "%d", CNetBufferWatchDog::ms_uiOutResultQueueSize ) ) ); } if ( ASE* pAse = ASE::GetInstance() ) m_StatusList.push_back ( StringPair ( "ASE queries", SString ( "%d (%d/min)", pAse->GetTotalQueryCount (), pAse->GetQueriesPerMinute () ) ) ); m_OptionsList.push_back ( StringPair ( "MinClientVersion", g_pGame->CalculateMinClientRequirement () ) ); m_OptionsList.push_back ( StringPair ( "RecommendedClientVersion", pConfig->GetRecommendedClientVersion () ) ); m_OptionsList.push_back ( StringPair ( "NetworkEncryptionEnabled", SString ( "%d", pConfig->GetNetworkEncryptionEnabled () ) ) ); m_OptionsList.push_back ( StringPair ( "VoiceEnabled", SString ( "%d", pConfig->IsVoiceEnabled () ) ) ); m_OptionsList.push_back ( StringPair ( "Busy sleep time", SString ( "%d ms", pConfig->GetPendingWorkToDoSleepTime () ) ) ); m_OptionsList.push_back ( StringPair ( "Idle sleep time", SString ( "%d ms", pConfig->GetNoWorkToDoSleepTime () ) ) ); m_OptionsList.push_back ( StringPair ( "BandwidthReductionMode", pConfig->GetSetting ( "bandwidth_reduction" ) ) ); m_OptionsList.push_back ( StringPair ( "LightSyncEnabled", SString ( "%d", g_pBandwidthSettings->bLightSyncEnabled ) ) ); m_OptionsList.push_back ( StringPair ( "ThreadNetEnabled", SString ( "%d", pConfig->GetThreadNetEnabled () ) ) ); const static CTickRateSettings defaultRates; if ( defaultRates.iPureSync != g_TickRateSettings.iPureSync ) m_OptionsList.push_back ( StringPair ( "Player sync interval", SString ( "%d", g_TickRateSettings.iPureSync ) ) ); if ( defaultRates.iLightSync != g_TickRateSettings.iLightSync ) m_OptionsList.push_back ( StringPair ( "Lightweight sync interval", SString ( "%d", g_TickRateSettings.iLightSync ) ) ); if ( defaultRates.iCamSync != g_TickRateSettings.iCamSync ) m_OptionsList.push_back ( StringPair ( "Camera sync interval", SString ( "%d", g_TickRateSettings.iCamSync ) ) ); if ( defaultRates.iPedSync != g_TickRateSettings.iPedSync ) m_OptionsList.push_back ( StringPair ( "Ped sync interval", SString ( "%d", g_TickRateSettings.iPedSync ) ) ); if ( defaultRates.iUnoccupiedVehicle != g_TickRateSettings.iUnoccupiedVehicle ) m_OptionsList.push_back ( StringPair ( "Unocc. veh. sync interval", SString ( "%d", g_TickRateSettings.iUnoccupiedVehicle ) ) ); if ( defaultRates.iKeySyncRotation != g_TickRateSettings.iKeySyncRotation ) m_OptionsList.push_back ( StringPair ( "Keysync mouse sync interval", SString ( "%d", g_TickRateSettings.iKeySyncRotation ) ) ); if ( defaultRates.iKeySyncAnalogMove != g_TickRateSettings.iKeySyncAnalogMove ) m_OptionsList.push_back ( StringPair ( "Keysync analog sync interval", SString ( "%d", g_TickRateSettings.iKeySyncAnalogMove ) ) ); if ( defaultRates.iKeySyncAnalogMove != g_TickRateSettings.iNearListUpdate ) m_OptionsList.push_back ( StringPair ( "Update near interval", SString ( "%d", g_TickRateSettings.iNearListUpdate ) ) ); if ( bIncludeDebugInfo ) { m_StatusList.push_back ( StringPair ( "Bytes/sec outgoing resent", CPerfStatManager::GetScaledByteString ( llOutgoingBytesResentPS ) ) ); m_StatusList.push_back ( StringPair ( "Msgs/sec outgoing resent", strOutgoingMessagesResentPS ) ); m_StatusList.push_back ( StringPair ( "Bytes/sec blocked", CPerfStatManager::GetScaledByteString ( llIncomingBytesPSBlocked ) ) ); m_StatusList.push_back ( StringPair ( "Packets/sec blocked", strIncomingPacketsPSBlocked ) ); m_StatusList.push_back ( StringPair ( "Usage incl. blocked", CPerfStatManager::GetScaledBitString ( llNetworkUsageBytesPSInclBlocked * 8LL ) + "/s" ) ); m_OptionsList.push_back ( StringPair ( "Main (Logic) core #", SString ( "%d", _GetCurrentProcessorNumber () ) ) ); m_OptionsList.push_back ( StringPair ( "Threadnet (Sync) core #", SString ( "%d", g_uiThreadnetProcessorNumber ) ) ); m_OptionsList.push_back ( StringPair ( "Raknet thread core #", SString ( "%d", m_PrevLiveStats.uiNetworkUpdateLoopProcessorNumber ) ) ); m_OptionsList.push_back ( StringPair ( "DB thread core #", SString ( "%d", g_uiDatabaseThreadProcessorNumber ) ) ); // Get net performance stats if ( m_NetPerformanceStatsUpdateTimer.Get() > 2000 ) { m_NetPerformanceStatsUpdateTimer.Reset(); g_pNetServer->GetNetPerformanceStatistics ( &m_NetPerformanceStats, true ); } m_OptionsList.push_back ( StringPair ( "Update cycle prep time max", SString ( "%s ms (Avg %s ms)", *CPerfStatManager::GetScaledFloatString( m_NetPerformanceStats.uiUpdateCyclePrepTimeMaxUs / 1000.f ), *CPerfStatManager::GetScaledFloatString( m_NetPerformanceStats.uiUpdateCyclePrepTimeAvgUs / 1000.f ) ) ) ); m_OptionsList.push_back ( StringPair ( "Update cycle process time max", SString ( "%s ms (Avg %s ms)", *CPerfStatManager::GetScaledFloatString( m_NetPerformanceStats.uiUpdateCycleProcessTimeMaxUs / 1000.f ), *CPerfStatManager::GetScaledFloatString( m_NetPerformanceStats.uiUpdateCycleProcessTimeAvgUs / 1000.f ) ) ) ); m_OptionsList.push_back ( StringPair ( "Update cycle datagrams max", SString ( "%d (Avg %s)", m_NetPerformanceStats.uiUpdateCycleDatagramsMax, *CPerfStatManager::GetScaledFloatString( m_NetPerformanceStats.fUpdateCycleDatagramsAvg ) ) ) ); m_OptionsList.push_back ( StringPair ( "Update cycle datagrams limit", SString ( "%d", m_NetPerformanceStats.uiUpdateCycleDatagramsLimit ) ) ); m_OptionsList.push_back ( StringPair ( "Update cycle sends limited", SString ( "%d (%s %%)", m_NetPerformanceStats.uiUpdateCycleSendsLimitedTotal, *CPerfStatManager::GetScaledFloatString( m_NetPerformanceStats.fUpdateCycleSendsLimitedPercent ) ) ) ); } // Add columns pResult->AddColumn ( "Info.Name" ); pResult->AddColumn ( "Info.Value" ); pResult->AddColumn ( "Status.Name" ); pResult->AddColumn ( "Status.Value" ); pResult->AddColumn ( "Settings.Name" ); pResult->AddColumn ( "Settings.Value" ); // Output rows std::vector < StringPair >* columnList[] = { &m_InfoList, &m_StatusList, &m_OptionsList }; uint uiMaxRows = Max ( Max ( m_InfoList.size (), m_StatusList.size () ), m_OptionsList.size () ); for ( uint i = 0 ; i < uiMaxRows ; i++ ) { SString* row = pResult->AddRow (); int c = 0; for ( uint a = 0 ; a < NUMELMS( columnList ) ; a++ ) { const std::vector < StringPair >& column = *columnList[a]; if ( i < column.size () ) { row[c++] = column[i].strName; row[c++] = column[i].strValue; } else { row[c++] = ""; row[c++] = ""; } } } }