From 97cab051df73552930462464e62a435f7afeb0d1 Mon Sep 17 00:00:00 2001 From: terminx Date: Sat, 4 Jun 2011 16:56:47 +0000 Subject: [PATCH] ENet 1.3.2 git-svn-id: https://svn.eduke32.com/eduke32@1902 1a8010ca-5511-0410-912e-c29ae57300e0 --- .../eduke32/source/enet/include/enet/enet.h | 12 +- .../source/enet/include/enet/protocol.h | 3 +- polymer/eduke32/source/enet/src/host.c | 1 + polymer/eduke32/source/enet/src/peer.c | 127 +++++++++--- polymer/eduke32/source/enet/src/protocol.c | 190 +++++++++++++++--- 5 files changed, 270 insertions(+), 63 deletions(-) diff --git a/polymer/eduke32/source/enet/include/enet/enet.h b/polymer/eduke32/source/enet/include/enet/enet.h index b572590ec..e938a9213 100644 --- a/polymer/eduke32/source/enet/include/enet/enet.h +++ b/polymer/eduke32/source/enet/include/enet/enet.h @@ -23,9 +23,13 @@ extern "C" #include "enet/list.h" #include "enet/callbacks.h" +#ifndef UNREFERENCED_PARAMETER +# define UNREFERENCED_PARAMETER(x) x=x +#endif + #define ENET_VERSION_MAJOR 1 #define ENET_VERSION_MINOR 3 -#define ENET_VERSION_PATCH 1 +#define ENET_VERSION_PATCH 2 #define ENET_VERSION_CREATE(major, minor, patch) (((major)<<16) | ((minor)<<8) | (patch)) #define ENET_VERSION ENET_VERSION_CREATE(ENET_VERSION_MAJOR, ENET_VERSION_MINOR, ENET_VERSION_PATCH) @@ -96,7 +100,10 @@ typedef enum _ENetPacketFlag */ ENET_PACKET_FLAG_UNSEQUENCED = (1 << 1), /** packet will not allocate data, and user must supply it instead */ - ENET_PACKET_FLAG_NO_ALLOCATE = (1 << 2) + ENET_PACKET_FLAG_NO_ALLOCATE = (1 << 2), + /** packet will be fragmented using unreliable (instead of reliable) sends + * if it exceeds the MTU */ + ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT = (1 << 3) } ENetPacketFlag; struct _ENetPacket; @@ -218,6 +225,7 @@ typedef struct _ENetChannel enet_uint16 usedReliableWindows; enet_uint16 reliableWindows [ENET_PEER_RELIABLE_WINDOWS]; enet_uint16 incomingReliableSequenceNumber; + enet_uint16 incomingUnreliableSequenceNumber; ENetList incomingReliableCommands; ENetList incomingUnreliableCommands; } ENetChannel; diff --git a/polymer/eduke32/source/enet/include/enet/protocol.h b/polymer/eduke32/source/enet/include/enet/protocol.h index 19f7e45de..faef91790 100644 --- a/polymer/eduke32/source/enet/include/enet/protocol.h +++ b/polymer/eduke32/source/enet/include/enet/protocol.h @@ -33,7 +33,8 @@ typedef enum _ENetProtocolCommand ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED = 9, ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT = 10, ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE = 11, - ENET_PROTOCOL_COMMAND_COUNT = 12, + ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT = 12, + ENET_PROTOCOL_COMMAND_COUNT = 13, ENET_PROTOCOL_COMMAND_MASK = 0x0F } ENetProtocolCommand; diff --git a/polymer/eduke32/source/enet/src/host.c b/polymer/eduke32/source/enet/src/host.c index 8bb2433fe..c44f2ed3c 100644 --- a/polymer/eduke32/source/enet/src/host.c +++ b/polymer/eduke32/source/enet/src/host.c @@ -210,6 +210,7 @@ enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelC channel -> outgoingReliableSequenceNumber = 0; channel -> outgoingUnreliableSequenceNumber = 0; channel -> incomingReliableSequenceNumber = 0; + channel -> incomingUnreliableSequenceNumber = 0; enet_list_clear (& channel -> incomingReliableCommands); enet_list_clear (& channel -> incomingUnreliableCommands); diff --git a/polymer/eduke32/source/enet/src/peer.c b/polymer/eduke32/source/enet/src/peer.c index e1c117f89..3ea24dd33 100644 --- a/polymer/eduke32/source/enet/src/peer.c +++ b/polymer/eduke32/source/enet/src/peer.c @@ -113,13 +113,26 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet) if (packet -> dataLength > fragmentLength) { - enet_uint16 startSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingReliableSequenceNumber + 1); enet_uint32 fragmentCount = ENET_HOST_TO_NET_32 ((packet -> dataLength + fragmentLength - 1) / fragmentLength), fragmentNumber, fragmentOffset; + enet_uint8 commandNumber; + enet_uint16 startSequenceNumber; ENetList fragments; ENetOutgoingCommand * fragment; + if ((packet -> flags & (ENET_PACKET_FLAG_RELIABLE | ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT)) == ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT && + channel -> outgoingUnreliableSequenceNumber < 0xFFFF) + { + commandNumber = ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT; + startSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingUnreliableSequenceNumber + 1); + } + else + { + commandNumber = ENET_PROTOCOL_COMMAND_SEND_FRAGMENT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; + startSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingReliableSequenceNumber + 1); + } + enet_list_clear (& fragments); for (fragmentNumber = 0, @@ -147,7 +160,7 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet) fragment -> fragmentOffset = fragmentOffset; fragment -> fragmentLength = fragmentLength; fragment -> packet = packet; - fragment -> command.header.command = ENET_PROTOCOL_COMMAND_SEND_FRAGMENT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; + fragment -> command.header.command = commandNumber; fragment -> command.header.channelID = channelID; fragment -> command.sendFragment.startSequenceNumber = startSequenceNumber; fragment -> command.sendFragment.dataLength = ENET_HOST_TO_NET_16 (fragmentLength); @@ -173,20 +186,13 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet) command.header.channelID = channelID; - if (packet -> flags & ENET_PACKET_FLAG_RELIABLE) - { - command.header.command = ENET_PROTOCOL_COMMAND_SEND_RELIABLE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; - command.sendReliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength); - } - else - if (packet -> flags & ENET_PACKET_FLAG_UNSEQUENCED) + if ((packet -> flags & (ENET_PACKET_FLAG_RELIABLE | ENET_PACKET_FLAG_UNSEQUENCED)) == ENET_PACKET_FLAG_UNSEQUENCED) { command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED | ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED; - command.sendUnsequenced.unsequencedGroup = ENET_HOST_TO_NET_16 (peer -> outgoingUnsequencedGroup + 1); command.sendUnsequenced.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength); } else - if (channel -> outgoingUnreliableSequenceNumber >= 0xFFFF) + if (packet -> flags & ENET_PACKET_FLAG_RELIABLE || channel -> outgoingUnreliableSequenceNumber >= 0xFFFF) { command.header.command = ENET_PROTOCOL_COMMAND_SEND_RELIABLE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; command.sendReliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength); @@ -194,7 +200,6 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet) else { command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE; - command.sendUnreliable.unreliableSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingUnreliableSequenceNumber + 1); command.sendUnreliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength); } @@ -257,14 +262,21 @@ enet_peer_reset_outgoing_commands (ENetList * queue) } static void -enet_peer_reset_incoming_commands (ENetList * queue) +enet_peer_remove_incoming_commands (ENetList * queue, ENetListIterator startCommand, ENetListIterator endCommand) { - ENetIncomingCommand * incomingCommand; + ENetListIterator currentCommand; - while (! enet_list_empty (queue)) + UNREFERENCED_PARAMETER(queue); + + + for (currentCommand = startCommand; currentCommand != endCommand; ) { - incomingCommand = (ENetIncomingCommand *) enet_list_remove (enet_list_begin (queue)); + ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand; + currentCommand = enet_list_next (currentCommand); + + enet_list_remove (& incomingCommand -> incomingCommandList); + if (incomingCommand -> packet != NULL) { -- incomingCommand -> packet -> referenceCount; @@ -280,6 +292,12 @@ enet_peer_reset_incoming_commands (ENetList * queue) } } +static void +enet_peer_reset_incoming_commands (ENetList * queue) +{ + enet_peer_remove_incoming_commands(queue, enet_list_begin (queue), enet_list_end(queue)); +} + void enet_peer_reset_queues (ENetPeer * peer) { @@ -550,7 +568,8 @@ enet_peer_setup_outgoing_command (ENetPeer * peer, ENetOutgoingCommand * outgoin } else { - ++ channel -> outgoingUnreliableSequenceNumber; + if (outgoingCommand -> fragmentOffset == 0) + ++ channel -> outgoingUnreliableSequenceNumber; outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber; outgoingCommand -> unreliableSequenceNumber = channel -> outgoingUnreliableSequenceNumber; @@ -562,6 +581,20 @@ enet_peer_setup_outgoing_command (ENetPeer * peer, ENetOutgoingCommand * outgoin outgoingCommand -> roundTripTimeoutLimit = 0; outgoingCommand -> command.header.reliableSequenceNumber = ENET_HOST_TO_NET_16 (outgoingCommand -> reliableSequenceNumber); + switch (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) + { + case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE: + outgoingCommand -> command.sendUnreliable.unreliableSequenceNumber = ENET_HOST_TO_NET_16 (outgoingCommand -> unreliableSequenceNumber); + break; + + case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED: + outgoingCommand -> command.sendUnsequenced.unsequencedGroup = ENET_HOST_TO_NET_16 (peer -> outgoingUnsequencedGroup); + break; + + default: + break; + } + if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) enet_list_insert (enet_list_end (& peer -> outgoingReliableCommands), outgoingCommand); else @@ -590,30 +623,55 @@ enet_peer_queue_outgoing_command (ENetPeer * peer, const ENetProtocol * command, void enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel * channel) { - ENetListIterator currentCommand; + ENetListIterator droppedCommand, startCommand, currentCommand; - for (currentCommand = enet_list_begin (& channel -> incomingUnreliableCommands); + for (droppedCommand = startCommand = currentCommand = enet_list_begin (& channel -> incomingUnreliableCommands); currentCommand != enet_list_end (& channel -> incomingUnreliableCommands); currentCommand = enet_list_next (currentCommand)) { ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand; - if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE && - incomingCommand -> reliableSequenceNumber != channel -> incomingReliableSequenceNumber) + if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED) + continue; + else + if (incomingCommand -> reliableSequenceNumber != channel -> incomingReliableSequenceNumber) break; + else + if (incomingCommand -> fragmentsRemaining <= 0) + channel -> incomingUnreliableSequenceNumber = incomingCommand -> unreliableSequenceNumber; + else + if (startCommand == currentCommand) + startCommand = enet_list_next (currentCommand); + else + { + enet_list_move (enet_list_end (& peer -> dispatchedCommands), startCommand, enet_list_previous (currentCommand)); + + if (! peer -> needsDispatch) + { + enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList); + + peer -> needsDispatch = 1; + } + + droppedCommand = startCommand = enet_list_next (currentCommand); + } } - if (currentCommand == enet_list_begin (& channel -> incomingUnreliableCommands)) - return; - - enet_list_move (enet_list_end (& peer -> dispatchedCommands), enet_list_begin (& channel -> incomingUnreliableCommands), enet_list_previous (currentCommand)); - - if (! peer -> needsDispatch) + if (startCommand != currentCommand) { - enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList); + enet_list_move (enet_list_end (& peer -> dispatchedCommands), startCommand, enet_list_previous (currentCommand)); - peer -> needsDispatch = 1; + if (! peer -> needsDispatch) + { + enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList); + + peer -> needsDispatch = 1; + } + + droppedCommand = startCommand = enet_list_next (currentCommand); } + + enet_peer_remove_incoming_commands (& channel -> incomingUnreliableCommands, enet_list_begin (& channel -> incomingUnreliableCommands), droppedCommand); } void @@ -640,6 +698,8 @@ enet_peer_dispatch_incoming_reliable_commands (ENetPeer * peer, ENetChannel * ch if (currentCommand == enet_list_begin (& channel -> incomingReliableCommands)) return; + channel -> incomingUnreliableSequenceNumber = 0; + enet_list_move (enet_list_end (& peer -> dispatchedCommands), enet_list_begin (& channel -> incomingReliableCommands), enet_list_previous (currentCommand)); if (! peer -> needsDispatch) @@ -684,7 +744,7 @@ enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command, case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT: case ENET_PROTOCOL_COMMAND_SEND_RELIABLE: if (reliableSequenceNumber == channel -> incomingReliableSequenceNumber) - goto freePacket; + goto freePacket; for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands)); currentCommand != enet_list_end (& channel -> incomingReliableCommands); @@ -712,15 +772,20 @@ enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command, break; case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE: + case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT: unreliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> sendUnreliable.unreliableSequenceNumber); + if (reliableSequenceNumber == channel -> incomingReliableSequenceNumber && + unreliableSequenceNumber <= channel -> incomingUnreliableSequenceNumber) + goto freePacket; + for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingUnreliableCommands)); currentCommand != enet_list_end (& channel -> incomingUnreliableCommands); currentCommand = enet_list_previous (currentCommand)) { incomingCommand = (ENetIncomingCommand *) currentCommand; - if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE) + if ((command -> header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED) continue; if (reliableSequenceNumber >= channel -> incomingReliableSequenceNumber) diff --git a/polymer/eduke32/source/enet/src/protocol.c b/polymer/eduke32/source/enet/src/protocol.c index 39d95bc52..6904a62e7 100644 --- a/polymer/eduke32/source/enet/src/protocol.c +++ b/polymer/eduke32/source/enet/src/protocol.c @@ -9,10 +9,6 @@ #include "enet/time.h" #include "enet/enet.h" -#ifndef UNREFERENCED_PARAMETER -# define UNREFERENCED_PARAMETER(x) x=x -#endif - static size_t commandSizes [ENET_PROTOCOL_COMMAND_COUNT] = { 0, @@ -27,6 +23,7 @@ static size_t commandSizes [ENET_PROTOCOL_COMMAND_COUNT] = sizeof (ENetProtocolSendUnsequenced), sizeof (ENetProtocolBandwidthLimit), sizeof (ENetProtocolThrottleConfigure), + sizeof (ENetProtocolSendFragment) }; size_t @@ -87,7 +84,7 @@ enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event) return 1; default: - break; + return 0; } } @@ -262,7 +259,7 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet ENetProtocol verifyCommand; UNREFERENCED_PARAMETER(header); - + channelCount = ENET_NET_TO_HOST_32 (command -> connect.channelCount); if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT || @@ -327,6 +324,7 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet channel -> outgoingReliableSequenceNumber = 0; channel -> outgoingUnreliableSequenceNumber = 0; channel -> incomingReliableSequenceNumber = 0; + channel -> incomingUnreliableSequenceNumber = 0; enet_list_clear (& channel -> incomingReliableCommands); enet_list_clear (& channel -> incomingUnreliableCommands); @@ -581,12 +579,6 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet return -1; hostCommand.header.reliableSequenceNumber = startSequenceNumber; - hostCommand.sendFragment.startSequenceNumber = startSequenceNumber; - hostCommand.sendFragment.dataLength = fragmentLength; - hostCommand.sendFragment.fragmentNumber = fragmentNumber; - hostCommand.sendFragment.fragmentCount = fragmentCount; - hostCommand.sendFragment.fragmentOffset = fragmentOffset; - hostCommand.sendFragment.totalLength = totalLength; startCommand = enet_peer_queue_incoming_command (peer, & hostCommand, packet, fragmentCount); if (startCommand == NULL) @@ -613,19 +605,139 @@ enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENet return 0; } +static int +enet_protocol_handle_send_unreliable_fragment (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData) +{ + enet_uint32 fragmentNumber, + fragmentCount, + fragmentOffset, + fragmentLength, + reliableSequenceNumber, + startSequenceNumber, + totalLength; + enet_uint16 reliableWindow, currentWindow; + ENetChannel * channel; + ENetListIterator currentCommand; + ENetIncomingCommand * startCommand = NULL; + + if (command -> header.channelID >= peer -> channelCount || + (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)) + return -1; + + fragmentLength = ENET_NET_TO_HOST_16 (command -> sendFragment.dataLength); + * currentData += fragmentLength; + if (* currentData > & host -> receivedData [host -> receivedDataLength]) + return -1; + + channel = & peer -> channels [command -> header.channelID]; + reliableSequenceNumber = command -> header.reliableSequenceNumber; + startSequenceNumber = ENET_NET_TO_HOST_16 (command -> sendFragment.startSequenceNumber); + + reliableWindow = reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; + currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; + + if (reliableSequenceNumber < channel -> incomingReliableSequenceNumber) + reliableWindow += ENET_PEER_RELIABLE_WINDOWS; + + if (reliableWindow < currentWindow || reliableWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1) + return 0; + + if (reliableSequenceNumber == channel -> incomingReliableSequenceNumber && + startSequenceNumber <= channel -> incomingUnreliableSequenceNumber) + return 0; + + fragmentNumber = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentNumber); + fragmentCount = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentCount); + fragmentOffset = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentOffset); + totalLength = ENET_NET_TO_HOST_32 (command -> sendFragment.totalLength); + + if (fragmentOffset >= totalLength || + fragmentOffset + fragmentLength > totalLength || + fragmentNumber >= fragmentCount) + return -1; + + for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingUnreliableCommands)); + currentCommand != enet_list_end (& channel -> incomingUnreliableCommands); + currentCommand = enet_list_previous (currentCommand)) + { + ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand; + + if (reliableSequenceNumber >= channel -> incomingReliableSequenceNumber) + { + if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber) + continue; + } + else + if (incomingCommand -> reliableSequenceNumber >= channel -> incomingReliableSequenceNumber) + break; + + if (incomingCommand -> reliableSequenceNumber < reliableSequenceNumber) + break; + + if (incomingCommand -> reliableSequenceNumber > reliableSequenceNumber) + continue; + + if (incomingCommand -> unreliableSequenceNumber <= startSequenceNumber) + { + if (incomingCommand -> unreliableSequenceNumber < startSequenceNumber) + break; + + if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT || + totalLength != incomingCommand -> packet -> dataLength || + fragmentCount != incomingCommand -> fragmentCount) + return -1; + + startCommand = incomingCommand; + break; + } + } + + if (startCommand == NULL) + { + ENetPacket * packet = enet_packet_create (NULL, totalLength, ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT); + if (packet == NULL) + return -1; + + startCommand = enet_peer_queue_incoming_command (peer, command, packet, fragmentCount); + if (startCommand == NULL) + return -1; + } + + if ((startCommand -> fragments [fragmentNumber / 32] & (1 << (fragmentNumber % 32))) == 0) + { + -- startCommand -> fragmentsRemaining; + + startCommand -> fragments [fragmentNumber / 32] |= (1 << (fragmentNumber % 32)); + + if (fragmentOffset + fragmentLength > startCommand -> packet -> dataLength) + fragmentLength = startCommand -> packet -> dataLength - fragmentOffset; + + memcpy (startCommand -> packet -> data + fragmentOffset, + (enet_uint8 *) command + sizeof (ENetProtocolSendFragment), + fragmentLength); + + if (startCommand -> fragmentsRemaining <= 0) + enet_peer_dispatch_incoming_unreliable_commands (peer, channel); + } + + return 0; +} + static int enet_protocol_handle_ping (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) { - UNREFERENCED_PARAMETER(host); - UNREFERENCED_PARAMETER(peer); - UNREFERENCED_PARAMETER(command); - + UNREFERENCED_PARAMETER(host); + UNREFERENCED_PARAMETER(peer); + UNREFERENCED_PARAMETER(command); + return 0; } static int enet_protocol_handle_bandwidth_limit (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) { + UNREFERENCED_PARAMETER(host); + peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> bandwidthLimit.incomingBandwidth); peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> bandwidthLimit.outgoingBandwidth); @@ -648,7 +760,7 @@ static int enet_protocol_handle_throttle_configure (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) { UNREFERENCED_PARAMETER(host); - + peer -> packetThrottleInterval = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleInterval); peer -> packetThrottleAcceleration = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleAcceleration); peer -> packetThrottleDeceleration = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleDeceleration); @@ -762,9 +874,8 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer * enet_list_empty (& peer -> outgoingUnreliableCommands) && enet_list_empty (& peer -> sentReliableCommands)) enet_peer_disconnect (peer, peer -> eventData); - break; default: - break; + break; } return 0; @@ -868,7 +979,8 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event) if (peer -> state == ENET_PEER_STATE_DISCONNECTED || peer -> state == ENET_PEER_STATE_ZOMBIE || - (host -> receivedAddress.host != peer -> address.host && + ((host -> receivedAddress.host != peer -> address.host || + host -> receivedAddress.port != peer -> address.port) && peer -> address.host != ENET_HOST_BROADCAST) || (peer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID && sessionID != peer -> incomingSessionID)) @@ -1001,6 +1113,11 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event) goto commandError; break; + case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT: + if (enet_protocol_handle_send_unreliable_fragment (host, peer, command, & currentData)) + goto commandError; + break; + default: goto commandError; } @@ -1154,7 +1271,7 @@ enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * pee buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] || peer -> mtu - host -> packetSize < commandSize || (outgoingCommand -> packet != NULL && - peer -> mtu - host -> packetSize < commandSize + outgoingCommand -> packet -> dataLength)) + peer -> mtu - host -> packetSize < commandSize + outgoingCommand -> fragmentLength)) { host -> continueSending = 1; @@ -1163,20 +1280,35 @@ enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * pee currentCommand = enet_list_next (currentCommand); - if (outgoingCommand -> packet != NULL) + if (outgoingCommand -> packet != NULL && outgoingCommand -> fragmentOffset == 0) { peer -> packetThrottleCounter += ENET_PEER_PACKET_THROTTLE_COUNTER; peer -> packetThrottleCounter %= ENET_PEER_PACKET_THROTTLE_SCALE; if (peer -> packetThrottleCounter > peer -> packetThrottle) { - -- outgoingCommand -> packet -> referenceCount; + enet_uint16 reliableSequenceNumber = outgoingCommand -> reliableSequenceNumber, + unreliableSequenceNumber = outgoingCommand -> unreliableSequenceNumber; + for (;;) + { + -- outgoingCommand -> packet -> referenceCount; - if (outgoingCommand -> packet -> referenceCount == 0) - enet_packet_destroy (outgoingCommand -> packet); + if (outgoingCommand -> packet -> referenceCount == 0) + enet_packet_destroy (outgoingCommand -> packet); - enet_list_remove (& outgoingCommand -> outgoingCommandList); - enet_free (outgoingCommand); + enet_list_remove (& outgoingCommand -> outgoingCommandList); + enet_free (outgoingCommand); + + if (currentCommand == enet_list_end (& peer -> outgoingUnreliableCommands)) + break; + + outgoingCommand = (ENetOutgoingCommand *) currentCommand; + if (outgoingCommand -> reliableSequenceNumber != reliableSequenceNumber || + outgoingCommand -> unreliableSequenceNumber != unreliableSequenceNumber) + break; + + currentCommand = enet_list_next (currentCommand); + } continue; } @@ -1195,8 +1327,8 @@ enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * pee { ++ buffer; - buffer -> data = outgoingCommand -> packet -> data; - buffer -> dataLength = outgoingCommand -> packet -> dataLength; + buffer -> data = outgoingCommand -> packet -> data + outgoingCommand -> fragmentOffset; + buffer -> dataLength = outgoingCommand -> fragmentLength; host -> packetSize += buffer -> dataLength;