From f71d1497856ccebb4dfb8a794ff2a2434e4218bf Mon Sep 17 00:00:00 2001 From: SirLynix Date: Thu, 22 Feb 2024 20:12:34 +0100 Subject: [PATCH] Network/ENetPacket: Fix acknowledge callback on fragmented packets --- include/Nazara/Network/ENetPacket.hpp | 1 + src/Nazara/Network/ENetPeer.cpp | 51 ++++++++++++++++----------- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/include/Nazara/Network/ENetPacket.hpp b/include/Nazara/Network/ENetPacket.hpp index 4fdcaf625..cd4cec505 100644 --- a/include/Nazara/Network/ENetPacket.hpp +++ b/include/Nazara/Network/ENetPacket.hpp @@ -38,6 +38,7 @@ namespace Nz NetPacket data; std::size_t poolIndex; std::size_t referenceCount = 0; + UInt32 remainingFragments; // for ack NazaraSignal(OnAcknowledged); }; diff --git a/src/Nazara/Network/ENetPeer.cpp b/src/Nazara/Network/ENetPeer.cpp index ac13a5f5d..2851fe6fc 100644 --- a/src/Nazara/Network/ENetPeer.cpp +++ b/src/Nazara/Network/ENetPeer.cpp @@ -224,6 +224,8 @@ namespace Nz startSequenceNumber = HostToNet(channel.outgoingReliableSequenceNumber + 1); } + packetRef->remainingFragments = fragmentCount; + for (UInt32 fragmentNumber = 0, fragmentOffset = 0; fragmentOffset < packetSize; ++fragmentNumber, fragmentOffset += fragmentLength) { if (packetSize - fragmentOffset < fragmentLength) @@ -247,29 +249,33 @@ namespace Nz return true; } - - ENetProtocol command; - command.header.channelID = channelId; - - if ((packetRef->flags & (ENetPacketFlag::Reliable | ENetPacketFlag::Unsequenced)) == ENetPacketFlag::Unsequenced) - { - command.header.command = ENetProtocolCommand_SendUnsequenced | ENetProtocolFlag_Unsequenced; - command.sendUnsequenced.dataLength = HostToNet(UInt16(packetRef->data.GetDataSize())); - } - else if (packetRef->flags & ENetPacketFlag::Reliable || channel.outgoingUnreliableSequenceNumber >= 0xFFFF) - { - command.header.command = ENetProtocolCommand_SendReliable | ENetProtocolFlag_Acknowledge; - command.sendReliable.dataLength = HostToNet(UInt16(packetRef->data.GetDataSize())); - } else { - command.header.command = ENetProtocolCommand_SendUnreliable; - command.sendUnreliable.dataLength = HostToNet(UInt16(packetRef->data.GetDataSize())); + packetRef->remainingFragments = 1; + + ENetProtocol command; + command.header.channelID = channelId; + + if ((packetRef->flags & (ENetPacketFlag::Reliable | ENetPacketFlag::Unsequenced)) == ENetPacketFlag::Unsequenced) + { + command.header.command = ENetProtocolCommand_SendUnsequenced | ENetProtocolFlag_Unsequenced; + command.sendUnsequenced.dataLength = HostToNet(UInt16(packetRef->data.GetDataSize())); + } + else if (packetRef->flags & ENetPacketFlag::Reliable || channel.outgoingUnreliableSequenceNumber >= 0xFFFF) + { + command.header.command = ENetProtocolCommand_SendReliable | ENetProtocolFlag_Acknowledge; + command.sendReliable.dataLength = HostToNet(UInt16(packetRef->data.GetDataSize())); + } + else + { + command.header.command = ENetProtocolCommand_SendUnreliable; + command.sendUnreliable.dataLength = HostToNet(UInt16(packetRef->data.GetDataSize())); + } + + QueueOutgoingCommand(command, packetRef, 0, UInt16(packetSize)); + + return true; } - - QueueOutgoingCommand(command, packetRef, 0, UInt16(packetSize)); - - return true; } void ENetPeer::ThrottleConfigure(UInt32 interval, UInt32 acceleration, UInt32 deceleration) @@ -1031,7 +1037,10 @@ namespace Nz if (currentCommand->packet && wasSent) { m_reliableDataInTransit -= currentCommand->fragmentLength; - currentCommand->packet->OnAcknowledged(); + + assert(currentCommand->packet->remainingFragments > 0); + if (--currentCommand->packet->remainingFragments == 0) + currentCommand->packet->OnAcknowledged(); } commandList->erase(currentCommand);