@@ -59,7 +59,8 @@ class CServerCache : public CServerCacheInterface
5959 virtual void GetServerCachedInfo (CServerListItem* pItem);
6060 virtual void SetServerCachedInfo (const CServerListItem* pItem);
6161 virtual void GetServerListCachedInfo (CServerList* pList);
62- virtual bool GenerateServerList (CServerList* pList);
62+ virtual bool GenerateServerList (CServerList* pList, bool bAllowNonResponding = false );
63+ virtual void SetServerListCachedInfo (CServerList* pList);
6364
6465 CServerCache ();
6566 ~CServerCache ();
@@ -93,7 +94,9 @@ CServerCacheInterface* GetServerCache()
9394//
9495// CServerCache::CServerCache
9596//
96- //
97+ // Initialize server cache by loading from persistent disk storage.
98+ // The cache file (servercache.xml) is never deleted and persists across sessions.
99+ // Cache entries are synced (updated) on each session, not regenerated.
97100//
98101// /////////////////////////////////////////////////////////////
99102CServerCache::CServerCache ()
@@ -117,6 +120,8 @@ CServerCache::~CServerCache()
117120// CServerCache::LoadServerCache
118121//
119122// Load cache data from config
123+ // The in-memory cache is cleared and reloaded from disk.
124+ // The disk file is never deleted; it persists across game sessions.
120125//
121126// /////////////////////////////////////////////////////////////
122127bool CServerCache::LoadServerCache ()
@@ -197,7 +202,8 @@ bool CServerCache::LoadServerCache()
197202//
198203// CServerCache::SaveServerCache
199204//
200- // Save cache data to config
205+ // Persist cache changes to disk when data has been modified.
206+ // Always syncs complete state; never clears the disk file.
201207//
202208// /////////////////////////////////////////////////////////////
203209void CServerCache::SaveServerCache (bool bWaitUntilFinished)
@@ -256,7 +262,9 @@ DWORD WINAPI CServerCache::StaticThreadProc(LPVOID lpdwThreadParam)
256262//
257263// CServerCache::StaticSaveServerCache
258264//
259- //
265+ // Synchronize cache to disk by writing all current in-memory entries.
266+ // The XML tree is rebuilt on each save (not appended to) for consistency,
267+ // but the file itself is never deleted. Servers are synced, not purged.
260268//
261269// /////////////////////////////////////////////////////////////
262270void CServerCache::StaticSaveServerCache ()
@@ -273,18 +281,17 @@ void CServerCache::StaticSaveServerCache()
273281 if (!pNode)
274282 return ;
275283
276- // Start by clearing out all previous nodes
284+ // Clear in-memory XML structure and rebuild from current cache state.
285+ // This does NOT delete the disk file; it only rewrites its contents with current data.
277286 pNode->DeleteAllSubNodes ();
278287
279288 // Transfer each item from m_ServerCachedMap into dataSet
280289 CDataInfoSet dataSet;
281- for (std::map<CCachedKey, CCachedInfo>::iterator it = ms_ServerCachedMap. begin (); it != ms_ServerCachedMap. end (); ++it )
290+ for (const auto & [key, info] : ms_ServerCachedMap)
282291 {
283- const CCachedKey& key = it->first ;
284- const CCachedInfo& info = it->second ;
285292
286- // Don't save cache of non responding servers
287- if (info.nMaxPlayers == 0 || info. uiCacheNoReplyCount > 3 )
293+ // Only exclude servers that have failed multiple consecutive query attempts
294+ if (info.uiCacheNoReplyCount > 3 )
288295 continue ;
289296
290297 SDataInfoItem item;
@@ -327,6 +334,9 @@ void CServerCache::StaticSaveServerCache()
327334// /////////////////////////////////////////////////////////////
328335void CServerCache::GetServerCachedInfo (CServerListItem* pItem)
329336{
337+ if (!pItem)
338+ return ;
339+
330340 CCachedKey key;
331341 key.ulIp = pItem->Address .s_addr ;
332342 key.usGamePort = pItem->usGamePort ;
@@ -378,6 +388,9 @@ void CServerCache::GetServerCachedInfo(CServerListItem* pItem)
378388// /////////////////////////////////////////////////////////////
379389void CServerCache::SetServerCachedInfo (const CServerListItem* pItem)
380390{
391+ if (!pItem)
392+ return ;
393+
381394 CCachedKey key;
382395 key.ulIp = pItem->Address .s_addr ;
383396 key.usGamePort = pItem->usGamePort ;
@@ -424,15 +437,21 @@ void CServerCache::SetServerCachedInfo(const CServerListItem* pItem)
424437// /////////////////////////////////////////////////////////////
425438void CServerCache::GetServerListCachedInfo (CServerList* pList)
426439{
427- // Get cached info for each server
428- for (CServerListIterator it = pList->IteratorBegin (); it != pList->IteratorEnd (); it++)
429- GetServerCachedInfo (*it);
440+ if (!pList)
441+ return ;
442+
443+ for (auto it = pList->IteratorBegin (); it != pList->IteratorEnd (); ++it)
444+ {
445+ if (*it)
446+ GetServerCachedInfo (*it);
447+ }
430448
431- // Remove servers not in serverlist from cache
432449 std::map<CCachedKey, CCachedInfo> nextServerCachedMap;
433- for (CServerListIterator it = pList->IteratorBegin (); it != pList->IteratorEnd (); it++ )
450+ for (auto it = pList->IteratorBegin (); it != pList->IteratorEnd (); ++it )
434451 {
435452 CServerListItem* pItem = *it;
453+ if (!pItem)
454+ continue ;
436455 CCachedKey key;
437456 key.ulIp = pItem->Address .s_addr ;
438457 key.usGamePort = pItem->usGamePort ;
@@ -442,22 +461,44 @@ void CServerCache::GetServerListCachedInfo(CServerList* pList)
442461 m_ServerCachedMap = nextServerCachedMap;
443462}
444463
464+ // /////////////////////////////////////////////////////////////
465+ //
466+ // CServerCache::SetServerListCachedInfo
467+ //
468+ // Cache all servers in list
469+ //
470+ // /////////////////////////////////////////////////////////////
471+ void CServerCache::SetServerListCachedInfo (CServerList* pList)
472+ {
473+ if (!pList)
474+ return ;
475+
476+ for (auto it = pList->IteratorBegin (); it != pList->IteratorEnd (); ++it)
477+ {
478+ if (*it)
479+ SetServerCachedInfo (*it);
480+ }
481+ }
482+
445483// /////////////////////////////////////////////////////////////
446484//
447485// CServerCache::GenerateServerList
448486//
449487// Create serverlist content from the cache
450488//
451489// /////////////////////////////////////////////////////////////
452- bool CServerCache::GenerateServerList (CServerList* pList)
490+ bool CServerCache::GenerateServerList (CServerList* pList, bool bAllowNonResponding )
453491{
454- for (std::map<CCachedKey, CCachedInfo>::iterator it = m_ServerCachedMap.begin (); it != m_ServerCachedMap.end (); ++it)
492+ if (!pList)
493+ return false ;
494+
495+ for (const auto & [key, info] : m_ServerCachedMap)
455496 {
456- const CCachedKey& key = it->first ;
457- const CCachedInfo& info = it->second ;
458497
459- // Don't add non responding servers
460- if (info.nMaxPlayers == 0 || info.uiCacheNoReplyCount > 3 )
498+ // When master server is offline, include all cached servers. Otherwise exclude servers that
499+ // have consistently failed to respond (uiCacheNoReplyCount > 3). New servers without response data
500+ // should still be included since they may not have been queried yet.
501+ if (!bAllowNonResponding && (info.uiCacheNoReplyCount > 3 ))
461502 continue ;
462503
463504 ushort usGamePort = key.usGamePort ;
0 commit comments