From b27c33714b1086eb62aabe40f4e78ede33173654 Mon Sep 17 00:00:00 2001 From: Caball009 <82909616+Caball009@users.noreply.github.com> Date: Tue, 2 Jun 2026 22:37:37 +0200 Subject: [PATCH 1/5] Removed unused static (packet and command count) variables. --- Core/GameEngine/Source/GameNetwork/ConnectionManager.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Core/GameEngine/Source/GameNetwork/ConnectionManager.cpp b/Core/GameEngine/Source/GameNetwork/ConnectionManager.cpp index 9ea8927d696..8c60c360bdc 100644 --- a/Core/GameEngine/Source/GameNetwork/ConnectionManager.cpp +++ b/Core/GameEngine/Source/GameNetwork/ConnectionManager.cpp @@ -459,8 +459,6 @@ void ConnectionManager::destroyGameMessages() { * assumption that a command will only be relayed once. */ void ConnectionManager::doRelay() { - static Int numPackets = 0; - static Int numCommands = 0; NetPacket *packet = nullptr; @@ -489,10 +487,7 @@ void ConnectionManager::doRelay() { sendRemoteCommand(cmd); } cmd = cmd->getNext(); - - ++numCommands; } - ++numPackets; // Delete this packet since we won't be needing it anymore. deleteInstance(packet); @@ -516,10 +511,7 @@ void ConnectionManager::doRelay() { sendRemoteCommand(cmd); } cmd = cmd->getNext(); - - ++numCommands; } - ++numPackets; // Delete this packet since we won't be needing it anymore. deleteInstance(packet); From 17822550cf2d40127430f70d06df0c8601a9af99 Mon Sep 17 00:00:00 2001 From: Caball009 <82909616+Caball009@users.noreply.github.com> Date: Tue, 2 Jun 2026 22:44:39 +0200 Subject: [PATCH 2/5] Reduced the number of packet (re)allocations significantly. --- .../Include/GameNetwork/NetPacket.h | 3 ++- .../Source/GameNetwork/Connection.cpp | 19 +++++++------------ .../Source/GameNetwork/ConnectionManager.cpp | 14 ++++---------- .../Source/GameNetwork/NetPacket.cpp | 15 ++++++++++----- 4 files changed, 23 insertions(+), 28 deletions(-) diff --git a/Core/GameEngine/Include/GameNetwork/NetPacket.h b/Core/GameEngine/Include/GameNetwork/NetPacket.h index cdd498b1ad8..668a38973a3 100644 --- a/Core/GameEngine/Include/GameNetwork/NetPacket.h +++ b/Core/GameEngine/Include/GameNetwork/NetPacket.h @@ -50,11 +50,12 @@ class NetPacket : public MemoryPoolObject MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(NetPacket, "NetPacket") public: NetPacket(); - NetPacket(TransportMessage *msg); + NetPacket(const TransportMessage& msg); //virtual ~NetPacket(); void init(); void reset(); + void CopyTransportMessage(const TransportMessage& msg); void setAddress(Int addr, Int port); Bool addCommand(NetCommandRef *msg); Int getNumCommands(); diff --git a/Core/GameEngine/Source/GameNetwork/Connection.cpp b/Core/GameEngine/Source/GameNetwork/Connection.cpp index c1f84e88881..805188c7fc3 100644 --- a/Core/GameEngine/Source/GameNetwork/Connection.cpp +++ b/Core/GameEngine/Source/GameNetwork/Connection.cpp @@ -131,18 +131,13 @@ User * Connection::getUser() { * The relay mostly has to do with the packet router. */ void Connection::sendNetCommandMsg(NetCommandMsg *msg, UnsignedByte relay) { - static NetPacket *packet = nullptr; - - // this is done so we don't have to allocate and delete a packet every time we send a message. - if (packet == nullptr) { - packet = newInstance(NetPacket); - } - - if (m_isQuitting) return; if (m_netCommandList != nullptr) { + // this is done so we don't have to allocate and delete a packet every time we send a message. + static NetPacket* packet = newInstance(NetPacket); + // check to see if this command will fit in a packet. If not, we need to split it up. // we are splitting up the command here so that the retry logic will not try to // resend the ENTIRE command (i.e. multiple packets work of data) and only do the retry @@ -269,9 +264,11 @@ UnsignedInt Connection::doSend() { // iterate through all the messages and put them into a packet(s). NetCommandRef *msg = m_netCommandList->getFirstMessage(); + // this is done so we don't have to allocate and delete a packet every time we send a message. + static NetPacket* packet = newInstance(NetPacket); + while ((msg != nullptr) && couldQueue) { - NetPacket *packet = newInstance(NetPacket); - packet->init(); + packet->reset(); packet->setAddress(m_user->GetIPAddr(), m_user->GetPort()); Bool notDone = TRUE; @@ -314,8 +311,6 @@ UnsignedInt Connection::doSend() { couldQueue = m_transport->queueSend(packet->getAddr(), packet->getPort(), packet->getData(), packet->getLength()); m_lastTimeSent = curtime; } - - deleteInstance(packet); // delete the packet now that we're done with it. } return numpackets; diff --git a/Core/GameEngine/Source/GameNetwork/ConnectionManager.cpp b/Core/GameEngine/Source/GameNetwork/ConnectionManager.cpp index 8c60c360bdc..31012bc1aea 100644 --- a/Core/GameEngine/Source/GameNetwork/ConnectionManager.cpp +++ b/Core/GameEngine/Source/GameNetwork/ConnectionManager.cpp @@ -459,15 +459,17 @@ void ConnectionManager::destroyGameMessages() { * assumption that a command will only be relayed once. */ void ConnectionManager::doRelay() { + // this is done so we don't have to allocate and delete a packet every time we relay a message. + static NetPacket* packet = newInstance(NetPacket); - NetPacket *packet = nullptr; for (Int i = 0; i < MAX_MESSAGES; ++i) { if (m_transport->m_inBuffer[i].length != 0) { // This transport buffer has yet to be processed. // make a NetPacket out of this data so it can be broken up into individual commands. - packet = newInstance(NetPacket)(&(m_transport->m_inBuffer[i])); + packet->reset(); + packet->CopyTransportMessage(m_transport->m_inBuffer[i]); //DEBUG_LOG(("ConnectionManager::doRelay() - got a packet with %d commands", packet->getNumCommands())); //LOGBUFFER( packet->getData(), packet->getLength() ); @@ -489,10 +491,6 @@ void ConnectionManager::doRelay() { cmd = cmd->getNext(); } - // Delete this packet since we won't be needing it anymore. - deleteInstance(packet); - packet = nullptr; - deleteInstance(cmdList); cmdList = nullptr; @@ -513,10 +511,6 @@ void ConnectionManager::doRelay() { cmd = cmd->getNext(); } - // Delete this packet since we won't be needing it anymore. - deleteInstance(packet); - packet = nullptr; - deleteInstance(cmdList); cmdList = nullptr; } diff --git a/Core/GameEngine/Source/GameNetwork/NetPacket.cpp b/Core/GameEngine/Source/GameNetwork/NetPacket.cpp index c04446d7e51..1f11a691b94 100644 --- a/Core/GameEngine/Source/GameNetwork/NetPacket.cpp +++ b/Core/GameEngine/Source/GameNetwork/NetPacket.cpp @@ -173,13 +173,18 @@ NetPacket::NetPacket() { /** * Constructor given raw transport data. */ -NetPacket::NetPacket(TransportMessage *msg) { +NetPacket::NetPacket(const TransportMessage& msg) { init(); - m_packetLen = msg->length; - memcpy(m_packet, msg->data, MAX_PACKET_SIZE); + CopyTransportMessage(msg); +} + +void NetPacket::CopyTransportMessage(const TransportMessage& msg) +{ + m_packetLen = msg.length; + memcpy(m_packet, msg.data, MAX_PACKET_SIZE); m_numCommands = -1; - m_addr = msg->addr; - m_port = msg->port; + m_addr = msg.addr; + m_port = msg.port; } /** From 8a74350cdf1442299c3a69f46365765877e40c62 Mon Sep 17 00:00:00 2001 From: Caball009 <82909616+Caball009@users.noreply.github.com> Date: Tue, 2 Jun 2026 22:46:40 +0200 Subject: [PATCH 3/5] Refactored while loops to for loops. --- Core/GameEngine/Source/GameNetwork/ConnectionManager.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Core/GameEngine/Source/GameNetwork/ConnectionManager.cpp b/Core/GameEngine/Source/GameNetwork/ConnectionManager.cpp index 31012bc1aea..6883bd56180 100644 --- a/Core/GameEngine/Source/GameNetwork/ConnectionManager.cpp +++ b/Core/GameEngine/Source/GameNetwork/ConnectionManager.cpp @@ -476,19 +476,18 @@ void ConnectionManager::doRelay() { // Get the command list from the packet. NetCommandList *cmdList = packet->getCommandList(); - NetCommandRef *cmd = cmdList->getFirstMessage(); // Iterate through the commands in this packet and send them to the proper connections. - while (cmd != nullptr) { + for (NetCommandRef* cmd = cmdList->getFirstMessage(); cmd; cmd = cmd->getNext()) { //DEBUG_LOG(("ConnectionManager::doRelay() - Looking at a command of type %s", //GetNetCommandTypeAsString(cmd->getCommand()->getNetCommandType()))); + if (CommandRequiresAck(cmd->getCommand())) { ackCommand(cmd, m_localSlot); } if (!processNetCommand(cmd)) { sendRemoteCommand(cmd); } - cmd = cmd->getNext(); } deleteInstance(cmdList); @@ -500,15 +499,13 @@ void ConnectionManager::doRelay() { } NetCommandList *cmdList = m_netCommandWrapperList->getReadyCommands(); - NetCommandRef *cmd = cmdList->getFirstMessage(); - while (cmd != nullptr) { + for (NetCommandRef* cmd = cmdList->getFirstMessage(); cmd; cmd = cmd->getNext()) { if (CommandRequiresAck(cmd->getCommand())) { ackCommand(cmd, m_localSlot); } if (!processNetCommand(cmd)) { sendRemoteCommand(cmd); } - cmd = cmd->getNext(); } deleteInstance(cmdList); From 4dc62aa0a0dd7c6323c5adb1dcd16f427dd22446 Mon Sep 17 00:00:00 2001 From: Caball009 <82909616+Caball009@users.noreply.github.com> Date: Tue, 2 Jun 2026 22:49:04 +0200 Subject: [PATCH 4/5] Improved loop logic performance. --- .../Source/GameNetwork/ConnectionManager.cpp | 7 ++-- Core/GameEngine/Source/GameNetwork/LANAPI.cpp | 9 +++-- Core/GameEngine/Source/GameNetwork/NAT.cpp | 4 ++- .../Source/GameNetwork/Transport.cpp | 36 +++++++++---------- 4 files changed, 32 insertions(+), 24 deletions(-) diff --git a/Core/GameEngine/Source/GameNetwork/ConnectionManager.cpp b/Core/GameEngine/Source/GameNetwork/ConnectionManager.cpp index 6883bd56180..eac89f0f16d 100644 --- a/Core/GameEngine/Source/GameNetwork/ConnectionManager.cpp +++ b/Core/GameEngine/Source/GameNetwork/ConnectionManager.cpp @@ -462,9 +462,8 @@ void ConnectionManager::doRelay() { // this is done so we don't have to allocate and delete a packet every time we relay a message. static NetPacket* packet = newInstance(NetPacket); - - for (Int i = 0; i < MAX_MESSAGES; ++i) { - if (m_transport->m_inBuffer[i].length != 0) { + for (size_t i = 0; i < ARRAY_SIZE(m_transport->m_inBuffer); ++i) { + if (m_transport->m_inBuffer[i].length > 0) { // This transport buffer has yet to be processed. // make a NetPacket out of this data so it can be broken up into individual commands. @@ -495,6 +494,8 @@ void ConnectionManager::doRelay() { // signal that this has been processed. m_transport->m_inBuffer[i].length = 0; + } else { + break; } } diff --git a/Core/GameEngine/Source/GameNetwork/LANAPI.cpp b/Core/GameEngine/Source/GameNetwork/LANAPI.cpp index 1016d26f66b..6275953f525 100644 --- a/Core/GameEngine/Source/GameNetwork/LANAPI.cpp +++ b/Core/GameEngine/Source/GameNetwork/LANAPI.cpp @@ -341,9 +341,10 @@ void LANAPI::update() } // Handle any new messages - int i; - for (i=0; im_inBuffer); ++i) { + DEBUG_ASSERTCRASH(!LANbuttonPushed, ("LANbuttonPushed has an unexpected value")); + if (m_transport->m_inBuffer[i].length > 0) { // Process the new message @@ -432,6 +433,10 @@ void LANAPI::update() // Mark it as read m_transport->m_inBuffer[i].length = 0; } + else + { + break; + } } if(LANbuttonPushed) return; diff --git a/Core/GameEngine/Source/GameNetwork/NAT.cpp b/Core/GameEngine/Source/GameNetwork/NAT.cpp index 159d8532cfa..d68470b0505 100644 --- a/Core/GameEngine/Source/GameNetwork/NAT.cpp +++ b/Core/GameEngine/Source/GameNetwork/NAT.cpp @@ -325,7 +325,7 @@ NATConnectionState NAT::connectionUpdate() { m_transport->update(); // check to see if we've been probed. - for (Int i = 0; i < MAX_MESSAGES; ++i) { + for (size_t i = 0; i < ARRAY_SIZE(m_transport->m_inBuffer); ++i) { if (m_transport->m_inBuffer[i].length > 0) { #ifdef DEBUG_LOGGING UnsignedInt ip = m_transport->m_inBuffer[i].addr; @@ -368,6 +368,8 @@ NATConnectionState NAT::connectionUpdate() { PRINTF_IP_AS_4_INTS(ip), m_transport->m_inBuffer[i].port)); m_transport->m_inBuffer[i].length = 0; } + } else { + break; } } diff --git a/Core/GameEngine/Source/GameNetwork/Transport.cpp b/Core/GameEngine/Source/GameNetwork/Transport.cpp index 04dc7d624f5..2c55434db4c 100644 --- a/Core/GameEngine/Source/GameNetwork/Transport.cpp +++ b/Core/GameEngine/Source/GameNetwork/Transport.cpp @@ -211,8 +211,7 @@ Bool Transport::doSend() { } // Send all messages - int i; - for (i=0; iRead(buf, MAX_NETWORK_MESSAGE_LEN, &from)) > 0 ) { @@ -330,36 +330,38 @@ Bool Transport::doRecv() m_incomingPackets[m_statisticsSlot]++; m_incomingBytes[m_statisticsSlot] += len; - for (int i=0; im_latencyAverage + (Int)(TheGlobalData->m_latencyAmplitude * sin(now * TheGlobalData->m_latencyPeriod)) + GameClientRandomValue(-TheGlobalData->m_latencyNoise, TheGlobalData->m_latencyNoise); - m_delayedInBuffer[i].message.length = incomingMessage.length; - m_delayedInBuffer[i].message.addr = ntohl(from.sin_addr.S_un.S_addr); - m_delayedInBuffer[i].message.port = ntohs(from.sin_port); - memcpy(&m_delayedInBuffer[i].message, buf, len); + m_delayedInBuffer[bufferIndex].message.length = incomingMessage.length; + m_delayedInBuffer[bufferIndex].message.addr = ntohl(from.sin_addr.S_un.S_addr); + m_delayedInBuffer[bufferIndex].message.port = ntohs(from.sin_port); + memcpy(&m_delayedInBuffer[bufferIndex].message, buf, len); + ++bufferIndex; break; } } else { #endif - if (m_inBuffer[i].length == 0) + if (m_inBuffer[bufferIndex].length == 0) { // Empty slot; use it - m_inBuffer[i].length = incomingMessage.length; - m_inBuffer[i].addr = ntohl(from.sin_addr.S_un.S_addr); - m_inBuffer[i].port = ntohs(from.sin_port); - memcpy(&m_inBuffer[i], buf, len); + m_inBuffer[bufferIndex].length = incomingMessage.length; + m_inBuffer[bufferIndex].addr = ntohl(from.sin_addr.S_un.S_addr); + m_inBuffer[bufferIndex].port = ntohs(from.sin_port); + memcpy(&m_inBuffer[bufferIndex], buf, len); + ++bufferIndex; break; } #if defined(RTS_DEBUG) @@ -381,15 +383,13 @@ Bool Transport::doRecv() Bool Transport::queueSend(UnsignedInt addr, UnsignedShort port, const UnsignedByte *buf, Int len /*, NetMessageFlags flags, Int id */) { - int i; - if (len < 1 || len > MAX_PACKET_SIZE) { DEBUG_LOG(("Transport::queueSend - Invalid Packet size")); return false; } - for (i=0; i Date: Tue, 2 Jun 2026 22:54:35 +0200 Subject: [PATCH 5/5] Removed unnecessary (de)allocation. --- .../Source/GameNetwork/Connection.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/Core/GameEngine/Source/GameNetwork/Connection.cpp b/Core/GameEngine/Source/GameNetwork/Connection.cpp index 805188c7fc3..4a5496c7249 100644 --- a/Core/GameEngine/Source/GameNetwork/Connection.cpp +++ b/Core/GameEngine/Source/GameNetwork/Connection.cpp @@ -145,16 +145,14 @@ void Connection::sendNetCommandMsg(NetCommandMsg *msg, UnsignedByte relay) { packet->reset(); NetCommandRef *tempref = NEW_NETCOMMANDREF(msg); + if (packet->addCommand(tempref)) { + deleteInstance(tempref); + tempref = nullptr; + } else { + tempref->setRelay(relay); - Bool msgFits = packet->addCommand(tempref); - deleteInstance(tempref); // delete the temporary reference. - tempref = nullptr; - - if (!msgFits) { - NetCommandRef *origref = NEW_NETCOMMANDREF(msg); - origref->setRelay(relay); // the message doesn't fit in a single packet, need to split it up. - NetPacketList packetList = NetPacket::ConstructBigCommandPacketList(origref); + NetPacketList packetList = NetPacket::ConstructBigCommandPacketList(tempref); NetPacketListIter tempPacketPtr = packetList.begin(); while (tempPacketPtr != packetList.end()) { @@ -177,8 +175,8 @@ void Connection::sendNetCommandMsg(NetCommandMsg *msg, UnsignedByte relay) { list = nullptr; } - deleteInstance(origref); - origref = nullptr; + deleteInstance(tempref); + tempref = nullptr; return; }