Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 28 additions & 11 deletions Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2055,12 +2055,14 @@
break;
}


//---------------------------------------------------------------------------------------------
case GameMessage::MSG_LOGIC_CRC:
{
if (TheNetwork)
{
if (TheNetwork->sawCRCMismatch())
break;

Int slotIndex = -1;
for (Int i=0; i<MAX_SLOTS; ++i)
{
Expand All @@ -2079,29 +2081,44 @@
#if defined(RTS_DEBUG)
// don't even put this in release, cause someone might hack it.
if (!TheDebugIgnoreSyncErrors)
{
#endif
m_shouldValidateCRCs = TRUE;
#if defined(RTS_DEBUG)
}
#endif
m_validationModeCRC = CRCMODE_NETWORK;

Check failure on line 2085 in Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / vc6+t+e

'CRCMODE_NETWORK' : undeclared identifier

Check failure on line 2085 in Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / vc6+t+e

'm_validationModeCRC' : undeclared identifier

Check failure on line 2085 in Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / vc6-profile+t+e

'CRCMODE_NETWORK' : undeclared identifier

Check failure on line 2085 in Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / vc6-profile+t+e

'm_validationModeCRC' : undeclared identifier

Check failure on line 2085 in Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / vc6-debug+t+e

'CRCMODE_NETWORK' : undeclared identifier

Check failure on line 2085 in Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / vc6-debug+t+e

'm_validationModeCRC' : undeclared identifier

Check failure on line 2085 in Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / win32-debug+t+e

'CRCMODE_NETWORK': undeclared identifier

Check failure on line 2085 in Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / win32-debug+t+e

'm_validationModeCRC': undeclared identifier

Check failure on line 2085 in Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / win32+t+e

'CRCMODE_NETWORK': undeclared identifier

Check failure on line 2085 in Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / win32+t+e

'm_validationModeCRC': undeclared identifier

Check failure on line 2085 in Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / win32-profile+t+e

'CRCMODE_NETWORK': undeclared identifier

Check failure on line 2085 in Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / win32-profile+t+e

'm_validationModeCRC': undeclared identifier
}

UnsignedInt newCRC = msg->getArgument(0)->integer;
const UnsignedInt newCRC = msg->getArgument(0)->integer;
//DEBUG_LOG(("Received CRC of %8.8X from %ls on frame %d", newCRC,
//msgPlayer->getPlayerDisplayName().str(), m_frame));

m_cachedCRCs[msgPlayer->getPlayerIndex()] = newCRC;
}
else if (TheRecorder && TheRecorder->isPlaybackMode())
{
UnsignedInt newCRC = msg->getArgument(0)->integer;
//DEBUG_LOG(("Saw CRC of %X from player %d. Our CRC is %X. Arg count is %d",
if (TheRecorder->sawCRCMismatch())
break;

DEBUG_ASSERTCRASH(msg->getArgument(1)->boolean == msgPlayer->isLocalPlayer(),
("CRC message origin is unexpected; playback message argument doesn't match message player index"));

const UnsignedInt newCRC = msg->getArgument(0)->integer;
//DEBUG_LOG(("Saw CRC of %X from player %d. Our CRC is %X. Arg count is %d",
//newCRC, msgPlayer->getPlayerIndex(), getCRC(), msg->getArgumentCount()));

TheRecorder->handleCRCMessage(newCRC, msgPlayer->getPlayerIndex(), (msg->getArgument(1)->boolean));
if (msgPlayer->isLocalPlayer())
{
TheRecorder->handlePlaybackCRCMessage(newCRC);

Check failure on line 2108 in Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / vc6+t+e

'handlePlaybackCRCMessage' : is not a member of 'RecorderClass'

Check failure on line 2108 in Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / vc6-profile+t+e

'handlePlaybackCRCMessage' : is not a member of 'RecorderClass'

Check failure on line 2108 in Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / vc6-debug+t+e

'handlePlaybackCRCMessage' : is not a member of 'RecorderClass'

Check failure on line 2108 in Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / win32-debug+t+e

'handlePlaybackCRCMessage': is not a member of 'RecorderClass'

Check failure on line 2108 in Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / win32+t+e

'handlePlaybackCRCMessage': is not a member of 'RecorderClass'

Check failure on line 2108 in Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / win32-profile+t+e

'handlePlaybackCRCMessage': is not a member of 'RecorderClass'
}
else
{
#if defined(RTS_DEBUG)
// don't even put this in release, cause someone might hack it.
if (!TheDebugIgnoreSyncErrors)
#endif
m_validationModeCRC = CRCMODE_REPLAY;

Check failure on line 2116 in Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / vc6+t+e

'CRCMODE_REPLAY' : undeclared identifier

Check failure on line 2116 in Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / vc6-profile+t+e

'CRCMODE_REPLAY' : undeclared identifier

Check failure on line 2116 in Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / vc6-debug+t+e

'CRCMODE_REPLAY' : undeclared identifier

Check failure on line 2116 in Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / win32-debug+t+e

'CRCMODE_REPLAY': undeclared identifier

Check failure on line 2116 in Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / win32-debug+t+e

'm_validationModeCRC': undeclared identifier

Check failure on line 2116 in Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / win32+t+e

'CRCMODE_REPLAY': undeclared identifier

Check failure on line 2116 in Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / win32+t+e

'm_validationModeCRC': undeclared identifier

Check failure on line 2116 in Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / win32-profile+t+e

'CRCMODE_REPLAY': undeclared identifier

Check failure on line 2116 in Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / win32-profile+t+e

'm_validationModeCRC': undeclared identifier

TheRecorder->handlePlayerCRCMessage(msgPlayer->getPlayerIndex(), newCRC);

Check failure on line 2118 in Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / vc6+t+e

'handlePlayerCRCMessage' : is not a member of 'RecorderClass'

Check failure on line 2118 in Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / vc6-profile+t+e

'handlePlayerCRCMessage' : is not a member of 'RecorderClass'

Check failure on line 2118 in Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / vc6-debug+t+e

'handlePlayerCRCMessage' : is not a member of 'RecorderClass'

Check failure on line 2118 in Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / win32-debug+t+e

'handlePlayerCRCMessage': is not a member of 'RecorderClass'

Check failure on line 2118 in Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / win32+t+e

'handlePlayerCRCMessage': is not a member of 'RecorderClass'

Check failure on line 2118 in Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp

View workflow job for this annotation

GitHub Actions / Build Generals / win32-profile+t+e

'handlePlayerCRCMessage': is not a member of 'RecorderClass'
}
}
break;

}

//---------------------------------------------------------------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,8 @@ class GlobalData : public SubsystemInterface
Bool m_afterIntro; ///< we need to tell the game our intro is done
Bool m_allowExitOutOfMovies; ///< flag to allow exit out of movies only after the Intro has played

Bool m_replayOnlyCheckLocalPlayer; ///< flag to check only the CRC messages from the player that recorded a replay

Bool m_loadScreenRender; ///< flag to disallow rendering of almost everything during a loadscreen

Real m_keyboardScrollFactor; ///< Factor applied to game scrolling speed via keyboard scrolling
Expand Down
2 changes: 1 addition & 1 deletion GeneralsMD/Code/GameEngine/Include/Common/Player.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ class Player : public Snapshot

void deletePlayerAI();

UnicodeString getPlayerDisplayName() { return m_playerDisplayName; }
UnicodeString getPlayerDisplayName() const { return m_playerDisplayName; }
NameKeyType getPlayerNameKey() const { return m_playerNameKey; }

AsciiString getSide() const { return m_side; }
Expand Down
55 changes: 43 additions & 12 deletions GeneralsMD/Code/GameEngine/Include/Common/Recorder.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,20 +67,50 @@ class RecorderClass : public SubsystemInterface
class CRCInfo
{
public:
struct MismatchData
{
MismatchData() :
mismatched(false),
playerIndex(0),
queueSize(0),
playbackCRC(0),
playerCRC(0)
{}

MismatchData(Byte playerIndex, UnsignedShort queueSize, UnsignedInt playbackCRC, UnsignedInt playerCRC) :
mismatched(true),
playerIndex(playerIndex),
queueSize(queueSize),
playbackCRC(playbackCRC),
playerCRC(playerCRC)
{}

Bool mismatched;
Byte playerIndex;
UnsignedShort queueSize;
UnsignedInt playbackCRC;
UnsignedInt playerCRC;
};

CRCInfo();
CRCInfo(UnsignedInt localPlayer, Bool isMultiplayer);
void addCRC(UnsignedInt val);
UnsignedInt readCRC();
int GetQueueSize() const { return m_data.size(); }
UnsignedInt getLocalPlayer() const { return m_localPlayer; }
void setSawCRCMismatch() { m_sawCRCMismatch = TRUE; }
Bool sawCRCMismatch() const { return m_sawCRCMismatch; }
void init(Bool isMultiplayer, Int localPlayerIndex);
void addPlaybackCRC(UnsignedInt val);
void addPlayerCRC(Int playerIndex, UnsignedInt val);
void setSawCRCMismatch();
Bool sawCRCMismatch() const;
Byte getLocalPlayerIndex() const;
MismatchData getMismatchData();

protected:
Bool m_sawCRCMismatch;
UnsignedInt getLargestQueueSize() const;
UnsignedInt getPlaybackCRC();

Bool m_skippedOne;
UnsignedInt m_localPlayer;
std::list<UnsignedInt> m_data;
Bool m_sawCRCMismatch;
Byte m_localPlayerIndex;
std::list<UnsignedInt> m_playbackData;
std::vector<UnsignedInt> m_playerData[MAX_PLAYER_COUNT];
Bool m_inactivePlayer[MAX_PLAYER_COUNT];
};

public:
Expand Down Expand Up @@ -110,8 +140,9 @@ class RecorderClass : public SubsystemInterface
#endif
Bool isPlaybackInProgress() const;

public:
void handleCRCMessage(UnsignedInt newCRC, Int playerIndex, Bool fromPlayback);
void handlePlaybackCRCMessage(UnsignedInt newCRC);
void handlePlayerCRCMessage(Int playerIndex, UnsignedInt newCRC);
void checkForMismatch();

// read in info relating to a replay, conditionally setting up m_file for playback
struct ReplayHeader
Expand Down
9 changes: 8 additions & 1 deletion GeneralsMD/Code/GameEngine/Include/GameLogic/GameLogic.h
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,13 @@ class GameLogic : public SubsystemInterface, public Snapshot

private:

enum CRCValidationMode CPP_11(: UnsignedByte)
{
CRCMODE_NONE,
CRCMODE_NETWORK,
CRCMODE_REPLAY,
};

/**
overrides to thing template buildable status. doesn't really belong here,
but has to go somewhere. (srj)
Expand All @@ -317,7 +324,7 @@ class GameLogic : public SubsystemInterface, public Snapshot
// CRC cache system -----------------------------------------------------------------------------
UnsignedInt m_CRC; ///< Cache of previous CRC value
std::map<Int, UnsignedInt> m_cachedCRCs; ///< CRCs we've seen this frame
Bool m_shouldValidateCRCs; ///< Should we validate CRCs this frame?
CRCValidationMode m_validationModeCRC; ///< (How) should we validate CRCs this frame?
//-----------------------------------------------------------------------------------------------
//Bool m_loadingScene;
Bool m_loadingMap;
Expand Down
10 changes: 10 additions & 0 deletions GeneralsMD/Code/GameEngine/Source/Common/CommandLine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,13 @@ Int parseJobs(char *args[], int num)
return 1;
}

Int parseReplayCRC(char* args[], int num)
{
TheWritableGlobalData->m_replayOnlyCheckLocalPlayer = TRUE;

return 1;
}

Int parseXRes(char *args[], int num)
{
if (num > 1)
Expand Down Expand Up @@ -1166,6 +1173,9 @@ static CommandLineParam paramsForEngineInit[] =
// TheSuperHackers @feature xezon 03/08/2025 Force full viewport for 'Control Bar Pro' Addons like GenTool did it.
{ "-forcefullviewport", parseFullViewport },

// TheSuperHackers @feature Caball009 03/06/2026 Enable checking only the CRC messages from the player that recorded a replay.
{ "-replayLocalPlayerCRC", parseReplayCRC },

#if defined(RTS_DEBUG)
{ "-noaudio", parseNoAudio },
{ "-map", parseMapName },
Expand Down
1 change: 1 addition & 0 deletions GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1014,6 +1014,7 @@ GlobalData::GlobalData()
m_playSizzle = TRUE;
m_afterIntro = FALSE;
m_allowExitOutOfMovies = FALSE;
m_replayOnlyCheckLocalPlayer = FALSE;
m_loadScreenRender = FALSE;

m_keyboardDefaultScrollFactor = m_keyboardScrollFactor = 0.5f;
Expand Down
Loading
Loading