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..4a5496c7249 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 @@ -150,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()) { @@ -182,8 +175,8 @@ void Connection::sendNetCommandMsg(NetCommandMsg *msg, UnsignedByte relay) { list = nullptr; } - deleteInstance(origref); - origref = nullptr; + deleteInstance(tempref); + tempref = nullptr; return; } @@ -269,9 +262,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 +309,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 9ea8927d696..eac89f0f16d 100644 --- a/Core/GameEngine/Source/GameNetwork/ConnectionManager.cpp +++ b/Core/GameEngine/Source/GameNetwork/ConnectionManager.cpp @@ -459,71 +459,55 @@ void ConnectionManager::destroyGameMessages() { * assumption that a command will only be relayed once. */ void ConnectionManager::doRelay() { - static Int numPackets = 0; - static Int numCommands = 0; + // 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) { + 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. - 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() ); // 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(); - - ++numCommands; } - ++numPackets; - - // Delete this packet since we won't be needing it anymore. - deleteInstance(packet); - packet = nullptr; deleteInstance(cmdList); cmdList = nullptr; // signal that this has been processed. m_transport->m_inBuffer[i].length = 0; + } else { + break; } } 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(); - - ++numCommands; } - ++numPackets; - - // 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/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/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; } /** 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