From bcfbc63af92ec3bcbc0758c0c0f148dd7a5ba01c Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Wed, 31 Dec 2025 11:30:09 -0800 Subject: [PATCH 1/3] fix(network): correct packed struct field types and sizes --- .../Include/GameNetwork/NetPacketStructs.h | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/Core/GameEngine/Include/GameNetwork/NetPacketStructs.h b/Core/GameEngine/Include/GameNetwork/NetPacketStructs.h index 35f5ce997a6..ef02ea83ed7 100644 --- a/Core/GameEngine/Include/GameNetwork/NetPacketStructs.h +++ b/Core/GameEngine/Include/GameNetwork/NetPacketStructs.h @@ -137,8 +137,6 @@ struct NetPacketPlayerLeaveCommand { // Run ahead metrics command packet structure // Fields: T + type, R + relay, P + playerID, C + commandID, D + averageLatency + averageFps -// TODO: averageFps should be UnsignedShort to match FillBufferWithRunAheadMetricsCommand, but -// original GetRunAheadMetricsCommandSize incorrectly counted it as UnsignedByte struct NetPacketRunAheadMetricsCommand { NetPacketCommandTypeField commandType; NetPacketRelayField relay; @@ -146,7 +144,7 @@ struct NetPacketRunAheadMetricsCommand { NetPacketCommandIdField commandId; NetPacketDataFieldHeader dataHeader; Real averageLatency; - UnsignedByte averageFps; + UnsignedShort averageFps; }; //////////////////////////////////////////////////////////////////////////////// @@ -362,24 +360,22 @@ struct NetPacketProgressMessage { }; // Load complete message packet -// Fields: T + type, R + relay, P + playerID, D -// TODO: commandId field is missing. FillBufferWithLoadCompleteMessage writes it, but -// original GetLoadCompleteMessageSize did not count it +// Fields: T + type, R + relay, P + playerID, C + commandID, D struct NetPacketLoadCompleteMessage { NetPacketCommandTypeField commandType; NetPacketRelayField relay; NetPacketPlayerIdField playerId; + NetPacketCommandIdField commandId; NetPacketDataFieldHeader dataHeader; }; // Timeout game start message packet -// Fields: T + type, R + relay, P + playerID, D -// TODO: commandId field is missing. FillBufferWithTimeOutGameStartMessage writes it, but -// original GetTimeOutGameStartMessageSize did not count it +// Fields: T + type, R + relay, P + playerID, C + commandID, D struct NetPacketTimeOutGameStartMessage { NetPacketCommandTypeField commandType; NetPacketRelayField relay; NetPacketPlayerIdField playerId; + NetPacketCommandIdField commandId; NetPacketDataFieldHeader dataHeader; }; From 1c50b5077e78564bb5d0c5ec925021958cc30ba8 Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Sun, 4 Jan 2026 08:40:50 -0800 Subject: [PATCH 2/3] fix(network): add missing CommandId size check in isRoomFor*Message functions --- Core/GameEngine/Source/GameNetwork/NetPacket.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Core/GameEngine/Source/GameNetwork/NetPacket.cpp b/Core/GameEngine/Source/GameNetwork/NetPacket.cpp index 92ec1928595..762f4f3b2f6 100644 --- a/Core/GameEngine/Source/GameNetwork/NetPacket.cpp +++ b/Core/GameEngine/Source/GameNetwork/NetPacket.cpp @@ -2457,6 +2457,7 @@ Bool NetPacket::addTimeOutGameStartMessage(NetCommandRef *msg) { */ Bool NetPacket::isRoomForTimeOutGameStartMessage(NetCommandRef *msg) { Int len = 0; + Bool needNewCommandID = FALSE; NetCommandMsg *cmdMsg = static_cast(msg->getCommand()); if (m_lastCommandType != cmdMsg->getNetCommandType()) { ++len; @@ -2468,6 +2469,10 @@ Bool NetPacket::isRoomForTimeOutGameStartMessage(NetCommandRef *msg) { if (m_lastPlayerID != cmdMsg->getPlayerID()) { ++len; len += sizeof(UnsignedByte); + needNewCommandID = TRUE; + } + if (((m_lastCommandID + 1) != (UnsignedShort)(cmdMsg->getID())) || (needNewCommandID == TRUE)) { + len += sizeof(UnsignedByte) + sizeof(UnsignedShort); } ++len; // for NetPacketFieldTypes::Data @@ -2549,6 +2554,7 @@ Bool NetPacket::addLoadCompleteMessage(NetCommandRef *msg) { */ Bool NetPacket::isRoomForLoadCompleteMessage(NetCommandRef *msg) { Int len = 0; + Bool needNewCommandID = FALSE; NetCommandMsg *cmdMsg = static_cast(msg->getCommand()); if (m_lastCommandType != cmdMsg->getNetCommandType()) { ++len; @@ -2560,6 +2566,10 @@ Bool NetPacket::isRoomForLoadCompleteMessage(NetCommandRef *msg) { if (m_lastPlayerID != cmdMsg->getPlayerID()) { ++len; len += sizeof(UnsignedByte); + needNewCommandID = TRUE; + } + if (((m_lastCommandID + 1) != (UnsignedShort)(cmdMsg->getID())) || (needNewCommandID == TRUE)) { + len += sizeof(UnsignedByte) + sizeof(UnsignedShort); } ++len; // for NetPacketFieldTypes::Data From 731993b230de5a5fb2874fdbf2760deb96e3245a Mon Sep 17 00:00:00 2001 From: Bobby Battista Date: Sun, 4 Jan 2026 08:41:40 -0800 Subject: [PATCH 3/3] fix(network): call correct isRoomForTimeOutGameStartMessage in addTimeOutGameStartMessage --- Core/GameEngine/Source/GameNetwork/NetPacket.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/GameEngine/Source/GameNetwork/NetPacket.cpp b/Core/GameEngine/Source/GameNetwork/NetPacket.cpp index 762f4f3b2f6..51cf3bf1e74 100644 --- a/Core/GameEngine/Source/GameNetwork/NetPacket.cpp +++ b/Core/GameEngine/Source/GameNetwork/NetPacket.cpp @@ -2392,7 +2392,7 @@ Bool NetPacket::isRoomForWrapperMessage(NetCommandRef *msg) { */ Bool NetPacket::addTimeOutGameStartMessage(NetCommandRef *msg) { Bool needNewCommandID = FALSE; - if (isRoomForLoadCompleteMessage(msg)) { + if (isRoomForTimeOutGameStartMessage(msg)) { NetCommandMsg *cmdMsg = static_cast(msg->getCommand()); // If necessary, put the NetCommandType into the packet.