Skip to content

Commit 9a9b1c2

Browse files
authored
bugfix(network): Improve compare method of command id's to keep network commands in chronological order when overflowing (#2736)
1 parent 8207c68 commit 9a9b1c2

5 files changed

Lines changed: 25 additions & 10 deletions

File tree

Core/GameEngine/Source/GameNetwork/NetCommandList.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,18 @@ void NetCommandList::reset() {
122122
m_lastMessageInserted = nullptr;
123123
}
124124

125+
static bool isCommandIdNewer(UnsignedShort newVal, UnsignedShort oldVal)
126+
{
127+
#if RETAIL_COMPATIBLE_NETWORKING
128+
return newVal > oldVal;
129+
#else
130+
// TheSuperHackers @bugfix Caball009 14/06/2026 Ensure messages are sorted
131+
// chronologically by including a command id overflow check.
132+
const UnsignedShort diff = newVal - oldVal;
133+
return diff != 0 && diff < 0x8000;
134+
#endif
135+
}
136+
125137
/**
126138
* Insert sorts msg. Assumes that all the previous message inserts were done using this function.
127139
* The message is sorted in based first on command type, then player id, and then command id.
@@ -157,10 +169,10 @@ NetCommandRef * NetCommandList::addMessage(NetCommandRef *&msg) {
157169
NetCommandRef *theNext = m_lastMessageInserted->getNext();
158170
if ((m_lastMessageInserted->getCommand()->getNetCommandType() == msg->getCommand()->getNetCommandType()) &&
159171
(m_lastMessageInserted->getCommand()->getPlayerID() == msg->getCommand()->getPlayerID()) &&
160-
(m_lastMessageInserted->getCommand()->getID() < msg->getCommand()->getID()) &&
172+
isCommandIdNewer(msg->getCommand()->getID(), m_lastMessageInserted->getCommand()->getID()) &&
161173
((theNext == nullptr) || ((theNext->getCommand()->getNetCommandType() > msg->getCommand()->getNetCommandType()) ||
162174
(theNext->getCommand()->getPlayerID() > msg->getCommand()->getPlayerID()) ||
163-
(theNext->getCommand()->getID() > msg->getCommand()->getID())))) {
175+
isCommandIdNewer(theNext->getCommand()->getID(), msg->getCommand()->getID())))) {
164176

165177
// Make sure this command isn't already in the list.
166178
if (isEqualCommandMsg(m_lastMessageInserted->getCommand(), msg->getCommand())) {
@@ -281,7 +293,10 @@ NetCommandRef * NetCommandList::addMessage(NetCommandRef *&msg) {
281293

282294
// Find the position within the player's section based on the command ID.
283295
// If the command type doesn't require a command ID, sort by whatever it should be sorted by.
284-
while ((tempmsg != nullptr) && (msg->getCommand()->getNetCommandType() == tempmsg->getCommand()->getNetCommandType()) && (msg->getCommand()->getPlayerID() == tempmsg->getCommand()->getPlayerID()) && (msg->getCommand()->getSortNumber() > tempmsg->getCommand()->getSortNumber())) {
296+
while (tempmsg != nullptr
297+
&& msg->getCommand()->getNetCommandType() == tempmsg->getCommand()->getNetCommandType()
298+
&& msg->getCommand()->getPlayerID() == tempmsg->getCommand()->getPlayerID()
299+
&& isCommandIdNewer(msg->getCommand()->getSortNumber(), tempmsg->getCommand()->getSortNumber())) {
285300
tempmsg = tempmsg->getNext();
286301
}
287302

Core/GameEngine/Source/GameNetwork/Network.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
#include "GameClient/MessageBox.h"
5454

5555

56-
#if defined(DEBUG_CRC)
56+
#if defined(DEBUG_CRC) && !RETAIL_COMPATIBLE_NETWORKING
5757
Int NET_CRC_INTERVAL = 1;
5858
#else
5959
Int NET_CRC_INTERVAL = 100;

Core/GameEngine/Source/GameNetwork/NetworkUtil.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,10 @@ UnsignedInt ResolveIP(AsciiString host)
102102
/**
103103
* Returns the next network command ID.
104104
*/
105-
UnsignedShort GenerateNextCommandID() {
106-
static UnsignedShort commandID = 64000;
107-
++commandID;
108-
return commandID;
105+
static UnsignedShort s_commandID = 0;
106+
UnsignedShort GenerateNextCommandID()
107+
{
108+
return s_commandID++;
109109
}
110110

111111
/**

Generals/Code/GameEngine/Source/Common/CommandLine.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ Int parseLogObjectCRCs(char *args[], int argc)
314314
//=============================================================================
315315
Int parseNetCRCInterval(char *args[], int argc)
316316
{
317-
#ifdef DEBUG_CRC
317+
#if defined(DEBUG_CRC) && !RETAIL_COMPATIBLE_NETWORKING
318318
if (argc > 1)
319319
{
320320
NET_CRC_INTERVAL = atoi(args[1]);

GeneralsMD/Code/GameEngine/Source/Common/CommandLine.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ Int parseLogObjectCRCs(char *args[], int argc)
314314
//=============================================================================
315315
Int parseNetCRCInterval(char *args[], int argc)
316316
{
317-
#ifdef DEBUG_CRC
317+
#if defined(DEBUG_CRC) && !RETAIL_COMPATIBLE_NETWORKING
318318
if (argc > 1)
319319
{
320320
NET_CRC_INTERVAL = atoi(args[1]);

0 commit comments

Comments
 (0)