void enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel * channel) { ENetListIterator droppedCommand, startCommand, currentCommand; for (droppedCommand = startCommand = currentCommand = enet_list_begin (& channel -> incomingUnreliableCommands); currentCommand != enet_list_end (& channel -> incomingUnreliableCommands); currentCommand = enet_list_next (currentCommand)) { ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand; if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED) continue; else if (incomingCommand -> reliableSequenceNumber != channel -> incomingReliableSequenceNumber) break; else if (incomingCommand -> fragmentsRemaining <= 0) channel -> incomingUnreliableSequenceNumber = incomingCommand -> unreliableSequenceNumber; else if (startCommand == currentCommand) startCommand = enet_list_next (currentCommand); else { enet_list_move (enet_list_end (& peer -> dispatchedCommands), startCommand, enet_list_previous (currentCommand)); if (! peer -> needsDispatch) { enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList); peer -> needsDispatch = 1; } droppedCommand = startCommand = enet_list_next (currentCommand); } } if (startCommand != currentCommand) { enet_list_move (enet_list_end (& peer -> dispatchedCommands), startCommand, enet_list_previous (currentCommand)); if (! peer -> needsDispatch) { enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList); peer -> needsDispatch = 1; } droppedCommand = startCommand = enet_list_next (currentCommand); } enet_peer_remove_incoming_commands (& channel -> incomingUnreliableCommands, enet_list_begin (& channel -> incomingUnreliableCommands), droppedCommand); }
void enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel * channel) { ENetListIterator currentCommand; for (currentCommand = enet_list_begin (& channel -> incomingUnreliableCommands); currentCommand != enet_list_end (& channel -> incomingUnreliableCommands); currentCommand = enet_list_next (currentCommand)) { ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand; if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE) { if (incomingCommand -> reliableSequenceNumber != channel -> incomingReliableSequenceNumber) break; channel -> incomingUnreliableSequenceNumber = incomingCommand -> unreliableSequenceNumber; } } if (currentCommand == enet_list_begin (& channel -> incomingUnreliableCommands)) return; enet_list_move (enet_list_end (& peer -> dispatchedCommands), enet_list_begin (& channel -> incomingUnreliableCommands), enet_list_previous (currentCommand)); if (! peer -> needsDispatch) { enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList); peer -> needsDispatch = 1; } }
static void enet_peer_remove_incoming_commands (ENetList * queue, ENetListIterator startCommand, ENetListIterator endCommand) { ENetListIterator currentCommand; for (currentCommand = startCommand; currentCommand != endCommand; ) { ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand; currentCommand = enet_list_next (currentCommand); enet_list_remove (& incomingCommand -> incomingCommandList); if (incomingCommand -> packet != NULL) { -- incomingCommand -> packet -> referenceCount; if (incomingCommand -> packet -> referenceCount == 0) enet_packet_destroy (incomingCommand -> packet); } if (incomingCommand -> fragments != NULL) enet_free (incomingCommand -> fragments); enet_free (incomingCommand); } }
size_t enet_list_size (ENetList * list) { size_t size = 0; ENetListIterator position; for (position = enet_list_begin (list); position != enet_list_end (list); position = enet_list_next (position)) ++ size; return size; }
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; 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)) break; acknowledgement = (ENetAcknowledgement *) currentAcknowledgement; if (peer -> state == ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT && acknowledgement -> command.header.command != ENET_PROTOCOL_COMMAND_DISCONNECT) continue; currentAcknowledgement = enet_list_next (currentAcknowledgement); buffer -> data = command; buffer -> dataLength = sizeof (ENetProtocolAcknowledge); host -> packetSize += buffer -> dataLength; command -> header.command = ENET_PROTOCOL_COMMAND_ACKNOWLEDGE; command -> header.channelID = acknowledgement -> command.header.channelID; command -> header.flags = 0; command -> header.commandLength = ENET_HOST_TO_NET_32 (sizeof (ENetProtocolAcknowledge)); command -> acknowledge.receivedReliableSequenceNumber = ENET_HOST_TO_NET_32 (acknowledgement -> command.header.reliableSequenceNumber); command -> acknowledge.receivedSentTime = ENET_HOST_TO_NET_32 (acknowledgement -> sentTime); if (acknowledgement -> command.header.command == ENET_PROTOCOL_COMMAND_DISCONNECT) peer -> state = 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; ENetListIterator currentCommand; currentCommand = enet_list_begin (& peer -> sentReliableCommands); while (currentCommand != enet_list_end (& peer -> sentReliableCommands)) { outgoingCommand = (ENetOutgoingCommand *) currentCommand; currentCommand = enet_list_next (currentCommand); if (ENET_TIME_DIFFERENCE (timeCurrent, outgoingCommand -> sentTime) < outgoingCommand -> roundTripTimeout) continue; if (outgoingCommand -> roundTripTimeout >= outgoingCommand -> roundTripTimeoutLimit) { event -> type = ENET_EVENT_TYPE_DISCONNECT; event -> peer = peer; enet_peer_reset (peer); return 1; } if (outgoingCommand -> packet != NULL) peer -> reliableDataInTransit -= outgoingCommand -> fragmentLength; ++ peer -> packetsLost; outgoingCommand -> roundTripTimeout *= 2; enet_list_insert (enet_list_begin (& peer -> outgoingReliableCommands), enet_list_remove (& outgoingCommand -> outgoingCommandList)); if (currentCommand == enet_list_begin (& peer -> sentReliableCommands) && enet_list_empty (& peer -> sentReliableCommands) == 0) { outgoingCommand = (ENetOutgoingCommand *) currentCommand; peer -> nextTimeout = outgoingCommand -> sentTime + outgoingCommand -> roundTripTimeout; } } return 0; }
static ENetProtocolCommand enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint32 reliableSequenceNumber, enet_uint8 channelID) { ENetOutgoingCommand * outgoingCommand; ENetListIterator currentCommand; ENetProtocolCommand commandNumber; 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)) return ENET_PROTOCOL_COMMAND_NONE; commandNumber = outgoingCommand -> command.header.command; enet_list_remove (& outgoingCommand -> outgoingCommandList); if (outgoingCommand -> packet != NULL) { peer -> reliableDataInTransit -= outgoingCommand -> fragmentLength; -- outgoingCommand -> packet -> referenceCount; if (outgoingCommand -> packet -> referenceCount == 0) 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; }
void enet_peer_dispatch_incoming_reliable_commands (ENetPeer * peer, ENetChannel * channel) { enet_uint16 oldReliableSequenceNumber = channel -> incomingReliableSequenceNumber; ENetListIterator currentCommand; for (currentCommand = enet_list_begin (& channel -> incomingReliableCommands); currentCommand != enet_list_end (& channel -> incomingReliableCommands); currentCommand = enet_list_next (currentCommand)) { ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand; if (incomingCommand -> fragmentsRemaining > 0 || incomingCommand -> reliableSequenceNumber != (enet_uint16) (channel -> incomingReliableSequenceNumber + 1)) break; channel -> incomingReliableSequenceNumber = incomingCommand -> reliableSequenceNumber; if (incomingCommand -> fragmentCount > 0) channel -> incomingReliableSequenceNumber += incomingCommand -> fragmentCount - 1; } if (currentCommand == enet_list_begin (& channel -> incomingReliableCommands)) return; channel -> incomingUnreliableSequenceNumber = 0; enet_list_move (enet_list_end (& peer -> dispatchedCommands), enet_list_begin (& channel -> incomingReliableCommands), enet_list_previous (currentCommand)); if (! peer -> needsDispatch) { enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList); peer -> needsDispatch = 1; } if (! enet_list_empty (& channel -> incomingUnreliableCommands)) enet_peer_dispatch_incoming_unreliable_commands (peer, channel); }
ENetIncomingCommand * enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command, ENetPacket * packet, enet_uint32 fragmentCount) { static ENetIncomingCommand dummyCommand; ENetChannel * channel = & peer -> channels [command -> header.channelID]; enet_uint32 unreliableSequenceNumber = 0, reliableSequenceNumber; enet_uint16 reliableWindow, currentWindow; ENetIncomingCommand * incomingCommand; ENetListIterator currentCommand; if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER) goto freePacket; if ((command -> header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED) { reliableSequenceNumber = command -> header.reliableSequenceNumber; 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) goto freePacket; } switch (command -> header.command & ENET_PROTOCOL_COMMAND_MASK) { case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT: case ENET_PROTOCOL_COMMAND_SEND_RELIABLE: if (reliableSequenceNumber == channel -> incomingReliableSequenceNumber) goto freePacket; for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands)); currentCommand != enet_list_end (& channel -> incomingReliableCommands); currentCommand = enet_list_previous (currentCommand)) { incomingCommand = (ENetIncomingCommand *) currentCommand; if (reliableSequenceNumber >= channel -> incomingReliableSequenceNumber) { if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber) continue; } else if (incomingCommand -> reliableSequenceNumber >= channel -> incomingReliableSequenceNumber) break; if (incomingCommand -> reliableSequenceNumber <= reliableSequenceNumber) { if (incomingCommand -> reliableSequenceNumber < reliableSequenceNumber) break; goto freePacket; } } break; case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE: unreliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> sendUnreliable.unreliableSequenceNumber); if (reliableSequenceNumber == channel -> incomingReliableSequenceNumber && unreliableSequenceNumber <= channel -> incomingUnreliableSequenceNumber) goto freePacket; for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingUnreliableCommands)); currentCommand != enet_list_end (& channel -> incomingUnreliableCommands); currentCommand = enet_list_previous (currentCommand)) { incomingCommand = (ENetIncomingCommand *) currentCommand; if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE) continue; 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 <= unreliableSequenceNumber) { if (incomingCommand -> unreliableSequenceNumber < unreliableSequenceNumber) break; goto freePacket; } } break; case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED: currentCommand = enet_list_end (& channel -> incomingUnreliableCommands); break; default: goto freePacket; } incomingCommand = (ENetIncomingCommand *) enet_malloc (sizeof (ENetIncomingCommand)); if (incomingCommand == NULL) goto notifyError; incomingCommand -> reliableSequenceNumber = command -> header.reliableSequenceNumber; incomingCommand -> unreliableSequenceNumber = unreliableSequenceNumber & 0xFFFF; incomingCommand -> command = * command; incomingCommand -> fragmentCount = fragmentCount; incomingCommand -> fragmentsRemaining = fragmentCount; incomingCommand -> packet = packet; incomingCommand -> fragments = NULL; if (fragmentCount > 0) { incomingCommand -> fragments = (enet_uint32 *) enet_malloc ((fragmentCount + 31) / 32 * sizeof (enet_uint32)); if (incomingCommand -> fragments == NULL) { enet_free (incomingCommand); goto notifyError; } memset (incomingCommand -> fragments, 0, (fragmentCount + 31) / 32 * sizeof (enet_uint32)); } if (packet != NULL) ++ packet -> referenceCount; enet_list_insert (enet_list_next (currentCommand), incomingCommand); switch (command -> header.command & ENET_PROTOCOL_COMMAND_MASK) { case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT: case ENET_PROTOCOL_COMMAND_SEND_RELIABLE: enet_peer_dispatch_incoming_reliable_commands (peer, channel); break; default: enet_peer_dispatch_incoming_unreliable_commands (peer, channel); break; } return incomingCommand; freePacket: if (fragmentCount > 0) goto notifyError; if (packet != NULL && packet -> referenceCount == 0) enet_packet_destroy (packet); return & dummyCommand; notifyError: if (packet != NULL && packet -> referenceCount == 0) enet_packet_destroy (packet); return NULL; }
ENetIncomingCommand * enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command, ENetPacket * packet, enet_uint32 fragmentCount) { ENetChannel * channel = & peer -> channels [command -> header.channelID]; enet_uint32 unreliableSequenceNumber = 0; ENetIncomingCommand * incomingCommand; ENetListIterator currentCommand; switch (command -> header.command) { case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT: case ENET_PROTOCOL_COMMAND_SEND_RELIABLE: for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands)); currentCommand != enet_list_end (& channel -> incomingReliableCommands); currentCommand = enet_list_previous (currentCommand)) { incomingCommand = (ENetIncomingCommand *) currentCommand; if (incomingCommand -> reliableSequenceNumber <= command -> header.reliableSequenceNumber) { if (incomingCommand -> reliableSequenceNumber < command -> header.reliableSequenceNumber) break; goto freePacket; } } break; case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE: unreliableSequenceNumber = ENET_NET_TO_HOST_32 (command -> sendUnreliable.unreliableSequenceNumber); if (command -> header.reliableSequenceNumber < channel -> incomingReliableSequenceNumber) goto freePacket; if (unreliableSequenceNumber <= channel -> incomingUnreliableSequenceNumber) goto freePacket; for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingUnreliableCommands)); currentCommand != enet_list_end (& channel -> incomingUnreliableCommands); currentCommand = enet_list_previous (currentCommand)) { incomingCommand = (ENetIncomingCommand *) currentCommand; if (incomingCommand -> unreliableSequenceNumber <= unreliableSequenceNumber) { if (incomingCommand -> unreliableSequenceNumber < unreliableSequenceNumber) break; goto freePacket; } } break; case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED: currentCommand = enet_list_end (& channel -> incomingUnreliableCommands); break; default: goto freePacket; } incomingCommand = (ENetIncomingCommand *) enet_malloc (sizeof (ENetIncomingCommand)); incomingCommand -> reliableSequenceNumber = command -> header.reliableSequenceNumber; incomingCommand -> unreliableSequenceNumber = unreliableSequenceNumber; incomingCommand -> command = * command; incomingCommand -> fragmentCount = fragmentCount; incomingCommand -> fragmentsRemaining = fragmentCount; incomingCommand -> packet = packet; incomingCommand -> fragments = NULL; if (fragmentCount > 0) { incomingCommand -> fragments = (enet_uint32 *) enet_malloc ((fragmentCount + 31) / 32 * sizeof (enet_uint32)); memset (incomingCommand -> fragments, 0, (fragmentCount + 31) / 32 * sizeof (enet_uint32)); } if (packet != NULL) ++ packet -> referenceCount; enet_list_insert (enet_list_next (currentCommand), incomingCommand); return incomingCommand; freePacket: if (packet != NULL) { if (packet -> referenceCount == 0) enet_packet_destroy (packet); } return NULL; }
void enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel * channel) { ENetListIterator droppedCommand, startCommand, currentCommand; for (droppedCommand = startCommand = currentCommand = enet_list_begin (& channel -> incomingUnreliableCommands); currentCommand != enet_list_end (& channel -> incomingUnreliableCommands); currentCommand = enet_list_next (currentCommand)) { ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand; if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED) continue; if (incomingCommand -> reliableSequenceNumber == channel -> incomingReliableSequenceNumber) { if (incomingCommand -> fragmentsRemaining <= 0) { channel -> incomingUnreliableSequenceNumber = incomingCommand -> unreliableSequenceNumber; continue; } if (startCommand != currentCommand) { enet_list_move (enet_list_end (& peer -> dispatchedCommands), startCommand, enet_list_previous (currentCommand)); if (! peer -> needsDispatch) { enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList); peer -> needsDispatch = 1; } droppedCommand = currentCommand; } else if (droppedCommand != currentCommand) droppedCommand = enet_list_previous (currentCommand); } else { enet_uint16 reliableWindow = incomingCommand -> reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE, currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber) reliableWindow += ENET_PEER_RELIABLE_WINDOWS; if (reliableWindow >= currentWindow && reliableWindow < currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1) break; droppedCommand = enet_list_next (currentCommand); if (startCommand != currentCommand) { enet_list_move (enet_list_end (& peer -> dispatchedCommands), startCommand, enet_list_previous (currentCommand)); if (! peer -> needsDispatch) { enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList); peer -> needsDispatch = 1; } } } startCommand = enet_list_next (currentCommand); } if (startCommand != currentCommand) { enet_list_move (enet_list_end (& peer -> dispatchedCommands), startCommand, enet_list_previous (currentCommand)); if (! peer -> needsDispatch) { enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList); peer -> needsDispatch = 1; } droppedCommand = currentCommand; } enet_peer_remove_incoming_commands (& channel -> incomingUnreliableCommands, enet_list_begin (& channel -> incomingUnreliableCommands), droppedCommand); }
static void enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer) { ENetProtocol * command = & host -> commands [host -> commandCount]; ENetBuffer * buffer = & host -> buffers [host -> bufferCount]; ENetOutgoingCommand * outgoingCommand; ENetListIterator currentCommand; currentCommand = enet_list_begin (& peer -> outgoingReliableCommands); while (currentCommand != enet_list_end (& peer -> outgoingReliableCommands)) { outgoingCommand = (ENetOutgoingCommand *) currentCommand; if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] || buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] || peer -> mtu - host -> packetSize < outgoingCommand -> command.header.commandLength) break; currentCommand = enet_list_next (currentCommand); if (outgoingCommand -> packet != NULL) { if ((enet_uint16) (peer -> mtu - host -> packetSize) < (enet_uint16) (outgoingCommand -> command.header.commandLength + outgoingCommand -> fragmentLength) || peer -> reliableDataInTransit + outgoingCommand -> fragmentLength > peer -> windowSize) break; } if (outgoingCommand -> roundTripTimeout == 0) { outgoingCommand -> roundTripTimeout = peer -> roundTripTime + 4 * peer -> roundTripTimeVariance; outgoingCommand -> roundTripTimeoutLimit = ENET_PEER_TIMEOUT_LIMIT * outgoingCommand -> roundTripTimeout; } if (enet_list_empty (& peer -> sentReliableCommands)) peer -> nextTimeout = timeCurrent + outgoingCommand -> roundTripTimeout; enet_list_insert (enet_list_end (& peer -> sentReliableCommands), enet_list_remove (& outgoingCommand -> outgoingCommandList)); outgoingCommand -> sentTime = timeCurrent; buffer -> data = command; buffer -> dataLength = outgoingCommand -> command.header.commandLength; host -> packetSize += buffer -> dataLength; * command = outgoingCommand -> command; if (outgoingCommand -> packet != NULL) { ++ buffer; buffer -> data = outgoingCommand -> packet -> data + outgoingCommand -> fragmentOffset; buffer -> dataLength = outgoingCommand -> fragmentLength; command -> header.commandLength += outgoingCommand -> fragmentLength; host -> packetSize += outgoingCommand -> fragmentLength; peer -> reliableDataInTransit += outgoingCommand -> fragmentLength; } command -> header.commandLength = ENET_HOST_TO_NET_32 (command -> header.commandLength); ++ peer -> packetsSent; ++ command; ++ buffer; } host -> commandCount = command - host -> commands; host -> bufferCount = buffer - host -> buffers; }
static void enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * peer) { ENetProtocol * command = & host -> commands [host -> commandCount]; ENetBuffer * buffer = & host -> buffers [host -> bufferCount]; ENetOutgoingCommand * outgoingCommand; ENetListIterator currentCommand; currentCommand = enet_list_begin (& peer -> outgoingUnreliableCommands); while (currentCommand != enet_list_end (& peer -> outgoingUnreliableCommands)) { outgoingCommand = (ENetOutgoingCommand *) currentCommand; if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] || buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] || peer -> mtu - host -> packetSize < outgoingCommand -> command.header.commandLength || (outgoingCommand -> packet != NULL && peer -> mtu - host -> packetSize < outgoingCommand -> command.header.commandLength + outgoingCommand -> packet -> dataLength)) break; currentCommand = enet_list_next (currentCommand); if (outgoingCommand -> packet != NULL) { peer -> packetThrottleCounter += ENET_PEER_PACKET_THROTTLE_COUNTER; peer -> packetThrottleCounter %= ENET_PEER_PACKET_THROTTLE_SCALE; if (peer -> packetThrottleCounter > peer -> packetThrottle) { -- outgoingCommand -> packet -> referenceCount; if (outgoingCommand -> packet -> referenceCount == 0) enet_packet_destroy (outgoingCommand -> packet); enet_list_remove (& outgoingCommand -> outgoingCommandList); enet_free (outgoingCommand); continue; } } buffer -> data = command; buffer -> dataLength = outgoingCommand -> command.header.commandLength; host -> packetSize += buffer -> dataLength; * command = outgoingCommand -> command; enet_list_remove (& outgoingCommand -> outgoingCommandList); if (outgoingCommand -> packet != NULL) { ++ buffer; buffer -> data = outgoingCommand -> packet -> data; buffer -> dataLength = outgoingCommand -> packet -> dataLength; command -> header.commandLength += buffer -> dataLength; host -> packetSize += buffer -> dataLength; enet_list_insert (enet_list_end (& peer -> sentUnreliableCommands), outgoingCommand); } else enet_free (outgoingCommand); command -> header.commandLength = ENET_HOST_TO_NET_32 (command -> header.commandLength); ++ command; ++ buffer; } host -> commandCount = command - host -> commands; host -> bufferCount = buffer - host -> buffers; }