diff options
author | eihrul <eihrul> | 2010-06-09 21:16:23 +0000 |
---|---|---|
committer | eihrul <eihrul> | 2010-06-09 21:16:23 +0000 |
commit | 572636062e61ad66cc2b4d232394d9de0645baf2 (patch) | |
tree | 1307f92de016aaf9fc32179eff193a820d49c2b6 | |
parent | 2d985dba913f815302b8fb86c9ff0956f3c2f1a3 (diff) | |
download | enet-572636062e61ad66cc2b4d232394d9de0645baf2.tar.gz enet-572636062e61ad66cc2b4d232394d9de0645baf2.zip |
1.3.0 import
-rw-r--r-- | ChangeLog | 17 | ||||
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | callbacks.c | 21 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rwxr-xr-x | docs/mainpage.dox | 11 | ||||
-rwxr-xr-x | docs/tutorial.dox | 4 | ||||
-rwxr-xr-x | enet.dsp | 4 | ||||
-rw-r--r-- | enet_dll.cbp | 3 | ||||
-rw-r--r-- | host.c | 89 | ||||
-rw-r--r-- | include/enet/callbacks.h | 2 | ||||
-rw-r--r-- | include/enet/enet.h | 51 | ||||
-rw-r--r-- | include/enet/protocol.h | 23 | ||||
-rw-r--r-- | peer.c | 6 | ||||
-rw-r--r-- | protocol.c | 198 |
14 files changed, 301 insertions, 132 deletions
@@ -1,3 +1,20 @@ +ENet 1.3.0 (June 5, 2010): + +* enet_host_create() now requires the channel limit to be specified as +a parameter +* enet_host_connect() now accepts a data parameter which is supplied +to the receiving receiving host in the event data field for a connect event +* added an adaptive order-2 PPM range coder as a built-in compressor option +which can be set with enet_host_compress_with_range_coder() +* added support for packet compression configurable with a callback +* improved session number handling to not rely on the packet checksum +field, saving 4 bytes per packet unless the checksum option is used +* removed the dependence on the rand callback for session number handling + +Caveats: This version is not protocol compatible with the 1.2 series or +earlier. The enet_host_connect and enet_host_create API functions require +supplying additional parameters. + ENet 1.2.2 (June 5, 2010): * checksum functionality is now enabled by setting a checksum callback diff --git a/Makefile.am b/Makefile.am index a96f350..d8fb923 100644 --- a/Makefile.am +++ b/Makefile.am @@ -14,7 +14,7 @@ enetinclude_HEADERS = \ include/enet/win32.h lib_LTLIBRARIES = libenet.la -libenet_la_SOURCES = host.c list.c callbacks.c packet.c peer.c protocol.c unix.c win32.c +libenet_la_SOURCES = callbacks.c compress.c host.c list.c packet.c peer.c protocol.c unix.c win32.c # see info '(libtool) Updating version info' before making a release libenet_la_LDFLAGS = $(AM_LDFLAGS) -version-info 0:0:0 INCLUDES = -Iinclude diff --git a/callbacks.c b/callbacks.c index a062694..f941282 100644 --- a/callbacks.c +++ b/callbacks.c @@ -5,11 +5,14 @@ #define ENET_BUILDING_LIB 1 #include "enet/enet.h" -static ENetCallbacks callbacks = { malloc, free, rand, abort }; +static ENetCallbacks callbacks = { malloc, free, abort }; int enet_initialize_with_callbacks (ENetVersion version, const ENetCallbacks * inits) { + if (version < ENET_VERSION_CREATE (1, 3, 0)) + return -1; + if (inits -> malloc != NULL || inits -> free != NULL) { if (inits -> malloc == NULL || inits -> free == NULL) @@ -19,14 +22,8 @@ enet_initialize_with_callbacks (ENetVersion version, const ENetCallbacks * inits callbacks.free = inits -> free; } - if (inits -> rand != NULL) - callbacks.rand = inits -> rand; - - if (version >= ENET_VERSION_CREATE (1, 2, 2)) - { - if (inits -> no_memory != NULL) - callbacks.no_memory = inits -> no_memory; - } + if (inits -> no_memory != NULL) + callbacks.no_memory = inits -> no_memory; return enet_initialize (); } @@ -48,9 +45,3 @@ enet_free (void * memory) callbacks.free (memory); } -int -enet_rand (void) -{ - return callbacks.rand (); -} - diff --git a/configure.ac b/configure.ac index 06a7526..981f4d2 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([libenet], [1.2.2]) +AC_INIT([libenet], [1.3.0]) AC_CONFIG_SRCDIR([include/enet/enet.h]) AM_INIT_AUTOMAKE([foreign]) diff --git a/docs/mainpage.dox b/docs/mainpage.dox index eafb0be..8c32b49 100755 --- a/docs/mainpage.dox +++ b/docs/mainpage.dox @@ -7,10 +7,10 @@ network communication layer on top of UDP (User Datagram Protocol). The primary feature it provides is optional reliable, in-order delivery of packets. -ENet is NOT intended to be a general purpose high level networking -library that handles authentication, lobbying, server discovery, -compression, encryption and other high level, often application level -or dependent tasks. +ENet omits certain higher level networking features such as authentication, +lobbying, server discovery, encryption, or other similar tasks that are +particularly application specific so that the library remains flexible, +portable, and easily embeddable. @ref Features @@ -36,7 +36,8 @@ or dependent tasks. You can retrieve the source to ENet by downloading it in either .tar.gz form or accessing the cvs distribution directly. -The most recent stable release (1.2.2) can be downloaded <a href="http://enet.bespin.org/download/enet-1.2.2.tar.gz">here</a>. +The most recent stable release (1.3.0) can be downloaded <a href="http://enet.bespin.org/download/enet-1.3.0.tar.gz">here</a>. +The last release that is protocol compatible with the 1.2 series or earlier (1.2.2) can be downloaded <a href="http://enet.bespin.org/download/enet-1.3.0.tar.gz">here</a> To access ENet via anonymous CVS, you must use the CVSROOT :pserver:anonymous\@bespin.org:/var/lib/cvs/enet with an empty diff --git a/docs/tutorial.dox b/docs/tutorial.dox index 62e615f..dd911d3 100755 --- a/docs/tutorial.dox +++ b/docs/tutorial.dox @@ -73,6 +73,7 @@ and the resources used by the host will be freed. server = enet_host_create (& address /* the address to bind the server host to */, 32 /* allow up to 32 clients and/or outgoing connections */, + 2 /* allow up to 2 channels to be used, 0 and 1 */, 0 /* assume any amount of incoming bandwidth */, 0 /* assume any amount of outgoing bandwidth */); if (server == NULL) @@ -100,6 +101,7 @@ may be simultaneously open. client = enet_host_create (NULL /* create a client host */, 1 /* only allow 1 outgoing connection */, + 2 /* allow up 2 channels to be used, 0 and 1 */, 57600 / 8 /* 56K modem with 56 Kbps downstream bandwidth */, 14400 / 8 /* 56K modem with 14 Kbps upstream bandwidth */); @@ -321,7 +323,7 @@ ENET_EVENT_TYPE_DISCONNECT will be generated. address.port = 1234; /* Initiate the connection, allocating the two channels 0 and 1. */ - peer = enet_host_connect (client, & address, 2); + peer = enet_host_connect (client, & address, 2, 0); if (peer == NULL) { @@ -101,6 +101,10 @@ SOURCE=.\callbacks.c # End Source File
# Begin Source File
+SOURCE=.\compress.c
+# End Source File
+# Begin Source File
+
SOURCE=.\packet.c
# End Source File
# Begin Source File
diff --git a/enet_dll.cbp b/enet_dll.cbp index fdd264a..961274c 100644 --- a/enet_dll.cbp +++ b/enet_dll.cbp @@ -44,6 +44,9 @@ <Unit filename="callbacks.c"> <Option compilerVar="CC" /> </Unit> + <Unit filename="compress.c"> + <Option compilerVar="CC" /> + </Unit> <Unit filename="host.c"> <Option compilerVar="CC" /> </Unit> @@ -4,6 +4,7 @@ */ #define ENET_BUILDING_LIB 1 #include <string.h> +#include <time.h> #include "enet/enet.h" /** @defgroup host ENet host functions @@ -14,6 +15,7 @@ @param address the address at which other peers may connect to this host. If NULL, then no peers may connect to the host. @param peerCount the maximum number of peers that should be allocated for the host. + @param channelLimit the maximum number of channels allowed; if 0, then this is equivalent to ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT @param incomingBandwidth downstream bandwidth of the host in bytes/second; if 0, ENet will assume unlimited bandwidth. @param outgoingBandwidth upstream bandwidth of the host in bytes/second; if 0, ENet will assume unlimited bandwidth. @@ -25,7 +27,7 @@ at any given time. */ ENetHost * -enet_host_create (const ENetAddress * address, size_t peerCount, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth) +enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelLimit, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth) { ENetHost * host; ENetPeer * currentPeer; @@ -66,7 +68,15 @@ enet_host_create (const ENetAddress * address, size_t peerCount, enet_uint32 inc if (address != NULL) host -> address = * address; - host -> channelLimit = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT; + if (! channelLimit || channelLimit > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT) + channelLimit = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT; + else + if (channelLimit < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT) + channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT; + + host -> randomSeed = (enet_uint32) time(NULL) + (enet_uint32) (size_t) host; + host -> randomSeed = (host -> randomSeed << 16) | (host -> randomSeed >> 16); + host -> channelLimit = channelLimit; host -> incomingBandwidth = incomingBandwidth; host -> outgoingBandwidth = outgoingBandwidth; host -> bandwidthThrottleEpoch = 0; @@ -78,6 +88,7 @@ enet_host_create (const ENetAddress * address, size_t peerCount, enet_uint32 inc host -> checksum = NULL; host -> receivedAddress.host = ENET_HOST_ANY; host -> receivedAddress.port = 0; + host -> receivedData = NULL; host -> receivedDataLength = 0; host -> totalSentData = 0; @@ -85,6 +96,11 @@ enet_host_create (const ENetAddress * address, size_t peerCount, enet_uint32 inc host -> totalReceivedData = 0; host -> totalReceivedPackets = 0; + host -> compressor.context = NULL; + host -> compressor.compress = NULL; + host -> compressor.decompress = NULL; + host -> compressor.destroy = NULL; + enet_list_clear (& host -> dispatchQueue); for (currentPeer = host -> peers; @@ -93,6 +109,7 @@ enet_host_create (const ENetAddress * address, size_t peerCount, enet_uint32 inc { currentPeer -> host = host; currentPeer -> incomingPeerID = currentPeer - host -> peers; + currentPeer -> outgoingSessionID = currentPeer -> incomingSessionID = 0xFF; currentPeer -> data = NULL; enet_list_clear (& currentPeer -> acknowledgements); @@ -104,7 +121,7 @@ enet_host_create (const ENetAddress * address, size_t peerCount, enet_uint32 inc enet_peer_reset (currentPeer); } - + return host; } @@ -125,6 +142,9 @@ enet_host_destroy (ENetHost * host) enet_peer_reset (currentPeer); } + if (host -> compressor.context != NULL && host -> compressor.destroy) + (* host -> compressor.destroy) (host -> compressor.context); + enet_free (host -> peers); enet_free (host); } @@ -133,12 +153,13 @@ enet_host_destroy (ENetHost * host) @param host host seeking the connection @param address destination for the connection @param channelCount number of channels to allocate + @param data user data supplied to the receiving host @returns a peer representing the foreign host on success, NULL on failure @remarks The peer returned will have not completed the connection until enet_host_service() notifies of an ENET_EVENT_TYPE_CONNECT event for the peer. */ ENetPeer * -enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelCount) +enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelCount, enet_uint32 data) { ENetPeer * currentPeer; ENetChannel * channel; @@ -167,7 +188,7 @@ enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelC currentPeer -> channelCount = channelCount; currentPeer -> state = ENET_PEER_STATE_CONNECTING; currentPeer -> address = * address; - currentPeer -> sessionID = (enet_uint32) enet_rand (); + currentPeer -> connectID = ++ host -> randomSeed; if (host -> outgoingBandwidth == 0) currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; @@ -200,7 +221,9 @@ enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelC command.header.command = ENET_PROTOCOL_COMMAND_CONNECT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; command.header.channelID = 0xFF; command.connect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID); - command.connect.mtu = ENET_HOST_TO_NET_16 (currentPeer -> mtu); + command.connect.incomingSessionID = currentPeer -> incomingSessionID; + command.connect.outgoingSessionID = currentPeer -> outgoingSessionID; + command.connect.mtu = ENET_HOST_TO_NET_32 (currentPeer -> mtu); command.connect.windowSize = ENET_HOST_TO_NET_32 (currentPeer -> windowSize); command.connect.channelCount = ENET_HOST_TO_NET_32 (channelCount); command.connect.incomingBandwidth = ENET_HOST_TO_NET_32 (host -> incomingBandwidth); @@ -208,29 +231,14 @@ enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelC command.connect.packetThrottleInterval = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleInterval); command.connect.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleAcceleration); command.connect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleDeceleration); - command.connect.sessionID = currentPeer -> sessionID; - + command.connect.connectID = currentPeer -> connectID; + command.connect.data = ENET_HOST_TO_NET_32 (data); + enet_peer_queue_outgoing_command (currentPeer, & command, NULL, 0, 0); return currentPeer; } -/** Limits the maximum allowed channels of future incoming connections. - @param host host to limit - @param channelLimit the maximum number of channels allowed; if 0, then this is equivalent to ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT -*/ -void -enet_host_channel_limit (ENetHost * host, size_t channelLimit) -{ - if (! channelLimit || channelLimit > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT) - channelLimit = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT; - else - if (channelLimit < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT) - channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT; - - host -> channelLimit = channelLimit; -} - /** Queues a packet to be sent to all peers associated with the host. @param host host on which to broadcast the packet @param channelID channel on which to broadcast @@ -255,6 +263,39 @@ enet_host_broadcast (ENetHost * host, enet_uint8 channelID, ENetPacket * packet) enet_packet_destroy (packet); } +/** Sets the packet compressor the host should use to compress and decompress packets. + @param host host to enable or disable compression for + @param compressor callbacks for for the packet compressor; if NULL, then compression is disabled +*/ +void +enet_host_compress (ENetHost * host, const ENetCompressor * compressor) +{ + if (host -> compressor.context != NULL && host -> compressor.destroy) + (* host -> compressor.destroy) (host -> compressor.context); + + if (compressor) + host -> compressor = * compressor; + else + host -> compressor.context = NULL; +} + +/** Limits the maximum allowed channels of future incoming connections. + @param host host to limit + @param channelLimit the maximum number of channels allowed; if 0, then this is equivalent to ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT +*/ +void +enet_host_channel_limit (ENetHost * host, size_t channelLimit) +{ + if (! channelLimit || channelLimit > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT) + channelLimit = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT; + else + if (channelLimit < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT) + channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT; + + host -> channelLimit = channelLimit; +} + + /** Adjusts the bandwidth limits of a host. @param host host to adjust @param incomingBandwidth new incoming bandwidth diff --git a/include/enet/callbacks.h b/include/enet/callbacks.h index b488ac7..340a4a9 100644 --- a/include/enet/callbacks.h +++ b/include/enet/callbacks.h @@ -11,7 +11,6 @@ typedef struct _ENetCallbacks { void * (ENET_CALLBACK * malloc) (size_t size); void (ENET_CALLBACK * free) (void * memory); - int (ENET_CALLBACK * rand) (void); void (ENET_CALLBACK * no_memory) (void); } ENetCallbacks; @@ -21,7 +20,6 @@ typedef struct _ENetCallbacks */ extern void * enet_malloc (size_t); extern void enet_free (void *); -extern int enet_rand (void); /** @} */ diff --git a/include/enet/enet.h b/include/enet/enet.h index 17a34e7..425e753 100644 --- a/include/enet/enet.h +++ b/include/enet/enet.h @@ -24,8 +24,8 @@ extern "C" #include "enet/callbacks.h" #define ENET_VERSION_MAJOR 1 -#define ENET_VERSION_MINOR 2 -#define ENET_VERSION_PATCH 2 +#define ENET_VERSION_MINOR 3 +#define ENET_VERSION_PATCH 0 #define ENET_VERSION_CREATE(major, minor, patch) (((major)<<16) | ((minor)<<8) | (patch)) #define ENET_VERSION ENET_VERSION_CREATE(ENET_VERSION_MAJOR, ENET_VERSION_MINOR, ENET_VERSION_PATCH) @@ -233,7 +233,9 @@ typedef struct _ENetPeer struct _ENetHost * host; enet_uint16 outgoingPeerID; enet_uint16 incomingPeerID; - enet_uint32 sessionID; + enet_uint32 connectID; + enet_uint8 outgoingSessionID; + enet_uint8 incomingSessionID; ENetAddress address; /**< Internet address of the peer */ void * data; /**< Application private data, may be freely modified */ ENetPeerState state; @@ -267,7 +269,7 @@ typedef struct _ENetPeer enet_uint32 highestRoundTripTimeVariance; enet_uint32 roundTripTime; /**< mean round trip time (RTT), in milliseconds, between sending a reliable packet and receiving its acknowledgement */ enet_uint32 roundTripTimeVariance; - enet_uint16 mtu; + enet_uint32 mtu; enet_uint32 windowSize; enet_uint32 reliableDataInTransit; enet_uint16 outgoingReliableSequenceNumber; @@ -281,15 +283,29 @@ typedef struct _ENetPeer enet_uint16 incomingUnsequencedGroup; enet_uint16 outgoingUnsequencedGroup; enet_uint32 unsequencedWindow [ENET_PEER_UNSEQUENCED_WINDOW_SIZE / 32]; - enet_uint32 disconnectData; + enet_uint32 eventData; } ENetPeer; +/** An ENet packet compressor for compressing UDP packets before socket sends or receives. + */ +typedef struct _ENetCompressor +{ + /**< Context data for the compressor. Must be non-NULL. */ + void * context; + /**< Compresses from inBuffers[0..inBufferCount-1], containing inLimit bytes, to outData, outputting at most outLimit bytes. Should return 0 on failure. */ + size_t (ENET_CALLBACK * compress) (void * context, const ENetBuffer * inBuffers, size_t inBufferCount, size_t inLimit, enet_uint8 * outData, size_t outLimit); + /**< Decompresses from inData, containing inLimit bytes, to outData, outputting at most outLimit bytes. Should return 0 on failure. */ + size_t (ENET_CALLBACK * decompress) (void * context, const enet_uint8 * inData, size_t inLimit, enet_uint8 * outData, size_t outLimit); + /**< Destroys the context when compression is disabled or the host is destroyed. May be NULL. */ + void (ENET_CALLBACK * destroy) (void * context); +} ENetCompressor; + /** Callback that computes the checksum of the data held in buffers [0..bufferCount-1] */ typedef enet_uint32 (ENET_CALLBACK * ENetChecksumCallback) (const ENetBuffer * buffers, size_t bufferCount); - + /** An ENet host for communicating with peers. * - * No fields should be modified. + * No fields should be modified unless otherwise stated. @sa enet_host_create() @sa enet_host_destroy() @@ -297,7 +313,8 @@ typedef enet_uint32 (ENET_CALLBACK * ENetChecksumCallback) (const ENetBuffer * b @sa enet_host_service() @sa enet_host_flush() @sa enet_host_broadcast() - @sa enet_host_checksum() + @sa enet_host_compress() + @sa enet_host_compress_with_range_coder() @sa enet_host_channel_limit() @sa enet_host_bandwidth_limit() @sa enet_host_bandwidth_throttle() @@ -310,6 +327,7 @@ typedef struct _ENetHost enet_uint32 outgoingBandwidth; /**< upstream bandwidth of the host */ enet_uint32 bandwidthThrottleEpoch; enet_uint32 mtu; + enet_uint32 randomSeed; int recalculateBandwidthLimits; ENetPeer * peers; /**< array of peers allocated for this host */ size_t peerCount; /**< number of peers allocated for this host */ @@ -323,9 +341,11 @@ typedef struct _ENetHost size_t commandCount; ENetBuffer buffers [ENET_BUFFER_MAXIMUM]; size_t bufferCount; - ENetChecksumCallback checksum; + ENetChecksumCallback checksum; /**< callback the user can set to enable packet checksums for this host */ + ENetCompressor compressor; + enet_uint8 packetData [2][ENET_PROTOCOL_MAXIMUM_MTU]; ENetAddress receivedAddress; - enet_uint8 receivedData [ENET_PROTOCOL_MAXIMUM_MTU]; + enet_uint8 * receivedData; size_t receivedDataLength; enet_uint32 totalSentData; /**< total data sent, user should reset to 0 as needed to prevent overflow */ enet_uint32 totalSentPackets; /**< total UDP packets sent, user should reset to 0 as needed to prevent overflow */ @@ -475,13 +495,15 @@ ENET_API void enet_packet_destroy (ENetPacket *); ENET_API int enet_packet_resize (ENetPacket *, size_t); extern enet_uint32 enet_crc32 (const ENetBuffer *, size_t); -ENET_API ENetHost * enet_host_create (const ENetAddress *, size_t, enet_uint32, enet_uint32); +ENET_API ENetHost * enet_host_create (const ENetAddress *, size_t, size_t, enet_uint32, enet_uint32); ENET_API void enet_host_destroy (ENetHost *); -ENET_API ENetPeer * enet_host_connect (ENetHost *, const ENetAddress *, size_t); +ENET_API ENetPeer * enet_host_connect (ENetHost *, const ENetAddress *, size_t, enet_uint32); ENET_API int enet_host_check_events (ENetHost *, ENetEvent *); ENET_API int enet_host_service (ENetHost *, ENetEvent *, enet_uint32); ENET_API void enet_host_flush (ENetHost *); ENET_API void enet_host_broadcast (ENetHost *, enet_uint8, ENetPacket *); +ENET_API void enet_host_compress (ENetHost *, const ENetCompressor *); +ENET_API int enet_host_compress_with_range_coder (ENetHost * host); ENET_API void enet_host_channel_limit (ENetHost *, size_t); ENET_API void enet_host_bandwidth_limit (ENetHost *, enet_uint32, enet_uint32); extern void enet_host_bandwidth_throttle (ENetHost *); @@ -503,6 +525,11 @@ extern ENetAcknowledgement * enet_peer_queue_acknowledgement (ENetPeer *, const extern void enet_peer_dispatch_incoming_unreliable_commands (ENetPeer *, ENetChannel *); extern void enet_peer_dispatch_incoming_reliable_commands (ENetPeer *, ENetChannel *); +ENET_API void * enet_range_coder_create (void); +ENET_API void enet_range_coder_destroy (void *); +ENET_API size_t enet_range_coder_compress (void *, const ENetBuffer *, size_t, size_t, enet_uint8 *, size_t); +ENET_API size_t enet_range_coder_decompress (void *, const enet_uint8 *, size_t, enet_uint8 *, size_t); + extern size_t enet_protocol_command_size (enet_uint8); #ifdef __cplusplus diff --git a/include/enet/protocol.h b/include/enet/protocol.h index 4e61cad..19f7e45 100644 --- a/include/enet/protocol.h +++ b/include/enet/protocol.h @@ -16,7 +16,7 @@ enum ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE = 32768, ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT = 1, ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT = 255, - ENET_PROTOCOL_MAXIMUM_PEER_ID = 0x7FFF + ENET_PROTOCOL_MAXIMUM_PEER_ID = 0xFFF }; typedef enum _ENetProtocolCommand @@ -43,8 +43,12 @@ typedef enum _ENetProtocolFlag ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE = (1 << 7), ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED = (1 << 6), - ENET_PROTOCOL_HEADER_FLAG_SENT_TIME = (1 << 15), - ENET_PROTOCOL_HEADER_FLAG_MASK = 0x8000 + ENET_PROTOCOL_HEADER_FLAG_COMPRESSED = (1 << 14), + ENET_PROTOCOL_HEADER_FLAG_SENT_TIME = (1 << 15), + ENET_PROTOCOL_HEADER_FLAG_MASK = ENET_PROTOCOL_HEADER_FLAG_COMPRESSED | ENET_PROTOCOL_HEADER_FLAG_SENT_TIME, + + ENET_PROTOCOL_HEADER_SESSION_MASK = (3 << 12), + ENET_PROTOCOL_HEADER_SESSION_SHIFT = 12 } ENetProtocolFlag; #ifdef _MSC_VER_ @@ -58,7 +62,6 @@ typedef enum _ENetProtocolFlag typedef struct _ENetProtocolHeader { - enet_uint32 checksum; enet_uint16 peerID; enet_uint16 sentTime; } ENET_PACKED ENetProtocolHeader; @@ -81,7 +84,9 @@ typedef struct _ENetProtocolConnect { ENetProtocolCommandHeader header; enet_uint16 outgoingPeerID; - enet_uint16 mtu; + enet_uint8 incomingSessionID; + enet_uint8 outgoingSessionID; + enet_uint32 mtu; enet_uint32 windowSize; enet_uint32 channelCount; enet_uint32 incomingBandwidth; @@ -89,14 +94,17 @@ typedef struct _ENetProtocolConnect enet_uint32 packetThrottleInterval; enet_uint32 packetThrottleAcceleration; enet_uint32 packetThrottleDeceleration; - enet_uint32 sessionID; + enet_uint32 connectID; + enet_uint32 data; } ENET_PACKED ENetProtocolConnect; typedef struct _ENetProtocolVerifyConnect { ENetProtocolCommandHeader header; enet_uint16 outgoingPeerID; - enet_uint16 mtu; + enet_uint8 incomingSessionID; + enet_uint8 outgoingSessionID; + enet_uint32 mtu; enet_uint32 windowSize; enet_uint32 channelCount; enet_uint32 incomingBandwidth; @@ -104,6 +112,7 @@ typedef struct _ENetProtocolVerifyConnect enet_uint32 packetThrottleInterval; enet_uint32 packetThrottleAcceleration; enet_uint32 packetThrottleDeceleration; + enet_uint32 connectID; } ENET_PACKED ENetProtocolVerifyConnect; typedef struct _ENetProtocolBandwidthLimit @@ -325,7 +325,7 @@ void enet_peer_reset (ENetPeer * peer) { peer -> outgoingPeerID = ENET_PROTOCOL_MAXIMUM_PEER_ID; - peer -> sessionID = 0; + peer -> connectID = 0; peer -> state = ENET_PEER_STATE_DISCONNECTED; @@ -363,7 +363,7 @@ enet_peer_reset (ENetPeer * peer) peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; peer -> incomingUnsequencedGroup = 0; peer -> outgoingUnsequencedGroup = 0; - peer -> disconnectData = 0; + peer -> eventData = 0; memset (peer -> unsequencedWindow, 0, sizeof (peer -> unsequencedWindow)); @@ -477,7 +477,7 @@ enet_peer_disconnect_later (ENetPeer * peer, enet_uint32 data) enet_list_empty (& peer -> sentReliableCommands))) { peer -> state = ENET_PEER_STATE_DISCONNECT_LATER; - peer -> disconnectData = data; + peer -> eventData = data; } else enet_peer_disconnect (peer, data); @@ -48,6 +48,7 @@ enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event) event -> type = ENET_EVENT_TYPE_CONNECT; event -> peer = peer; + event -> data = peer -> eventData; return 1; @@ -56,7 +57,7 @@ enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event) event -> type = ENET_EVENT_TYPE_DISCONNECT; event -> peer = peer; - event -> data = peer -> disconnectData; + event -> data = peer -> eventData; enet_peer_reset (peer); @@ -111,6 +112,7 @@ enet_protocol_notify_connect (ENetHost * host, ENetPeer * peer, ENetEvent * even 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); @@ -134,7 +136,11 @@ enet_protocol_notify_disconnect (ENetHost * host, ENetPeer * peer, ENetEvent * e enet_peer_reset (peer); } else + { + peer -> eventData = 0; + enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE); + } } static void @@ -238,31 +244,13 @@ enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint16 reliabl static ENetPeer * enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENetProtocol * command) { - enet_uint16 mtu; - enet_uint32 windowSize; + enet_uint8 incomingSessionID, outgoingSessionID; + enet_uint32 mtu, windowSize; ENetChannel * channel; size_t channelCount; ENetPeer * currentPeer; ENetProtocol verifyCommand; - if (host -> checksum != NULL) - { - enet_uint32 checksum = header -> checksum; - ENetBuffer buffer; - - command -> header.reliableSequenceNumber = ENET_HOST_TO_NET_16 (command -> header.reliableSequenceNumber); - - header -> checksum = command -> connect.sessionID; - - buffer.data = host -> receivedData; - buffer.dataLength = host -> receivedDataLength; - - if (host -> checksum (& buffer, 1) != checksum) - return NULL; - - command -> header.reliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> header.reliableSequenceNumber); - } - channelCount = ENET_NET_TO_HOST_32 (command -> connect.channelCount); if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT || @@ -276,7 +264,7 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet if (currentPeer -> state != ENET_PEER_STATE_DISCONNECTED && currentPeer -> address.host == host -> receivedAddress.host && currentPeer -> address.port == host -> receivedAddress.port && - currentPeer -> sessionID == command -> connect.sessionID) + currentPeer -> connectID == command -> connect.connectID) return NULL; } @@ -298,7 +286,7 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet return NULL; currentPeer -> channelCount = channelCount; currentPeer -> state = ENET_PEER_STATE_ACKNOWLEDGING_CONNECT; - currentPeer -> sessionID = command -> connect.sessionID; + currentPeer -> connectID = command -> connect.connectID; currentPeer -> address = host -> receivedAddress; currentPeer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> connect.outgoingPeerID); currentPeer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.incomingBandwidth); @@ -306,6 +294,19 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet currentPeer -> packetThrottleInterval = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleInterval); currentPeer -> packetThrottleAcceleration = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleAcceleration); currentPeer -> packetThrottleDeceleration = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleDeceleration); + currentPeer -> eventData = ENET_NET_TO_HOST_32 (command -> connect.data); + + incomingSessionID = command -> connect.incomingSessionID == 0xFF ? currentPeer -> outgoingSessionID : command -> connect.incomingSessionID; + incomingSessionID = (incomingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT); + if (incomingSessionID == currentPeer -> outgoingSessionID) + incomingSessionID = (incomingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT); + currentPeer -> outgoingSessionID = incomingSessionID; + + outgoingSessionID = command -> connect.outgoingSessionID == 0xFF ? currentPeer -> incomingSessionID : command -> connect.outgoingSessionID; + outgoingSessionID = (outgoingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT); + if (outgoingSessionID == currentPeer -> incomingSessionID) + outgoingSessionID = (outgoingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT); + currentPeer -> incomingSessionID = outgoingSessionID; for (channel = currentPeer -> channels; channel < & currentPeer -> channels [channelCount]; @@ -322,7 +323,7 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet memset (channel -> reliableWindows, 0, sizeof (channel -> reliableWindows)); } - mtu = ENET_NET_TO_HOST_16 (command -> connect.mtu); + mtu = ENET_NET_TO_HOST_32 (command -> connect.mtu); if (mtu < ENET_PROTOCOL_MINIMUM_MTU) mtu = ENET_PROTOCOL_MINIMUM_MTU; @@ -370,6 +371,8 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet 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 (currentPeer -> incomingPeerID); + verifyCommand.verifyConnect.incomingSessionID = incomingSessionID; + verifyCommand.verifyConnect.outgoingSessionID = outgoingSessionID; verifyCommand.verifyConnect.mtu = ENET_HOST_TO_NET_16 (currentPeer -> mtu); verifyCommand.verifyConnect.windowSize = ENET_HOST_TO_NET_32 (windowSize); verifyCommand.verifyConnect.channelCount = ENET_HOST_TO_NET_32 (channelCount); @@ -378,6 +381,7 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet verifyCommand.verifyConnect.packetThrottleInterval = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleInterval); verifyCommand.verifyConnect.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleAcceleration); verifyCommand.verifyConnect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleDeceleration); + verifyCommand.verifyConnect.connectID = currentPeer -> connectID; enet_peer_queue_outgoing_command (currentPeer, & verifyCommand, NULL, 0, 0); @@ -657,7 +661,9 @@ enet_protocol_handle_disconnect (ENetHost * host, ENetPeer * peer, const ENetPro else enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE); - peer -> disconnectData = ENET_NET_TO_HOST_32 (command -> disconnect.data); + if (peer -> state != ENET_PEER_STATE_DISCONNECTED) + peer -> eventData = ENET_NET_TO_HOST_32 (command -> disconnect.data); + return 0; } @@ -737,7 +743,7 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer * if (enet_list_empty (& peer -> outgoingReliableCommands) && enet_list_empty (& peer -> outgoingUnreliableCommands) && enet_list_empty (& peer -> sentReliableCommands)) - enet_peer_disconnect (peer, peer -> disconnectData); + enet_peer_disconnect (peer, peer -> eventData); break; } @@ -747,8 +753,7 @@ enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer * static int enet_protocol_handle_verify_connect (ENetHost * host, ENetEvent * event, ENetPeer * peer, const ENetProtocol * command) { - enet_uint16 mtu; - enet_uint32 windowSize; + enet_uint32 mtu, windowSize; size_t channelCount; if (peer -> state != ENET_PEER_STATE_CONNECTING) @@ -759,8 +764,11 @@ enet_protocol_handle_verify_connect (ENetHost * host, ENetEvent * event, ENetPee 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) + 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; @@ -772,8 +780,10 @@ enet_protocol_handle_verify_connect (ENetHost * host, ENetEvent * event, ENetPee 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_16 (command -> verifyConnect.mtu); + mtu = ENET_NET_TO_HOST_32 (command -> verifyConnect.mtu); if (mtu < ENET_PROTOCOL_MINIMUM_MTU) mtu = ENET_PROTOCOL_MINIMUM_MTU; @@ -811,15 +821,21 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event) enet_uint8 * currentData; size_t headerSize; enet_uint16 peerID, flags; + enet_uint8 sessionID; - if (host -> receivedDataLength < sizeof (ENetProtocolHeader)) + 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; + 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; @@ -831,34 +847,55 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event) peer = & host -> peers [peerID]; if (peer -> state == ENET_PEER_STATE_DISCONNECTED || - peer -> state == ENET_PEER_STATE_ZOMBIE || + peer -> state == ENET_PEER_STATE_ZOMBIE || (host -> receivedAddress.host != peer -> address.host && - peer -> address.host != ENET_HOST_BROADCAST)) + peer -> address.host != ENET_HOST_BROADCAST) || + (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 = header -> checksum; - ENetBuffer buffer; - - header -> checksum = peer -> sessionID; + if (host -> checksum != NULL) + { + enet_uint32 * checksum = (enet_uint32 *) & host -> receivedData [headerSize - sizeof (enet_uint32)], + desiredChecksum = * checksum; + ENetBuffer buffer; - buffer.data = host -> receivedData; - buffer.dataLength = host -> receivedDataLength; + * checksum = peer != NULL ? peer -> connectID : 0; - if (host -> checksum (& buffer, 1) != checksum) - return 0; - } - else - if (header -> checksum != peer -> sessionID) - return 0; + buffer.data = host -> receivedData; + buffer.dataLength = host -> receivedDataLength; + if (host -> checksum (& buffer, 1) != desiredChecksum) + return 0; + } + + if (peer != NULL) + { peer -> address.host = host -> receivedAddress.host; peer -> address.port = host -> receivedAddress.port; peer -> incomingDataTotal += host -> receivedDataLength; } - headerSize = (flags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME ? sizeof (ENetProtocolHeader) : (size_t) & ((ENetProtocolHeader *) 0) -> sentTime); currentData = host -> receivedData + headerSize; while (currentData < & host -> receivedData [host -> receivedDataLength]) @@ -991,8 +1028,8 @@ enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event) int receivedLength; ENetBuffer buffer; - buffer.data = host -> receivedData; - buffer.dataLength = sizeof (host -> receivedData); + buffer.data = host -> packetData [0]; + buffer.dataLength = sizeof (host -> packetData [0]); receivedLength = enet_socket_receive (host -> socket, & host -> receivedAddress, @@ -1005,6 +1042,7 @@ enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event) if (receivedLength == 0) return 0; + host -> receivedData = host -> packetData [0]; host -> receivedDataLength = receivedLength; host -> totalReceivedData += receivedLength; @@ -1158,7 +1196,7 @@ enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * pee enet_list_empty (& peer -> outgoingReliableCommands) && enet_list_empty (& peer -> outgoingUnreliableCommands) && enet_list_empty (& peer -> sentReliableCommands)) - enet_peer_disconnect (peer, peer -> disconnectData); + enet_peer_disconnect (peer, peer -> eventData); } static int @@ -1321,10 +1359,12 @@ enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer) static int enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int checkForTimeouts) { - ENetProtocolHeader header; + enet_uint8 headerData [sizeof (ENetProtocolHeader) + sizeof (enet_uint32)]; + ENetProtocolHeader * header = (ENetProtocolHeader *) headerData; ENetPeer * currentPeer; int sentLength; - + size_t shouldCompress = 0; + host -> continueSending = 1; while (host -> continueSending) @@ -1403,21 +1443,57 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch currentPeer -> packetsLost = 0; } - header.checksum = currentPeer -> sessionID; - header.peerID = ENET_HOST_TO_NET_16 (currentPeer -> outgoingPeerID | host -> headerFlags); - - host -> buffers -> data = & header; + host -> buffers -> data = headerData; if (host -> headerFlags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME) { - header.sentTime = ENET_HOST_TO_NET_16 (host -> serviceTime & 0xFFFF); + 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], + originalSize); + if (compressedSize > 0 && compressedSize < originalSize) + { + host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_COMPRESSED; + shouldCompress = compressedSize; +#ifdef ENET_DEBUG_COMPRESS +#ifdef WIN32 + printf ( +#else + fprintf (stderr, +#endif + "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) - header.checksum = host -> checksum (host -> buffers, host -> bufferCount); + { + 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; |