From 551093f064d4086e0866745b7cddd11ad9931e41 Mon Sep 17 00:00:00 2001 From: stm <14291421+stephanmeesters@users.noreply.github.com> Date: Sun, 1 Mar 2026 13:53:41 +0100 Subject: [PATCH 1/3] fix(logic): Check that game is ready for MSG_NEW_GAME --- .../Source/GameLogic/System/GameLogicDispatch.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp index a057812bec3..39b839a88cd 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp @@ -419,6 +419,18 @@ void GameLogic::logicMessageDispatcher( GameMessage *msg, void *userData ) //--------------------------------------------------------------------------------------------- case GameMessage::MSG_NEW_GAME: { +#if !RETAIL_COMPATIBLE_CRC + // TheSuperHackers @fix stephanmeesters 11/03/2026 + // Make sure we're ready to start a new game. This prevents an issue where an infinite disconnect screen + // ("DC bug") can be triggered in an online match. + if ( isInGame() || isClearingGameData() || isLoadingMap() ) + { + DEBUG_CRASH( ("Called MSG_NEW_GAME while game is not ready (inGame=%d, clearingData=%d, loadingMap=%d)", + isInGame(), isClearingGameData(), isLoadingMap()) ); + break; + } +#endif + //DEBUG_ASSERTCRASH(msg->getArgumentCount() == 1 || msg->getArgumentCount() == 2, ("%d arguments to MSG_NEW_GAME", msg->getArgumentCount())); GameMode gameMode = (GameMode)msg->getArgument( 0 )->integer; Int rankPoints = 0; From c18cddccfe6ba1c059d5b3953d0beac235b81dd6 Mon Sep 17 00:00:00 2001 From: stm <14291421+stephanmeesters@users.noreply.github.com> Date: Thu, 12 Mar 2026 13:01:33 +0100 Subject: [PATCH 2/3] Improve comment --- .../GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp index 39b839a88cd..b3b68e8744e 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp @@ -422,7 +422,7 @@ void GameLogic::logicMessageDispatcher( GameMessage *msg, void *userData ) #if !RETAIL_COMPATIBLE_CRC // TheSuperHackers @fix stephanmeesters 11/03/2026 // Make sure we're ready to start a new game. This prevents an issue where an infinite disconnect screen - // ("DC bug") can be triggered in an online match. + // can be force-triggered in an online match by using cheats. if ( isInGame() || isClearingGameData() || isLoadingMap() ) { DEBUG_CRASH( ("Called MSG_NEW_GAME while game is not ready (inGame=%d, clearingData=%d, loadingMap=%d)", From b5d35b3abeecf9040c66a223fe723e156997aac9 Mon Sep 17 00:00:00 2001 From: stm <14291421+stephanmeesters@users.noreply.github.com> Date: Thu, 12 Mar 2026 13:01:39 +0100 Subject: [PATCH 3/3] Replicate in Generals --- .../Source/GameLogic/System/GameLogicDispatch.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Generals/Code/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp b/Generals/Code/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp index 934f607b6c6..f945699efac 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp @@ -410,6 +410,18 @@ void GameLogic::logicMessageDispatcher( GameMessage *msg, void *userData ) //--------------------------------------------------------------------------------------------- case GameMessage::MSG_NEW_GAME: { +#if !RETAIL_COMPATIBLE_CRC + // TheSuperHackers @fix stephanmeesters 11/03/2026 + // Make sure we're ready to start a new game. This prevents an issue where an infinite disconnect screen + // can be force-triggered in an online match by using cheats. + if ( isInGame() || isClearingGameData() || isLoadingMap() ) + { + DEBUG_CRASH( ("Called MSG_NEW_GAME while game is not ready (inGame=%d, clearingData=%d, loadingMap=%d)", + isInGame(), isClearingGameData(), isLoadingMap()) ); + break; + } +#endif + //DEBUG_ASSERTCRASH(msg->getArgumentCount() == 1 || msg->getArgumentCount() == 2, ("%d arguments to MSG_NEW_GAME", msg->getArgumentCount())); GameMode gameMode = (GameMode)msg->getArgument( 0 )->integer; Int rankPoints = 0;