Skip to content

Commit 82f4b85

Browse files
authored
bugfix(crc): Fix spurious mismatches for disconnected players at low CRC intervals (#2796)
1 parent 9a9b1c2 commit 82f4b85

4 files changed

Lines changed: 44 additions & 20 deletions

File tree

Generals/Code/GameEngine/Include/GameLogic/GameLogic.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,8 @@ class GameLogic : public SubsystemInterface, public Snapshot
383383

384384
// CRC cache system -----------------------------------------------------------------------------
385385
UnsignedInt m_CRC; ///< Cache of previous CRC value
386-
std::map<Int, UnsignedInt> m_cachedCRCs; ///< CRCs we've seen this frame
386+
typedef std::map<Int, UnsignedInt> CachedCRCMap;
387+
CachedCRCMap m_cachedCRCs; ///< CRCs we've seen this frame
387388
Bool m_shouldValidateCRCs; ///< Should we validate CRCs this frame?
388389
//-----------------------------------------------------------------------------------------------
389390
//Bool m_loadingScene;

Generals/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2338,15 +2338,26 @@ void GameLogic::processCommandList( CommandList *list )
23382338
}
23392339
else
23402340
{
2341-
//DEBUG_LOG(("Comparing %d CRCs on frame %d", m_cachedCRCs.size(), m_frame));
2342-
std::map<Int, UnsignedInt>::const_iterator crcIt = m_cachedCRCs.begin();
2343-
Int validatorCRC = crcIt->second;
2344-
//DEBUG_LOG(("Validator CRC from player %d is %8.8X", crcIt->first, validatorCRC));
2345-
while (++crcIt != m_cachedCRCs.end())
2341+
Bool hasReferenceCRC = FALSE;
2342+
UnsignedInt referenceCRC = 0;
2343+
2344+
for (CachedCRCMap::const_iterator it = m_cachedCRCs.begin(); it != m_cachedCRCs.end(); ++it)
23462345
{
2347-
Int validatedCRC = crcIt->second;
2348-
//DEBUG_LOG(("CRC to validate is from player %d: %8.8X", crcIt->first, validatedCRC));
2349-
if (validatorCRC != validatedCRC)
2346+
// TheSuperHackers @bugfix Caball009 14/06/2026 Check if player is still connected,
2347+
// to avoid spurious mismatches at low CRC intervals, e.g. every frame.
2348+
if (!TheNetwork->isPlayerConnected(it->first))
2349+
continue;
2350+
2351+
const UnsignedInt crc = it->second;
2352+
2353+
if (!hasReferenceCRC)
2354+
{
2355+
hasReferenceCRC = TRUE;
2356+
referenceCRC = crc;
2357+
continue;
2358+
}
2359+
2360+
if (referenceCRC != crc)
23502361
{
23512362
DEBUG_CRASH(("CRC mismatch!"));
23522363
sawCRCMismatch = TRUE;
@@ -2359,7 +2370,7 @@ void GameLogic::processCommandList( CommandList *list )
23592370
{
23602371
#ifdef DEBUG_LOGGING
23612372
DEBUG_LOG(("CRC Mismatch - saw %d CRCs from %d players", m_cachedCRCs.size(), numPlayers));
2362-
for (std::map<Int, UnsignedInt>::const_iterator crcIt = m_cachedCRCs.begin(); crcIt != m_cachedCRCs.end(); ++crcIt)
2373+
for (CachedCRCMap::const_iterator crcIt = m_cachedCRCs.begin(); crcIt != m_cachedCRCs.end(); ++crcIt)
23632374
{
23642375
Player *player = ThePlayerList->getNthPlayer(crcIt->first);
23652376
DEBUG_LOG(("CRC from player %d (%ls) = %X", crcIt->first,

GeneralsMD/Code/GameEngine/Include/GameLogic/GameLogic.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,8 @@ class GameLogic : public SubsystemInterface, public Snapshot
390390

391391
// CRC cache system -----------------------------------------------------------------------------
392392
UnsignedInt m_CRC; ///< Cache of previous CRC value
393-
std::map<Int, UnsignedInt> m_cachedCRCs; ///< CRCs we've seen this frame
393+
typedef std::map<Int, UnsignedInt> CachedCRCMap;
394+
CachedCRCMap m_cachedCRCs; ///< CRCs we've seen this frame
394395
Bool m_shouldValidateCRCs; ///< Should we validate CRCs this frame?
395396
//-----------------------------------------------------------------------------------------------
396397
//Bool m_loadingScene;

GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2664,15 +2664,26 @@ void GameLogic::processCommandList( CommandList *list )
26642664
}
26652665
else
26662666
{
2667-
//DEBUG_LOG(("Comparing %d CRCs on frame %d", m_cachedCRCs.size(), m_frame));
2668-
std::map<Int, UnsignedInt>::const_iterator crcIt = m_cachedCRCs.begin();
2669-
Int validatorCRC = crcIt->second;
2670-
//DEBUG_LOG(("Validator CRC from player %d is %8.8X", crcIt->first, validatorCRC));
2671-
while (++crcIt != m_cachedCRCs.end())
2667+
Bool hasReferenceCRC = FALSE;
2668+
UnsignedInt referenceCRC = 0;
2669+
2670+
for (CachedCRCMap::const_iterator it = m_cachedCRCs.begin(); it != m_cachedCRCs.end(); ++it)
26722671
{
2673-
Int validatedCRC = crcIt->second;
2674-
//DEBUG_LOG(("CRC to validate is from player %d: %8.8X", crcIt->first, validatedCRC));
2675-
if (validatorCRC != validatedCRC)
2672+
// TheSuperHackers @bugfix Caball009 14/06/2026 Check if player is still connected,
2673+
// to avoid spurious mismatches at low CRC intervals, e.g. every frame.
2674+
if (!TheNetwork->isPlayerConnected(it->first))
2675+
continue;
2676+
2677+
const UnsignedInt crc = it->second;
2678+
2679+
if (!hasReferenceCRC)
2680+
{
2681+
hasReferenceCRC = TRUE;
2682+
referenceCRC = crc;
2683+
continue;
2684+
}
2685+
2686+
if (referenceCRC != crc)
26762687
{
26772688
DEBUG_CRASH(("CRC mismatch!"));
26782689
sawCRCMismatch = TRUE;
@@ -2685,7 +2696,7 @@ void GameLogic::processCommandList( CommandList *list )
26852696
{
26862697
#ifdef DEBUG_LOGGING
26872698
DEBUG_LOG(("CRC Mismatch - saw %d CRCs from %d players", m_cachedCRCs.size(), numPlayers));
2688-
for (std::map<Int, UnsignedInt>::const_iterator crcIt = m_cachedCRCs.begin(); crcIt != m_cachedCRCs.end(); ++crcIt)
2699+
for (CachedCRCMap::const_iterator crcIt = m_cachedCRCs.begin(); crcIt != m_cachedCRCs.end(); ++crcIt)
26892700
{
26902701
Player *player = ThePlayerList->getNthPlayer(crcIt->first);
26912702
DEBUG_LOG(("CRC from player %d (%ls) = %X", crcIt->first,

0 commit comments

Comments
 (0)