support for ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT
1.3.2 release prep
This commit is contained in:
+133
@@ -23,6 +23,7 @@ static size_t commandSizes [ENET_PROTOCOL_COMMAND_COUNT] =
|
||||
sizeof (ENetProtocolSendUnsequenced),
|
||||
sizeof (ENetProtocolBandwidthLimit),
|
||||
sizeof (ENetProtocolThrottleConfigure),
|
||||
sizeof (ENetProtocolSendFragment)
|
||||
};
|
||||
|
||||
size_t
|
||||
@@ -319,6 +320,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);
|
||||
@@ -605,6 +607,132 @@ 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)
|
||||
{
|
||||
ENetProtocol hostCommand = * command;
|
||||
ENetPacket * packet = enet_packet_create (NULL, totalLength, ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT);
|
||||
if (packet == NULL)
|
||||
return -1;
|
||||
|
||||
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)
|
||||
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)
|
||||
{
|
||||
@@ -986,6 +1114,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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user