| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  | /** 
 | 
					
						
							|  |  |  |  @file  protocol.c | 
					
						
							|  |  |  |  @brief ENet protocol functions | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | #define ENET_BUILDING_LIB 1
 | 
					
						
							|  |  |  | #include "enet/utility.h"
 | 
					
						
							|  |  |  | #include "enet/time.h"
 | 
					
						
							|  |  |  | #include "enet/enet.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  | static const size_t commandSizes [ENET_PROTOCOL_COMMAND_COUNT] = | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  | { | 
					
						
							|  |  |  |     0, | 
					
						
							|  |  |  |     sizeof (ENetProtocolAcknowledge), | 
					
						
							|  |  |  |     sizeof (ENetProtocolConnect), | 
					
						
							|  |  |  |     sizeof (ENetProtocolVerifyConnect), | 
					
						
							|  |  |  |     sizeof (ENetProtocolDisconnect), | 
					
						
							|  |  |  |     sizeof (ENetProtocolPing), | 
					
						
							|  |  |  |     sizeof (ENetProtocolSendReliable), | 
					
						
							|  |  |  |     sizeof (ENetProtocolSendUnreliable), | 
					
						
							|  |  |  |     sizeof (ENetProtocolSendFragment), | 
					
						
							|  |  |  |     sizeof (ENetProtocolSendUnsequenced), | 
					
						
							|  |  |  |     sizeof (ENetProtocolBandwidthLimit), | 
					
						
							|  |  |  |     sizeof (ENetProtocolThrottleConfigure), | 
					
						
							|  |  |  |     sizeof (ENetProtocolSendFragment) | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | size_t | 
					
						
							|  |  |  | enet_protocol_command_size (enet_uint8 commandNumber) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return commandSizes [commandNumber & ENET_PROTOCOL_COMMAND_MASK]; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | enet_protocol_change_state (ENetHost * host, ENetPeer * peer, ENetPeerState state) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (state == ENET_PEER_STATE_CONNECTED || state == ENET_PEER_STATE_DISCONNECT_LATER) | 
					
						
							|  |  |  |       enet_peer_on_connect (peer); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       enet_peer_on_disconnect (peer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     peer -> state = state; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | enet_protocol_dispatch_state (ENetHost * host, ENetPeer * peer, ENetPeerState state) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     enet_protocol_change_state (host, peer, state); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-21 12:26:42 +02:00
										 |  |  |     if (! (peer -> flags & ENET_PEER_FLAG_NEEDS_DISPATCH)) | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |     { | 
					
						
							|  |  |  |        enet_list_insert (enet_list_end (& host -> dispatchQueue), & peer -> dispatchList); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-21 12:26:42 +02:00
										 |  |  |        peer -> flags |= ENET_PEER_FLAG_NEEDS_DISPATCH; | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     while (! enet_list_empty (& host -> dispatchQueue)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |        ENetPeer * peer = (ENetPeer *) enet_list_remove (enet_list_begin (& host -> dispatchQueue)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-21 12:26:42 +02:00
										 |  |  |        peer -> flags &= ~ ENET_PEER_FLAG_NEEDS_DISPATCH; | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  |        switch (peer -> state) | 
					
						
							|  |  |  |        { | 
					
						
							|  |  |  |        case ENET_PEER_STATE_CONNECTION_PENDING: | 
					
						
							|  |  |  |        case ENET_PEER_STATE_CONNECTION_SUCCEEDED: | 
					
						
							|  |  |  |            enet_protocol_change_state (host, peer, ENET_PEER_STATE_CONNECTED); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            event -> type = ENET_EVENT_TYPE_CONNECT; | 
					
						
							|  |  |  |            event -> peer = peer; | 
					
						
							|  |  |  |            event -> data = peer -> eventData; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            return 1; | 
					
						
							|  |  |  |             | 
					
						
							|  |  |  |        case ENET_PEER_STATE_ZOMBIE: | 
					
						
							|  |  |  |            host -> recalculateBandwidthLimits = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            event -> type = ENET_EVENT_TYPE_DISCONNECT; | 
					
						
							|  |  |  |            event -> peer = peer; | 
					
						
							|  |  |  |            event -> data = peer -> eventData; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            enet_peer_reset (peer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            return 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        case ENET_PEER_STATE_CONNECTED: | 
					
						
							|  |  |  |            if (enet_list_empty (& peer -> dispatchedCommands)) | 
					
						
							|  |  |  |              continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            event -> packet = enet_peer_receive (peer, & event -> channelID); | 
					
						
							|  |  |  |            if (event -> packet == NULL) | 
					
						
							|  |  |  |              continue; | 
					
						
							|  |  |  |               | 
					
						
							|  |  |  |            event -> type = ENET_EVENT_TYPE_RECEIVE; | 
					
						
							|  |  |  |            event -> peer = peer; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            if (! enet_list_empty (& peer -> dispatchedCommands)) | 
					
						
							|  |  |  |            { | 
					
						
							| 
									
										
										
										
											2020-04-21 12:26:42 +02:00
										 |  |  |               peer -> flags |= ENET_PEER_FLAG_NEEDS_DISPATCH; | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |           | 
					
						
							|  |  |  |               enet_list_insert (enet_list_end (& host -> dispatchQueue), & peer -> dispatchList); | 
					
						
							|  |  |  |            } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            return 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        default: | 
					
						
							|  |  |  |            break; | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | enet_protocol_notify_connect (ENetHost * host, ENetPeer * peer, ENetEvent * event) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     host -> recalculateBandwidthLimits = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (event != NULL) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         enet_protocol_change_state (host, peer, ENET_PEER_STATE_CONNECTED); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         event -> type = ENET_EVENT_TYPE_CONNECT; | 
					
						
							|  |  |  |         event -> peer = peer; | 
					
						
							|  |  |  |         event -> data = peer -> eventData; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else  | 
					
						
							|  |  |  |         enet_protocol_dispatch_state (host, peer, peer -> state == ENET_PEER_STATE_CONNECTING ? ENET_PEER_STATE_CONNECTION_SUCCEEDED : ENET_PEER_STATE_CONNECTION_PENDING); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | enet_protocol_notify_disconnect (ENetHost * host, ENetPeer * peer, ENetEvent * event) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (peer -> state >= ENET_PEER_STATE_CONNECTION_PENDING) | 
					
						
							|  |  |  |        host -> recalculateBandwidthLimits = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (peer -> state != ENET_PEER_STATE_CONNECTING && peer -> state < ENET_PEER_STATE_CONNECTION_SUCCEEDED) | 
					
						
							|  |  |  |         enet_peer_reset (peer); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     if (event != NULL) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         event -> type = ENET_EVENT_TYPE_DISCONNECT; | 
					
						
							|  |  |  |         event -> peer = peer; | 
					
						
							|  |  |  |         event -> data = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         enet_peer_reset (peer); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else  | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         peer -> eventData = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  | enet_protocol_remove_sent_unreliable_commands (ENetPeer * peer, ENetList * sentUnreliableCommands) | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  | { | 
					
						
							|  |  |  |     ENetOutgoingCommand * outgoingCommand; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |     if (enet_list_empty (sentUnreliableCommands)) | 
					
						
							| 
									
										
										
										
											2020-01-05 19:19:56 +01:00
										 |  |  |       return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     do | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |         outgoingCommand = (ENetOutgoingCommand *) enet_list_front (sentUnreliableCommands); | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |          | 
					
						
							|  |  |  |         enet_list_remove (& outgoingCommand -> outgoingCommandList); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (outgoingCommand -> packet != NULL) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |            -- outgoingCommand -> packet -> referenceCount; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            if (outgoingCommand -> packet -> referenceCount == 0) | 
					
						
							|  |  |  |            { | 
					
						
							|  |  |  |               outgoingCommand -> packet -> flags |= ENET_PACKET_FLAG_SENT; | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  |               enet_packet_destroy (outgoingCommand -> packet); | 
					
						
							|  |  |  |            } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         enet_free (outgoingCommand); | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |     } while (! enet_list_empty (sentUnreliableCommands)); | 
					
						
							| 
									
										
										
										
											2020-01-05 19:19:56 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER && | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |         ! enet_peer_has_outgoing_commands (peer)) | 
					
						
							| 
									
										
										
										
											2020-01-05 19:19:56 +01:00
										 |  |  |       enet_peer_disconnect (peer, peer -> eventData); | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  | static ENetOutgoingCommand * | 
					
						
							|  |  |  | enet_protocol_find_sent_reliable_command (ENetList * list, enet_uint16 reliableSequenceNumber, enet_uint8 channelID) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     ENetListIterator currentCommand; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (currentCommand = enet_list_begin (list); | 
					
						
							|  |  |  |          currentCommand != enet_list_end (list); | 
					
						
							|  |  |  |          currentCommand = enet_list_next (currentCommand)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |        ENetOutgoingCommand * outgoingCommand = (ENetOutgoingCommand *) currentCommand; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        if (! (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)) | 
					
						
							|  |  |  |          continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        if (outgoingCommand -> sendAttempts < 1) | 
					
						
							|  |  |  |          break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        if (outgoingCommand -> reliableSequenceNumber == reliableSequenceNumber && | 
					
						
							|  |  |  |            outgoingCommand -> command.header.channelID == channelID) | 
					
						
							|  |  |  |          return outgoingCommand; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  | static ENetProtocolCommand | 
					
						
							|  |  |  | enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint16 reliableSequenceNumber, enet_uint8 channelID) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     ENetOutgoingCommand * outgoingCommand = NULL; | 
					
						
							|  |  |  |     ENetListIterator currentCommand; | 
					
						
							|  |  |  |     ENetProtocolCommand commandNumber; | 
					
						
							|  |  |  |     int wasSent = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (currentCommand = enet_list_begin (& peer -> sentReliableCommands); | 
					
						
							|  |  |  |          currentCommand != enet_list_end (& peer -> sentReliableCommands); | 
					
						
							|  |  |  |          currentCommand = enet_list_next (currentCommand)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |        outgoingCommand = (ENetOutgoingCommand *) currentCommand; | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |        if (outgoingCommand -> reliableSequenceNumber == reliableSequenceNumber && | 
					
						
							|  |  |  |            outgoingCommand -> command.header.channelID == channelID) | 
					
						
							|  |  |  |          break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (currentCommand == enet_list_end (& peer -> sentReliableCommands)) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |        outgoingCommand = enet_protocol_find_sent_reliable_command (& peer -> outgoingCommands, reliableSequenceNumber, channelID); | 
					
						
							|  |  |  |        if (outgoingCommand == NULL) | 
					
						
							|  |  |  |          outgoingCommand = enet_protocol_find_sent_reliable_command (& peer -> outgoingSendReliableCommands, reliableSequenceNumber, channelID); | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  |        wasSent = 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (outgoingCommand == NULL) | 
					
						
							|  |  |  |       return ENET_PROTOCOL_COMMAND_NONE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (channelID < peer -> channelCount) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |        ENetChannel * channel = & peer -> channels [channelID]; | 
					
						
							|  |  |  |        enet_uint16 reliableWindow = reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; | 
					
						
							|  |  |  |        if (channel -> reliableWindows [reliableWindow] > 0) | 
					
						
							|  |  |  |        { | 
					
						
							|  |  |  |           -- channel -> reliableWindows [reliableWindow]; | 
					
						
							|  |  |  |           if (! channel -> reliableWindows [reliableWindow]) | 
					
						
							|  |  |  |             channel -> usedReliableWindows &= ~ (1 << reliableWindow); | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     commandNumber = (ENetProtocolCommand) (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK); | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     enet_list_remove (& outgoingCommand -> outgoingCommandList); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (outgoingCommand -> packet != NULL) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |        if (wasSent) | 
					
						
							|  |  |  |          peer -> reliableDataInTransit -= outgoingCommand -> fragmentLength; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        -- outgoingCommand -> packet -> referenceCount; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        if (outgoingCommand -> packet -> referenceCount == 0) | 
					
						
							|  |  |  |        { | 
					
						
							|  |  |  |           outgoingCommand -> packet -> flags |= ENET_PACKET_FLAG_SENT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           enet_packet_destroy (outgoingCommand -> packet); | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     enet_free (outgoingCommand); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (enet_list_empty (& peer -> sentReliableCommands)) | 
					
						
							|  |  |  |       return commandNumber; | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     outgoingCommand = (ENetOutgoingCommand *) enet_list_front (& peer -> sentReliableCommands); | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     peer -> nextTimeout = outgoingCommand -> sentTime + outgoingCommand -> roundTripTimeout; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return commandNumber; | 
					
						
							|  |  |  | }  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static ENetPeer * | 
					
						
							|  |  |  | enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENetProtocol * command) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     enet_uint8 incomingSessionID, outgoingSessionID; | 
					
						
							|  |  |  |     enet_uint32 mtu, windowSize; | 
					
						
							|  |  |  |     ENetChannel * channel; | 
					
						
							|  |  |  |     size_t channelCount, duplicatePeers = 0; | 
					
						
							|  |  |  |     ENetPeer * currentPeer, * peer = NULL; | 
					
						
							|  |  |  |     ENetProtocol verifyCommand; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     channelCount = ENET_NET_TO_HOST_32 (command -> connect.channelCount); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT || | 
					
						
							|  |  |  |         channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT) | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (currentPeer = host -> peers; | 
					
						
							|  |  |  |          currentPeer < & host -> peers [host -> peerCount]; | 
					
						
							|  |  |  |          ++ currentPeer) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if (peer == NULL) | 
					
						
							|  |  |  |               peer = currentPeer; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else  | 
					
						
							|  |  |  |         if (currentPeer -> state != ENET_PEER_STATE_CONNECTING && | 
					
						
							| 
									
										
										
										
											2017-01-22 05:53:08 +01:00
										 |  |  |             enet_host_equal(currentPeer -> address.host, host -> receivedAddress.host)) | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |         { | 
					
						
							|  |  |  |             if (currentPeer -> address.port == host -> receivedAddress.port && | 
					
						
							|  |  |  |                 currentPeer -> connectID == command -> connect.connectID) | 
					
						
							|  |  |  |               return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             ++ duplicatePeers; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (peer == NULL || duplicatePeers >= host -> duplicatePeers) | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (channelCount > host -> channelLimit) | 
					
						
							|  |  |  |       channelCount = host -> channelLimit; | 
					
						
							|  |  |  |     peer -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel)); | 
					
						
							|  |  |  |     if (peer -> channels == NULL) | 
					
						
							|  |  |  |       return NULL; | 
					
						
							|  |  |  |     peer -> channelCount = channelCount; | 
					
						
							|  |  |  |     peer -> state = ENET_PEER_STATE_ACKNOWLEDGING_CONNECT; | 
					
						
							|  |  |  |     peer -> connectID = command -> connect.connectID; | 
					
						
							|  |  |  |     peer -> address = host -> receivedAddress; | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |     peer -> mtu = host -> mtu; | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |     peer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> connect.outgoingPeerID); | 
					
						
							|  |  |  |     peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.incomingBandwidth); | 
					
						
							|  |  |  |     peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.outgoingBandwidth); | 
					
						
							|  |  |  |     peer -> packetThrottleInterval = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleInterval); | 
					
						
							|  |  |  |     peer -> packetThrottleAcceleration = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleAcceleration); | 
					
						
							|  |  |  |     peer -> packetThrottleDeceleration = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleDeceleration); | 
					
						
							|  |  |  |     peer -> eventData = ENET_NET_TO_HOST_32 (command -> connect.data); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     incomingSessionID = command -> connect.incomingSessionID == 0xFF ? peer -> outgoingSessionID : command -> connect.incomingSessionID; | 
					
						
							|  |  |  |     incomingSessionID = (incomingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT); | 
					
						
							|  |  |  |     if (incomingSessionID == peer -> outgoingSessionID) | 
					
						
							|  |  |  |       incomingSessionID = (incomingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT); | 
					
						
							|  |  |  |     peer -> outgoingSessionID = incomingSessionID; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     outgoingSessionID = command -> connect.outgoingSessionID == 0xFF ? peer -> incomingSessionID : command -> connect.outgoingSessionID; | 
					
						
							|  |  |  |     outgoingSessionID = (outgoingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT); | 
					
						
							|  |  |  |     if (outgoingSessionID == peer -> incomingSessionID) | 
					
						
							|  |  |  |       outgoingSessionID = (outgoingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT); | 
					
						
							|  |  |  |     peer -> incomingSessionID = outgoingSessionID; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (channel = peer -> channels; | 
					
						
							|  |  |  |          channel < & peer -> channels [channelCount]; | 
					
						
							|  |  |  |          ++ channel) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         channel -> outgoingReliableSequenceNumber = 0; | 
					
						
							|  |  |  |         channel -> outgoingUnreliableSequenceNumber = 0; | 
					
						
							|  |  |  |         channel -> incomingReliableSequenceNumber = 0; | 
					
						
							|  |  |  |         channel -> incomingUnreliableSequenceNumber = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         enet_list_clear (& channel -> incomingReliableCommands); | 
					
						
							|  |  |  |         enet_list_clear (& channel -> incomingUnreliableCommands); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         channel -> usedReliableWindows = 0; | 
					
						
							|  |  |  |         memset (channel -> reliableWindows, 0, sizeof (channel -> reliableWindows)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     mtu = ENET_NET_TO_HOST_32 (command -> connect.mtu); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (mtu < ENET_PROTOCOL_MINIMUM_MTU) | 
					
						
							|  |  |  |       mtu = ENET_PROTOCOL_MINIMUM_MTU; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     if (mtu > ENET_PROTOCOL_MAXIMUM_MTU) | 
					
						
							|  |  |  |       mtu = ENET_PROTOCOL_MAXIMUM_MTU; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |     if (mtu < peer -> mtu) | 
					
						
							|  |  |  |       peer -> mtu = mtu; | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if (host -> outgoingBandwidth == 0 && | 
					
						
							|  |  |  |         peer -> incomingBandwidth == 0) | 
					
						
							|  |  |  |       peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     if (host -> outgoingBandwidth == 0 || | 
					
						
							|  |  |  |         peer -> incomingBandwidth == 0) | 
					
						
							|  |  |  |       peer -> windowSize = (ENET_MAX (host -> outgoingBandwidth, peer -> incomingBandwidth) / | 
					
						
							|  |  |  |                                     ENET_PEER_WINDOW_SIZE_SCALE) * | 
					
						
							|  |  |  |                                       ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       peer -> windowSize = (ENET_MIN (host -> outgoingBandwidth, peer -> incomingBandwidth) / | 
					
						
							|  |  |  |                                     ENET_PEER_WINDOW_SIZE_SCALE) *  | 
					
						
							|  |  |  |                                       ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (peer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) | 
					
						
							|  |  |  |       peer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     if (peer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) | 
					
						
							|  |  |  |       peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (host -> incomingBandwidth == 0) | 
					
						
							|  |  |  |       windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       windowSize = (host -> incomingBandwidth / ENET_PEER_WINDOW_SIZE_SCALE) * | 
					
						
							|  |  |  |                      ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (windowSize > ENET_NET_TO_HOST_32 (command -> connect.windowSize)) | 
					
						
							|  |  |  |       windowSize = ENET_NET_TO_HOST_32 (command -> connect.windowSize); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) | 
					
						
							|  |  |  |       windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     if (windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) | 
					
						
							|  |  |  |       windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     verifyCommand.header.command = ENET_PROTOCOL_COMMAND_VERIFY_CONNECT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; | 
					
						
							|  |  |  |     verifyCommand.header.channelID = 0xFF; | 
					
						
							|  |  |  |     verifyCommand.verifyConnect.outgoingPeerID = ENET_HOST_TO_NET_16 (peer -> incomingPeerID); | 
					
						
							|  |  |  |     verifyCommand.verifyConnect.incomingSessionID = incomingSessionID; | 
					
						
							|  |  |  |     verifyCommand.verifyConnect.outgoingSessionID = outgoingSessionID; | 
					
						
							|  |  |  |     verifyCommand.verifyConnect.mtu = ENET_HOST_TO_NET_32 (peer -> mtu); | 
					
						
							|  |  |  |     verifyCommand.verifyConnect.windowSize = ENET_HOST_TO_NET_32 (windowSize); | 
					
						
							|  |  |  |     verifyCommand.verifyConnect.channelCount = ENET_HOST_TO_NET_32 (channelCount); | 
					
						
							|  |  |  |     verifyCommand.verifyConnect.incomingBandwidth = ENET_HOST_TO_NET_32 (host -> incomingBandwidth); | 
					
						
							|  |  |  |     verifyCommand.verifyConnect.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth); | 
					
						
							|  |  |  |     verifyCommand.verifyConnect.packetThrottleInterval = ENET_HOST_TO_NET_32 (peer -> packetThrottleInterval); | 
					
						
							|  |  |  |     verifyCommand.verifyConnect.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (peer -> packetThrottleAcceleration); | 
					
						
							|  |  |  |     verifyCommand.verifyConnect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (peer -> packetThrottleDeceleration); | 
					
						
							|  |  |  |     verifyCommand.verifyConnect.connectID = peer -> connectID; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     enet_peer_queue_outgoing_command (peer, & verifyCommand, NULL, 0, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return peer; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | enet_protocol_handle_send_reliable (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     size_t dataLength; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (command -> header.channelID >= peer -> channelCount || | 
					
						
							|  |  |  |         (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)) | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     dataLength = ENET_NET_TO_HOST_16 (command -> sendReliable.dataLength); | 
					
						
							|  |  |  |     * currentData += dataLength; | 
					
						
							|  |  |  |     if (dataLength > host -> maximumPacketSize || | 
					
						
							|  |  |  |         * currentData < host -> receivedData || | 
					
						
							|  |  |  |         * currentData > & host -> receivedData [host -> receivedDataLength]) | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (enet_peer_queue_incoming_command (peer, command, (const enet_uint8 *) command + sizeof (ENetProtocolSendReliable), dataLength, ENET_PACKET_FLAG_RELIABLE, 0) == NULL) | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | enet_protocol_handle_send_unsequenced (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     enet_uint32 unsequencedGroup, index; | 
					
						
							|  |  |  |     size_t dataLength; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (command -> header.channelID >= peer -> channelCount || | 
					
						
							|  |  |  |         (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)) | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     dataLength = ENET_NET_TO_HOST_16 (command -> sendUnsequenced.dataLength); | 
					
						
							|  |  |  |     * currentData += dataLength; | 
					
						
							|  |  |  |     if (dataLength > host -> maximumPacketSize || | 
					
						
							|  |  |  |         * currentData < host -> receivedData || | 
					
						
							|  |  |  |         * currentData > & host -> receivedData [host -> receivedDataLength]) | 
					
						
							|  |  |  |       return -1;  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     unsequencedGroup = ENET_NET_TO_HOST_16 (command -> sendUnsequenced.unsequencedGroup); | 
					
						
							|  |  |  |     index = unsequencedGroup % ENET_PEER_UNSEQUENCED_WINDOW_SIZE; | 
					
						
							|  |  |  |     | 
					
						
							|  |  |  |     if (unsequencedGroup < peer -> incomingUnsequencedGroup) | 
					
						
							|  |  |  |       unsequencedGroup += 0x10000; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (unsequencedGroup >= (enet_uint32) peer -> incomingUnsequencedGroup + ENET_PEER_FREE_UNSEQUENCED_WINDOWS * ENET_PEER_UNSEQUENCED_WINDOW_SIZE) | 
					
						
							|  |  |  |       return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     unsequencedGroup &= 0xFFFF; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (unsequencedGroup - index != peer -> incomingUnsequencedGroup) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         peer -> incomingUnsequencedGroup = unsequencedGroup - index; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         memset (peer -> unsequencedWindow, 0, sizeof (peer -> unsequencedWindow)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     if (peer -> unsequencedWindow [index / 32] & (1 << (index % 32))) | 
					
						
							|  |  |  |       return 0; | 
					
						
							|  |  |  |        | 
					
						
							|  |  |  |     if (enet_peer_queue_incoming_command (peer, command, (const enet_uint8 *) command + sizeof (ENetProtocolSendUnsequenced), dataLength, ENET_PACKET_FLAG_UNSEQUENCED, 0) == NULL) | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  |     | 
					
						
							|  |  |  |     peer -> unsequencedWindow [index / 32] |= 1 << (index % 32); | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | enet_protocol_handle_send_unreliable (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     size_t dataLength; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (command -> header.channelID >= peer -> channelCount || | 
					
						
							|  |  |  |         (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)) | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     dataLength = ENET_NET_TO_HOST_16 (command -> sendUnreliable.dataLength); | 
					
						
							|  |  |  |     * currentData += dataLength; | 
					
						
							|  |  |  |     if (dataLength > host -> maximumPacketSize || | 
					
						
							|  |  |  |         * currentData < host -> receivedData || | 
					
						
							|  |  |  |         * currentData > & host -> receivedData [host -> receivedDataLength]) | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (enet_peer_queue_incoming_command (peer, command, (const enet_uint8 *) command + sizeof (ENetProtocolSendUnreliable), dataLength, 0, 0) == NULL) | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     enet_uint32 fragmentNumber, | 
					
						
							|  |  |  |            fragmentCount, | 
					
						
							|  |  |  |            fragmentOffset, | 
					
						
							|  |  |  |            fragmentLength, | 
					
						
							|  |  |  |            startSequenceNumber, | 
					
						
							|  |  |  |            totalLength; | 
					
						
							|  |  |  |     ENetChannel * channel; | 
					
						
							|  |  |  |     enet_uint16 startWindow, currentWindow; | 
					
						
							|  |  |  |     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; | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |     if (fragmentLength <= 0 || | 
					
						
							|  |  |  |         fragmentLength > host -> maximumPacketSize || | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |         * currentData < host -> receivedData || | 
					
						
							|  |  |  |         * currentData > & host -> receivedData [host -> receivedDataLength]) | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     channel = & peer -> channels [command -> header.channelID]; | 
					
						
							|  |  |  |     startSequenceNumber = ENET_NET_TO_HOST_16 (command -> sendFragment.startSequenceNumber); | 
					
						
							|  |  |  |     startWindow = startSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; | 
					
						
							|  |  |  |     currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (startSequenceNumber < channel -> incomingReliableSequenceNumber) | 
					
						
							|  |  |  |       startWindow += ENET_PEER_RELIABLE_WINDOWS; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (startWindow < currentWindow || startWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1) | 
					
						
							|  |  |  |       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 (fragmentCount > ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT || | 
					
						
							|  |  |  |         fragmentNumber >= fragmentCount || | 
					
						
							|  |  |  |         totalLength > host -> maximumPacketSize || | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |         totalLength < fragmentCount || | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |         fragmentOffset >= totalLength || | 
					
						
							|  |  |  |         fragmentLength > totalLength - fragmentOffset) | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  |     for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands)); | 
					
						
							|  |  |  |          currentCommand != enet_list_end (& channel -> incomingReliableCommands); | 
					
						
							|  |  |  |          currentCommand = enet_list_previous (currentCommand)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |        ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        if (startSequenceNumber >= channel -> incomingReliableSequenceNumber) | 
					
						
							|  |  |  |        { | 
					
						
							|  |  |  |           if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber) | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  |        else | 
					
						
							|  |  |  |        if (incomingCommand -> reliableSequenceNumber >= channel -> incomingReliableSequenceNumber) | 
					
						
							|  |  |  |          break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        if (incomingCommand -> reliableSequenceNumber <= startSequenceNumber) | 
					
						
							|  |  |  |        { | 
					
						
							|  |  |  |           if (incomingCommand -> reliableSequenceNumber < startSequenceNumber) | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |           if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_FRAGMENT || | 
					
						
							|  |  |  |               totalLength != incomingCommand -> packet -> dataLength || | 
					
						
							|  |  |  |               fragmentCount != incomingCommand -> fragmentCount) | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           startCommand = incomingCommand; | 
					
						
							|  |  |  |           break; | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  |     if (startCommand == NULL) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |        ENetProtocol hostCommand = * command; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        hostCommand.header.reliableSequenceNumber = startSequenceNumber; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        startCommand = enet_peer_queue_incoming_command (peer, & hostCommand, NULL, totalLength, ENET_PACKET_FLAG_RELIABLE, 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) | 
					
						
							| 
									
										
										
										
											2021-01-08 12:01:40 +01:00
										 |  |  |           enet_peer_dispatch_incoming_reliable_commands (peer, channel, NULL); | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     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 (fragmentLength > host -> maximumPacketSize || | 
					
						
							|  |  |  |         * currentData < host -> receivedData || | 
					
						
							|  |  |  |         * 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 (fragmentCount > ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT || | 
					
						
							|  |  |  |         fragmentNumber >= fragmentCount || | 
					
						
							|  |  |  |         totalLength > host -> maximumPacketSize || | 
					
						
							|  |  |  |         fragmentOffset >= totalLength || | 
					
						
							|  |  |  |         fragmentLength > totalLength - fragmentOffset) | 
					
						
							|  |  |  |       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) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |        startCommand = enet_peer_queue_incoming_command (peer, command, NULL, totalLength, ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT, 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) | 
					
						
							| 
									
										
										
										
											2021-01-08 12:01:40 +01:00
										 |  |  |           enet_peer_dispatch_incoming_unreliable_commands (peer, channel, NULL); | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | enet_protocol_handle_ping (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | enet_protocol_handle_bandwidth_limit (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (peer -> incomingBandwidth != 0) | 
					
						
							|  |  |  |       -- host -> bandwidthLimitedPeers; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> bandwidthLimit.incomingBandwidth); | 
					
						
							|  |  |  |     peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> bandwidthLimit.outgoingBandwidth); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (peer -> incomingBandwidth != 0) | 
					
						
							|  |  |  |       ++ host -> bandwidthLimitedPeers; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (peer -> incomingBandwidth == 0 && host -> outgoingBandwidth == 0) | 
					
						
							|  |  |  |       peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     if (peer -> incomingBandwidth == 0 || host -> outgoingBandwidth == 0) | 
					
						
							|  |  |  |       peer -> windowSize = (ENET_MAX (peer -> incomingBandwidth, host -> outgoingBandwidth) / | 
					
						
							|  |  |  |                              ENET_PEER_WINDOW_SIZE_SCALE) * ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       peer -> windowSize = (ENET_MIN (peer -> incomingBandwidth, host -> outgoingBandwidth) / | 
					
						
							|  |  |  |                              ENET_PEER_WINDOW_SIZE_SCALE) * ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (peer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) | 
					
						
							|  |  |  |       peer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     if (peer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) | 
					
						
							|  |  |  |       peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | enet_protocol_handle_throttle_configure (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) | 
					
						
							|  |  |  |       return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     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); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | enet_protocol_handle_disconnect (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (peer -> state == ENET_PEER_STATE_DISCONNECTED || peer -> state == ENET_PEER_STATE_ZOMBIE || peer -> state == ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT) | 
					
						
							|  |  |  |       return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     enet_peer_reset_queues (peer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (peer -> state == ENET_PEER_STATE_CONNECTION_SUCCEEDED || peer -> state == ENET_PEER_STATE_DISCONNECTING || peer -> state == ENET_PEER_STATE_CONNECTING) | 
					
						
							|  |  |  |         enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (peer -> state == ENET_PEER_STATE_CONNECTION_PENDING) host -> recalculateBandwidthLimits = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         enet_peer_reset (peer); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     if (command -> header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) | 
					
						
							|  |  |  |       enet_protocol_change_state (host, peer, ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (peer -> state != ENET_PEER_STATE_DISCONNECTED) | 
					
						
							|  |  |  |       peer -> eventData = ENET_NET_TO_HOST_32 (command -> disconnect.data); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer * peer, const ENetProtocol * command) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     enet_uint32 roundTripTime, | 
					
						
							|  |  |  |            receivedSentTime, | 
					
						
							|  |  |  |            receivedReliableSequenceNumber; | 
					
						
							|  |  |  |     ENetProtocolCommand commandNumber; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (peer -> state == ENET_PEER_STATE_DISCONNECTED || peer -> state == ENET_PEER_STATE_ZOMBIE) | 
					
						
							|  |  |  |       return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     receivedSentTime = ENET_NET_TO_HOST_16 (command -> acknowledge.receivedSentTime); | 
					
						
							|  |  |  |     receivedSentTime |= host -> serviceTime & 0xFFFF0000; | 
					
						
							|  |  |  |     if ((receivedSentTime & 0x8000) > (host -> serviceTime & 0x8000)) | 
					
						
							|  |  |  |         receivedSentTime -= 0x10000; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (ENET_TIME_LESS (host -> serviceTime, receivedSentTime)) | 
					
						
							|  |  |  |       return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     roundTripTime = ENET_TIME_DIFFERENCE (host -> serviceTime, receivedSentTime); | 
					
						
							| 
									
										
										
										
											2020-04-21 12:26:42 +02:00
										 |  |  |     roundTripTime = ENET_MAX (roundTripTime, 1); | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-21 12:26:42 +02:00
										 |  |  |     if (peer -> lastReceiveTime > 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |        enet_peer_throttle (peer, roundTripTime); | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-08 12:01:40 +01:00
										 |  |  |        peer -> roundTripTimeVariance -= peer -> roundTripTimeVariance / 4; | 
					
						
							| 
									
										
										
										
											2020-04-21 12:26:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-08 12:01:40 +01:00
										 |  |  |        if (roundTripTime >= peer -> roundTripTime) | 
					
						
							|  |  |  |        { | 
					
						
							|  |  |  |           enet_uint32 diff = roundTripTime - peer -> roundTripTime; | 
					
						
							|  |  |  |           peer -> roundTripTimeVariance += diff / 4; | 
					
						
							|  |  |  |           peer -> roundTripTime += diff / 8; | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  |        else | 
					
						
							|  |  |  |        { | 
					
						
							|  |  |  |           enet_uint32 diff = peer -> roundTripTime - roundTripTime; | 
					
						
							|  |  |  |           peer -> roundTripTimeVariance += diff / 4; | 
					
						
							|  |  |  |           peer -> roundTripTime -= diff / 8; | 
					
						
							|  |  |  |        } | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |     } | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2020-04-21 12:26:42 +02:00
										 |  |  |        peer -> roundTripTime = roundTripTime; | 
					
						
							|  |  |  |        peer -> roundTripTimeVariance = (roundTripTime + 1) / 2; | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (peer -> roundTripTime < peer -> lowestRoundTripTime) | 
					
						
							|  |  |  |       peer -> lowestRoundTripTime = peer -> roundTripTime; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-08 12:01:40 +01:00
										 |  |  |     if (peer -> roundTripTimeVariance > peer -> highestRoundTripTimeVariance) | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |       peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (peer -> packetThrottleEpoch == 0 || | 
					
						
							|  |  |  |         ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> packetThrottleEpoch) >= peer -> packetThrottleInterval) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         peer -> lastRoundTripTime = peer -> lowestRoundTripTime; | 
					
						
							| 
									
										
										
										
											2021-01-08 12:01:40 +01:00
										 |  |  |         peer -> lastRoundTripTimeVariance = ENET_MAX (peer -> highestRoundTripTimeVariance, 1); | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |         peer -> lowestRoundTripTime = peer -> roundTripTime; | 
					
						
							|  |  |  |         peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance; | 
					
						
							|  |  |  |         peer -> packetThrottleEpoch = host -> serviceTime; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-21 12:26:42 +02:00
										 |  |  |     peer -> lastReceiveTime = ENET_MAX (host -> serviceTime, 1); | 
					
						
							|  |  |  |     peer -> earliestTimeout = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |     receivedReliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> acknowledge.receivedReliableSequenceNumber); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     commandNumber = enet_protocol_remove_sent_reliable_command (peer, receivedReliableSequenceNumber, command -> header.channelID); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     switch (peer -> state) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     case ENET_PEER_STATE_ACKNOWLEDGING_CONNECT: | 
					
						
							|  |  |  |        if (commandNumber != ENET_PROTOCOL_COMMAND_VERIFY_CONNECT) | 
					
						
							|  |  |  |          return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        enet_protocol_notify_connect (host, peer, event); | 
					
						
							|  |  |  |        break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case ENET_PEER_STATE_DISCONNECTING: | 
					
						
							|  |  |  |        if (commandNumber != ENET_PROTOCOL_COMMAND_DISCONNECT) | 
					
						
							|  |  |  |          return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        enet_protocol_notify_disconnect (host, peer, event); | 
					
						
							|  |  |  |        break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     case ENET_PEER_STATE_DISCONNECT_LATER: | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |        if (! enet_peer_has_outgoing_commands (peer)) | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |          enet_peer_disconnect (peer, peer -> eventData); | 
					
						
							|  |  |  |        break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |        break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | enet_protocol_handle_verify_connect (ENetHost * host, ENetEvent * event, ENetPeer * peer, const ENetProtocol * command) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     enet_uint32 mtu, windowSize; | 
					
						
							|  |  |  |     size_t channelCount; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (peer -> state != ENET_PEER_STATE_CONNECTING) | 
					
						
							|  |  |  |       return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     channelCount = ENET_NET_TO_HOST_32 (command -> verifyConnect.channelCount); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT || channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT || | 
					
						
							|  |  |  |         ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleInterval) != peer -> packetThrottleInterval || | 
					
						
							|  |  |  |         ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleAcceleration) != peer -> packetThrottleAcceleration || | 
					
						
							|  |  |  |         ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleDeceleration) != peer -> packetThrottleDeceleration || | 
					
						
							|  |  |  |         command -> verifyConnect.connectID != peer -> connectID) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         peer -> eventData = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     enet_protocol_remove_sent_reliable_command (peer, 1, 0xFF); | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     if (channelCount < peer -> channelCount) | 
					
						
							|  |  |  |       peer -> channelCount = channelCount; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     peer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> verifyConnect.outgoingPeerID); | 
					
						
							|  |  |  |     peer -> incomingSessionID = command -> verifyConnect.incomingSessionID; | 
					
						
							|  |  |  |     peer -> outgoingSessionID = command -> verifyConnect.outgoingSessionID; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     mtu = ENET_NET_TO_HOST_32 (command -> verifyConnect.mtu); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (mtu < ENET_PROTOCOL_MINIMUM_MTU) | 
					
						
							|  |  |  |       mtu = ENET_PROTOCOL_MINIMUM_MTU; | 
					
						
							|  |  |  |     else  | 
					
						
							|  |  |  |     if (mtu > ENET_PROTOCOL_MAXIMUM_MTU) | 
					
						
							|  |  |  |       mtu = ENET_PROTOCOL_MAXIMUM_MTU; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (mtu < peer -> mtu) | 
					
						
							|  |  |  |       peer -> mtu = mtu; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     windowSize = ENET_NET_TO_HOST_32 (command -> verifyConnect.windowSize); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) | 
					
						
							|  |  |  |       windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) | 
					
						
							|  |  |  |       windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (windowSize < peer -> windowSize) | 
					
						
							|  |  |  |       peer -> windowSize = windowSize; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> verifyConnect.incomingBandwidth); | 
					
						
							|  |  |  |     peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> verifyConnect.outgoingBandwidth); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     enet_protocol_notify_connect (host, peer, event); | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     ENetProtocolHeader * header; | 
					
						
							|  |  |  |     ENetProtocol * command; | 
					
						
							|  |  |  |     ENetPeer * peer; | 
					
						
							|  |  |  |     enet_uint8 * currentData; | 
					
						
							|  |  |  |     size_t headerSize; | 
					
						
							|  |  |  |     enet_uint16 peerID, flags; | 
					
						
							|  |  |  |     enet_uint8 sessionID; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (host -> receivedDataLength < (size_t) & ((ENetProtocolHeader *) 0) -> sentTime) | 
					
						
							|  |  |  |       return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     header = (ENetProtocolHeader *) host -> receivedData; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     peerID = ENET_NET_TO_HOST_16 (header -> peerID); | 
					
						
							|  |  |  |     sessionID = (peerID & ENET_PROTOCOL_HEADER_SESSION_MASK) >> ENET_PROTOCOL_HEADER_SESSION_SHIFT; | 
					
						
							|  |  |  |     flags = peerID & ENET_PROTOCOL_HEADER_FLAG_MASK; | 
					
						
							|  |  |  |     peerID &= ~ (ENET_PROTOCOL_HEADER_FLAG_MASK | ENET_PROTOCOL_HEADER_SESSION_MASK); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     headerSize = (flags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME ? sizeof (ENetProtocolHeader) : (size_t) & ((ENetProtocolHeader *) 0) -> sentTime); | 
					
						
							|  |  |  |     if (host -> checksum != NULL) | 
					
						
							|  |  |  |       headerSize += sizeof (enet_uint32); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (peerID == ENET_PROTOCOL_MAXIMUM_PEER_ID) | 
					
						
							|  |  |  |       peer = NULL; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     if (peerID >= host -> peerCount) | 
					
						
							|  |  |  |       return 0; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |        peer = & host -> peers [peerID]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        if (peer -> state == ENET_PEER_STATE_DISCONNECTED || | 
					
						
							|  |  |  |            peer -> state == ENET_PEER_STATE_ZOMBIE || | 
					
						
							| 
									
										
										
										
											2017-01-22 05:53:08 +01:00
										 |  |  |            (!enet_host_equal(host -> receivedAddress.host, peer -> address.host) || | 
					
						
							|  |  |  |              host -> receivedAddress.port != peer -> address.port) || | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |            (peer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID && | 
					
						
							|  |  |  |             sessionID != peer -> incomingSessionID)) | 
					
						
							|  |  |  |          return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  |     if (flags & ENET_PROTOCOL_HEADER_FLAG_COMPRESSED) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         size_t originalSize; | 
					
						
							|  |  |  |         if (host -> compressor.context == NULL || host -> compressor.decompress == NULL) | 
					
						
							|  |  |  |           return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         originalSize = host -> compressor.decompress (host -> compressor.context, | 
					
						
							|  |  |  |                                     host -> receivedData + headerSize,  | 
					
						
							|  |  |  |                                     host -> receivedDataLength - headerSize,  | 
					
						
							|  |  |  |                                     host -> packetData [1] + headerSize,  | 
					
						
							|  |  |  |                                     sizeof (host -> packetData [1]) - headerSize); | 
					
						
							|  |  |  |         if (originalSize <= 0 || originalSize > sizeof (host -> packetData [1]) - headerSize) | 
					
						
							|  |  |  |           return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         memcpy (host -> packetData [1], header, headerSize); | 
					
						
							|  |  |  |         host -> receivedData = host -> packetData [1]; | 
					
						
							|  |  |  |         host -> receivedDataLength = headerSize + originalSize; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (host -> checksum != NULL) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         enet_uint32 * checksum = (enet_uint32 *) & host -> receivedData [headerSize - sizeof (enet_uint32)], | 
					
						
							|  |  |  |                     desiredChecksum = * checksum; | 
					
						
							|  |  |  |         ENetBuffer buffer; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         * checksum = peer != NULL ? peer -> connectID : 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         buffer.data = host -> receivedData; | 
					
						
							|  |  |  |         buffer.dataLength = host -> receivedDataLength; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (host -> checksum (& buffer, 1) != desiredChecksum) | 
					
						
							|  |  |  |           return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |         | 
					
						
							|  |  |  |     if (peer != NULL) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2017-01-22 05:53:08 +01:00
										 |  |  |        enet_address_set_ip(&(peer -> address), host -> receivedAddress.host, 16); | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |        peer -> address.port = host -> receivedAddress.port; | 
					
						
							|  |  |  |        peer -> incomingDataTotal += host -> receivedDataLength; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     currentData = host -> receivedData + headerSize; | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |     while (currentData < & host -> receivedData [host -> receivedDataLength]) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |        enet_uint8 commandNumber; | 
					
						
							|  |  |  |        size_t commandSize; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        command = (ENetProtocol *) currentData; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        if (currentData + sizeof (ENetProtocolCommandHeader) > & host -> receivedData [host -> receivedDataLength]) | 
					
						
							|  |  |  |          break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        commandNumber = command -> header.command & ENET_PROTOCOL_COMMAND_MASK; | 
					
						
							|  |  |  |        if (commandNumber >= ENET_PROTOCOL_COMMAND_COUNT)  | 
					
						
							|  |  |  |          break; | 
					
						
							|  |  |  |         | 
					
						
							|  |  |  |        commandSize = commandSizes [commandNumber]; | 
					
						
							|  |  |  |        if (commandSize == 0 || currentData + commandSize > & host -> receivedData [host -> receivedDataLength]) | 
					
						
							|  |  |  |          break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        currentData += commandSize; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        if (peer == NULL && commandNumber != ENET_PROTOCOL_COMMAND_CONNECT) | 
					
						
							|  |  |  |          break; | 
					
						
							|  |  |  |           | 
					
						
							|  |  |  |        command -> header.reliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> header.reliableSequenceNumber); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        switch (commandNumber) | 
					
						
							|  |  |  |        { | 
					
						
							|  |  |  |        case ENET_PROTOCOL_COMMAND_ACKNOWLEDGE: | 
					
						
							|  |  |  |           if (enet_protocol_handle_acknowledge (host, event, peer, command)) | 
					
						
							|  |  |  |             goto commandError; | 
					
						
							|  |  |  |           break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        case ENET_PROTOCOL_COMMAND_CONNECT: | 
					
						
							|  |  |  |           if (peer != NULL) | 
					
						
							|  |  |  |             goto commandError; | 
					
						
							|  |  |  |           peer = enet_protocol_handle_connect (host, header, command); | 
					
						
							|  |  |  |           if (peer == NULL) | 
					
						
							|  |  |  |             goto commandError; | 
					
						
							|  |  |  |           break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        case ENET_PROTOCOL_COMMAND_VERIFY_CONNECT: | 
					
						
							|  |  |  |           if (enet_protocol_handle_verify_connect (host, event, peer, command)) | 
					
						
							|  |  |  |             goto commandError; | 
					
						
							|  |  |  |           break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        case ENET_PROTOCOL_COMMAND_DISCONNECT: | 
					
						
							|  |  |  |           if (enet_protocol_handle_disconnect (host, peer, command)) | 
					
						
							|  |  |  |             goto commandError; | 
					
						
							|  |  |  |           break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        case ENET_PROTOCOL_COMMAND_PING: | 
					
						
							|  |  |  |           if (enet_protocol_handle_ping (host, peer, command)) | 
					
						
							|  |  |  |             goto commandError; | 
					
						
							|  |  |  |           break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        case ENET_PROTOCOL_COMMAND_SEND_RELIABLE: | 
					
						
							|  |  |  |           if (enet_protocol_handle_send_reliable (host, peer, command, & currentData)) | 
					
						
							|  |  |  |             goto commandError; | 
					
						
							|  |  |  |           break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE: | 
					
						
							|  |  |  |           if (enet_protocol_handle_send_unreliable (host, peer, command, & currentData)) | 
					
						
							|  |  |  |             goto commandError; | 
					
						
							|  |  |  |           break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED: | 
					
						
							|  |  |  |           if (enet_protocol_handle_send_unsequenced (host, peer, command, & currentData)) | 
					
						
							|  |  |  |             goto commandError; | 
					
						
							|  |  |  |           break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT: | 
					
						
							|  |  |  |           if (enet_protocol_handle_send_fragment (host, peer, command, & currentData)) | 
					
						
							|  |  |  |             goto commandError; | 
					
						
							|  |  |  |           break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        case ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT: | 
					
						
							|  |  |  |           if (enet_protocol_handle_bandwidth_limit (host, peer, command)) | 
					
						
							|  |  |  |             goto commandError; | 
					
						
							|  |  |  |           break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        case ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE: | 
					
						
							|  |  |  |           if (enet_protocol_handle_throttle_configure (host, peer, command)) | 
					
						
							|  |  |  |             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; | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        if (peer != NULL && | 
					
						
							|  |  |  |            (command -> header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) != 0) | 
					
						
							|  |  |  |        { | 
					
						
							|  |  |  |            enet_uint16 sentTime; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            if (! (flags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME)) | 
					
						
							|  |  |  |              break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            sentTime = ENET_NET_TO_HOST_16 (header -> sentTime); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            switch (peer -> state) | 
					
						
							|  |  |  |            { | 
					
						
							|  |  |  |            case ENET_PEER_STATE_DISCONNECTING: | 
					
						
							|  |  |  |            case ENET_PEER_STATE_ACKNOWLEDGING_CONNECT: | 
					
						
							|  |  |  |            case ENET_PEER_STATE_DISCONNECTED: | 
					
						
							|  |  |  |            case ENET_PEER_STATE_ZOMBIE: | 
					
						
							|  |  |  |               break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            case ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT: | 
					
						
							|  |  |  |               if ((command -> header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_DISCONNECT) | 
					
						
							|  |  |  |                 enet_peer_queue_acknowledgement (peer, command, sentTime); | 
					
						
							|  |  |  |               break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |            default:    | 
					
						
							|  |  |  |               enet_peer_queue_acknowledgement (peer, command, sentTime);         | 
					
						
							|  |  |  |               break; | 
					
						
							|  |  |  |            } | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | commandError: | 
					
						
							|  |  |  |     if (event != NULL && event -> type != ENET_EVENT_TYPE_NONE) | 
					
						
							|  |  |  |       return 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     int packets; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (packets = 0; packets < 256; ++ packets) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |        int receivedLength; | 
					
						
							|  |  |  |        ENetBuffer buffer; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        buffer.data = host -> packetData [0]; | 
					
						
							|  |  |  |        buffer.dataLength = sizeof (host -> packetData [0]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        receivedLength = enet_socket_receive (host -> socket, | 
					
						
							|  |  |  |                                              & host -> receivedAddress, | 
					
						
							|  |  |  |                                              & buffer, | 
					
						
							|  |  |  |                                              1); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |        if (receivedLength == -2) | 
					
						
							|  |  |  |          continue; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |        if (receivedLength < 0) | 
					
						
							|  |  |  |          return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        if (receivedLength == 0) | 
					
						
							|  |  |  |          return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        host -> receivedData = host -> packetData [0]; | 
					
						
							|  |  |  |        host -> receivedDataLength = receivedLength; | 
					
						
							|  |  |  |        | 
					
						
							|  |  |  |        host -> totalReceivedData += receivedLength; | 
					
						
							|  |  |  |        host -> totalReceivedPackets ++; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        if (host -> intercept != NULL) | 
					
						
							|  |  |  |        { | 
					
						
							|  |  |  |           switch (host -> intercept (host, event)) | 
					
						
							|  |  |  |           { | 
					
						
							|  |  |  |           case 1: | 
					
						
							|  |  |  |              if (event != NULL && event -> type != ENET_EVENT_TYPE_NONE) | 
					
						
							|  |  |  |                return 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |              continue; | 
					
						
							|  |  |  |            | 
					
						
							|  |  |  |           case -1: | 
					
						
							|  |  |  |              return -1; | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |           default: | 
					
						
							|  |  |  |              break; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |        switch (enet_protocol_handle_incoming_commands (host, event)) | 
					
						
							|  |  |  |        { | 
					
						
							|  |  |  |        case 1: | 
					
						
							|  |  |  |           return 1; | 
					
						
							|  |  |  |         | 
					
						
							|  |  |  |        case -1: | 
					
						
							|  |  |  |           return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        default: | 
					
						
							|  |  |  |           break; | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-21 12:26:42 +02:00
										 |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | enet_protocol_send_acknowledgements (ENetHost * host, ENetPeer * peer) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     ENetProtocol * command = & host -> commands [host -> commandCount]; | 
					
						
							|  |  |  |     ENetBuffer * buffer = & host -> buffers [host -> bufferCount]; | 
					
						
							|  |  |  |     ENetAcknowledgement * acknowledgement; | 
					
						
							|  |  |  |     ENetListIterator currentAcknowledgement; | 
					
						
							|  |  |  |     enet_uint16 reliableSequenceNumber; | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  |     currentAcknowledgement = enet_list_begin (& peer -> acknowledgements); | 
					
						
							|  |  |  |           | 
					
						
							|  |  |  |     while (currentAcknowledgement != enet_list_end (& peer -> acknowledgements)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |        if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] || | 
					
						
							|  |  |  |            buffer >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] || | 
					
						
							|  |  |  |            peer -> mtu - host -> packetSize < sizeof (ENetProtocolAcknowledge)) | 
					
						
							|  |  |  |        { | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |           peer -> flags |= ENET_PEER_FLAG_CONTINUE_SENDING; | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  |           break; | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        acknowledgement = (ENetAcknowledgement *) currentAcknowledgement; | 
					
						
							|  |  |  |   | 
					
						
							|  |  |  |        currentAcknowledgement = enet_list_next (currentAcknowledgement); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        buffer -> data = command; | 
					
						
							|  |  |  |        buffer -> dataLength = sizeof (ENetProtocolAcknowledge); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        host -> packetSize += buffer -> dataLength; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        reliableSequenceNumber = ENET_HOST_TO_NET_16 (acknowledgement -> command.header.reliableSequenceNumber); | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |        command -> header.command = ENET_PROTOCOL_COMMAND_ACKNOWLEDGE; | 
					
						
							|  |  |  |        command -> header.channelID = acknowledgement -> command.header.channelID; | 
					
						
							|  |  |  |        command -> header.reliableSequenceNumber = reliableSequenceNumber; | 
					
						
							|  |  |  |        command -> acknowledge.receivedReliableSequenceNumber = reliableSequenceNumber; | 
					
						
							|  |  |  |        command -> acknowledge.receivedSentTime = ENET_HOST_TO_NET_16 (acknowledgement -> sentTime); | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  |        if ((acknowledgement -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_DISCONNECT) | 
					
						
							|  |  |  |          enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        enet_list_remove (& acknowledgement -> acknowledgementList); | 
					
						
							|  |  |  |        enet_free (acknowledgement); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        ++ command; | 
					
						
							|  |  |  |        ++ buffer; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     host -> commandCount = command - host -> commands; | 
					
						
							|  |  |  |     host -> bufferCount = buffer - host -> buffers; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * event) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     ENetOutgoingCommand * outgoingCommand; | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |     ENetListIterator currentCommand, insertPosition, insertSendReliablePosition; | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     currentCommand = enet_list_begin (& peer -> sentReliableCommands); | 
					
						
							| 
									
										
										
										
											2021-01-08 12:01:40 +01:00
										 |  |  |     insertPosition = enet_list_begin (& peer -> outgoingCommands); | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |     insertSendReliablePosition = enet_list_begin (& peer -> outgoingSendReliableCommands); | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     while (currentCommand != enet_list_end (& peer -> sentReliableCommands)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |        outgoingCommand = (ENetOutgoingCommand *) currentCommand; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        currentCommand = enet_list_next (currentCommand); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        if (ENET_TIME_DIFFERENCE (host -> serviceTime, outgoingCommand -> sentTime) < outgoingCommand -> roundTripTimeout) | 
					
						
							|  |  |  |          continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        if (peer -> earliestTimeout == 0 || | 
					
						
							|  |  |  |            ENET_TIME_LESS (outgoingCommand -> sentTime, peer -> earliestTimeout)) | 
					
						
							|  |  |  |          peer -> earliestTimeout = outgoingCommand -> sentTime; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        if (peer -> earliestTimeout != 0 && | 
					
						
							|  |  |  |              (ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> earliestTimeout) >= peer -> timeoutMaximum || | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |                ((1 << (outgoingCommand -> sendAttempts - 1)) >= peer -> timeoutLimit && | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |                  ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> earliestTimeout) >= peer -> timeoutMinimum))) | 
					
						
							|  |  |  |        { | 
					
						
							|  |  |  |           enet_protocol_notify_disconnect (host, peer, event); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           return 1; | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        ++ peer -> packetsLost; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        outgoingCommand -> roundTripTimeout *= 2; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |        if (outgoingCommand -> packet != NULL) | 
					
						
							|  |  |  |        { | 
					
						
							|  |  |  |          peer -> reliableDataInTransit -= outgoingCommand -> fragmentLength; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |          enet_list_insert (insertSendReliablePosition, enet_list_remove (& outgoingCommand -> outgoingCommandList)); | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  |        else | 
					
						
							|  |  |  |          enet_list_insert (insertPosition, enet_list_remove (& outgoingCommand -> outgoingCommandList)); | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  |        if (currentCommand == enet_list_begin (& peer -> sentReliableCommands) && | 
					
						
							|  |  |  |            ! enet_list_empty (& peer -> sentReliableCommands)) | 
					
						
							|  |  |  |        { | 
					
						
							|  |  |  |           outgoingCommand = (ENetOutgoingCommand *) currentCommand; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           peer -> nextTimeout = outgoingCommand -> sentTime + outgoingCommand -> roundTripTimeout; | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  | enet_protocol_check_outgoing_commands (ENetHost * host, ENetPeer * peer, ENetList * sentUnreliableCommands) | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  | { | 
					
						
							|  |  |  |     ENetProtocol * command = & host -> commands [host -> commandCount]; | 
					
						
							|  |  |  |     ENetBuffer * buffer = & host -> buffers [host -> bufferCount]; | 
					
						
							|  |  |  |     ENetOutgoingCommand * outgoingCommand; | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |     ENetListIterator currentCommand, currentSendReliableCommand; | 
					
						
							|  |  |  |     ENetChannel *channel = NULL; | 
					
						
							|  |  |  |     enet_uint16 reliableWindow = 0; | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |     size_t commandSize; | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |     int windowWrap = 0, canPing = 1; | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-08 12:01:40 +01:00
										 |  |  |     currentCommand = enet_list_begin (& peer -> outgoingCommands); | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |     currentSendReliableCommand = enet_list_begin (& peer -> outgoingSendReliableCommands); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (;;) | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |        if (currentCommand != enet_list_end (& peer -> outgoingCommands)) | 
					
						
							|  |  |  |        { | 
					
						
							|  |  |  |           outgoingCommand = (ENetOutgoingCommand *) currentCommand; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           if (currentSendReliableCommand != enet_list_end (& peer -> outgoingSendReliableCommands) && | 
					
						
							|  |  |  |               ENET_TIME_LESS (((ENetOutgoingCommand *) currentSendReliableCommand) -> queueTime, outgoingCommand -> queueTime)) | 
					
						
							|  |  |  |             goto useSendReliableCommand; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           currentCommand = enet_list_next (currentCommand); | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  |        else | 
					
						
							|  |  |  |        if (currentSendReliableCommand != enet_list_end (& peer -> outgoingSendReliableCommands)) | 
					
						
							|  |  |  |        { | 
					
						
							|  |  |  |        useSendReliableCommand: | 
					
						
							|  |  |  |           outgoingCommand = (ENetOutgoingCommand *) currentSendReliableCommand; | 
					
						
							|  |  |  |           currentSendReliableCommand = enet_list_next (currentSendReliableCommand); | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  |        else | 
					
						
							|  |  |  |          break; | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-08 12:01:40 +01:00
										 |  |  |        if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |        { | 
					
						
							| 
									
										
										
										
											2021-01-08 12:01:40 +01:00
										 |  |  |           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) | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |           { | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |              if (windowWrap) | 
					
						
							|  |  |  |                continue; | 
					
						
							|  |  |  |              else | 
					
						
							|  |  |  |              if (outgoingCommand -> sendAttempts < 1 && | 
					
						
							| 
									
										
										
										
											2021-01-08 12:01:40 +01:00
										 |  |  |                   ! (outgoingCommand -> reliableSequenceNumber % ENET_PEER_RELIABLE_WINDOW_SIZE) && | 
					
						
							|  |  |  |                   (channel -> reliableWindows [(reliableWindow + ENET_PEER_RELIABLE_WINDOWS - 1) % ENET_PEER_RELIABLE_WINDOWS] >= ENET_PEER_RELIABLE_WINDOW_SIZE || | 
					
						
							|  |  |  |                     channel -> usedReliableWindows & ((((1 << (ENET_PEER_FREE_RELIABLE_WINDOWS + 2)) - 1) << reliableWindow) | | 
					
						
							|  |  |  |                       (((1 << (ENET_PEER_FREE_RELIABLE_WINDOWS + 2)) - 1) >> (ENET_PEER_RELIABLE_WINDOWS - reliableWindow))))) | 
					
						
							|  |  |  |              { | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |                 windowWrap = 1; | 
					
						
							|  |  |  |                 currentSendReliableCommand = enet_list_end (& peer -> outgoingSendReliableCommands); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-08 12:01:40 +01:00
										 |  |  |                 continue; | 
					
						
							|  |  |  |              } | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |           } | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-08 12:01:40 +01:00
										 |  |  |           if (outgoingCommand -> packet != NULL) | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |           { | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |              enet_uint32 windowSize = (peer -> packetThrottle * peer -> windowSize) / ENET_PEER_PACKET_THROTTLE_SCALE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |              if (peer -> reliableDataInTransit + outgoingCommand -> fragmentLength > ENET_MAX (windowSize, peer -> mtu)) | 
					
						
							| 
									
										
										
										
											2021-01-08 12:01:40 +01:00
										 |  |  |              { | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |                 currentSendReliableCommand = enet_list_end (& peer -> outgoingSendReliableCommands); | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-08 12:01:40 +01:00
										 |  |  |                 continue; | 
					
						
							|  |  |  |              } | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-08 12:01:40 +01:00
										 |  |  |           canPing = 0; | 
					
						
							|  |  |  |        } | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  |        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 || | 
					
						
							|  |  |  |            (outgoingCommand -> packet != NULL &&  | 
					
						
							|  |  |  |              (enet_uint16) (peer -> mtu - host -> packetSize) < (enet_uint16) (commandSize + outgoingCommand -> fragmentLength))) | 
					
						
							|  |  |  |        { | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |           peer -> flags |= ENET_PEER_FLAG_CONTINUE_SENDING; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |           break; | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-08 12:01:40 +01:00
										 |  |  |        if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |        { | 
					
						
							| 
									
										
										
										
											2021-01-08 12:01:40 +01:00
										 |  |  |           if (channel != NULL && outgoingCommand -> sendAttempts < 1) | 
					
						
							|  |  |  |           { | 
					
						
							|  |  |  |              channel -> usedReliableWindows |= 1 << reliableWindow; | 
					
						
							|  |  |  |              ++ channel -> reliableWindows [reliableWindow]; | 
					
						
							|  |  |  |           } | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-08 12:01:40 +01:00
										 |  |  |           ++ outgoingCommand -> sendAttempts; | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |   | 
					
						
							| 
									
										
										
										
											2021-01-08 12:01:40 +01:00
										 |  |  |           if (outgoingCommand -> roundTripTimeout == 0) | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |             outgoingCommand -> roundTripTimeout = peer -> roundTripTime + 4 * peer -> roundTripTimeVariance; | 
					
						
							| 
									
										
										
										
											2021-01-08 12:01:40 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |           if (enet_list_empty (& peer -> sentReliableCommands)) | 
					
						
							|  |  |  |             peer -> nextTimeout = host -> serviceTime + outgoingCommand -> roundTripTimeout; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           enet_list_insert (enet_list_end (& peer -> sentReliableCommands), | 
					
						
							|  |  |  |                             enet_list_remove (& outgoingCommand -> outgoingCommandList)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           outgoingCommand -> sentTime = host -> serviceTime; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_SENT_TIME; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           peer -> reliableDataInTransit += outgoingCommand -> fragmentLength; | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |        } | 
					
						
							| 
									
										
										
										
											2021-01-08 12:01:40 +01:00
										 |  |  |        else | 
					
						
							|  |  |  |        { | 
					
						
							|  |  |  |           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) | 
					
						
							|  |  |  |              { | 
					
						
							|  |  |  |                 enet_uint16 reliableSequenceNumber = outgoingCommand -> reliableSequenceNumber, | 
					
						
							|  |  |  |                             unreliableSequenceNumber = outgoingCommand -> unreliableSequenceNumber; | 
					
						
							|  |  |  |                 for (;;) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                    -- outgoingCommand -> packet -> referenceCount; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                    if (outgoingCommand -> packet -> referenceCount == 0) | 
					
						
							|  |  |  |                      enet_packet_destroy (outgoingCommand -> packet); | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-08 12:01:40 +01:00
										 |  |  |                    enet_list_remove (& outgoingCommand -> outgoingCommandList); | 
					
						
							|  |  |  |                    enet_free (outgoingCommand); | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-08 12:01:40 +01:00
										 |  |  |                    if (currentCommand == enet_list_end (& peer -> outgoingCommands)) | 
					
						
							|  |  |  |                      break; | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-08 12:01:40 +01:00
										 |  |  |                    outgoingCommand = (ENetOutgoingCommand *) currentCommand; | 
					
						
							|  |  |  |                    if (outgoingCommand -> reliableSequenceNumber != reliableSequenceNumber || | 
					
						
							|  |  |  |                        outgoingCommand -> unreliableSequenceNumber != unreliableSequenceNumber) | 
					
						
							|  |  |  |                      break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                    currentCommand = enet_list_next (currentCommand); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 continue; | 
					
						
							|  |  |  |              } | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           enet_list_remove (& outgoingCommand -> outgoingCommandList); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           if (outgoingCommand -> packet != NULL) | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |             enet_list_insert (enet_list_end (sentUnreliableCommands), outgoingCommand); | 
					
						
							| 
									
										
										
										
											2021-01-08 12:01:40 +01:00
										 |  |  |        } | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  |        buffer -> data = command; | 
					
						
							|  |  |  |        buffer -> dataLength = commandSize; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        host -> packetSize += buffer -> dataLength; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        * command = outgoingCommand -> command; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        if (outgoingCommand -> packet != NULL) | 
					
						
							|  |  |  |        { | 
					
						
							|  |  |  |           ++ buffer; | 
					
						
							|  |  |  |            | 
					
						
							|  |  |  |           buffer -> data = outgoingCommand -> packet -> data + outgoingCommand -> fragmentOffset; | 
					
						
							|  |  |  |           buffer -> dataLength = outgoingCommand -> fragmentLength; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           host -> packetSize += outgoingCommand -> fragmentLength; | 
					
						
							|  |  |  |        } | 
					
						
							| 
									
										
										
										
											2021-01-08 12:01:40 +01:00
										 |  |  |        else | 
					
						
							|  |  |  |        if (! (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)) | 
					
						
							|  |  |  |          enet_free (outgoingCommand); | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  |        ++ peer -> packetsSent; | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |        ++ command; | 
					
						
							|  |  |  |        ++ buffer; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     host -> commandCount = command - host -> commands; | 
					
						
							|  |  |  |     host -> bufferCount = buffer - host -> buffers; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-08 12:01:40 +01:00
										 |  |  |     if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER && | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |         ! enet_peer_has_outgoing_commands (peer) && | 
					
						
							|  |  |  |         enet_list_empty (sentUnreliableCommands)) | 
					
						
							| 
									
										
										
										
											2021-01-08 12:01:40 +01:00
										 |  |  |       enet_peer_disconnect (peer, peer -> eventData); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |     return canPing; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int | 
					
						
							|  |  |  | enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int checkForTimeouts) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     enet_uint8 headerData [sizeof (ENetProtocolHeader) + sizeof (enet_uint32)]; | 
					
						
							|  |  |  |     ENetProtocolHeader * header = (ENetProtocolHeader *) headerData; | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |     int sentLength = 0; | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |     size_t shouldCompress = 0; | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |     ENetList sentUnreliableCommands; | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |     enet_list_clear (& sentUnreliableCommands); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (int sendPass = 0, continueSending = 0; sendPass <= continueSending; ++ sendPass) | 
					
						
							|  |  |  |     for (ENetPeer * currentPeer = host -> peers; | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |          currentPeer < & host -> peers [host -> peerCount]; | 
					
						
							|  |  |  |          ++ currentPeer) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED || | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |             currentPeer -> state == ENET_PEER_STATE_ZOMBIE || | 
					
						
							|  |  |  |             (sendPass > 0 && ! (currentPeer -> flags & ENET_PEER_FLAG_CONTINUE_SENDING))) | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |           continue; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |         currentPeer -> flags &= ~ ENET_PEER_FLAG_CONTINUE_SENDING; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |         host -> headerFlags = 0; | 
					
						
							|  |  |  |         host -> commandCount = 0; | 
					
						
							|  |  |  |         host -> bufferCount = 1; | 
					
						
							|  |  |  |         host -> packetSize = sizeof (ENetProtocolHeader); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (! enet_list_empty (& currentPeer -> acknowledgements)) | 
					
						
							|  |  |  |           enet_protocol_send_acknowledgements (host, currentPeer); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (checkForTimeouts != 0 && | 
					
						
							|  |  |  |             ! enet_list_empty (& currentPeer -> sentReliableCommands) && | 
					
						
							|  |  |  |             ENET_TIME_GREATER_EQUAL (host -> serviceTime, currentPeer -> nextTimeout) && | 
					
						
							|  |  |  |             enet_protocol_check_timeouts (host, currentPeer, event) == 1) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if (event != NULL && event -> type != ENET_EVENT_TYPE_NONE) | 
					
						
							|  |  |  |               return 1; | 
					
						
							|  |  |  |             else | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |               goto nextPeer; | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |         if (((enet_list_empty (& currentPeer -> outgoingCommands) && | 
					
						
							|  |  |  |               enet_list_empty (& currentPeer -> outgoingSendReliableCommands)) || | 
					
						
							|  |  |  |              enet_protocol_check_outgoing_commands (host, currentPeer, & sentUnreliableCommands)) && | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |             enet_list_empty (& currentPeer -> sentReliableCommands) && | 
					
						
							|  |  |  |             ENET_TIME_DIFFERENCE (host -> serviceTime, currentPeer -> lastReceiveTime) >= currentPeer -> pingInterval && | 
					
						
							|  |  |  |             currentPeer -> mtu - host -> packetSize >= sizeof (ENetProtocolPing)) | 
					
						
							|  |  |  |         {  | 
					
						
							|  |  |  |             enet_peer_ping (currentPeer); | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |             enet_protocol_check_outgoing_commands (host, currentPeer, & sentUnreliableCommands); | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (host -> commandCount == 0) | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |           goto nextPeer; | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (currentPeer -> packetLossEpoch == 0) | 
					
						
							|  |  |  |           currentPeer -> packetLossEpoch = host -> serviceTime; | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         if (ENET_TIME_DIFFERENCE (host -> serviceTime, currentPeer -> packetLossEpoch) >= ENET_PEER_PACKET_LOSS_INTERVAL && | 
					
						
							|  |  |  |             currentPeer -> packetsSent > 0) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |            enet_uint32 packetLoss = currentPeer -> packetsLost * ENET_PEER_PACKET_LOSS_SCALE / currentPeer -> packetsSent; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifdef ENET_DEBUG
 | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |            printf ("peer %u: %f%%+-%f%% packet loss, %u+-%u ms round trip time, %f%% throttle, %u outgoing, %u/%u incoming\n", currentPeer -> incomingPeerID, currentPeer -> packetLoss / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> packetLossVariance / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> roundTripTime, currentPeer -> roundTripTimeVariance, currentPeer -> packetThrottle / (float) ENET_PEER_PACKET_THROTTLE_SCALE, enet_list_size (& currentPeer -> outgoingCommands) + enet_list_size (& currentPeer -> outgoingSendReliableCommands), currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingReliableCommands) : 0, currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingUnreliableCommands) : 0); | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-04-21 12:26:42 +02:00
										 |  |  |            currentPeer -> packetLossVariance = (currentPeer -> packetLossVariance * 3 + ENET_DIFFERENCE (packetLoss, currentPeer -> packetLoss)) / 4; | 
					
						
							|  |  |  |            currentPeer -> packetLoss = (currentPeer -> packetLoss * 7 + packetLoss) / 8; | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  |            currentPeer -> packetLossEpoch = host -> serviceTime; | 
					
						
							|  |  |  |            currentPeer -> packetsSent = 0; | 
					
						
							|  |  |  |            currentPeer -> packetsLost = 0; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         host -> buffers -> data = headerData; | 
					
						
							|  |  |  |         if (host -> headerFlags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             header -> sentTime = ENET_HOST_TO_NET_16 (host -> serviceTime & 0xFFFF); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             host -> buffers -> dataLength = sizeof (ENetProtocolHeader); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |           host -> buffers -> dataLength = (size_t) & ((ENetProtocolHeader *) 0) -> sentTime; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         shouldCompress = 0; | 
					
						
							|  |  |  |         if (host -> compressor.context != NULL && host -> compressor.compress != NULL) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             size_t originalSize = host -> packetSize - sizeof(ENetProtocolHeader), | 
					
						
							|  |  |  |                    compressedSize = host -> compressor.compress (host -> compressor.context, | 
					
						
							|  |  |  |                                         & host -> buffers [1], host -> bufferCount - 1, | 
					
						
							|  |  |  |                                         originalSize, | 
					
						
							|  |  |  |                                         host -> packetData [1], | 
					
						
							| 
									
										
										
										
											2020-01-05 19:05:42 +01:00
										 |  |  |                                         originalSize); | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |             if (compressedSize > 0 && compressedSize < originalSize) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_COMPRESSED; | 
					
						
							|  |  |  |                 shouldCompress = compressedSize; | 
					
						
							|  |  |  | #ifdef ENET_DEBUG_COMPRESS
 | 
					
						
							|  |  |  |                 printf ("peer %u: compressed %u -> %u (%u%%)\n", currentPeer -> incomingPeerID, originalSize, compressedSize, (compressedSize * 100) / originalSize); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (currentPeer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID) | 
					
						
							|  |  |  |           host -> headerFlags |= currentPeer -> outgoingSessionID << ENET_PROTOCOL_HEADER_SESSION_SHIFT; | 
					
						
							|  |  |  |         header -> peerID = ENET_HOST_TO_NET_16 (currentPeer -> outgoingPeerID | host -> headerFlags); | 
					
						
							|  |  |  |         if (host -> checksum != NULL) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             enet_uint32 * checksum = (enet_uint32 *) & headerData [host -> buffers -> dataLength]; | 
					
						
							|  |  |  |             * checksum = currentPeer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID ? currentPeer -> connectID : 0; | 
					
						
							|  |  |  |             host -> buffers -> dataLength += sizeof (enet_uint32); | 
					
						
							|  |  |  |             * checksum = host -> checksum (host -> buffers, host -> bufferCount); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (shouldCompress > 0) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             host -> buffers [1].data = host -> packetData [1]; | 
					
						
							|  |  |  |             host -> buffers [1].dataLength = shouldCompress; | 
					
						
							|  |  |  |             host -> bufferCount = 2; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         currentPeer -> lastSendTime = host -> serviceTime; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         sentLength = enet_socket_send (host -> socket, & currentPeer -> address, host -> buffers, host -> bufferCount); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  |         enet_protocol_remove_sent_unreliable_commands (currentPeer, & sentUnreliableCommands); | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if (sentLength < 0) | 
					
						
							|  |  |  |           return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         host -> totalSentData += sentLength; | 
					
						
							|  |  |  |         host -> totalSentPackets ++; | 
					
						
							| 
									
										
										
										
											2023-07-19 09:46:53 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     nextPeer: | 
					
						
							|  |  |  |         if (currentPeer -> flags & ENET_PEER_FLAG_CONTINUE_SENDING) | 
					
						
							|  |  |  |           continueSending = sendPass + 1; | 
					
						
							| 
									
										
										
										
											2016-08-14 13:29:25 -03:00
										 |  |  |     } | 
					
						
							|  |  |  |     | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** Sends any queued packets on the host specified to its designated peers.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @param host   host to flush | 
					
						
							|  |  |  |     @remarks this function need only be used in circumstances where one wishes to send queued packets earlier than in a call to enet_host_service(). | 
					
						
							|  |  |  |     @ingroup host | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | enet_host_flush (ENetHost * host) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     host -> serviceTime = enet_time_get (); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     enet_protocol_send_outgoing_commands (host, NULL, 0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** Checks for any queued events on the host and dispatches one if available.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @param host    host to check for events | 
					
						
							|  |  |  |     @param event   an event structure where event details will be placed if available | 
					
						
							|  |  |  |     @retval > 0 if an event was dispatched | 
					
						
							|  |  |  |     @retval 0 if no events are available | 
					
						
							|  |  |  |     @retval < 0 on failure | 
					
						
							|  |  |  |     @ingroup host | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | enet_host_check_events (ENetHost * host, ENetEvent * event) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (event == NULL) return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     event -> type = ENET_EVENT_TYPE_NONE; | 
					
						
							|  |  |  |     event -> peer = NULL; | 
					
						
							|  |  |  |     event -> packet = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return enet_protocol_dispatch_incoming_commands (host, event); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** Waits for events on the host specified and shuttles packets between
 | 
					
						
							|  |  |  |     the host and its peers. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     @param host    host to service | 
					
						
							|  |  |  |     @param event   an event structure where event details will be placed if one occurs | 
					
						
							|  |  |  |                    if event == NULL then no events will be delivered | 
					
						
							|  |  |  |     @param timeout number of milliseconds that ENet should wait for events | 
					
						
							|  |  |  |     @retval > 0 if an event occurred within the specified time limit | 
					
						
							|  |  |  |     @retval 0 if no event occurred | 
					
						
							|  |  |  |     @retval < 0 on failure | 
					
						
							|  |  |  |     @remarks enet_host_service should be called fairly regularly for adequate performance | 
					
						
							|  |  |  |     @ingroup host | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | int | 
					
						
							|  |  |  | enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     enet_uint32 waitCondition; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (event != NULL) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         event -> type = ENET_EVENT_TYPE_NONE; | 
					
						
							|  |  |  |         event -> peer = NULL; | 
					
						
							|  |  |  |         event -> packet = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         switch (enet_protocol_dispatch_incoming_commands (host, event)) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |         case 1: | 
					
						
							|  |  |  |             return 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         case -1: | 
					
						
							|  |  |  | #ifdef ENET_DEBUG
 | 
					
						
							|  |  |  |             perror ("Error dispatching incoming packets"); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         default: | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     host -> serviceTime = enet_time_get (); | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     timeout += host -> serviceTime; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     do | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |        if (ENET_TIME_DIFFERENCE (host -> serviceTime, host -> bandwidthThrottleEpoch) >= ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL) | 
					
						
							|  |  |  |          enet_host_bandwidth_throttle (host); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        switch (enet_protocol_send_outgoing_commands (host, event, 1)) | 
					
						
							|  |  |  |        { | 
					
						
							|  |  |  |        case 1: | 
					
						
							|  |  |  |           return 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        case -1: | 
					
						
							|  |  |  | #ifdef ENET_DEBUG
 | 
					
						
							|  |  |  |           perror ("Error sending outgoing packets"); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        default: | 
					
						
							|  |  |  |           break; | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        switch (enet_protocol_receive_incoming_commands (host, event)) | 
					
						
							|  |  |  |        { | 
					
						
							|  |  |  |        case 1: | 
					
						
							|  |  |  |           return 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        case -1: | 
					
						
							|  |  |  | #ifdef ENET_DEBUG
 | 
					
						
							|  |  |  |           perror ("Error receiving incoming packets"); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        default: | 
					
						
							|  |  |  |           break; | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        switch (enet_protocol_send_outgoing_commands (host, event, 1)) | 
					
						
							|  |  |  |        { | 
					
						
							|  |  |  |        case 1: | 
					
						
							|  |  |  |           return 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        case -1: | 
					
						
							|  |  |  | #ifdef ENET_DEBUG
 | 
					
						
							|  |  |  |           perror ("Error sending outgoing packets"); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        default: | 
					
						
							|  |  |  |           break; | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        if (event != NULL) | 
					
						
							|  |  |  |        { | 
					
						
							|  |  |  |           switch (enet_protocol_dispatch_incoming_commands (host, event)) | 
					
						
							|  |  |  |           { | 
					
						
							|  |  |  |           case 1: | 
					
						
							|  |  |  |              return 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           case -1: | 
					
						
							|  |  |  | #ifdef ENET_DEBUG
 | 
					
						
							|  |  |  |              perror ("Error dispatching incoming packets"); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |              return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           default: | 
					
						
							|  |  |  |              break; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        if (ENET_TIME_GREATER_EQUAL (host -> serviceTime, timeout)) | 
					
						
							|  |  |  |          return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        do | 
					
						
							|  |  |  |        { | 
					
						
							|  |  |  |           host -> serviceTime = enet_time_get (); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           if (ENET_TIME_GREATER_EQUAL (host -> serviceTime, timeout)) | 
					
						
							|  |  |  |             return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           waitCondition = ENET_SOCKET_WAIT_RECEIVE | ENET_SOCKET_WAIT_INTERRUPT; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           if (enet_socket_wait (host -> socket, & waitCondition, ENET_TIME_DIFFERENCE (timeout, host -> serviceTime)) != 0) | 
					
						
							|  |  |  |             return -1; | 
					
						
							|  |  |  |        } | 
					
						
							|  |  |  |        while (waitCondition & ENET_SOCKET_WAIT_INTERRUPT); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |        host -> serviceTime = enet_time_get (); | 
					
						
							|  |  |  |     } while (waitCondition & ENET_SOCKET_WAIT_RECEIVE); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 0;  | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 |