diff options
-rw-r--r-- | host.c | 3 | ||||
-rw-r--r-- | include/enet/enet.h | 7 | ||||
-rw-r--r-- | peer.c | 4 | ||||
-rw-r--r-- | protocol.c | 40 |
4 files changed, 46 insertions, 8 deletions
@@ -169,6 +169,9 @@ enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelC enet_list_clear (& channel -> incomingReliableCommands); enet_list_clear (& channel -> incomingUnreliableCommands); + + channel -> currentReliableWindow = 0; + memset (channel -> reliableWindows, 0, sizeof (channel -> reliableWindows)); } command.header.command = ENET_PROTOCOL_COMMAND_CONNECT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; diff --git a/include/enet/enet.h b/include/enet/enet.h index 2ba8340..04e3011 100644 --- a/include/enet/enet.h +++ b/include/enet/enet.h @@ -143,6 +143,7 @@ typedef struct _ENetOutgoingCommand enet_uint32 roundTripTimeoutLimit; enet_uint32 fragmentOffset; enet_uint16 fragmentLength; + enet_uint16 sendAttempts; ENetProtocol command; ENetPacket * packet; } ENetOutgoingCommand; @@ -198,7 +199,9 @@ enum ENET_PEER_TIMEOUT_MINIMUM = 5000, ENET_PEER_TIMEOUT_MAXIMUM = 30000, ENET_PEER_PING_INTERVAL = 500, - ENET_PEER_UNSEQUENCED_WINDOW_SIZE = 4 * 32 + ENET_PEER_UNSEQUENCED_WINDOW_SIZE = 4 * 32, + ENET_PEER_RELIABLE_WINDOWS = 16, + ENET_PEER_RELIABLE_WINDOW_SIZE = 0x1000 }; typedef struct _ENetChannel @@ -209,6 +212,8 @@ typedef struct _ENetChannel enet_uint16 incomingUnreliableSequenceNumber; ENetList incomingReliableCommands; ENetList incomingUnreliableCommands; + enet_uint16 currentReliableWindow; + enet_uint16 reliableWindows [ENET_PEER_RELIABLE_WINDOWS]; } ENetChannel; /** @@ -145,6 +145,9 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet) command.header.channelID = channelID; + if (! (packet -> flags & (ENET_PACKET_FLAG_RELIABLE | ENET_PACKET_FLAG_UNSEQUENCED)) && channel -> outgoingUnreliableSequenceNumber >= 0xFFFF) + packet -> flags |= ENET_PACKET_FLAG_RELIABLE; + if (packet -> flags & ENET_PACKET_FLAG_RELIABLE) { command.header.command = ENET_PROTOCOL_COMMAND_SEND_RELIABLE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; @@ -525,6 +528,7 @@ enet_peer_queue_outgoing_command (ENetPeer * peer, const ENetProtocol * command, outgoingCommand -> unreliableSequenceNumber = channel -> outgoingUnreliableSequenceNumber; } + outgoingCommand -> sendAttempts = 0; outgoingCommand -> sentTime = 0; outgoingCommand -> roundTripTimeout = 0; outgoingCommand -> roundTripTimeoutLimit = 0; @@ -163,6 +163,8 @@ enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint16 reliabl ENetOutgoingCommand * outgoingCommand; ENetListIterator currentCommand; ENetProtocolCommand commandNumber; + ENetChannel * channel; + enet_uint16 reliableWindow; for (currentCommand = enet_list_begin (& peer -> sentReliableCommands); currentCommand != enet_list_end (& peer -> sentReliableCommands); @@ -178,8 +180,13 @@ enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint16 reliabl if (currentCommand == enet_list_end (& peer -> sentReliableCommands)) return ENET_PROTOCOL_COMMAND_NONE; - commandNumber = outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK; + reliableWindow = reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; + channel = & peer -> channels [channelID]; + if (channel -> reliableWindows [reliableWindow] > 0) + -- channel -> reliableWindows [reliableWindow]; + commandNumber = outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK; + enet_list_remove (& outgoingCommand -> outgoingCommandList); if (outgoingCommand -> packet != NULL) @@ -284,6 +291,9 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet enet_list_clear (& channel -> incomingReliableCommands); enet_list_clear (& channel -> incomingUnreliableCommands); + + channel -> currentReliableWindow = 0; + memset (channel -> reliableWindows, 0, sizeof (channel -> reliableWindows)); } mtu = ENET_NET_TO_HOST_16 (command -> connect.mtu); @@ -1146,16 +1156,24 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer) ENetBuffer * buffer = & host -> buffers [host -> bufferCount]; ENetOutgoingCommand * outgoingCommand; ENetListIterator currentCommand; + ENetChannel *channel; + enet_uint16 reliableWindow; + size_t commandSize; currentCommand = enet_list_begin (& peer -> outgoingReliableCommands); while (currentCommand != enet_list_end (& peer -> outgoingReliableCommands)) { - size_t commandSize; - outgoingCommand = (ENetOutgoingCommand *) currentCommand; + + channel = outgoingCommand -> command.header.channelID < peer -> channelCount ? & peer -> channels [outgoingCommand -> command.header.channelID] : NULL; + reliableWindow = outgoingCommand -> reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; + if (channel != NULL && outgoingCommand -> sendAttempts < 1 && + channel -> currentReliableWindow != reliableWindow && + channel -> reliableWindows [reliableWindow] > 0) + break; + commandSize = commandSizes [outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK]; - if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] || buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] || peer -> mtu - host -> packetSize < commandSize) @@ -1165,8 +1183,6 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer) break; } - currentCommand = enet_list_next (currentCommand); - if (outgoingCommand -> packet != NULL) { if (peer -> reliableDataInTransit + outgoingCommand -> fragmentLength > peer -> windowSize) @@ -1179,7 +1195,17 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer) break; } } - + + currentCommand = enet_list_next (currentCommand); + + if (channel != NULL && outgoingCommand -> sendAttempts < 1) + { + if (channel -> currentReliableWindow != reliableWindow) channel -> currentReliableWindow = reliableWindow; + ++ channel -> reliableWindows [reliableWindow]; + } + + ++ outgoingCommand -> sendAttempts; + if (outgoingCommand -> roundTripTimeout == 0) { outgoingCommand -> roundTripTimeout = peer -> roundTripTime + 4 * peer -> roundTripTimeVariance; |