├── ChangeLog ├── LICENSE ├── README.rst ├── build.sh └── jni ├── Android.mk ├── Application.mk ├── Makefile ├── callbacks.c ├── compress.c ├── enet ├── callbacks.h ├── enet.h ├── list.h ├── protocol.h ├── time.h ├── types.h ├── unix.h ├── utility.h └── win32.h ├── host.c ├── list.c ├── packet.c ├── peer.c ├── protocol.c ├── unix.c └── win32.c /ChangeLog: -------------------------------------------------------------------------------- 1 | Android port (Dec, 2010): 2 | * Added Application.mk and Android.mk 3 | 4 | ENet 1.3.0 (June 5, 2010): 5 | 6 | * enet_host_create() now requires the channel limit to be specified as 7 | a parameter 8 | * enet_host_connect() now accepts a data parameter which is supplied 9 | to the receiving receiving host in the event data field for a connect event 10 | * added an adaptive order-2 PPM range coder as a built-in compressor option 11 | which can be set with enet_host_compress_with_range_coder() 12 | * added support for packet compression configurable with a callback 13 | * improved session number handling to not rely on the packet checksum 14 | field, saving 4 bytes per packet unless the checksum option is used 15 | * removed the dependence on the rand callback for session number handling 16 | 17 | Caveats: This version is not protocol compatible with the 1.2 series or 18 | earlier. The enet_host_connect and enet_host_create API functions require 19 | supplying additional parameters. 20 | 21 | ENet 1.2.2 (June 5, 2010): 22 | 23 | * checksum functionality is now enabled by setting a checksum callback 24 | inside ENetHost instead of being a configure script option 25 | * added totalSentData, totalSentPackets, totalReceivedData, and 26 | totalReceivedPackets counters inside ENetHost for getting usage 27 | statistics 28 | * added enet_host_channel_limit() for limiting the maximum number of 29 | channels allowed by connected peers 30 | * now uses dispatch queues for event dispatch rather than potentially 31 | unscalable array walking 32 | * added no_memory callback that is called when a malloc attempt fails, 33 | such that if no_memory returns rather than aborts (the default behavior), 34 | then the error is propagated to the return value of the API calls 35 | * now uses packed attribute for protocol structures on platforms with 36 | strange alignment rules 37 | * improved autoconf build system contributed by Nathan Brink allowing 38 | for easier building as a shared library 39 | 40 | Caveats: If you were using the compile-time option that enabled checksums, 41 | make sure to set the checksum callback inside ENetHost to enet_crc32 to 42 | regain the old behavior. The ENetCallbacks structure has added new fields, 43 | so make sure to clear the structure to zero before use if 44 | using enet_initialize_with_callbacks(). 45 | 46 | ENet 1.2.1 (November 12, 2009): 47 | 48 | * fixed bug that could cause disconnect events to be dropped 49 | * added thin wrapper around select() for portable usage 50 | * added ENET_SOCKOPT_REUSEADDR socket option 51 | * factored enet_socket_bind()/enet_socket_listen() out of enet_socket_create() 52 | * added contributed Code::Blocks build file 53 | 54 | ENet 1.2 (February 12, 2008): 55 | 56 | * fixed bug in VERIFY_CONNECT acknowledgement that could cause connect 57 | attempts to occasionally timeout 58 | * fixed acknowledgements to check both the outgoing and sent queues 59 | when removing acknowledged packets 60 | * fixed accidental bit rot in the MSVC project file 61 | * revised sequence number overflow handling to address some possible 62 | disconnect bugs 63 | * added enet_host_check_events() for getting only local queued events 64 | * factored out socket option setting into enet_socket_set_option() so 65 | that socket options are now set separately from enet_socket_create() 66 | 67 | Caveats: While this release is superficially protocol compatible with 1.1, 68 | differences in the sequence number overflow handling can potentially cause 69 | random disconnects. 70 | 71 | ENet 1.1 (June 6, 2007): 72 | 73 | * optional CRC32 just in case someone needs a stronger checksum than UDP 74 | provides (--enable-crc32 configure option) 75 | * the size of packet headers are half the size they used to be (so less 76 | overhead when sending small packets) 77 | * enet_peer_disconnect_later() that waits till all queued outgoing 78 | packets get sent before issuing an actual disconnect 79 | * freeCallback field in individual packets for notification of when a 80 | packet is about to be freed 81 | * ENET_PACKET_FLAG_NO_ALLOCATE for supplying pre-allocated data to a 82 | packet (can be used in concert with freeCallback to support some custom 83 | allocation schemes that the normal memory allocation callbacks would 84 | normally not allow) 85 | * enet_address_get_host_ip() for printing address numbers 86 | * promoted the enet_socket_*() functions to be part of the API now 87 | * a few stability/crash fixes 88 | 89 | 90 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2002-2010 Lee Salzman 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | ENet for Android 2 | ================ 3 | This is a repackaging of the ENet 1.3 network library for Android NDK by Julien Rebetez. 4 | 5 | ENet has been written by Lee Salzman and the original ENet homepage is http://enet.bespin.org 6 | 7 | Assuming the 'ndk-build' tool is in your path, you can build the enet as a static library by simply using the 'build.sh' script. 8 | 9 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ndk-build NDK_PROJECT_PATH=./ $@ 3 | -------------------------------------------------------------------------------- /jni/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | include $(CLEAR_VARS) 3 | 4 | LOCAL_CFLAGS := -DHAS_SOCKLEN_T 5 | 6 | LOCAL_MODULE := libenet 7 | LOCAL_SRC_FILES :=\ 8 | callbacks.c \ 9 | compress.c \ 10 | host.c \ 11 | list.c \ 12 | packet.c \ 13 | peer.c \ 14 | protocol.c \ 15 | unix.c 16 | 17 | LOCAL_LDLIBS := 18 | 19 | #include $(BUILD_SHARED_LIBRARY) 20 | include $(BUILD_STATIC_LIBRARY) 21 | -------------------------------------------------------------------------------- /jni/Application.mk: -------------------------------------------------------------------------------- 1 | APP_OPTIM := release 2 | APP_MODULES := libenet 3 | -------------------------------------------------------------------------------- /jni/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=-c -Wall -DHAS_SOCKLEN_T -I. -fPIC 3 | LDFLAGS= 4 | SOURCES=list.c callbacks.c compress.c host.c packet.c protocol.c peer.c unix.c 5 | OBJECTS=$(SOURCES:.c=.o) 6 | LIBRARY=../bin/linux/libenet.a 7 | 8 | 9 | all: $(SOURCES) $(LIBRARY) 10 | 11 | $(LIBRARY): $(OBJECTS) 12 | mkdir -p ../bin/linux 13 | #gcc -shared -o $(LIBRARY) $(OBJECTS) 14 | ar rcs $(LIBRARY) $(OBJECTS) 15 | 16 | .c.o: 17 | $(CC) $(CFLAGS) $< -o $@ 18 | 19 | clean: 20 | rm -f $(LIBRARY) 21 | rm -f *.o 22 | -------------------------------------------------------------------------------- /jni/callbacks.c: -------------------------------------------------------------------------------- 1 | /** 2 | @file callbacks.c 3 | @brief ENet callback functions 4 | */ 5 | #define ENET_BUILDING_LIB 1 6 | #include "enet/enet.h" 7 | 8 | static ENetCallbacks callbacks = { malloc, free, abort }; 9 | 10 | int 11 | enet_initialize_with_callbacks (ENetVersion version, const ENetCallbacks * inits) 12 | { 13 | if (version < ENET_VERSION_CREATE (1, 3, 0)) 14 | return -1; 15 | 16 | if (inits -> malloc != NULL || inits -> free != NULL) 17 | { 18 | if (inits -> malloc == NULL || inits -> free == NULL) 19 | return -1; 20 | 21 | callbacks.malloc = inits -> malloc; 22 | callbacks.free = inits -> free; 23 | } 24 | 25 | if (inits -> no_memory != NULL) 26 | callbacks.no_memory = inits -> no_memory; 27 | 28 | return enet_initialize (); 29 | } 30 | 31 | void * 32 | enet_malloc (size_t size) 33 | { 34 | void * memory = callbacks.malloc (size); 35 | 36 | if (memory == NULL) 37 | callbacks.no_memory (); 38 | 39 | return memory; 40 | } 41 | 42 | void 43 | enet_free (void * memory) 44 | { 45 | callbacks.free (memory); 46 | } 47 | 48 | -------------------------------------------------------------------------------- /jni/compress.c: -------------------------------------------------------------------------------- 1 | /** 2 | @file compress.c 3 | @brief An adaptive order-2 PPM range coder 4 | */ 5 | #define ENET_BUILDING_LIB 1 6 | #include 7 | #include "enet/enet.h" 8 | 9 | typedef struct _ENetSymbol 10 | { 11 | /* binary indexed tree of symbols */ 12 | enet_uint8 value; 13 | enet_uint8 count; 14 | enet_uint16 under; 15 | enet_uint16 left, right; 16 | 17 | /* context defined by this symbol */ 18 | enet_uint16 symbols; 19 | enet_uint16 escapes; 20 | enet_uint16 total; 21 | enet_uint16 parent; 22 | } ENetSymbol; 23 | 24 | /* adaptation constants tuned aggressively for small packet sizes rather than large file compression */ 25 | enum 26 | { 27 | ENET_RANGE_CODER_TOP = 1<<24, 28 | ENET_RANGE_CODER_BOTTOM = 1<<16, 29 | 30 | ENET_CONTEXT_SYMBOL_DELTA = 3, 31 | ENET_CONTEXT_SYMBOL_MINIMUM = 1, 32 | ENET_CONTEXT_ESCAPE_MINIMUM = 1, 33 | 34 | ENET_SUBCONTEXT_ORDER = 2, 35 | ENET_SUBCONTEXT_SYMBOL_DELTA = 2, 36 | ENET_SUBCONTEXT_ESCAPE_DELTA = 5 37 | }; 38 | 39 | /* context exclusion roughly halves compression speed, so disable for now */ 40 | #undef ENET_CONTEXT_EXCLUSION 41 | 42 | typedef struct _ENetRangeCoder 43 | { 44 | /* only allocate enough symbols for reasonable MTUs, would need to be larger for large file compression */ 45 | ENetSymbol symbols[4096]; 46 | } ENetRangeCoder; 47 | 48 | void * 49 | enet_range_coder_create (void) 50 | { 51 | ENetRangeCoder * rangeCoder = (ENetRangeCoder *) enet_malloc (sizeof (ENetRangeCoder)); 52 | if (rangeCoder == NULL) 53 | return NULL; 54 | 55 | return rangeCoder; 56 | } 57 | 58 | void 59 | enet_range_coder_destroy (void * context) 60 | { 61 | ENetRangeCoder * rangeCoder = (ENetRangeCoder *) context; 62 | if (rangeCoder == NULL) 63 | return; 64 | 65 | enet_free (rangeCoder); 66 | } 67 | 68 | #define ENET_SYMBOL_CREATE(symbol, value_, count_) \ 69 | { \ 70 | symbol = & rangeCoder -> symbols [nextSymbol ++]; \ 71 | symbol -> value = value_; \ 72 | symbol -> count = count_; \ 73 | symbol -> under = count_; \ 74 | symbol -> left = 0; \ 75 | symbol -> right = 0; \ 76 | symbol -> symbols = 0; \ 77 | symbol -> escapes = 0; \ 78 | symbol -> total = 0; \ 79 | symbol -> parent = 0; \ 80 | } 81 | 82 | #define ENET_CONTEXT_CREATE(context, escapes_, minimum) \ 83 | { \ 84 | ENET_SYMBOL_CREATE (context, 0, 0); \ 85 | (context) -> escapes = escapes_; \ 86 | (context) -> total = escapes_ + 256*minimum; \ 87 | (context) -> symbols = 0; \ 88 | } 89 | 90 | static enet_uint16 91 | enet_symbol_rescale (ENetSymbol * symbol) 92 | { 93 | enet_uint16 total = 0; 94 | for (;;) 95 | { 96 | symbol -> count -= symbol->count >> 1; 97 | symbol -> under = symbol -> count; 98 | if (symbol -> left) 99 | symbol -> under += enet_symbol_rescale (symbol + symbol -> left); 100 | total += symbol -> under; 101 | if (! symbol -> right) break; 102 | symbol += symbol -> right; 103 | } 104 | return total; 105 | } 106 | 107 | #define ENET_CONTEXT_RESCALE(context, minimum) \ 108 | { \ 109 | (context) -> total = (context) -> symbols ? enet_symbol_rescale ((context) + (context) -> symbols) : 0; \ 110 | (context) -> escapes -= (context) -> escapes >> 1; \ 111 | (context) -> total += (context) -> escapes + 256*minimum; \ 112 | } 113 | 114 | #define ENET_RANGE_CODER_OUTPUT(value) \ 115 | { \ 116 | if (outData >= outEnd) \ 117 | return 0; \ 118 | * outData ++ = value; \ 119 | } 120 | 121 | #define ENET_RANGE_CODER_ENCODE(under, count, total) \ 122 | { \ 123 | encodeRange /= (total); \ 124 | encodeLow += (under) * encodeRange; \ 125 | encodeRange *= (count); \ 126 | for (;;) \ 127 | { \ 128 | if((encodeLow ^ (encodeLow + encodeRange)) >= ENET_RANGE_CODER_TOP) \ 129 | { \ 130 | if(encodeRange >= ENET_RANGE_CODER_BOTTOM) break; \ 131 | encodeRange = -encodeLow & (ENET_RANGE_CODER_BOTTOM - 1); \ 132 | } \ 133 | ENET_RANGE_CODER_OUTPUT (encodeLow >> 24); \ 134 | encodeRange <<= 8; \ 135 | encodeLow <<= 8; \ 136 | } \ 137 | } 138 | 139 | #define ENET_RANGE_CODER_FLUSH \ 140 | { \ 141 | while (encodeLow) \ 142 | { \ 143 | ENET_RANGE_CODER_OUTPUT (encodeLow >> 24); \ 144 | encodeLow <<= 8; \ 145 | } \ 146 | } 147 | 148 | #define ENET_RANGE_CODER_FREE_SYMBOLS \ 149 | { \ 150 | if (nextSymbol >= sizeof (rangeCoder -> symbols) / sizeof (ENetSymbol) - ENET_SUBCONTEXT_ORDER ) \ 151 | { \ 152 | nextSymbol = 0; \ 153 | ENET_CONTEXT_CREATE (root, ENET_CONTEXT_ESCAPE_MINIMUM, ENET_CONTEXT_SYMBOL_MINIMUM); \ 154 | predicted = 0; \ 155 | order = 0; \ 156 | } \ 157 | } 158 | 159 | #define ENET_CONTEXT_ENCODE(context, symbol_, value_, under_, count_, update, minimum) \ 160 | { \ 161 | under_ = value*minimum; \ 162 | count_ = minimum; \ 163 | if (! (context) -> symbols) \ 164 | { \ 165 | ENET_SYMBOL_CREATE (symbol_, value_, update); \ 166 | (context) -> symbols = symbol_ - (context); \ 167 | } \ 168 | else \ 169 | { \ 170 | ENetSymbol * node = (context) + (context) -> symbols; \ 171 | for (;;) \ 172 | { \ 173 | if (value_ < node -> value) \ 174 | { \ 175 | node -> under += update; \ 176 | if (node -> left) { node += node -> left; continue; } \ 177 | ENET_SYMBOL_CREATE (symbol_, value_, update); \ 178 | node -> left = symbol_ - node; \ 179 | } \ 180 | else \ 181 | if (value_ > node -> value) \ 182 | { \ 183 | under_ += node -> under; \ 184 | if (node -> right) { node += node -> right; continue; } \ 185 | ENET_SYMBOL_CREATE (symbol_, value_, update); \ 186 | node -> right = symbol_ - node; \ 187 | } \ 188 | else \ 189 | { \ 190 | count_ += node -> count; \ 191 | under_ += node -> under - node -> count; \ 192 | node -> under += update; \ 193 | node -> count += update; \ 194 | symbol_ = node; \ 195 | } \ 196 | break; \ 197 | } \ 198 | } \ 199 | } 200 | 201 | #ifdef ENET_CONTEXT_EXCLUSION 202 | static const ENetSymbol emptyContext = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 203 | 204 | #define ENET_CONTEXT_WALK(context, body) \ 205 | { \ 206 | const ENetSymbol * node = (context) + (context) -> symbols; \ 207 | const ENetSymbol * stack [256]; \ 208 | size_t stackSize = 0; \ 209 | while (node -> left) \ 210 | { \ 211 | stack [stackSize ++] = node; \ 212 | node += node -> left; \ 213 | } \ 214 | for (;;) \ 215 | { \ 216 | body; \ 217 | if (node -> right) \ 218 | { \ 219 | node += node -> right; \ 220 | while (node -> left) \ 221 | { \ 222 | stack [stackSize ++] = node; \ 223 | node += node -> left; \ 224 | } \ 225 | } \ 226 | else \ 227 | if (stackSize <= 0) \ 228 | break; \ 229 | else \ 230 | node = stack [-- stackSize]; \ 231 | } \ 232 | } 233 | 234 | #define ENET_CONTEXT_ENCODE_EXCLUDE(context, value_, under, total, minimum) \ 235 | ENET_CONTEXT_WALK(context, { \ 236 | if (node -> value != value_) \ 237 | { \ 238 | enet_uint16 parentCount = rangeCoder -> symbols [node -> parent].count + minimum; \ 239 | if (node -> value < value_) \ 240 | under -= parentCount; \ 241 | total -= parentCount; \ 242 | } \ 243 | }) 244 | #endif 245 | 246 | size_t 247 | enet_range_coder_compress (void * context, const ENetBuffer * inBuffers, size_t inBufferCount, size_t inLimit, enet_uint8 * outData, size_t outLimit) 248 | { 249 | ENetRangeCoder * rangeCoder = (ENetRangeCoder *) context; 250 | enet_uint8 * outStart = outData, * outEnd = & outData [outLimit]; 251 | const enet_uint8 * inData, * inEnd; 252 | enet_uint32 encodeLow = 0, encodeRange = ~0; 253 | ENetSymbol * root; 254 | enet_uint16 predicted = 0; 255 | size_t order = 0, nextSymbol = 0; 256 | 257 | if (rangeCoder == NULL || inBufferCount <= 0 || inLimit <= 0) 258 | return 0; 259 | 260 | inData = (const enet_uint8 *) inBuffers -> data; 261 | inEnd = & inData [inBuffers -> dataLength]; 262 | inBuffers ++; 263 | inBufferCount --; 264 | 265 | ENET_CONTEXT_CREATE (root, ENET_CONTEXT_ESCAPE_MINIMUM, ENET_CONTEXT_SYMBOL_MINIMUM); 266 | 267 | for (;;) 268 | { 269 | ENetSymbol * subcontext, * symbol; 270 | #ifdef ENET_CONTEXT_EXCLUSION 271 | const ENetSymbol * childContext = & emptyContext; 272 | #endif 273 | enet_uint8 value; 274 | enet_uint16 count, under, * parent = & predicted, total; 275 | if (inData >= inEnd) 276 | { 277 | if (inBufferCount <= 0) 278 | break; 279 | inData = (const enet_uint8 *) inBuffers -> data; 280 | inEnd = & inData [inBuffers -> dataLength]; 281 | inBuffers ++; 282 | inBufferCount --; 283 | } 284 | value = * inData ++; 285 | 286 | for (subcontext = & rangeCoder -> symbols [predicted]; 287 | subcontext != root; 288 | #ifdef ENET_CONTEXT_EXCLUSION 289 | childContext = subcontext, 290 | #endif 291 | subcontext = & rangeCoder -> symbols [subcontext -> parent]) 292 | { 293 | ENET_CONTEXT_ENCODE (subcontext, symbol, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0); 294 | * parent = symbol - rangeCoder -> symbols; 295 | parent = & symbol -> parent; 296 | total = subcontext -> total; 297 | #ifdef ENET_CONTEXT_EXCLUSION 298 | if (childContext -> total > ENET_SUBCONTEXT_SYMBOL_DELTA + ENET_SUBCONTEXT_ESCAPE_DELTA) 299 | ENET_CONTEXT_ENCODE_EXCLUDE (childContext, value, under, total, 0); 300 | #endif 301 | if (count > 0) 302 | { 303 | ENET_RANGE_CODER_ENCODE (subcontext -> escapes + under, count, total); 304 | } 305 | else 306 | { 307 | if (subcontext -> escapes > 0 && subcontext -> escapes < total) 308 | ENET_RANGE_CODER_ENCODE (0, subcontext -> escapes, total); 309 | subcontext -> escapes += ENET_SUBCONTEXT_ESCAPE_DELTA; 310 | subcontext -> total += ENET_SUBCONTEXT_ESCAPE_DELTA; 311 | } 312 | subcontext -> total += ENET_SUBCONTEXT_SYMBOL_DELTA; 313 | if (count > 0xFF - 2*ENET_SUBCONTEXT_SYMBOL_DELTA || subcontext -> total > ENET_RANGE_CODER_BOTTOM - 0x100) 314 | ENET_CONTEXT_RESCALE (subcontext, 0); 315 | if (count > 0) goto nextInput; 316 | } 317 | 318 | ENET_CONTEXT_ENCODE (root, symbol, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM); 319 | * parent = symbol - rangeCoder -> symbols; 320 | parent = & symbol -> parent; 321 | total = root -> total; 322 | #ifdef ENET_CONTEXT_EXCLUSION 323 | if (childContext -> total > ENET_SUBCONTEXT_SYMBOL_DELTA + ENET_SUBCONTEXT_ESCAPE_DELTA) 324 | ENET_CONTEXT_ENCODE_EXCLUDE (childContext, value, under, total, ENET_CONTEXT_SYMBOL_MINIMUM); 325 | #endif 326 | ENET_RANGE_CODER_ENCODE (root -> escapes + under, count, total); 327 | root -> total += ENET_CONTEXT_SYMBOL_DELTA; 328 | if (count > 0xFF - 2*ENET_CONTEXT_SYMBOL_DELTA + ENET_CONTEXT_SYMBOL_MINIMUM || root -> total > ENET_RANGE_CODER_BOTTOM - 0x100) 329 | ENET_CONTEXT_RESCALE (root, ENET_CONTEXT_SYMBOL_MINIMUM); 330 | 331 | nextInput: 332 | if (order >= ENET_SUBCONTEXT_ORDER) 333 | predicted = rangeCoder -> symbols [predicted].parent; 334 | else 335 | order ++; 336 | ENET_RANGE_CODER_FREE_SYMBOLS; 337 | } 338 | 339 | ENET_RANGE_CODER_FLUSH; 340 | 341 | return (size_t) (outData - outStart); 342 | } 343 | 344 | #define ENET_RANGE_CODER_SEED \ 345 | { \ 346 | if (inData < inEnd) decodeCode |= * inData ++ << 24; \ 347 | if (inData < inEnd) decodeCode |= * inData ++ << 16; \ 348 | if (inData < inEnd) decodeCode |= * inData ++ << 8; \ 349 | if (inData < inEnd) decodeCode |= * inData ++; \ 350 | } 351 | 352 | #define ENET_RANGE_CODER_READ(total) ((decodeCode - decodeLow) / (decodeRange /= (total))) 353 | 354 | #define ENET_RANGE_CODER_DECODE(under, count, total) \ 355 | { \ 356 | decodeLow += (under) * decodeRange; \ 357 | decodeRange *= (count); \ 358 | for (;;) \ 359 | { \ 360 | if((decodeLow ^ (decodeLow + decodeRange)) >= ENET_RANGE_CODER_TOP) \ 361 | { \ 362 | if(decodeRange >= ENET_RANGE_CODER_BOTTOM) break; \ 363 | decodeRange = -decodeLow & (ENET_RANGE_CODER_BOTTOM - 1); \ 364 | } \ 365 | decodeCode <<= 8; \ 366 | if (inData < inEnd) \ 367 | decodeCode |= * inData ++; \ 368 | decodeRange <<= 8; \ 369 | decodeLow <<= 8; \ 370 | } \ 371 | } 372 | 373 | #define ENET_CONTEXT_DECODE(context, symbol_, code, value_, under_, count_, update, minimum, createRoot, visitNode, createRight, createLeft) \ 374 | { \ 375 | under_ = 0; \ 376 | count_ = minimum; \ 377 | if (! (context) -> symbols) \ 378 | { \ 379 | createRoot; \ 380 | } \ 381 | else \ 382 | { \ 383 | ENetSymbol * node = (context) + (context) -> symbols; \ 384 | for (;;) \ 385 | { \ 386 | enet_uint16 after = under_ + node -> under + (node -> value + 1)*minimum, before = node -> count + minimum; \ 387 | visitNode; \ 388 | if (code >= after) \ 389 | { \ 390 | under_ += node -> under; \ 391 | if (node -> right) { node += node -> right; continue; } \ 392 | createRight; \ 393 | } \ 394 | else \ 395 | if (code < after - before) \ 396 | { \ 397 | node -> under += update; \ 398 | if (node -> left) { node += node -> left; continue; } \ 399 | createLeft; \ 400 | } \ 401 | else \ 402 | { \ 403 | value_ = node -> value; \ 404 | count_ += node -> count; \ 405 | under_ = after - before; \ 406 | node -> under += update; \ 407 | node -> count += update; \ 408 | symbol_ = node; \ 409 | } \ 410 | break; \ 411 | } \ 412 | } \ 413 | } 414 | 415 | #define ENET_CONTEXT_TRY_DECODE(context, symbol_, code, value_, under_, count_, update, minimum, exclude) \ 416 | ENET_CONTEXT_DECODE (context, symbol_, code, value_, under_, count_, update, minimum, return 0, exclude (node -> value, after, before), return 0, return 0) 417 | 418 | #define ENET_CONTEXT_ROOT_DECODE(context, symbol_, code, value_, under_, count_, update, minimum, exclude) \ 419 | ENET_CONTEXT_DECODE (context, symbol_, code, value_, under_, count_, update, minimum, \ 420 | { \ 421 | value_ = code / minimum; \ 422 | under_ = code - code%minimum; \ 423 | ENET_SYMBOL_CREATE (symbol_, value_, update); \ 424 | (context) -> symbols = symbol_ - (context); \ 425 | }, \ 426 | exclude (node -> value, after, before), \ 427 | { \ 428 | value_ = node->value + 1 + (code - after)/minimum; \ 429 | under_ = code - (code - after)%minimum; \ 430 | ENET_SYMBOL_CREATE (symbol_, value_, update); \ 431 | node -> right = symbol_ - node; \ 432 | }, \ 433 | { \ 434 | value_ = node->value - 1 - (after - before - code - 1)/minimum; \ 435 | under_ = code - (after - before - code - 1)%minimum; \ 436 | ENET_SYMBOL_CREATE (symbol_, value_, update); \ 437 | node -> left = symbol_ - node; \ 438 | }) \ 439 | 440 | #ifdef ENET_CONTEXT_EXCLUSION 441 | typedef struct _ENetExclude 442 | { 443 | enet_uint8 value; 444 | enet_uint16 under; 445 | } ENetExclude; 446 | 447 | #define ENET_CONTEXT_DECODE_EXCLUDE(context, total, minimum) \ 448 | { \ 449 | enet_uint16 under = 0; \ 450 | nextExclude = excludes; \ 451 | ENET_CONTEXT_WALK (context, { \ 452 | under += rangeCoder -> symbols [node -> parent].count + minimum; \ 453 | nextExclude -> value = node -> value; \ 454 | nextExclude -> under = under; \ 455 | nextExclude ++; \ 456 | }); \ 457 | total -= under; \ 458 | } 459 | 460 | #define ENET_CONTEXT_EXCLUDED(value_, after, before) \ 461 | { \ 462 | size_t low = 0, high = nextExclude - excludes; \ 463 | for(;;) \ 464 | { \ 465 | size_t mid = (low + high) >> 1; \ 466 | const ENetExclude * exclude = & excludes [mid]; \ 467 | if (value_ < exclude -> value) \ 468 | { \ 469 | if (low + 1 < high) \ 470 | { \ 471 | high = mid; \ 472 | continue; \ 473 | } \ 474 | if (exclude > excludes) \ 475 | after -= exclude [-1].under; \ 476 | } \ 477 | else \ 478 | { \ 479 | if (value_ > exclude -> value) \ 480 | { \ 481 | if (low + 1 < high) \ 482 | { \ 483 | low = mid; \ 484 | continue; \ 485 | } \ 486 | } \ 487 | else \ 488 | before = 0; \ 489 | after -= exclude -> under; \ 490 | } \ 491 | break; \ 492 | } \ 493 | } 494 | #endif 495 | 496 | #define ENET_CONTEXT_NOT_EXCLUDED(value_, after, before) 497 | 498 | size_t 499 | enet_range_coder_decompress (void * context, const enet_uint8 * inData, size_t inLimit, enet_uint8 * outData, size_t outLimit) 500 | { 501 | ENetRangeCoder * rangeCoder = (ENetRangeCoder *) context; 502 | enet_uint8 * outStart = outData, * outEnd = & outData [outLimit]; 503 | const enet_uint8 * inEnd = & inData [inLimit]; 504 | enet_uint32 decodeLow = 0, decodeCode = 0, decodeRange = ~0; 505 | ENetSymbol * root; 506 | enet_uint16 predicted = 0; 507 | size_t order = 0, nextSymbol = 0; 508 | #ifdef ENET_CONTEXT_EXCLUSION 509 | ENetExclude excludes [256]; 510 | ENetExclude * nextExclude = excludes; 511 | #endif 512 | 513 | if (rangeCoder == NULL || inLimit <= 0) 514 | return 0; 515 | 516 | ENET_CONTEXT_CREATE (root, ENET_CONTEXT_ESCAPE_MINIMUM, ENET_CONTEXT_SYMBOL_MINIMUM); 517 | 518 | ENET_RANGE_CODER_SEED; 519 | 520 | for (;;) 521 | { 522 | ENetSymbol * subcontext, * symbol, * patch; 523 | #ifdef ENET_CONTEXT_EXCLUSION 524 | const ENetSymbol * childContext = & emptyContext; 525 | #endif 526 | enet_uint8 value = 0; 527 | enet_uint16 code, under, count, bottom, * parent = & predicted, total; 528 | 529 | for (subcontext = & rangeCoder -> symbols [predicted]; 530 | subcontext != root; 531 | #ifdef ENET_CONTEXT_EXCLUSION 532 | childContext = subcontext, 533 | #endif 534 | subcontext = & rangeCoder -> symbols [subcontext -> parent]) 535 | { 536 | if (subcontext -> escapes <= 0) 537 | continue; 538 | total = subcontext -> total; 539 | #ifdef ENET_CONTEXT_EXCLUSION 540 | if (childContext -> total > 0) 541 | ENET_CONTEXT_DECODE_EXCLUDE (childContext, total, 0); 542 | #endif 543 | if (subcontext -> escapes >= total) 544 | continue; 545 | code = ENET_RANGE_CODER_READ (total); 546 | if (code < subcontext -> escapes) 547 | { 548 | ENET_RANGE_CODER_DECODE (0, subcontext -> escapes, total); 549 | continue; 550 | } 551 | code -= subcontext -> escapes; 552 | #ifdef ENET_CONTEXT_EXCLUSION 553 | if (childContext -> total > 0) 554 | { 555 | ENET_CONTEXT_TRY_DECODE (subcontext, symbol, code, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0, ENET_CONTEXT_EXCLUDED); 556 | } 557 | else 558 | #endif 559 | { 560 | ENET_CONTEXT_TRY_DECODE (subcontext, symbol, code, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0, ENET_CONTEXT_NOT_EXCLUDED); 561 | } 562 | bottom = symbol - rangeCoder -> symbols; 563 | ENET_RANGE_CODER_DECODE (subcontext -> escapes + under, count, total); 564 | subcontext -> total += ENET_SUBCONTEXT_SYMBOL_DELTA; 565 | if (count > 0xFF - 2*ENET_SUBCONTEXT_SYMBOL_DELTA || subcontext -> total > ENET_RANGE_CODER_BOTTOM - 0x100) 566 | ENET_CONTEXT_RESCALE (subcontext, 0); 567 | goto patchContexts; 568 | } 569 | 570 | total = root -> total; 571 | #ifdef ENET_CONTEXT_EXCLUSION 572 | if (childContext -> total > 0) 573 | ENET_CONTEXT_DECODE_EXCLUDE (childContext, total, ENET_CONTEXT_SYMBOL_MINIMUM); 574 | #endif 575 | code = ENET_RANGE_CODER_READ (total); 576 | if (code < root -> escapes) 577 | { 578 | ENET_RANGE_CODER_DECODE (0, root -> escapes, total); 579 | break; 580 | } 581 | code -= root -> escapes; 582 | #ifdef ENET_CONTEXT_EXCLUSION 583 | if (childContext -> total > 0) 584 | { 585 | ENET_CONTEXT_ROOT_DECODE (root, symbol, code, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM, ENET_CONTEXT_EXCLUDED); 586 | } 587 | else 588 | #endif 589 | { 590 | ENET_CONTEXT_ROOT_DECODE (root, symbol, code, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM, ENET_CONTEXT_NOT_EXCLUDED); 591 | } 592 | bottom = symbol - rangeCoder -> symbols; 593 | ENET_RANGE_CODER_DECODE (root -> escapes + under, count, total); 594 | root -> total += ENET_CONTEXT_SYMBOL_DELTA; 595 | if (count > 0xFF - 2*ENET_CONTEXT_SYMBOL_DELTA + ENET_CONTEXT_SYMBOL_MINIMUM || root -> total > ENET_RANGE_CODER_BOTTOM - 0x100) 596 | ENET_CONTEXT_RESCALE (root, ENET_CONTEXT_SYMBOL_MINIMUM); 597 | 598 | patchContexts: 599 | for (patch = & rangeCoder -> symbols [predicted]; 600 | patch != subcontext; 601 | patch = & rangeCoder -> symbols [patch -> parent]) 602 | { 603 | ENET_CONTEXT_ENCODE (patch, symbol, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0); 604 | * parent = symbol - rangeCoder -> symbols; 605 | parent = & symbol -> parent; 606 | if (count <= 0) 607 | { 608 | patch -> escapes += ENET_SUBCONTEXT_ESCAPE_DELTA; 609 | patch -> total += ENET_SUBCONTEXT_ESCAPE_DELTA; 610 | } 611 | patch -> total += ENET_SUBCONTEXT_SYMBOL_DELTA; 612 | if (count > 0xFF - 2*ENET_SUBCONTEXT_SYMBOL_DELTA || patch -> total > ENET_RANGE_CODER_BOTTOM - 0x100) 613 | ENET_CONTEXT_RESCALE (patch, 0); 614 | } 615 | * parent = bottom; 616 | 617 | ENET_RANGE_CODER_OUTPUT (value); 618 | 619 | if (order >= ENET_SUBCONTEXT_ORDER) 620 | predicted = rangeCoder -> symbols [predicted].parent; 621 | else 622 | order ++; 623 | ENET_RANGE_CODER_FREE_SYMBOLS; 624 | } 625 | 626 | return (size_t) (outData - outStart); 627 | } 628 | 629 | /** @defgroup host ENet host functions 630 | @{ 631 | */ 632 | 633 | /** Sets the packet compressor the host should use to the default range coder. 634 | @param host host to enable the range coder for 635 | @returns 0 on success, < 0 on failure 636 | */ 637 | int 638 | enet_host_compress_with_range_coder (ENetHost * host) 639 | { 640 | ENetCompressor compressor; 641 | memset (& compressor, 0, sizeof (compressor)); 642 | compressor.context = enet_range_coder_create(); 643 | if (compressor.context == NULL) 644 | return -1; 645 | compressor.compress = enet_range_coder_compress; 646 | compressor.decompress = enet_range_coder_decompress; 647 | compressor.destroy = enet_range_coder_destroy; 648 | enet_host_compress (host, & compressor); 649 | return 0; 650 | } 651 | 652 | /** @} */ 653 | 654 | 655 | -------------------------------------------------------------------------------- /jni/enet/callbacks.h: -------------------------------------------------------------------------------- 1 | /** 2 | @file callbacks.h 3 | @brief ENet callbacks 4 | */ 5 | #ifndef __ENET_CALLBACKS_H__ 6 | #define __ENET_CALLBACKS_H__ 7 | 8 | #include 9 | 10 | typedef struct _ENetCallbacks 11 | { 12 | void * (ENET_CALLBACK * malloc) (size_t size); 13 | void (ENET_CALLBACK * free) (void * memory); 14 | void (ENET_CALLBACK * no_memory) (void); 15 | } ENetCallbacks; 16 | 17 | /** @defgroup callbacks ENet internal callbacks 18 | @{ 19 | @ingroup private 20 | */ 21 | extern void * enet_malloc (size_t); 22 | extern void enet_free (void *); 23 | 24 | /** @} */ 25 | 26 | #endif /* __ENET_CALLBACKS_H__ */ 27 | 28 | -------------------------------------------------------------------------------- /jni/enet/enet.h: -------------------------------------------------------------------------------- 1 | /** 2 | @file enet.h 3 | @brief ENet public header file 4 | */ 5 | #ifndef __ENET_ENET_H__ 6 | #define __ENET_ENET_H__ 7 | 8 | #ifdef __cplusplus 9 | extern "C" 10 | { 11 | #endif 12 | 13 | #include 14 | 15 | #ifdef WIN32 16 | #include "enet/win32.h" 17 | #else 18 | #include "enet/unix.h" 19 | #endif 20 | 21 | #include "enet/types.h" 22 | #include "enet/protocol.h" 23 | #include "enet/list.h" 24 | #include "enet/callbacks.h" 25 | 26 | #define ENET_VERSION_MAJOR 1 27 | #define ENET_VERSION_MINOR 3 28 | #define ENET_VERSION_PATCH 0 29 | #define ENET_VERSION_CREATE(major, minor, patch) (((major)<<16) | ((minor)<<8) | (patch)) 30 | #define ENET_VERSION ENET_VERSION_CREATE(ENET_VERSION_MAJOR, ENET_VERSION_MINOR, ENET_VERSION_PATCH) 31 | 32 | typedef enet_uint32 ENetVersion; 33 | 34 | typedef enum _ENetSocketType 35 | { 36 | ENET_SOCKET_TYPE_STREAM = 1, 37 | ENET_SOCKET_TYPE_DATAGRAM = 2 38 | } ENetSocketType; 39 | 40 | typedef enum _ENetSocketWait 41 | { 42 | ENET_SOCKET_WAIT_NONE = 0, 43 | ENET_SOCKET_WAIT_SEND = (1 << 0), 44 | ENET_SOCKET_WAIT_RECEIVE = (1 << 1) 45 | } ENetSocketWait; 46 | 47 | typedef enum _ENetSocketOption 48 | { 49 | ENET_SOCKOPT_NONBLOCK = 1, 50 | ENET_SOCKOPT_BROADCAST = 2, 51 | ENET_SOCKOPT_RCVBUF = 3, 52 | ENET_SOCKOPT_SNDBUF = 4, 53 | ENET_SOCKOPT_REUSEADDR = 5 54 | } ENetSocketOption; 55 | 56 | enum 57 | { 58 | ENET_HOST_ANY = 0, /**< specifies the default server host */ 59 | ENET_HOST_BROADCAST = 0xFFFFFFFF, /**< specifies a subnet-wide broadcast */ 60 | 61 | ENET_PORT_ANY = 0 /**< specifies that a port should be automatically chosen */ 62 | }; 63 | 64 | /** 65 | * Portable internet address structure. 66 | * 67 | * The host must be specified in network byte-order, and the port must be in host 68 | * byte-order. The constant ENET_HOST_ANY may be used to specify the default 69 | * server host. The constant ENET_HOST_BROADCAST may be used to specify the 70 | * broadcast address (255.255.255.255). This makes sense for enet_host_connect, 71 | * but not for enet_host_create. Once a server responds to a broadcast, the 72 | * address is updated from ENET_HOST_BROADCAST to the server's actual IP address. 73 | */ 74 | typedef struct _ENetAddress 75 | { 76 | enet_uint32 host; 77 | enet_uint16 port; 78 | } ENetAddress; 79 | 80 | /** 81 | * Packet flag bit constants. 82 | * 83 | * The host must be specified in network byte-order, and the port must be in 84 | * host byte-order. The constant ENET_HOST_ANY may be used to specify the 85 | * default server host. 86 | 87 | @sa ENetPacket 88 | */ 89 | typedef enum _ENetPacketFlag 90 | { 91 | /** packet must be received by the target peer and resend attempts should be 92 | * made until the packet is delivered */ 93 | ENET_PACKET_FLAG_RELIABLE = (1 << 0), 94 | /** packet will not be sequenced with other packets 95 | * not supported for reliable packets 96 | */ 97 | ENET_PACKET_FLAG_UNSEQUENCED = (1 << 1), 98 | /** packet will not allocate data, and user must supply it instead */ 99 | ENET_PACKET_FLAG_NO_ALLOCATE = (1 << 2) 100 | } ENetPacketFlag; 101 | 102 | struct _ENetPacket; 103 | typedef void (ENET_CALLBACK * ENetPacketFreeCallback) (struct _ENetPacket *); 104 | 105 | /** 106 | * ENet packet structure. 107 | * 108 | * An ENet data packet that may be sent to or received from a peer. The shown 109 | * fields should only be read and never modified. The data field contains the 110 | * allocated data for the packet. The dataLength fields specifies the length 111 | * of the allocated data. The flags field is either 0 (specifying no flags), 112 | * or a bitwise-or of any combination of the following flags: 113 | * 114 | * ENET_PACKET_FLAG_RELIABLE - packet must be received by the target peer 115 | * and resend attempts should be made until the packet is delivered 116 | * 117 | * ENET_PACKET_FLAG_UNSEQUENCED - packet will not be sequenced with other packets 118 | * (not supported for reliable packets) 119 | * 120 | * ENET_PACKET_FLAG_NO_ALLOCATE - packet will not allocate data, and user must supply it instead 121 | 122 | @sa ENetPacketFlag 123 | */ 124 | typedef struct _ENetPacket 125 | { 126 | size_t referenceCount; /**< internal use only */ 127 | enet_uint32 flags; /**< bitwise-or of ENetPacketFlag constants */ 128 | enet_uint8 * data; /**< allocated data for packet */ 129 | size_t dataLength; /**< length of data */ 130 | ENetPacketFreeCallback freeCallback; /**< function to be called when the packet is no longer in use */ 131 | } ENetPacket; 132 | 133 | typedef struct _ENetAcknowledgement 134 | { 135 | ENetListNode acknowledgementList; 136 | enet_uint32 sentTime; 137 | ENetProtocol command; 138 | } ENetAcknowledgement; 139 | 140 | typedef struct _ENetOutgoingCommand 141 | { 142 | ENetListNode outgoingCommandList; 143 | enet_uint16 reliableSequenceNumber; 144 | enet_uint16 unreliableSequenceNumber; 145 | enet_uint32 sentTime; 146 | enet_uint32 roundTripTimeout; 147 | enet_uint32 roundTripTimeoutLimit; 148 | enet_uint32 fragmentOffset; 149 | enet_uint16 fragmentLength; 150 | enet_uint16 sendAttempts; 151 | ENetProtocol command; 152 | ENetPacket * packet; 153 | } ENetOutgoingCommand; 154 | 155 | typedef struct _ENetIncomingCommand 156 | { 157 | ENetListNode incomingCommandList; 158 | enet_uint16 reliableSequenceNumber; 159 | enet_uint16 unreliableSequenceNumber; 160 | ENetProtocol command; 161 | enet_uint32 fragmentCount; 162 | enet_uint32 fragmentsRemaining; 163 | enet_uint32 * fragments; 164 | ENetPacket * packet; 165 | } ENetIncomingCommand; 166 | 167 | typedef enum _ENetPeerState 168 | { 169 | ENET_PEER_STATE_DISCONNECTED = 0, 170 | ENET_PEER_STATE_CONNECTING = 1, 171 | ENET_PEER_STATE_ACKNOWLEDGING_CONNECT = 2, 172 | ENET_PEER_STATE_CONNECTION_PENDING = 3, 173 | ENET_PEER_STATE_CONNECTION_SUCCEEDED = 4, 174 | ENET_PEER_STATE_CONNECTED = 5, 175 | ENET_PEER_STATE_DISCONNECT_LATER = 6, 176 | ENET_PEER_STATE_DISCONNECTING = 7, 177 | ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT = 8, 178 | ENET_PEER_STATE_ZOMBIE = 9 179 | } ENetPeerState; 180 | 181 | #ifndef ENET_BUFFER_MAXIMUM 182 | #define ENET_BUFFER_MAXIMUM (1 + 2 * ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS) 183 | #endif 184 | 185 | enum 186 | { 187 | ENET_HOST_RECEIVE_BUFFER_SIZE = 256 * 1024, 188 | ENET_HOST_SEND_BUFFER_SIZE = 256 * 1024, 189 | ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL = 1000, 190 | ENET_HOST_DEFAULT_MTU = 1400, 191 | 192 | ENET_PEER_DEFAULT_ROUND_TRIP_TIME = 500, 193 | ENET_PEER_DEFAULT_PACKET_THROTTLE = 32, 194 | ENET_PEER_PACKET_THROTTLE_SCALE = 32, 195 | ENET_PEER_PACKET_THROTTLE_COUNTER = 7, 196 | ENET_PEER_PACKET_THROTTLE_ACCELERATION = 2, 197 | ENET_PEER_PACKET_THROTTLE_DECELERATION = 2, 198 | ENET_PEER_PACKET_THROTTLE_INTERVAL = 5000, 199 | ENET_PEER_PACKET_LOSS_SCALE = (1 << 16), 200 | ENET_PEER_PACKET_LOSS_INTERVAL = 10000, 201 | ENET_PEER_WINDOW_SIZE_SCALE = 64 * 1024, 202 | ENET_PEER_TIMEOUT_LIMIT = 32, 203 | ENET_PEER_TIMEOUT_MINIMUM = 5000, 204 | ENET_PEER_TIMEOUT_MAXIMUM = 30000, 205 | ENET_PEER_PING_INTERVAL = 500, 206 | ENET_PEER_UNSEQUENCED_WINDOWS = 64, 207 | ENET_PEER_UNSEQUENCED_WINDOW_SIZE = 1024, 208 | ENET_PEER_FREE_UNSEQUENCED_WINDOWS = 32, 209 | ENET_PEER_RELIABLE_WINDOWS = 16, 210 | ENET_PEER_RELIABLE_WINDOW_SIZE = 0x1000, 211 | ENET_PEER_FREE_RELIABLE_WINDOWS = 8 212 | }; 213 | 214 | typedef struct _ENetChannel 215 | { 216 | enet_uint16 outgoingReliableSequenceNumber; 217 | enet_uint16 outgoingUnreliableSequenceNumber; 218 | enet_uint16 usedReliableWindows; 219 | enet_uint16 reliableWindows [ENET_PEER_RELIABLE_WINDOWS]; 220 | enet_uint16 incomingReliableSequenceNumber; 221 | ENetList incomingReliableCommands; 222 | ENetList incomingUnreliableCommands; 223 | } ENetChannel; 224 | 225 | /** 226 | * An ENet peer which data packets may be sent or received from. 227 | * 228 | * No fields should be modified unless otherwise specified. 229 | */ 230 | typedef struct _ENetPeer 231 | { 232 | ENetListNode dispatchList; 233 | struct _ENetHost * host; 234 | enet_uint16 outgoingPeerID; 235 | enet_uint16 incomingPeerID; 236 | enet_uint32 connectID; 237 | enet_uint8 outgoingSessionID; 238 | enet_uint8 incomingSessionID; 239 | ENetAddress address; /**< Internet address of the peer */ 240 | void * data; /**< Application private data, may be freely modified */ 241 | ENetPeerState state; 242 | ENetChannel * channels; 243 | size_t channelCount; /**< Number of channels allocated for communication with peer */ 244 | enet_uint32 incomingBandwidth; /**< Downstream bandwidth of the client in bytes/second */ 245 | enet_uint32 outgoingBandwidth; /**< Upstream bandwidth of the client in bytes/second */ 246 | enet_uint32 incomingBandwidthThrottleEpoch; 247 | enet_uint32 outgoingBandwidthThrottleEpoch; 248 | enet_uint32 incomingDataTotal; 249 | enet_uint32 outgoingDataTotal; 250 | enet_uint32 lastSendTime; 251 | enet_uint32 lastReceiveTime; 252 | enet_uint32 nextTimeout; 253 | enet_uint32 earliestTimeout; 254 | enet_uint32 packetLossEpoch; 255 | enet_uint32 packetsSent; 256 | enet_uint32 packetsLost; 257 | enet_uint32 packetLoss; /**< mean packet loss of reliable packets as a ratio with respect to the constant ENET_PEER_PACKET_LOSS_SCALE */ 258 | enet_uint32 packetLossVariance; 259 | enet_uint32 packetThrottle; 260 | enet_uint32 packetThrottleLimit; 261 | enet_uint32 packetThrottleCounter; 262 | enet_uint32 packetThrottleEpoch; 263 | enet_uint32 packetThrottleAcceleration; 264 | enet_uint32 packetThrottleDeceleration; 265 | enet_uint32 packetThrottleInterval; 266 | enet_uint32 lastRoundTripTime; 267 | enet_uint32 lowestRoundTripTime; 268 | enet_uint32 lastRoundTripTimeVariance; 269 | enet_uint32 highestRoundTripTimeVariance; 270 | enet_uint32 roundTripTime; /**< mean round trip time (RTT), in milliseconds, between sending a reliable packet and receiving its acknowledgement */ 271 | enet_uint32 roundTripTimeVariance; 272 | enet_uint32 mtu; 273 | enet_uint32 windowSize; 274 | enet_uint32 reliableDataInTransit; 275 | enet_uint16 outgoingReliableSequenceNumber; 276 | ENetList acknowledgements; 277 | ENetList sentReliableCommands; 278 | ENetList sentUnreliableCommands; 279 | ENetList outgoingReliableCommands; 280 | ENetList outgoingUnreliableCommands; 281 | ENetList dispatchedCommands; 282 | int needsDispatch; 283 | enet_uint16 incomingUnsequencedGroup; 284 | enet_uint16 outgoingUnsequencedGroup; 285 | enet_uint32 unsequencedWindow [ENET_PEER_UNSEQUENCED_WINDOW_SIZE / 32]; 286 | enet_uint32 eventData; 287 | } ENetPeer; 288 | 289 | /** An ENet packet compressor for compressing UDP packets before socket sends or receives. 290 | */ 291 | typedef struct _ENetCompressor 292 | { 293 | /** Context data for the compressor. Must be non-NULL. */ 294 | void * context; 295 | /** Compresses from inBuffers[0:inBufferCount-1], containing inLimit bytes, to outData, outputting at most outLimit bytes. Should return 0 on failure. */ 296 | size_t (ENET_CALLBACK * compress) (void * context, const ENetBuffer * inBuffers, size_t inBufferCount, size_t inLimit, enet_uint8 * outData, size_t outLimit); 297 | /** Decompresses from inData, containing inLimit bytes, to outData, outputting at most outLimit bytes. Should return 0 on failure. */ 298 | size_t (ENET_CALLBACK * decompress) (void * context, const enet_uint8 * inData, size_t inLimit, enet_uint8 * outData, size_t outLimit); 299 | /** Destroys the context when compression is disabled or the host is destroyed. May be NULL. */ 300 | void (ENET_CALLBACK * destroy) (void * context); 301 | } ENetCompressor; 302 | 303 | /** Callback that computes the checksum of the data held in buffers[0:bufferCount-1] */ 304 | typedef enet_uint32 (ENET_CALLBACK * ENetChecksumCallback) (const ENetBuffer * buffers, size_t bufferCount); 305 | 306 | /** An ENet host for communicating with peers. 307 | * 308 | * No fields should be modified unless otherwise stated. 309 | 310 | @sa enet_host_create() 311 | @sa enet_host_destroy() 312 | @sa enet_host_connect() 313 | @sa enet_host_service() 314 | @sa enet_host_flush() 315 | @sa enet_host_broadcast() 316 | @sa enet_host_compress() 317 | @sa enet_host_compress_with_range_coder() 318 | @sa enet_host_channel_limit() 319 | @sa enet_host_bandwidth_limit() 320 | @sa enet_host_bandwidth_throttle() 321 | */ 322 | typedef struct _ENetHost 323 | { 324 | ENetSocket socket; 325 | ENetAddress address; /**< Internet address of the host */ 326 | enet_uint32 incomingBandwidth; /**< downstream bandwidth of the host */ 327 | enet_uint32 outgoingBandwidth; /**< upstream bandwidth of the host */ 328 | enet_uint32 bandwidthThrottleEpoch; 329 | enet_uint32 mtu; 330 | enet_uint32 randomSeed; 331 | int recalculateBandwidthLimits; 332 | ENetPeer * peers; /**< array of peers allocated for this host */ 333 | size_t peerCount; /**< number of peers allocated for this host */ 334 | size_t channelLimit; /**< maximum number of channels allowed for connected peers */ 335 | enet_uint32 serviceTime; 336 | ENetList dispatchQueue; 337 | int continueSending; 338 | size_t packetSize; 339 | enet_uint16 headerFlags; 340 | ENetProtocol commands [ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS]; 341 | size_t commandCount; 342 | ENetBuffer buffers [ENET_BUFFER_MAXIMUM]; 343 | size_t bufferCount; 344 | ENetChecksumCallback checksum; /**< callback the user can set to enable packet checksums for this host */ 345 | ENetCompressor compressor; 346 | enet_uint8 packetData [2][ENET_PROTOCOL_MAXIMUM_MTU]; 347 | ENetAddress receivedAddress; 348 | enet_uint8 * receivedData; 349 | size_t receivedDataLength; 350 | enet_uint32 totalSentData; /**< total data sent, user should reset to 0 as needed to prevent overflow */ 351 | enet_uint32 totalSentPackets; /**< total UDP packets sent, user should reset to 0 as needed to prevent overflow */ 352 | enet_uint32 totalReceivedData; /**< total data received, user should reset to 0 as needed to prevent overflow */ 353 | enet_uint32 totalReceivedPackets; /**< total UDP packets received, user should reset to 0 as needed to prevent overflow */ 354 | } ENetHost; 355 | 356 | /** 357 | * An ENet event type, as specified in @ref ENetEvent. 358 | */ 359 | typedef enum _ENetEventType 360 | { 361 | /** no event occurred within the specified time limit */ 362 | ENET_EVENT_TYPE_NONE = 0, 363 | 364 | /** a connection request initiated by enet_host_connect has completed. 365 | * The peer field contains the peer which successfully connected. 366 | */ 367 | ENET_EVENT_TYPE_CONNECT = 1, 368 | 369 | /** a peer has disconnected. This event is generated on a successful 370 | * completion of a disconnect initiated by enet_pper_disconnect, if 371 | * a peer has timed out, or if a connection request intialized by 372 | * enet_host_connect has timed out. The peer field contains the peer 373 | * which disconnected. The data field contains user supplied data 374 | * describing the disconnection, or 0, if none is available. 375 | */ 376 | ENET_EVENT_TYPE_DISCONNECT = 2, 377 | 378 | /** a packet has been received from a peer. The peer field specifies the 379 | * peer which sent the packet. The channelID field specifies the channel 380 | * number upon which the packet was received. The packet field contains 381 | * the packet that was received; this packet must be destroyed with 382 | * enet_packet_destroy after use. 383 | */ 384 | ENET_EVENT_TYPE_RECEIVE = 3 385 | } ENetEventType; 386 | 387 | /** 388 | * An ENet event as returned by enet_host_service(). 389 | 390 | @sa enet_host_service 391 | */ 392 | typedef struct _ENetEvent 393 | { 394 | ENetEventType type; /**< type of the event */ 395 | ENetPeer * peer; /**< peer that generated a connect, disconnect or receive event */ 396 | enet_uint8 channelID; /**< channel on the peer that generated the event, if appropriate */ 397 | enet_uint32 data; /**< data associated with the event, if appropriate */ 398 | ENetPacket * packet; /**< packet associated with the event, if appropriate */ 399 | } ENetEvent; 400 | 401 | /** @defgroup global ENet global functions 402 | @{ 403 | */ 404 | 405 | /** 406 | Initializes ENet globally. Must be called prior to using any functions in 407 | ENet. 408 | @returns 0 on success, < 0 on failure 409 | */ 410 | ENET_API int enet_initialize (void); 411 | 412 | /** 413 | Initializes ENet globally and supplies user-overridden callbacks. Must be called prior to using any functions in ENet. Do not use enet_initialize() if you use this variant. Make sure the ENetCallbacks structure is zeroed out so that any additional callbacks added in future versions will be properly ignored. 414 | 415 | @param version the constant ENET_VERSION should be supplied so ENet knows which version of ENetCallbacks struct to use 416 | @param inits user-overriden callbacks where any NULL callbacks will use ENet's defaults 417 | @returns 0 on success, < 0 on failure 418 | */ 419 | ENET_API int enet_initialize_with_callbacks (ENetVersion version, const ENetCallbacks * inits); 420 | 421 | /** 422 | Shuts down ENet globally. Should be called when a program that has 423 | initialized ENet exits. 424 | */ 425 | ENET_API void enet_deinitialize (void); 426 | 427 | /** @} */ 428 | 429 | /** @defgroup private ENet private implementation functions */ 430 | 431 | /** 432 | Returns the wall-time in milliseconds. Its initial value is unspecified 433 | unless otherwise set. 434 | */ 435 | ENET_API enet_uint32 enet_time_get (void); 436 | /** 437 | Sets the current wall-time in milliseconds. 438 | */ 439 | ENET_API void enet_time_set (enet_uint32); 440 | 441 | /** @defgroup socket ENet socket functions 442 | @{ 443 | */ 444 | ENET_API ENetSocket enet_socket_create (ENetSocketType); 445 | ENET_API int enet_socket_bind (ENetSocket, const ENetAddress *); 446 | ENET_API int enet_socket_listen (ENetSocket, int); 447 | ENET_API ENetSocket enet_socket_accept (ENetSocket, ENetAddress *); 448 | ENET_API int enet_socket_connect (ENetSocket, const ENetAddress *); 449 | ENET_API int enet_socket_send (ENetSocket, const ENetAddress *, const ENetBuffer *, size_t); 450 | ENET_API int enet_socket_receive (ENetSocket, ENetAddress *, ENetBuffer *, size_t); 451 | ENET_API int enet_socket_wait (ENetSocket, enet_uint32 *, enet_uint32); 452 | ENET_API int enet_socket_set_option (ENetSocket, ENetSocketOption, int); 453 | ENET_API void enet_socket_destroy (ENetSocket); 454 | ENET_API int enet_socketset_select (ENetSocket, ENetSocketSet *, ENetSocketSet *, enet_uint32); 455 | 456 | /** @} */ 457 | 458 | /** @defgroup Address ENet address functions 459 | @{ 460 | */ 461 | /** Attempts to resolve the host named by the parameter hostName and sets 462 | the host field in the address parameter if successful. 463 | @param address destination to store resolved address 464 | @param hostName host name to lookup 465 | @retval 0 on success 466 | @retval < 0 on failure 467 | @returns the address of the given hostName in address on success 468 | */ 469 | ENET_API int enet_address_set_host (ENetAddress * address, const char * hostName); 470 | 471 | /** Gives the printable form of the ip address specified in the address parameter. 472 | @param address address printed 473 | @param hostName destination for name, must not be NULL 474 | @param nameLength maximum length of hostName. 475 | @returns the null-terminated name of the host in hostName on success 476 | @retval 0 on success 477 | @retval < 0 on failure 478 | */ 479 | ENET_API int enet_address_get_host_ip (const ENetAddress * address, char * hostName, size_t nameLength); 480 | 481 | /** Attempts to do a reverse lookup of the host field in the address parameter. 482 | @param address address used for reverse lookup 483 | @param hostName destination for name, must not be NULL 484 | @param nameLength maximum length of hostName. 485 | @returns the null-terminated name of the host in hostName on success 486 | @retval 0 on success 487 | @retval < 0 on failure 488 | */ 489 | ENET_API int enet_address_get_host (const ENetAddress * address, char * hostName, size_t nameLength); 490 | 491 | /** @} */ 492 | 493 | ENET_API ENetPacket * enet_packet_create (const void *, size_t, enet_uint32); 494 | ENET_API void enet_packet_destroy (ENetPacket *); 495 | ENET_API int enet_packet_resize (ENetPacket *, size_t); 496 | extern enet_uint32 enet_crc32 (const ENetBuffer *, size_t); 497 | 498 | ENET_API ENetHost * enet_host_create (const ENetAddress *, size_t, size_t, enet_uint32, enet_uint32); 499 | ENET_API void enet_host_destroy (ENetHost *); 500 | ENET_API ENetPeer * enet_host_connect (ENetHost *, const ENetAddress *, size_t, enet_uint32); 501 | ENET_API int enet_host_check_events (ENetHost *, ENetEvent *); 502 | ENET_API int enet_host_service (ENetHost *, ENetEvent *, enet_uint32); 503 | ENET_API void enet_host_flush (ENetHost *); 504 | ENET_API void enet_host_broadcast (ENetHost *, enet_uint8, ENetPacket *); 505 | ENET_API void enet_host_compress (ENetHost *, const ENetCompressor *); 506 | ENET_API int enet_host_compress_with_range_coder (ENetHost * host); 507 | ENET_API void enet_host_channel_limit (ENetHost *, size_t); 508 | ENET_API void enet_host_bandwidth_limit (ENetHost *, enet_uint32, enet_uint32); 509 | extern void enet_host_bandwidth_throttle (ENetHost *); 510 | 511 | ENET_API int enet_peer_send (ENetPeer *, enet_uint8, ENetPacket *); 512 | ENET_API ENetPacket * enet_peer_receive (ENetPeer *, enet_uint8 * channelID); 513 | ENET_API void enet_peer_ping (ENetPeer *); 514 | ENET_API void enet_peer_reset (ENetPeer *); 515 | ENET_API void enet_peer_disconnect (ENetPeer *, enet_uint32); 516 | ENET_API void enet_peer_disconnect_now (ENetPeer *, enet_uint32); 517 | ENET_API void enet_peer_disconnect_later (ENetPeer *, enet_uint32); 518 | ENET_API void enet_peer_throttle_configure (ENetPeer *, enet_uint32, enet_uint32, enet_uint32); 519 | extern int enet_peer_throttle (ENetPeer *, enet_uint32); 520 | extern void enet_peer_reset_queues (ENetPeer *); 521 | extern void enet_peer_setup_outgoing_command (ENetPeer *, ENetOutgoingCommand *); 522 | extern ENetOutgoingCommand * enet_peer_queue_outgoing_command (ENetPeer *, const ENetProtocol *, ENetPacket *, enet_uint32, enet_uint16); 523 | extern ENetIncomingCommand * enet_peer_queue_incoming_command (ENetPeer *, const ENetProtocol *, ENetPacket *, enet_uint32); 524 | extern ENetAcknowledgement * enet_peer_queue_acknowledgement (ENetPeer *, const ENetProtocol *, enet_uint16); 525 | extern void enet_peer_dispatch_incoming_unreliable_commands (ENetPeer *, ENetChannel *); 526 | extern void enet_peer_dispatch_incoming_reliable_commands (ENetPeer *, ENetChannel *); 527 | 528 | ENET_API void * enet_range_coder_create (void); 529 | ENET_API void enet_range_coder_destroy (void *); 530 | ENET_API size_t enet_range_coder_compress (void *, const ENetBuffer *, size_t, size_t, enet_uint8 *, size_t); 531 | ENET_API size_t enet_range_coder_decompress (void *, const enet_uint8 *, size_t, enet_uint8 *, size_t); 532 | 533 | extern size_t enet_protocol_command_size (enet_uint8); 534 | 535 | #ifdef __cplusplus 536 | } 537 | #endif 538 | 539 | #endif /* __ENET_ENET_H__ */ 540 | 541 | -------------------------------------------------------------------------------- /jni/enet/list.h: -------------------------------------------------------------------------------- 1 | /** 2 | @file list.h 3 | @brief ENet list management 4 | */ 5 | #ifndef __ENET_LIST_H__ 6 | #define __ENET_LIST_H__ 7 | 8 | #include 9 | 10 | typedef struct _ENetListNode 11 | { 12 | struct _ENetListNode * next; 13 | struct _ENetListNode * previous; 14 | } ENetListNode; 15 | 16 | typedef ENetListNode * ENetListIterator; 17 | 18 | typedef struct _ENetList 19 | { 20 | ENetListNode sentinel; 21 | } ENetList; 22 | 23 | extern void enet_list_clear (ENetList *); 24 | 25 | extern ENetListIterator enet_list_insert (ENetListIterator, void *); 26 | extern void * enet_list_remove (ENetListIterator); 27 | extern ENetListIterator enet_list_move (ENetListIterator, void *, void *); 28 | 29 | extern size_t enet_list_size (ENetList *); 30 | 31 | #define enet_list_begin(list) ((list) -> sentinel.next) 32 | #define enet_list_end(list) (& (list) -> sentinel) 33 | 34 | #define enet_list_empty(list) (enet_list_begin (list) == enet_list_end (list)) 35 | 36 | #define enet_list_next(iterator) ((iterator) -> next) 37 | #define enet_list_previous(iterator) ((iterator) -> previous) 38 | 39 | #define enet_list_front(list) ((void *) (list) -> sentinel.next) 40 | #define enet_list_back(list) ((void *) (list) -> sentinel.previous) 41 | 42 | #endif /* __ENET_LIST_H__ */ 43 | 44 | -------------------------------------------------------------------------------- /jni/enet/protocol.h: -------------------------------------------------------------------------------- 1 | /** 2 | @file protocol.h 3 | @brief ENet protocol 4 | */ 5 | #ifndef __ENET_PROTOCOL_H__ 6 | #define __ENET_PROTOCOL_H__ 7 | 8 | #include "enet/types.h" 9 | 10 | enum 11 | { 12 | ENET_PROTOCOL_MINIMUM_MTU = 576, 13 | ENET_PROTOCOL_MAXIMUM_MTU = 4096, 14 | ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS = 32, 15 | ENET_PROTOCOL_MINIMUM_WINDOW_SIZE = 4096, 16 | ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE = 32768, 17 | ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT = 1, 18 | ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT = 255, 19 | ENET_PROTOCOL_MAXIMUM_PEER_ID = 0xFFF 20 | }; 21 | 22 | typedef enum _ENetProtocolCommand 23 | { 24 | ENET_PROTOCOL_COMMAND_NONE = 0, 25 | ENET_PROTOCOL_COMMAND_ACKNOWLEDGE = 1, 26 | ENET_PROTOCOL_COMMAND_CONNECT = 2, 27 | ENET_PROTOCOL_COMMAND_VERIFY_CONNECT = 3, 28 | ENET_PROTOCOL_COMMAND_DISCONNECT = 4, 29 | ENET_PROTOCOL_COMMAND_PING = 5, 30 | ENET_PROTOCOL_COMMAND_SEND_RELIABLE = 6, 31 | ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE = 7, 32 | ENET_PROTOCOL_COMMAND_SEND_FRAGMENT = 8, 33 | ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED = 9, 34 | ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT = 10, 35 | ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE = 11, 36 | ENET_PROTOCOL_COMMAND_COUNT = 12, 37 | 38 | ENET_PROTOCOL_COMMAND_MASK = 0x0F 39 | } ENetProtocolCommand; 40 | 41 | typedef enum _ENetProtocolFlag 42 | { 43 | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE = (1 << 7), 44 | ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED = (1 << 6), 45 | 46 | ENET_PROTOCOL_HEADER_FLAG_COMPRESSED = (1 << 14), 47 | ENET_PROTOCOL_HEADER_FLAG_SENT_TIME = (1 << 15), 48 | ENET_PROTOCOL_HEADER_FLAG_MASK = ENET_PROTOCOL_HEADER_FLAG_COMPRESSED | ENET_PROTOCOL_HEADER_FLAG_SENT_TIME, 49 | 50 | ENET_PROTOCOL_HEADER_SESSION_MASK = (3 << 12), 51 | ENET_PROTOCOL_HEADER_SESSION_SHIFT = 12 52 | } ENetProtocolFlag; 53 | 54 | #ifdef _MSC_VER_ 55 | #pragma pack(push, 1) 56 | #define ENET_PACKED 57 | #elif defined(__GNUC__) 58 | #define ENET_PACKED __attribute__ ((packed)) 59 | #else 60 | #define ENET_PACKED 61 | #endif 62 | 63 | typedef struct _ENetProtocolHeader 64 | { 65 | enet_uint16 peerID; 66 | enet_uint16 sentTime; 67 | } ENET_PACKED ENetProtocolHeader; 68 | 69 | typedef struct _ENetProtocolCommandHeader 70 | { 71 | enet_uint8 command; 72 | enet_uint8 channelID; 73 | enet_uint16 reliableSequenceNumber; 74 | } ENET_PACKED ENetProtocolCommandHeader; 75 | 76 | typedef struct _ENetProtocolAcknowledge 77 | { 78 | ENetProtocolCommandHeader header; 79 | enet_uint16 receivedReliableSequenceNumber; 80 | enet_uint16 receivedSentTime; 81 | } ENET_PACKED ENetProtocolAcknowledge; 82 | 83 | typedef struct _ENetProtocolConnect 84 | { 85 | ENetProtocolCommandHeader header; 86 | enet_uint16 outgoingPeerID; 87 | enet_uint8 incomingSessionID; 88 | enet_uint8 outgoingSessionID; 89 | enet_uint32 mtu; 90 | enet_uint32 windowSize; 91 | enet_uint32 channelCount; 92 | enet_uint32 incomingBandwidth; 93 | enet_uint32 outgoingBandwidth; 94 | enet_uint32 packetThrottleInterval; 95 | enet_uint32 packetThrottleAcceleration; 96 | enet_uint32 packetThrottleDeceleration; 97 | enet_uint32 connectID; 98 | enet_uint32 data; 99 | } ENET_PACKED ENetProtocolConnect; 100 | 101 | typedef struct _ENetProtocolVerifyConnect 102 | { 103 | ENetProtocolCommandHeader header; 104 | enet_uint16 outgoingPeerID; 105 | enet_uint8 incomingSessionID; 106 | enet_uint8 outgoingSessionID; 107 | enet_uint32 mtu; 108 | enet_uint32 windowSize; 109 | enet_uint32 channelCount; 110 | enet_uint32 incomingBandwidth; 111 | enet_uint32 outgoingBandwidth; 112 | enet_uint32 packetThrottleInterval; 113 | enet_uint32 packetThrottleAcceleration; 114 | enet_uint32 packetThrottleDeceleration; 115 | enet_uint32 connectID; 116 | } ENET_PACKED ENetProtocolVerifyConnect; 117 | 118 | typedef struct _ENetProtocolBandwidthLimit 119 | { 120 | ENetProtocolCommandHeader header; 121 | enet_uint32 incomingBandwidth; 122 | enet_uint32 outgoingBandwidth; 123 | } ENET_PACKED ENetProtocolBandwidthLimit; 124 | 125 | typedef struct _ENetProtocolThrottleConfigure 126 | { 127 | ENetProtocolCommandHeader header; 128 | enet_uint32 packetThrottleInterval; 129 | enet_uint32 packetThrottleAcceleration; 130 | enet_uint32 packetThrottleDeceleration; 131 | } ENET_PACKED ENetProtocolThrottleConfigure; 132 | 133 | typedef struct _ENetProtocolDisconnect 134 | { 135 | ENetProtocolCommandHeader header; 136 | enet_uint32 data; 137 | } ENET_PACKED ENetProtocolDisconnect; 138 | 139 | typedef struct _ENetProtocolPing 140 | { 141 | ENetProtocolCommandHeader header; 142 | } ENET_PACKED ENetProtocolPing; 143 | 144 | typedef struct _ENetProtocolSendReliable 145 | { 146 | ENetProtocolCommandHeader header; 147 | enet_uint16 dataLength; 148 | } ENET_PACKED ENetProtocolSendReliable; 149 | 150 | typedef struct _ENetProtocolSendUnreliable 151 | { 152 | ENetProtocolCommandHeader header; 153 | enet_uint16 unreliableSequenceNumber; 154 | enet_uint16 dataLength; 155 | } ENET_PACKED ENetProtocolSendUnreliable; 156 | 157 | typedef struct _ENetProtocolSendUnsequenced 158 | { 159 | ENetProtocolCommandHeader header; 160 | enet_uint16 unsequencedGroup; 161 | enet_uint16 dataLength; 162 | } ENET_PACKED ENetProtocolSendUnsequenced; 163 | 164 | typedef struct _ENetProtocolSendFragment 165 | { 166 | ENetProtocolCommandHeader header; 167 | enet_uint16 startSequenceNumber; 168 | enet_uint16 dataLength; 169 | enet_uint32 fragmentCount; 170 | enet_uint32 fragmentNumber; 171 | enet_uint32 totalLength; 172 | enet_uint32 fragmentOffset; 173 | } ENET_PACKED ENetProtocolSendFragment; 174 | 175 | typedef union _ENetProtocol 176 | { 177 | ENetProtocolCommandHeader header; 178 | ENetProtocolAcknowledge acknowledge; 179 | ENetProtocolConnect connect; 180 | ENetProtocolVerifyConnect verifyConnect; 181 | ENetProtocolDisconnect disconnect; 182 | ENetProtocolPing ping; 183 | ENetProtocolSendReliable sendReliable; 184 | ENetProtocolSendUnreliable sendUnreliable; 185 | ENetProtocolSendUnsequenced sendUnsequenced; 186 | ENetProtocolSendFragment sendFragment; 187 | ENetProtocolBandwidthLimit bandwidthLimit; 188 | ENetProtocolThrottleConfigure throttleConfigure; 189 | } ENET_PACKED ENetProtocol; 190 | 191 | #ifdef _MSC_VER_ 192 | #pragma pack(pop) 193 | #endif 194 | 195 | #endif /* __ENET_PROTOCOL_H__ */ 196 | 197 | -------------------------------------------------------------------------------- /jni/enet/time.h: -------------------------------------------------------------------------------- 1 | /** 2 | @file time.h 3 | @brief ENet time constants and macros 4 | */ 5 | #ifndef __ENET_TIME_H__ 6 | #define __ENET_TIME_H__ 7 | 8 | #define ENET_TIME_OVERFLOW 86400000 9 | 10 | #define ENET_TIME_LESS(a, b) ((a) - (b) >= ENET_TIME_OVERFLOW) 11 | #define ENET_TIME_GREATER(a, b) ((b) - (a) >= ENET_TIME_OVERFLOW) 12 | #define ENET_TIME_LESS_EQUAL(a, b) (! ENET_TIME_GREATER (a, b)) 13 | #define ENET_TIME_GREATER_EQUAL(a, b) (! ENET_TIME_LESS (a, b)) 14 | 15 | #define ENET_TIME_DIFFERENCE(a, b) ((a) - (b) >= ENET_TIME_OVERFLOW ? (b) - (a) : (a) - (b)) 16 | 17 | #endif /* __ENET_TIME_H__ */ 18 | 19 | -------------------------------------------------------------------------------- /jni/enet/types.h: -------------------------------------------------------------------------------- 1 | /** 2 | @file types.h 3 | @brief type definitions for ENet 4 | */ 5 | #ifndef __ENET_TYPES_H__ 6 | #define __ENET_TYPES_H__ 7 | 8 | typedef unsigned char enet_uint8; /**< unsigned 8-bit type */ 9 | typedef unsigned short enet_uint16; /**< unsigned 16-bit type */ 10 | typedef unsigned int enet_uint32; /**< unsigned 32-bit type */ 11 | 12 | #endif /* __ENET_TYPES_H__ */ 13 | 14 | -------------------------------------------------------------------------------- /jni/enet/unix.h: -------------------------------------------------------------------------------- 1 | /** 2 | @file unix.h 3 | @brief ENet Unix header 4 | */ 5 | #ifndef __ENET_UNIX_H__ 6 | #define __ENET_UNIX_H__ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | typedef int ENetSocket; 15 | 16 | enum 17 | { 18 | ENET_SOCKET_NULL = -1 19 | }; 20 | 21 | #define ENET_HOST_TO_NET_16(value) (htons (value)) /**< macro that converts host to net byte-order of a 16-bit value */ 22 | #define ENET_HOST_TO_NET_32(value) (htonl (value)) /**< macro that converts host to net byte-order of a 32-bit value */ 23 | 24 | #define ENET_NET_TO_HOST_16(value) (ntohs (value)) /**< macro that converts net to host byte-order of a 16-bit value */ 25 | #define ENET_NET_TO_HOST_32(value) (ntohl (value)) /**< macro that converts net to host byte-order of a 32-bit value */ 26 | 27 | typedef struct 28 | { 29 | void * data; 30 | size_t dataLength; 31 | } ENetBuffer; 32 | 33 | #define ENET_CALLBACK 34 | 35 | #define ENET_API extern 36 | 37 | typedef fd_set ENetSocketSet; 38 | 39 | #define ENET_SOCKETSET_EMPTY(sockset) FD_ZERO (& (sockset)) 40 | #define ENET_SOCKETSET_ADD(sockset, socket) FD_SET (socket, & (sockset)) 41 | #define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLEAR (socket, & (sockset)) 42 | #define ENET_SOCKETSET_CHECK(sockset, socket) FD_ISSET (socket, & (sockset)) 43 | 44 | #endif /* __ENET_UNIX_H__ */ 45 | 46 | -------------------------------------------------------------------------------- /jni/enet/utility.h: -------------------------------------------------------------------------------- 1 | /** 2 | @file utility.h 3 | @brief ENet utility header 4 | */ 5 | #ifndef __ENET_UTILITY_H__ 6 | #define __ENET_UTILITY_H__ 7 | 8 | #define ENET_MAX(x, y) ((x) > (y) ? (x) : (y)) 9 | #define ENET_MIN(x, y) ((x) < (y) ? (x) : (y)) 10 | 11 | #endif /* __ENET_UTILITY_H__ */ 12 | 13 | -------------------------------------------------------------------------------- /jni/enet/win32.h: -------------------------------------------------------------------------------- 1 | /** 2 | @file win32.h 3 | @brief ENet Win32 header 4 | */ 5 | #ifndef __ENET_WIN32_H__ 6 | #define __ENET_WIN32_H__ 7 | 8 | #ifdef ENET_BUILDING_LIB 9 | #pragma warning (disable: 4996) // 'strncpy' was declared deprecated 10 | #pragma warning (disable: 4267) // size_t to int conversion 11 | #pragma warning (disable: 4244) // 64bit to 32bit int 12 | #pragma warning (disable: 4018) // signed/unsigned mismatch 13 | #endif 14 | 15 | #include 16 | #include 17 | 18 | typedef SOCKET ENetSocket; 19 | 20 | enum 21 | { 22 | ENET_SOCKET_NULL = INVALID_SOCKET 23 | }; 24 | 25 | #define ENET_HOST_TO_NET_16(value) (htons (value)) 26 | #define ENET_HOST_TO_NET_32(value) (htonl (value)) 27 | 28 | #define ENET_NET_TO_HOST_16(value) (ntohs (value)) 29 | #define ENET_NET_TO_HOST_32(value) (ntohl (value)) 30 | 31 | typedef struct 32 | { 33 | size_t dataLength; 34 | void * data; 35 | } ENetBuffer; 36 | 37 | #define ENET_CALLBACK __cdecl 38 | 39 | #if defined ENET_DLL 40 | #if defined ENET_BUILDING_LIB 41 | #define ENET_API __declspec( dllexport ) 42 | #else 43 | #define ENET_API __declspec( dllimport ) 44 | #endif /* ENET_BUILDING_LIB */ 45 | #else /* !ENET_DLL */ 46 | #define ENET_API extern 47 | #endif /* ENET_DLL */ 48 | 49 | typedef fd_set ENetSocketSet; 50 | 51 | #define ENET_SOCKETSET_EMPTY(sockset) FD_ZERO (& (sockset)) 52 | #define ENET_SOCKETSET_ADD(sockset, socket) FD_SET (socket, & (sockset)) 53 | #define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLEAR (socket, & (sockset)) 54 | #define ENET_SOCKETSET_CHECK(sockset, socket) FD_ISSET (socket, & (sockset)) 55 | 56 | #endif /* __ENET_WIN32_H__ */ 57 | 58 | 59 | -------------------------------------------------------------------------------- /jni/host.c: -------------------------------------------------------------------------------- 1 | /** 2 | @file host.c 3 | @brief ENet host management functions 4 | */ 5 | #define ENET_BUILDING_LIB 1 6 | #include 7 | #include 8 | #include "enet/enet.h" 9 | 10 | /** @defgroup host ENet host functions 11 | @{ 12 | */ 13 | 14 | /** Creates a host for communicating to peers. 15 | 16 | @param address the address at which other peers may connect to this host. If NULL, then no peers may connect to the host. 17 | @param peerCount the maximum number of peers that should be allocated for the host. 18 | @param channelLimit the maximum number of channels allowed; if 0, then this is equivalent to ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT 19 | @param incomingBandwidth downstream bandwidth of the host in bytes/second; if 0, ENet will assume unlimited bandwidth. 20 | @param outgoingBandwidth upstream bandwidth of the host in bytes/second; if 0, ENet will assume unlimited bandwidth. 21 | 22 | @returns the host on success and NULL on failure 23 | 24 | @remarks ENet will strategically drop packets on specific sides of a connection between hosts 25 | to ensure the host's bandwidth is not overwhelmed. The bandwidth parameters also determine 26 | the window size of a connection which limits the amount of reliable packets that may be in transit 27 | at any given time. 28 | */ 29 | ENetHost * 30 | enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelLimit, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth) 31 | { 32 | ENetHost * host; 33 | ENetPeer * currentPeer; 34 | 35 | if (peerCount > ENET_PROTOCOL_MAXIMUM_PEER_ID) 36 | return NULL; 37 | 38 | host = (ENetHost *) enet_malloc (sizeof (ENetHost)); 39 | if (host == NULL) 40 | return NULL; 41 | 42 | host -> peers = (ENetPeer *) enet_malloc (peerCount * sizeof (ENetPeer)); 43 | if (host -> peers == NULL) 44 | { 45 | enet_free (host); 46 | 47 | return NULL; 48 | } 49 | memset (host -> peers, 0, peerCount * sizeof (ENetPeer)); 50 | 51 | host -> socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM); 52 | if (host -> socket == ENET_SOCKET_NULL || (address != NULL && enet_socket_bind (host -> socket, address) < 0)) 53 | { 54 | if (host -> socket != ENET_SOCKET_NULL) 55 | enet_socket_destroy (host -> socket); 56 | 57 | enet_free (host -> peers); 58 | enet_free (host); 59 | 60 | return NULL; 61 | } 62 | 63 | enet_socket_set_option (host -> socket, ENET_SOCKOPT_NONBLOCK, 1); 64 | enet_socket_set_option (host -> socket, ENET_SOCKOPT_BROADCAST, 1); 65 | enet_socket_set_option (host -> socket, ENET_SOCKOPT_RCVBUF, ENET_HOST_RECEIVE_BUFFER_SIZE); 66 | enet_socket_set_option (host -> socket, ENET_SOCKOPT_SNDBUF, ENET_HOST_SEND_BUFFER_SIZE); 67 | 68 | if (address != NULL) 69 | host -> address = * address; 70 | 71 | if (! channelLimit || channelLimit > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT) 72 | channelLimit = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT; 73 | else 74 | if (channelLimit < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT) 75 | channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT; 76 | 77 | host -> randomSeed = (enet_uint32) time(NULL) + (enet_uint32) (size_t) host; 78 | host -> randomSeed = (host -> randomSeed << 16) | (host -> randomSeed >> 16); 79 | host -> channelLimit = channelLimit; 80 | host -> incomingBandwidth = incomingBandwidth; 81 | host -> outgoingBandwidth = outgoingBandwidth; 82 | host -> bandwidthThrottleEpoch = 0; 83 | host -> recalculateBandwidthLimits = 0; 84 | host -> mtu = ENET_HOST_DEFAULT_MTU; 85 | host -> peerCount = peerCount; 86 | host -> commandCount = 0; 87 | host -> bufferCount = 0; 88 | host -> checksum = NULL; 89 | host -> receivedAddress.host = ENET_HOST_ANY; 90 | host -> receivedAddress.port = 0; 91 | host -> receivedData = NULL; 92 | host -> receivedDataLength = 0; 93 | 94 | host -> totalSentData = 0; 95 | host -> totalSentPackets = 0; 96 | host -> totalReceivedData = 0; 97 | host -> totalReceivedPackets = 0; 98 | 99 | host -> compressor.context = NULL; 100 | host -> compressor.compress = NULL; 101 | host -> compressor.decompress = NULL; 102 | host -> compressor.destroy = NULL; 103 | 104 | enet_list_clear (& host -> dispatchQueue); 105 | 106 | for (currentPeer = host -> peers; 107 | currentPeer < & host -> peers [host -> peerCount]; 108 | ++ currentPeer) 109 | { 110 | currentPeer -> host = host; 111 | currentPeer -> incomingPeerID = currentPeer - host -> peers; 112 | currentPeer -> outgoingSessionID = currentPeer -> incomingSessionID = 0xFF; 113 | currentPeer -> data = NULL; 114 | 115 | enet_list_clear (& currentPeer -> acknowledgements); 116 | enet_list_clear (& currentPeer -> sentReliableCommands); 117 | enet_list_clear (& currentPeer -> sentUnreliableCommands); 118 | enet_list_clear (& currentPeer -> outgoingReliableCommands); 119 | enet_list_clear (& currentPeer -> outgoingUnreliableCommands); 120 | enet_list_clear (& currentPeer -> dispatchedCommands); 121 | 122 | enet_peer_reset (currentPeer); 123 | } 124 | 125 | return host; 126 | } 127 | 128 | /** Destroys the host and all resources associated with it. 129 | @param host pointer to the host to destroy 130 | */ 131 | void 132 | enet_host_destroy (ENetHost * host) 133 | { 134 | ENetPeer * currentPeer; 135 | 136 | enet_socket_destroy (host -> socket); 137 | 138 | for (currentPeer = host -> peers; 139 | currentPeer < & host -> peers [host -> peerCount]; 140 | ++ currentPeer) 141 | { 142 | enet_peer_reset (currentPeer); 143 | } 144 | 145 | if (host -> compressor.context != NULL && host -> compressor.destroy) 146 | (* host -> compressor.destroy) (host -> compressor.context); 147 | 148 | enet_free (host -> peers); 149 | enet_free (host); 150 | } 151 | 152 | /** Initiates a connection to a foreign host. 153 | @param host host seeking the connection 154 | @param address destination for the connection 155 | @param channelCount number of channels to allocate 156 | @param data user data supplied to the receiving host 157 | @returns a peer representing the foreign host on success, NULL on failure 158 | @remarks The peer returned will have not completed the connection until enet_host_service() 159 | notifies of an ENET_EVENT_TYPE_CONNECT event for the peer. 160 | */ 161 | ENetPeer * 162 | enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelCount, enet_uint32 data) 163 | { 164 | ENetPeer * currentPeer; 165 | ENetChannel * channel; 166 | ENetProtocol command; 167 | 168 | if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT) 169 | channelCount = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT; 170 | else 171 | if (channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT) 172 | channelCount = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT; 173 | 174 | for (currentPeer = host -> peers; 175 | currentPeer < & host -> peers [host -> peerCount]; 176 | ++ currentPeer) 177 | { 178 | if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED) 179 | break; 180 | } 181 | 182 | if (currentPeer >= & host -> peers [host -> peerCount]) 183 | return NULL; 184 | 185 | currentPeer -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel)); 186 | if (currentPeer -> channels == NULL) 187 | return NULL; 188 | currentPeer -> channelCount = channelCount; 189 | currentPeer -> state = ENET_PEER_STATE_CONNECTING; 190 | currentPeer -> address = * address; 191 | currentPeer -> connectID = ++ host -> randomSeed; 192 | 193 | if (host -> outgoingBandwidth == 0) 194 | currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; 195 | else 196 | currentPeer -> windowSize = (host -> outgoingBandwidth / 197 | ENET_PEER_WINDOW_SIZE_SCALE) * 198 | ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; 199 | 200 | if (currentPeer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) 201 | currentPeer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; 202 | else 203 | if (currentPeer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) 204 | currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; 205 | 206 | for (channel = currentPeer -> channels; 207 | channel < & currentPeer -> channels [channelCount]; 208 | ++ channel) 209 | { 210 | channel -> outgoingReliableSequenceNumber = 0; 211 | channel -> outgoingUnreliableSequenceNumber = 0; 212 | channel -> incomingReliableSequenceNumber = 0; 213 | 214 | enet_list_clear (& channel -> incomingReliableCommands); 215 | enet_list_clear (& channel -> incomingUnreliableCommands); 216 | 217 | channel -> usedReliableWindows = 0; 218 | memset (channel -> reliableWindows, 0, sizeof (channel -> reliableWindows)); 219 | } 220 | 221 | command.header.command = ENET_PROTOCOL_COMMAND_CONNECT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; 222 | command.header.channelID = 0xFF; 223 | command.connect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID); 224 | command.connect.incomingSessionID = currentPeer -> incomingSessionID; 225 | command.connect.outgoingSessionID = currentPeer -> outgoingSessionID; 226 | command.connect.mtu = ENET_HOST_TO_NET_32 (currentPeer -> mtu); 227 | command.connect.windowSize = ENET_HOST_TO_NET_32 (currentPeer -> windowSize); 228 | command.connect.channelCount = ENET_HOST_TO_NET_32 (channelCount); 229 | command.connect.incomingBandwidth = ENET_HOST_TO_NET_32 (host -> incomingBandwidth); 230 | command.connect.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth); 231 | command.connect.packetThrottleInterval = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleInterval); 232 | command.connect.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleAcceleration); 233 | command.connect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleDeceleration); 234 | command.connect.connectID = currentPeer -> connectID; 235 | command.connect.data = ENET_HOST_TO_NET_32 (data); 236 | 237 | enet_peer_queue_outgoing_command (currentPeer, & command, NULL, 0, 0); 238 | 239 | return currentPeer; 240 | } 241 | 242 | /** Queues a packet to be sent to all peers associated with the host. 243 | @param host host on which to broadcast the packet 244 | @param channelID channel on which to broadcast 245 | @param packet packet to broadcast 246 | */ 247 | void 248 | enet_host_broadcast (ENetHost * host, enet_uint8 channelID, ENetPacket * packet) 249 | { 250 | ENetPeer * currentPeer; 251 | 252 | for (currentPeer = host -> peers; 253 | currentPeer < & host -> peers [host -> peerCount]; 254 | ++ currentPeer) 255 | { 256 | if (currentPeer -> state != ENET_PEER_STATE_CONNECTED) 257 | continue; 258 | 259 | enet_peer_send (currentPeer, channelID, packet); 260 | } 261 | 262 | if (packet -> referenceCount == 0) 263 | enet_packet_destroy (packet); 264 | } 265 | 266 | /** Sets the packet compressor the host should use to compress and decompress packets. 267 | @param host host to enable or disable compression for 268 | @param compressor callbacks for for the packet compressor; if NULL, then compression is disabled 269 | */ 270 | void 271 | enet_host_compress (ENetHost * host, const ENetCompressor * compressor) 272 | { 273 | if (host -> compressor.context != NULL && host -> compressor.destroy) 274 | (* host -> compressor.destroy) (host -> compressor.context); 275 | 276 | if (compressor) 277 | host -> compressor = * compressor; 278 | else 279 | host -> compressor.context = NULL; 280 | } 281 | 282 | /** Limits the maximum allowed channels of future incoming connections. 283 | @param host host to limit 284 | @param channelLimit the maximum number of channels allowed; if 0, then this is equivalent to ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT 285 | */ 286 | void 287 | enet_host_channel_limit (ENetHost * host, size_t channelLimit) 288 | { 289 | if (! channelLimit || channelLimit > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT) 290 | channelLimit = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT; 291 | else 292 | if (channelLimit < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT) 293 | channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT; 294 | 295 | host -> channelLimit = channelLimit; 296 | } 297 | 298 | 299 | /** Adjusts the bandwidth limits of a host. 300 | @param host host to adjust 301 | @param incomingBandwidth new incoming bandwidth 302 | @param outgoingBandwidth new outgoing bandwidth 303 | @remarks the incoming and outgoing bandwidth parameters are identical in function to those 304 | specified in enet_host_create(). 305 | */ 306 | void 307 | enet_host_bandwidth_limit (ENetHost * host, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth) 308 | { 309 | host -> incomingBandwidth = incomingBandwidth; 310 | host -> outgoingBandwidth = outgoingBandwidth; 311 | host -> recalculateBandwidthLimits = 1; 312 | } 313 | 314 | void 315 | enet_host_bandwidth_throttle (ENetHost * host) 316 | { 317 | enet_uint32 timeCurrent = enet_time_get (), 318 | elapsedTime = timeCurrent - host -> bandwidthThrottleEpoch, 319 | peersTotal = 0, 320 | dataTotal = 0, 321 | peersRemaining, 322 | bandwidth, 323 | throttle = 0, 324 | bandwidthLimit = 0; 325 | int needsAdjustment; 326 | ENetPeer * peer; 327 | ENetProtocol command; 328 | 329 | if (elapsedTime < ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL) 330 | return; 331 | 332 | for (peer = host -> peers; 333 | peer < & host -> peers [host -> peerCount]; 334 | ++ peer) 335 | { 336 | if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) 337 | continue; 338 | 339 | ++ peersTotal; 340 | dataTotal += peer -> outgoingDataTotal; 341 | } 342 | 343 | if (peersTotal == 0) 344 | return; 345 | 346 | peersRemaining = peersTotal; 347 | needsAdjustment = 1; 348 | 349 | if (host -> outgoingBandwidth == 0) 350 | bandwidth = ~0; 351 | else 352 | bandwidth = (host -> outgoingBandwidth * elapsedTime) / 1000; 353 | 354 | while (peersRemaining > 0 && needsAdjustment != 0) 355 | { 356 | needsAdjustment = 0; 357 | 358 | if (dataTotal < bandwidth) 359 | throttle = ENET_PEER_PACKET_THROTTLE_SCALE; 360 | else 361 | throttle = (bandwidth * ENET_PEER_PACKET_THROTTLE_SCALE) / dataTotal; 362 | 363 | for (peer = host -> peers; 364 | peer < & host -> peers [host -> peerCount]; 365 | ++ peer) 366 | { 367 | enet_uint32 peerBandwidth; 368 | 369 | if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) || 370 | peer -> incomingBandwidth == 0 || 371 | peer -> outgoingBandwidthThrottleEpoch == timeCurrent) 372 | continue; 373 | 374 | peerBandwidth = (peer -> incomingBandwidth * elapsedTime) / 1000; 375 | if ((throttle * peer -> outgoingDataTotal) / ENET_PEER_PACKET_THROTTLE_SCALE <= peerBandwidth) 376 | continue; 377 | 378 | peer -> packetThrottleLimit = (peerBandwidth * 379 | ENET_PEER_PACKET_THROTTLE_SCALE) / peer -> outgoingDataTotal; 380 | 381 | if (peer -> packetThrottleLimit == 0) 382 | peer -> packetThrottleLimit = 1; 383 | 384 | if (peer -> packetThrottle > peer -> packetThrottleLimit) 385 | peer -> packetThrottle = peer -> packetThrottleLimit; 386 | 387 | peer -> outgoingBandwidthThrottleEpoch = timeCurrent; 388 | 389 | 390 | needsAdjustment = 1; 391 | -- peersRemaining; 392 | bandwidth -= peerBandwidth; 393 | dataTotal -= peerBandwidth; 394 | } 395 | } 396 | 397 | if (peersRemaining > 0) 398 | for (peer = host -> peers; 399 | peer < & host -> peers [host -> peerCount]; 400 | ++ peer) 401 | { 402 | if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) || 403 | peer -> outgoingBandwidthThrottleEpoch == timeCurrent) 404 | continue; 405 | 406 | peer -> packetThrottleLimit = throttle; 407 | 408 | if (peer -> packetThrottle > peer -> packetThrottleLimit) 409 | peer -> packetThrottle = peer -> packetThrottleLimit; 410 | } 411 | 412 | if (host -> recalculateBandwidthLimits) 413 | { 414 | host -> recalculateBandwidthLimits = 0; 415 | 416 | peersRemaining = peersTotal; 417 | bandwidth = host -> incomingBandwidth; 418 | needsAdjustment = 1; 419 | 420 | if (bandwidth == 0) 421 | bandwidthLimit = 0; 422 | else 423 | while (peersRemaining > 0 && needsAdjustment != 0) 424 | { 425 | needsAdjustment = 0; 426 | bandwidthLimit = bandwidth / peersRemaining; 427 | 428 | for (peer = host -> peers; 429 | peer < & host -> peers [host -> peerCount]; 430 | ++ peer) 431 | { 432 | if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) || 433 | peer -> incomingBandwidthThrottleEpoch == timeCurrent) 434 | continue; 435 | 436 | if (peer -> outgoingBandwidth > 0 && 437 | peer -> outgoingBandwidth >= bandwidthLimit) 438 | continue; 439 | 440 | peer -> incomingBandwidthThrottleEpoch = timeCurrent; 441 | 442 | needsAdjustment = 1; 443 | -- peersRemaining; 444 | bandwidth -= peer -> outgoingBandwidth; 445 | } 446 | } 447 | 448 | for (peer = host -> peers; 449 | peer < & host -> peers [host -> peerCount]; 450 | ++ peer) 451 | { 452 | if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) 453 | continue; 454 | 455 | command.header.command = ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; 456 | command.header.channelID = 0xFF; 457 | command.bandwidthLimit.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth); 458 | 459 | if (peer -> incomingBandwidthThrottleEpoch == timeCurrent) 460 | command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (peer -> outgoingBandwidth); 461 | else 462 | command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (bandwidthLimit); 463 | 464 | enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0); 465 | } 466 | } 467 | 468 | host -> bandwidthThrottleEpoch = timeCurrent; 469 | 470 | for (peer = host -> peers; 471 | peer < & host -> peers [host -> peerCount]; 472 | ++ peer) 473 | { 474 | peer -> incomingDataTotal = 0; 475 | peer -> outgoingDataTotal = 0; 476 | } 477 | } 478 | 479 | /** @} */ 480 | -------------------------------------------------------------------------------- /jni/list.c: -------------------------------------------------------------------------------- 1 | /** 2 | @file list.c 3 | @brief ENet linked list functions 4 | */ 5 | #define ENET_BUILDING_LIB 1 6 | #include "enet/list.h" 7 | 8 | /** 9 | @defgroup list ENet linked list utility functions 10 | @ingroup private 11 | @{ 12 | */ 13 | void 14 | enet_list_clear (ENetList * list) 15 | { 16 | list -> sentinel.next = & list -> sentinel; 17 | list -> sentinel.previous = & list -> sentinel; 18 | } 19 | 20 | ENetListIterator 21 | enet_list_insert (ENetListIterator position, void * data) 22 | { 23 | ENetListIterator result = (ENetListIterator) data; 24 | 25 | result -> previous = position -> previous; 26 | result -> next = position; 27 | 28 | result -> previous -> next = result; 29 | position -> previous = result; 30 | 31 | return result; 32 | } 33 | 34 | void * 35 | enet_list_remove (ENetListIterator position) 36 | { 37 | position -> previous -> next = position -> next; 38 | position -> next -> previous = position -> previous; 39 | 40 | return position; 41 | } 42 | 43 | ENetListIterator 44 | enet_list_move (ENetListIterator position, void * dataFirst, void * dataLast) 45 | { 46 | ENetListIterator first = (ENetListIterator) dataFirst, 47 | last = (ENetListIterator) dataLast; 48 | 49 | first -> previous -> next = last -> next; 50 | last -> next -> previous = first -> previous; 51 | 52 | first -> previous = position -> previous; 53 | last -> next = position; 54 | 55 | first -> previous -> next = first; 56 | position -> previous = last; 57 | 58 | return first; 59 | } 60 | 61 | size_t 62 | enet_list_size (ENetList * list) 63 | { 64 | size_t size = 0; 65 | ENetListIterator position; 66 | 67 | for (position = enet_list_begin (list); 68 | position != enet_list_end (list); 69 | position = enet_list_next (position)) 70 | ++ size; 71 | 72 | return size; 73 | } 74 | 75 | /** @} */ 76 | -------------------------------------------------------------------------------- /jni/packet.c: -------------------------------------------------------------------------------- 1 | /** 2 | @file packet.c 3 | @brief ENet packet management functions 4 | */ 5 | #include 6 | #define ENET_BUILDING_LIB 1 7 | #include "enet/enet.h" 8 | 9 | /** @defgroup Packet ENet packet functions 10 | @{ 11 | */ 12 | 13 | /** Creates a packet that may be sent to a peer. 14 | @param dataContents initial contents of the packet's data; the packet's data will remain uninitialized if dataContents is NULL. 15 | @param dataLength size of the data allocated for this packet 16 | @param flags flags for this packet as described for the ENetPacket structure. 17 | @returns the packet on success, NULL on failure 18 | */ 19 | ENetPacket * 20 | enet_packet_create (const void * data, size_t dataLength, enet_uint32 flags) 21 | { 22 | ENetPacket * packet = (ENetPacket *) enet_malloc (sizeof (ENetPacket)); 23 | if (packet == NULL) 24 | return NULL; 25 | 26 | if (flags & ENET_PACKET_FLAG_NO_ALLOCATE) 27 | packet -> data = (enet_uint8 *) data; 28 | else 29 | { 30 | packet -> data = (enet_uint8 *) enet_malloc (dataLength); 31 | if (packet -> data == NULL) 32 | { 33 | enet_free (packet); 34 | return NULL; 35 | } 36 | 37 | if (data != NULL) 38 | memcpy (packet -> data, data, dataLength); 39 | } 40 | 41 | packet -> referenceCount = 0; 42 | packet -> flags = flags; 43 | packet -> dataLength = dataLength; 44 | packet -> freeCallback = NULL; 45 | 46 | return packet; 47 | } 48 | 49 | /** Destroys the packet and deallocates its data. 50 | @param packet packet to be destroyed 51 | */ 52 | void 53 | enet_packet_destroy (ENetPacket * packet) 54 | { 55 | if (packet -> freeCallback != NULL) 56 | (* packet -> freeCallback) (packet); 57 | if (! (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE)) 58 | enet_free (packet -> data); 59 | enet_free (packet); 60 | } 61 | 62 | /** Attempts to resize the data in the packet to length specified in the 63 | dataLength parameter 64 | @param packet packet to resize 65 | @param dataLength new size for the packet data 66 | @returns 0 on success, < 0 on failure 67 | */ 68 | int 69 | enet_packet_resize (ENetPacket * packet, size_t dataLength) 70 | { 71 | enet_uint8 * newData; 72 | 73 | if (dataLength <= packet -> dataLength || (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE)) 74 | { 75 | packet -> dataLength = dataLength; 76 | 77 | return 0; 78 | } 79 | 80 | newData = (enet_uint8 *) enet_malloc (dataLength); 81 | if (newData == NULL) 82 | return -1; 83 | 84 | memcpy (newData, packet -> data, packet -> dataLength); 85 | enet_free (packet -> data); 86 | 87 | packet -> data = newData; 88 | packet -> dataLength = dataLength; 89 | 90 | return 0; 91 | } 92 | 93 | static int initializedCRC32 = 0; 94 | static enet_uint32 crcTable [256]; 95 | 96 | static enet_uint32 97 | reflect_crc (int val, int bits) 98 | { 99 | int result = 0, bit; 100 | 101 | for (bit = 0; bit < bits; bit ++) 102 | { 103 | if(val & 1) result |= 1 << (bits - 1 - bit); 104 | val >>= 1; 105 | } 106 | 107 | return result; 108 | } 109 | 110 | static void 111 | initialize_crc32 () 112 | { 113 | int byte; 114 | 115 | for (byte = 0; byte < 256; ++ byte) 116 | { 117 | enet_uint32 crc = reflect_crc (byte, 8) << 24; 118 | int offset; 119 | 120 | for(offset = 0; offset < 8; ++ offset) 121 | { 122 | if (crc & 0x80000000) 123 | crc = (crc << 1) ^ 0x04c11db7; 124 | else 125 | crc <<= 1; 126 | } 127 | 128 | crcTable [byte] = reflect_crc (crc, 32); 129 | } 130 | 131 | initializedCRC32 = 1; 132 | } 133 | 134 | enet_uint32 135 | enet_crc32 (const ENetBuffer * buffers, size_t bufferCount) 136 | { 137 | enet_uint32 crc = 0xFFFFFFFF; 138 | 139 | if (! initializedCRC32) initialize_crc32 (); 140 | 141 | while (bufferCount -- > 0) 142 | { 143 | const enet_uint8 * data = (const enet_uint8 *) buffers -> data, 144 | * dataEnd = & data [buffers -> dataLength]; 145 | 146 | while (data < dataEnd) 147 | { 148 | crc = (crc >> 8) ^ crcTable [(crc & 0xFF) ^ *data++]; 149 | } 150 | 151 | ++ buffers; 152 | } 153 | 154 | return ENET_HOST_TO_NET_32 (~ crc); 155 | } 156 | 157 | /** @} */ 158 | -------------------------------------------------------------------------------- /jni/peer.c: -------------------------------------------------------------------------------- 1 | /** 2 | @file peer.c 3 | @brief ENet peer management functions 4 | */ 5 | #include 6 | #define ENET_BUILDING_LIB 1 7 | #include "enet/enet.h" 8 | 9 | /** @defgroup peer ENet peer functions 10 | @{ 11 | */ 12 | 13 | /** Configures throttle parameter for a peer. 14 | 15 | Unreliable packets are dropped by ENet in response to the varying conditions 16 | of the Internet connection to the peer. The throttle represents a probability 17 | that an unreliable packet should not be dropped and thus sent by ENet to the peer. 18 | The lowest mean round trip time from the sending of a reliable packet to the 19 | receipt of its acknowledgement is measured over an amount of time specified by 20 | the interval parameter in milliseconds. If a measured round trip time happens to 21 | be significantly less than the mean round trip time measured over the interval, 22 | then the throttle probability is increased to allow more traffic by an amount 23 | specified in the acceleration parameter, which is a ratio to the ENET_PEER_PACKET_THROTTLE_SCALE 24 | constant. If a measured round trip time happens to be significantly greater than 25 | the mean round trip time measured over the interval, then the throttle probability 26 | is decreased to limit traffic by an amount specified in the deceleration parameter, which 27 | is a ratio to the ENET_PEER_PACKET_THROTTLE_SCALE constant. When the throttle has 28 | a value of ENET_PEER_PACKET_THROTTLE_SCALE, on unreliable packets are dropped by 29 | ENet, and so 100% of all unreliable packets will be sent. When the throttle has a 30 | value of 0, all unreliable packets are dropped by ENet, and so 0% of all unreliable 31 | packets will be sent. Intermediate values for the throttle represent intermediate 32 | probabilities between 0% and 100% of unreliable packets being sent. The bandwidth 33 | limits of the local and foreign hosts are taken into account to determine a 34 | sensible limit for the throttle probability above which it should not raise even in 35 | the best of conditions. 36 | 37 | @param peer peer to configure 38 | @param interval interval, in milliseconds, over which to measure lowest mean RTT; the default value is ENET_PEER_PACKET_THROTTLE_INTERVAL. 39 | @param acceleration rate at which to increase the throttle probability as mean RTT declines 40 | @param deceleration rate at which to decrease the throttle probability as mean RTT increases 41 | */ 42 | void 43 | enet_peer_throttle_configure (ENetPeer * peer, enet_uint32 interval, enet_uint32 acceleration, enet_uint32 deceleration) 44 | { 45 | ENetProtocol command; 46 | 47 | peer -> packetThrottleInterval = interval; 48 | peer -> packetThrottleAcceleration = acceleration; 49 | peer -> packetThrottleDeceleration = deceleration; 50 | 51 | command.header.command = ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; 52 | command.header.channelID = 0xFF; 53 | 54 | command.throttleConfigure.packetThrottleInterval = ENET_HOST_TO_NET_32 (interval); 55 | command.throttleConfigure.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (acceleration); 56 | command.throttleConfigure.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (deceleration); 57 | 58 | enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0); 59 | } 60 | 61 | int 62 | enet_peer_throttle (ENetPeer * peer, enet_uint32 rtt) 63 | { 64 | if (peer -> lastRoundTripTime <= peer -> lastRoundTripTimeVariance) 65 | { 66 | peer -> packetThrottle = peer -> packetThrottleLimit; 67 | } 68 | else 69 | if (rtt < peer -> lastRoundTripTime) 70 | { 71 | peer -> packetThrottle += peer -> packetThrottleAcceleration; 72 | 73 | if (peer -> packetThrottle > peer -> packetThrottleLimit) 74 | peer -> packetThrottle = peer -> packetThrottleLimit; 75 | 76 | return 1; 77 | } 78 | else 79 | if (rtt > peer -> lastRoundTripTime + 2 * peer -> lastRoundTripTimeVariance) 80 | { 81 | if (peer -> packetThrottle > peer -> packetThrottleDeceleration) 82 | peer -> packetThrottle -= peer -> packetThrottleDeceleration; 83 | else 84 | peer -> packetThrottle = 0; 85 | 86 | return -1; 87 | } 88 | 89 | return 0; 90 | } 91 | 92 | /** Queues a packet to be sent. 93 | @param peer destination for the packet 94 | @param channelID channel on which to send 95 | @param packet packet to send 96 | @retval 0 on success 97 | @retval < 0 on failure 98 | */ 99 | int 100 | enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet) 101 | { 102 | ENetChannel * channel = & peer -> channels [channelID]; 103 | ENetProtocol command; 104 | size_t fragmentLength; 105 | 106 | if (peer -> state != ENET_PEER_STATE_CONNECTED || 107 | channelID >= peer -> channelCount) 108 | return -1; 109 | 110 | fragmentLength = peer -> mtu - sizeof (ENetProtocolHeader) - sizeof (ENetProtocolSendFragment); 111 | 112 | if (packet -> dataLength > fragmentLength) 113 | { 114 | enet_uint16 startSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingReliableSequenceNumber + 1); 115 | enet_uint32 fragmentCount = ENET_HOST_TO_NET_32 ((packet -> dataLength + fragmentLength - 1) / fragmentLength), 116 | fragmentNumber, 117 | fragmentOffset; 118 | ENetList fragments; 119 | ENetOutgoingCommand * fragment; 120 | 121 | enet_list_clear (& fragments); 122 | 123 | for (fragmentNumber = 0, 124 | fragmentOffset = 0; 125 | fragmentOffset < packet -> dataLength; 126 | ++ fragmentNumber, 127 | fragmentOffset += fragmentLength) 128 | { 129 | if (packet -> dataLength - fragmentOffset < fragmentLength) 130 | fragmentLength = packet -> dataLength - fragmentOffset; 131 | 132 | fragment = (ENetOutgoingCommand *) enet_malloc (sizeof (ENetOutgoingCommand)); 133 | if (fragment == NULL) 134 | { 135 | while (! enet_list_empty (& fragments)) 136 | { 137 | fragment = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (& fragments)); 138 | 139 | enet_free (fragment); 140 | } 141 | 142 | return -1; 143 | } 144 | 145 | fragment -> fragmentOffset = fragmentOffset; 146 | fragment -> fragmentLength = fragmentLength; 147 | fragment -> packet = packet; 148 | fragment -> command.header.command = ENET_PROTOCOL_COMMAND_SEND_FRAGMENT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; 149 | fragment -> command.header.channelID = channelID; 150 | fragment -> command.sendFragment.startSequenceNumber = startSequenceNumber; 151 | fragment -> command.sendFragment.dataLength = ENET_HOST_TO_NET_16 (fragmentLength); 152 | fragment -> command.sendFragment.fragmentCount = fragmentCount; 153 | fragment -> command.sendFragment.fragmentNumber = ENET_HOST_TO_NET_32 (fragmentNumber); 154 | fragment -> command.sendFragment.totalLength = ENET_HOST_TO_NET_32 (packet -> dataLength); 155 | fragment -> command.sendFragment.fragmentOffset = ENET_NET_TO_HOST_32 (fragmentOffset); 156 | 157 | enet_list_insert (enet_list_end (& fragments), fragment); 158 | } 159 | 160 | packet -> referenceCount += fragmentNumber; 161 | 162 | while (! enet_list_empty (& fragments)) 163 | { 164 | fragment = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (& fragments)); 165 | 166 | enet_peer_setup_outgoing_command (peer, fragment); 167 | } 168 | 169 | return 0; 170 | } 171 | 172 | command.header.channelID = channelID; 173 | 174 | if (packet -> flags & ENET_PACKET_FLAG_RELIABLE) 175 | { 176 | command.header.command = ENET_PROTOCOL_COMMAND_SEND_RELIABLE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; 177 | command.sendReliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength); 178 | } 179 | else 180 | if (packet -> flags & ENET_PACKET_FLAG_UNSEQUENCED) 181 | { 182 | command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED | ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED; 183 | command.sendUnsequenced.unsequencedGroup = ENET_HOST_TO_NET_16 (peer -> outgoingUnsequencedGroup + 1); 184 | command.sendUnsequenced.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength); 185 | } 186 | else 187 | if (channel -> outgoingUnreliableSequenceNumber >= 0xFFFF) 188 | { 189 | command.header.command = ENET_PROTOCOL_COMMAND_SEND_RELIABLE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; 190 | command.sendReliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength); 191 | } 192 | else 193 | { 194 | command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE; 195 | command.sendUnreliable.unreliableSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingUnreliableSequenceNumber + 1); 196 | command.sendUnreliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength); 197 | } 198 | 199 | if (enet_peer_queue_outgoing_command (peer, & command, packet, 0, packet -> dataLength) == NULL) 200 | return -1; 201 | 202 | return 0; 203 | } 204 | 205 | /** Attempts to dequeue any incoming queued packet. 206 | @param peer peer to dequeue packets from 207 | @param channelID holds the channel ID of the channel the packet was received on success 208 | @returns a pointer to the packet, or NULL if there are no available incoming queued packets 209 | */ 210 | ENetPacket * 211 | enet_peer_receive (ENetPeer * peer, enet_uint8 * channelID) 212 | { 213 | ENetIncomingCommand * incomingCommand; 214 | ENetPacket * packet; 215 | 216 | if (enet_list_empty (& peer -> dispatchedCommands)) 217 | return NULL; 218 | 219 | incomingCommand = (ENetIncomingCommand *) enet_list_remove (enet_list_begin (& peer -> dispatchedCommands)); 220 | 221 | if (channelID != NULL) 222 | * channelID = incomingCommand -> command.header.channelID; 223 | 224 | packet = incomingCommand -> packet; 225 | 226 | -- packet -> referenceCount; 227 | 228 | if (incomingCommand -> fragments != NULL) 229 | enet_free (incomingCommand -> fragments); 230 | 231 | enet_free (incomingCommand); 232 | 233 | return packet; 234 | } 235 | 236 | static void 237 | enet_peer_reset_outgoing_commands (ENetList * queue) 238 | { 239 | ENetOutgoingCommand * outgoingCommand; 240 | 241 | while (! enet_list_empty (queue)) 242 | { 243 | outgoingCommand = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (queue)); 244 | 245 | if (outgoingCommand -> packet != NULL) 246 | { 247 | -- outgoingCommand -> packet -> referenceCount; 248 | 249 | if (outgoingCommand -> packet -> referenceCount == 0) 250 | enet_packet_destroy (outgoingCommand -> packet); 251 | } 252 | 253 | enet_free (outgoingCommand); 254 | } 255 | } 256 | 257 | static void 258 | enet_peer_reset_incoming_commands (ENetList * queue) 259 | { 260 | ENetIncomingCommand * incomingCommand; 261 | 262 | while (! enet_list_empty (queue)) 263 | { 264 | incomingCommand = (ENetIncomingCommand *) enet_list_remove (enet_list_begin (queue)); 265 | 266 | if (incomingCommand -> packet != NULL) 267 | { 268 | -- incomingCommand -> packet -> referenceCount; 269 | 270 | if (incomingCommand -> packet -> referenceCount == 0) 271 | enet_packet_destroy (incomingCommand -> packet); 272 | } 273 | 274 | if (incomingCommand -> fragments != NULL) 275 | enet_free (incomingCommand -> fragments); 276 | 277 | enet_free (incomingCommand); 278 | } 279 | } 280 | 281 | void 282 | enet_peer_reset_queues (ENetPeer * peer) 283 | { 284 | ENetChannel * channel; 285 | 286 | if (peer -> needsDispatch) 287 | { 288 | enet_list_remove (& peer -> dispatchList); 289 | 290 | peer -> needsDispatch = 0; 291 | } 292 | 293 | while (! enet_list_empty (& peer -> acknowledgements)) 294 | enet_free (enet_list_remove (enet_list_begin (& peer -> acknowledgements))); 295 | 296 | enet_peer_reset_outgoing_commands (& peer -> sentReliableCommands); 297 | enet_peer_reset_outgoing_commands (& peer -> sentUnreliableCommands); 298 | enet_peer_reset_outgoing_commands (& peer -> outgoingReliableCommands); 299 | enet_peer_reset_outgoing_commands (& peer -> outgoingUnreliableCommands); 300 | enet_peer_reset_incoming_commands (& peer -> dispatchedCommands); 301 | 302 | if (peer -> channels != NULL && peer -> channelCount > 0) 303 | { 304 | for (channel = peer -> channels; 305 | channel < & peer -> channels [peer -> channelCount]; 306 | ++ channel) 307 | { 308 | enet_peer_reset_incoming_commands (& channel -> incomingReliableCommands); 309 | enet_peer_reset_incoming_commands (& channel -> incomingUnreliableCommands); 310 | } 311 | 312 | enet_free (peer -> channels); 313 | } 314 | 315 | peer -> channels = NULL; 316 | peer -> channelCount = 0; 317 | } 318 | 319 | /** Forcefully disconnects a peer. 320 | @param peer peer to forcefully disconnect 321 | @remarks The foreign host represented by the peer is not notified of the disconnection and will timeout 322 | on its connection to the local host. 323 | */ 324 | void 325 | enet_peer_reset (ENetPeer * peer) 326 | { 327 | peer -> outgoingPeerID = ENET_PROTOCOL_MAXIMUM_PEER_ID; 328 | peer -> connectID = 0; 329 | 330 | peer -> state = ENET_PEER_STATE_DISCONNECTED; 331 | 332 | peer -> incomingBandwidth = 0; 333 | peer -> outgoingBandwidth = 0; 334 | peer -> incomingBandwidthThrottleEpoch = 0; 335 | peer -> outgoingBandwidthThrottleEpoch = 0; 336 | peer -> incomingDataTotal = 0; 337 | peer -> outgoingDataTotal = 0; 338 | peer -> lastSendTime = 0; 339 | peer -> lastReceiveTime = 0; 340 | peer -> nextTimeout = 0; 341 | peer -> earliestTimeout = 0; 342 | peer -> packetLossEpoch = 0; 343 | peer -> packetsSent = 0; 344 | peer -> packetsLost = 0; 345 | peer -> packetLoss = 0; 346 | peer -> packetLossVariance = 0; 347 | peer -> packetThrottle = ENET_PEER_DEFAULT_PACKET_THROTTLE; 348 | peer -> packetThrottleLimit = ENET_PEER_PACKET_THROTTLE_SCALE; 349 | peer -> packetThrottleCounter = 0; 350 | peer -> packetThrottleEpoch = 0; 351 | peer -> packetThrottleAcceleration = ENET_PEER_PACKET_THROTTLE_ACCELERATION; 352 | peer -> packetThrottleDeceleration = ENET_PEER_PACKET_THROTTLE_DECELERATION; 353 | peer -> packetThrottleInterval = ENET_PEER_PACKET_THROTTLE_INTERVAL; 354 | peer -> lastRoundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME; 355 | peer -> lowestRoundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME; 356 | peer -> lastRoundTripTimeVariance = 0; 357 | peer -> highestRoundTripTimeVariance = 0; 358 | peer -> roundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME; 359 | peer -> roundTripTimeVariance = 0; 360 | peer -> mtu = peer -> host -> mtu; 361 | peer -> reliableDataInTransit = 0; 362 | peer -> outgoingReliableSequenceNumber = 0; 363 | peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; 364 | peer -> incomingUnsequencedGroup = 0; 365 | peer -> outgoingUnsequencedGroup = 0; 366 | peer -> eventData = 0; 367 | 368 | memset (peer -> unsequencedWindow, 0, sizeof (peer -> unsequencedWindow)); 369 | 370 | enet_peer_reset_queues (peer); 371 | } 372 | 373 | /** Sends a ping request to a peer. 374 | @param peer destination for the ping request 375 | @remarks ping requests factor into the mean round trip time as designated by the 376 | roundTripTime field in the ENetPeer structure. Enet automatically pings all connected 377 | peers at regular intervals, however, this function may be called to ensure more 378 | frequent ping requests. 379 | */ 380 | void 381 | enet_peer_ping (ENetPeer * peer) 382 | { 383 | ENetProtocol command; 384 | 385 | if (peer -> state != ENET_PEER_STATE_CONNECTED) 386 | return; 387 | 388 | command.header.command = ENET_PROTOCOL_COMMAND_PING | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; 389 | command.header.channelID = 0xFF; 390 | 391 | enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0); 392 | } 393 | 394 | /** Force an immediate disconnection from a peer. 395 | @param peer peer to disconnect 396 | @param data data describing the disconnection 397 | @remarks No ENET_EVENT_DISCONNECT event will be generated. The foreign peer is not 398 | guarenteed to receive the disconnect notification, and is reset immediately upon 399 | return from this function. 400 | */ 401 | void 402 | enet_peer_disconnect_now (ENetPeer * peer, enet_uint32 data) 403 | { 404 | ENetProtocol command; 405 | 406 | if (peer -> state == ENET_PEER_STATE_DISCONNECTED) 407 | return; 408 | 409 | if (peer -> state != ENET_PEER_STATE_ZOMBIE && 410 | peer -> state != ENET_PEER_STATE_DISCONNECTING) 411 | { 412 | enet_peer_reset_queues (peer); 413 | 414 | command.header.command = ENET_PROTOCOL_COMMAND_DISCONNECT | ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED; 415 | command.header.channelID = 0xFF; 416 | command.disconnect.data = ENET_HOST_TO_NET_32 (data); 417 | 418 | enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0); 419 | 420 | enet_host_flush (peer -> host); 421 | } 422 | 423 | enet_peer_reset (peer); 424 | } 425 | 426 | /** Request a disconnection from a peer. 427 | @param peer peer to request a disconnection 428 | @param data data describing the disconnection 429 | @remarks An ENET_EVENT_DISCONNECT event will be generated by enet_host_service() 430 | once the disconnection is complete. 431 | */ 432 | void 433 | enet_peer_disconnect (ENetPeer * peer, enet_uint32 data) 434 | { 435 | ENetProtocol command; 436 | 437 | if (peer -> state == ENET_PEER_STATE_DISCONNECTING || 438 | peer -> state == ENET_PEER_STATE_DISCONNECTED || 439 | peer -> state == ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT || 440 | peer -> state == ENET_PEER_STATE_ZOMBIE) 441 | return; 442 | 443 | enet_peer_reset_queues (peer); 444 | 445 | command.header.command = ENET_PROTOCOL_COMMAND_DISCONNECT; 446 | command.header.channelID = 0xFF; 447 | command.disconnect.data = ENET_HOST_TO_NET_32 (data); 448 | 449 | if (peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER) 450 | command.header.command |= ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; 451 | else 452 | command.header.command |= ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED; 453 | 454 | enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0); 455 | 456 | if (peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER) 457 | peer -> state = ENET_PEER_STATE_DISCONNECTING; 458 | else 459 | { 460 | enet_host_flush (peer -> host); 461 | enet_peer_reset (peer); 462 | } 463 | } 464 | 465 | /** Request a disconnection from a peer, but only after all queued outgoing packets are sent. 466 | @param peer peer to request a disconnection 467 | @param data data describing the disconnection 468 | @remarks An ENET_EVENT_DISCONNECT event will be generated by enet_host_service() 469 | once the disconnection is complete. 470 | */ 471 | void 472 | enet_peer_disconnect_later (ENetPeer * peer, enet_uint32 data) 473 | { 474 | if ((peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER) && 475 | ! (enet_list_empty (& peer -> outgoingReliableCommands) && 476 | enet_list_empty (& peer -> outgoingUnreliableCommands) && 477 | enet_list_empty (& peer -> sentReliableCommands))) 478 | { 479 | peer -> state = ENET_PEER_STATE_DISCONNECT_LATER; 480 | peer -> eventData = data; 481 | } 482 | else 483 | enet_peer_disconnect (peer, data); 484 | } 485 | 486 | ENetAcknowledgement * 487 | enet_peer_queue_acknowledgement (ENetPeer * peer, const ENetProtocol * command, enet_uint16 sentTime) 488 | { 489 | ENetAcknowledgement * acknowledgement; 490 | 491 | if (command -> header.channelID < peer -> channelCount) 492 | { 493 | ENetChannel * channel = & peer -> channels [command -> header.channelID]; 494 | enet_uint16 reliableWindow = command -> header.reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE, 495 | currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; 496 | 497 | if (command -> header.reliableSequenceNumber < channel -> incomingReliableSequenceNumber) 498 | reliableWindow += ENET_PEER_RELIABLE_WINDOWS; 499 | 500 | if (reliableWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1 && reliableWindow <= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS) 501 | return NULL; 502 | } 503 | 504 | acknowledgement = (ENetAcknowledgement *) enet_malloc (sizeof (ENetAcknowledgement)); 505 | if (acknowledgement == NULL) 506 | return NULL; 507 | 508 | peer -> outgoingDataTotal += sizeof (ENetProtocolAcknowledge); 509 | 510 | acknowledgement -> sentTime = sentTime; 511 | acknowledgement -> command = * command; 512 | 513 | enet_list_insert (enet_list_end (& peer -> acknowledgements), acknowledgement); 514 | 515 | return acknowledgement; 516 | } 517 | 518 | void 519 | enet_peer_setup_outgoing_command (ENetPeer * peer, ENetOutgoingCommand * outgoingCommand) 520 | { 521 | ENetChannel * channel = & peer -> channels [outgoingCommand -> command.header.channelID]; 522 | 523 | peer -> outgoingDataTotal += enet_protocol_command_size (outgoingCommand -> command.header.command) + outgoingCommand -> fragmentLength; 524 | 525 | if (outgoingCommand -> command.header.channelID == 0xFF) 526 | { 527 | ++ peer -> outgoingReliableSequenceNumber; 528 | 529 | outgoingCommand -> reliableSequenceNumber = peer -> outgoingReliableSequenceNumber; 530 | outgoingCommand -> unreliableSequenceNumber = 0; 531 | } 532 | else 533 | if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) 534 | { 535 | ++ channel -> outgoingReliableSequenceNumber; 536 | channel -> outgoingUnreliableSequenceNumber = 0; 537 | 538 | outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber; 539 | outgoingCommand -> unreliableSequenceNumber = 0; 540 | } 541 | else 542 | if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED) 543 | { 544 | ++ peer -> outgoingUnsequencedGroup; 545 | 546 | outgoingCommand -> reliableSequenceNumber = 0; 547 | outgoingCommand -> unreliableSequenceNumber = 0; 548 | } 549 | else 550 | { 551 | ++ channel -> outgoingUnreliableSequenceNumber; 552 | 553 | outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber; 554 | outgoingCommand -> unreliableSequenceNumber = channel -> outgoingUnreliableSequenceNumber; 555 | } 556 | 557 | outgoingCommand -> sendAttempts = 0; 558 | outgoingCommand -> sentTime = 0; 559 | outgoingCommand -> roundTripTimeout = 0; 560 | outgoingCommand -> roundTripTimeoutLimit = 0; 561 | outgoingCommand -> command.header.reliableSequenceNumber = ENET_HOST_TO_NET_16 (outgoingCommand -> reliableSequenceNumber); 562 | 563 | if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) 564 | enet_list_insert (enet_list_end (& peer -> outgoingReliableCommands), outgoingCommand); 565 | else 566 | enet_list_insert (enet_list_end (& peer -> outgoingUnreliableCommands), outgoingCommand); 567 | } 568 | 569 | ENetOutgoingCommand * 570 | enet_peer_queue_outgoing_command (ENetPeer * peer, const ENetProtocol * command, ENetPacket * packet, enet_uint32 offset, enet_uint16 length) 571 | { 572 | ENetOutgoingCommand * outgoingCommand = (ENetOutgoingCommand *) enet_malloc (sizeof (ENetOutgoingCommand)); 573 | if (outgoingCommand == NULL) 574 | return NULL; 575 | 576 | outgoingCommand -> command = * command; 577 | outgoingCommand -> fragmentOffset = offset; 578 | outgoingCommand -> fragmentLength = length; 579 | outgoingCommand -> packet = packet; 580 | if (packet != NULL) 581 | ++ packet -> referenceCount; 582 | 583 | enet_peer_setup_outgoing_command (peer, outgoingCommand); 584 | 585 | return outgoingCommand; 586 | } 587 | 588 | void 589 | enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel * channel) 590 | { 591 | ENetListIterator currentCommand; 592 | 593 | for (currentCommand = enet_list_begin (& channel -> incomingUnreliableCommands); 594 | currentCommand != enet_list_end (& channel -> incomingUnreliableCommands); 595 | currentCommand = enet_list_next (currentCommand)) 596 | { 597 | ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand; 598 | 599 | if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE && 600 | incomingCommand -> reliableSequenceNumber != channel -> incomingReliableSequenceNumber) 601 | break; 602 | } 603 | 604 | if (currentCommand == enet_list_begin (& channel -> incomingUnreliableCommands)) 605 | return; 606 | 607 | enet_list_move (enet_list_end (& peer -> dispatchedCommands), enet_list_begin (& channel -> incomingUnreliableCommands), enet_list_previous (currentCommand)); 608 | 609 | if (! peer -> needsDispatch) 610 | { 611 | enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList); 612 | 613 | peer -> needsDispatch = 1; 614 | } 615 | } 616 | 617 | void 618 | enet_peer_dispatch_incoming_reliable_commands (ENetPeer * peer, ENetChannel * channel) 619 | { 620 | ENetListIterator currentCommand; 621 | 622 | for (currentCommand = enet_list_begin (& channel -> incomingReliableCommands); 623 | currentCommand != enet_list_end (& channel -> incomingReliableCommands); 624 | currentCommand = enet_list_next (currentCommand)) 625 | { 626 | ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand; 627 | 628 | if (incomingCommand -> fragmentsRemaining > 0 || 629 | incomingCommand -> reliableSequenceNumber != (enet_uint16) (channel -> incomingReliableSequenceNumber + 1)) 630 | break; 631 | 632 | channel -> incomingReliableSequenceNumber = incomingCommand -> reliableSequenceNumber; 633 | 634 | if (incomingCommand -> fragmentCount > 0) 635 | channel -> incomingReliableSequenceNumber += incomingCommand -> fragmentCount - 1; 636 | } 637 | 638 | if (currentCommand == enet_list_begin (& channel -> incomingReliableCommands)) 639 | return; 640 | 641 | enet_list_move (enet_list_end (& peer -> dispatchedCommands), enet_list_begin (& channel -> incomingReliableCommands), enet_list_previous (currentCommand)); 642 | 643 | if (! peer -> needsDispatch) 644 | { 645 | enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList); 646 | 647 | peer -> needsDispatch = 1; 648 | } 649 | 650 | enet_peer_dispatch_incoming_unreliable_commands (peer, channel); 651 | } 652 | 653 | ENetIncomingCommand * 654 | enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command, ENetPacket * packet, enet_uint32 fragmentCount) 655 | { 656 | static ENetIncomingCommand dummyCommand; 657 | 658 | ENetChannel * channel = & peer -> channels [command -> header.channelID]; 659 | enet_uint32 unreliableSequenceNumber = 0, reliableSequenceNumber; 660 | enet_uint16 reliableWindow, currentWindow; 661 | ENetIncomingCommand * incomingCommand; 662 | ENetListIterator currentCommand; 663 | 664 | if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER) 665 | goto freePacket; 666 | 667 | if ((command -> header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED) 668 | { 669 | reliableSequenceNumber = command -> header.reliableSequenceNumber; 670 | reliableWindow = reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; 671 | currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; 672 | 673 | if (reliableSequenceNumber < channel -> incomingReliableSequenceNumber) 674 | reliableWindow += ENET_PEER_RELIABLE_WINDOWS; 675 | 676 | if (reliableWindow < currentWindow || reliableWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1) 677 | goto freePacket; 678 | } 679 | 680 | switch (command -> header.command & ENET_PROTOCOL_COMMAND_MASK) 681 | { 682 | case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT: 683 | case ENET_PROTOCOL_COMMAND_SEND_RELIABLE: 684 | if (reliableSequenceNumber == channel -> incomingReliableSequenceNumber) 685 | goto freePacket; 686 | 687 | for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands)); 688 | currentCommand != enet_list_end (& channel -> incomingReliableCommands); 689 | currentCommand = enet_list_previous (currentCommand)) 690 | { 691 | incomingCommand = (ENetIncomingCommand *) currentCommand; 692 | 693 | if (reliableSequenceNumber >= channel -> incomingReliableSequenceNumber) 694 | { 695 | if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber) 696 | continue; 697 | } 698 | else 699 | if (incomingCommand -> reliableSequenceNumber >= channel -> incomingReliableSequenceNumber) 700 | break; 701 | 702 | if (incomingCommand -> reliableSequenceNumber <= reliableSequenceNumber) 703 | { 704 | if (incomingCommand -> reliableSequenceNumber < reliableSequenceNumber) 705 | break; 706 | 707 | goto freePacket; 708 | } 709 | } 710 | break; 711 | 712 | case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE: 713 | unreliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> sendUnreliable.unreliableSequenceNumber); 714 | 715 | for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingUnreliableCommands)); 716 | currentCommand != enet_list_end (& channel -> incomingUnreliableCommands); 717 | currentCommand = enet_list_previous (currentCommand)) 718 | { 719 | incomingCommand = (ENetIncomingCommand *) currentCommand; 720 | 721 | if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE) 722 | continue; 723 | 724 | if (reliableSequenceNumber >= channel -> incomingReliableSequenceNumber) 725 | { 726 | if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber) 727 | continue; 728 | } 729 | else 730 | if (incomingCommand -> reliableSequenceNumber >= channel -> incomingReliableSequenceNumber) 731 | break; 732 | 733 | if (incomingCommand -> reliableSequenceNumber < reliableSequenceNumber) 734 | break; 735 | 736 | if (incomingCommand -> reliableSequenceNumber > reliableSequenceNumber) 737 | continue; 738 | 739 | if (incomingCommand -> unreliableSequenceNumber <= unreliableSequenceNumber) 740 | { 741 | if (incomingCommand -> unreliableSequenceNumber < unreliableSequenceNumber) 742 | break; 743 | 744 | goto freePacket; 745 | } 746 | } 747 | break; 748 | 749 | case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED: 750 | currentCommand = enet_list_end (& channel -> incomingUnreliableCommands); 751 | break; 752 | 753 | default: 754 | goto freePacket; 755 | } 756 | 757 | incomingCommand = (ENetIncomingCommand *) enet_malloc (sizeof (ENetIncomingCommand)); 758 | if (incomingCommand == NULL) 759 | goto notifyError; 760 | 761 | incomingCommand -> reliableSequenceNumber = command -> header.reliableSequenceNumber; 762 | incomingCommand -> unreliableSequenceNumber = unreliableSequenceNumber & 0xFFFF; 763 | incomingCommand -> command = * command; 764 | incomingCommand -> fragmentCount = fragmentCount; 765 | incomingCommand -> fragmentsRemaining = fragmentCount; 766 | incomingCommand -> packet = packet; 767 | incomingCommand -> fragments = NULL; 768 | 769 | if (fragmentCount > 0) 770 | { 771 | incomingCommand -> fragments = (enet_uint32 *) enet_malloc ((fragmentCount + 31) / 32 * sizeof (enet_uint32)); 772 | if (incomingCommand -> fragments == NULL) 773 | { 774 | enet_free (incomingCommand); 775 | 776 | goto notifyError; 777 | } 778 | memset (incomingCommand -> fragments, 0, (fragmentCount + 31) / 32 * sizeof (enet_uint32)); 779 | } 780 | 781 | if (packet != NULL) 782 | ++ packet -> referenceCount; 783 | 784 | enet_list_insert (enet_list_next (currentCommand), incomingCommand); 785 | 786 | switch (command -> header.command & ENET_PROTOCOL_COMMAND_MASK) 787 | { 788 | case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT: 789 | case ENET_PROTOCOL_COMMAND_SEND_RELIABLE: 790 | enet_peer_dispatch_incoming_reliable_commands (peer, channel); 791 | break; 792 | 793 | default: 794 | enet_peer_dispatch_incoming_unreliable_commands (peer, channel); 795 | break; 796 | } 797 | 798 | return incomingCommand; 799 | 800 | freePacket: 801 | if (fragmentCount > 0) 802 | goto notifyError; 803 | 804 | if (packet != NULL && packet -> referenceCount == 0) 805 | enet_packet_destroy (packet); 806 | 807 | return & dummyCommand; 808 | 809 | notifyError: 810 | if (packet != NULL && packet -> referenceCount == 0) 811 | enet_packet_destroy (packet); 812 | 813 | return NULL; 814 | } 815 | 816 | /** @} */ 817 | -------------------------------------------------------------------------------- /jni/protocol.c: -------------------------------------------------------------------------------- 1 | /** 2 | @file protocol.c 3 | @brief ENet protocol functions 4 | */ 5 | #include 6 | #include 7 | #define ENET_BUILDING_LIB 1 8 | #include "enet/utility.h" 9 | #include "enet/time.h" 10 | #include "enet/enet.h" 11 | 12 | static size_t commandSizes [ENET_PROTOCOL_COMMAND_COUNT] = 13 | { 14 | 0, 15 | sizeof (ENetProtocolAcknowledge), 16 | sizeof (ENetProtocolConnect), 17 | sizeof (ENetProtocolVerifyConnect), 18 | sizeof (ENetProtocolDisconnect), 19 | sizeof (ENetProtocolPing), 20 | sizeof (ENetProtocolSendReliable), 21 | sizeof (ENetProtocolSendUnreliable), 22 | sizeof (ENetProtocolSendFragment), 23 | sizeof (ENetProtocolSendUnsequenced), 24 | sizeof (ENetProtocolBandwidthLimit), 25 | sizeof (ENetProtocolThrottleConfigure), 26 | }; 27 | 28 | size_t 29 | enet_protocol_command_size (enet_uint8 commandNumber) 30 | { 31 | return commandSizes [commandNumber & ENET_PROTOCOL_COMMAND_MASK]; 32 | } 33 | 34 | static int 35 | enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event) 36 | { 37 | while (! enet_list_empty (& host -> dispatchQueue)) 38 | { 39 | ENetPeer * peer = (ENetPeer *) enet_list_remove (enet_list_begin (& host -> dispatchQueue)); 40 | 41 | peer -> needsDispatch = 0; 42 | 43 | switch (peer -> state) 44 | { 45 | case ENET_PEER_STATE_CONNECTION_PENDING: 46 | case ENET_PEER_STATE_CONNECTION_SUCCEEDED: 47 | peer -> state = ENET_PEER_STATE_CONNECTED; 48 | 49 | event -> type = ENET_EVENT_TYPE_CONNECT; 50 | event -> peer = peer; 51 | event -> data = peer -> eventData; 52 | 53 | return 1; 54 | 55 | case ENET_PEER_STATE_ZOMBIE: 56 | host -> recalculateBandwidthLimits = 1; 57 | 58 | event -> type = ENET_EVENT_TYPE_DISCONNECT; 59 | event -> peer = peer; 60 | event -> data = peer -> eventData; 61 | 62 | enet_peer_reset (peer); 63 | 64 | return 1; 65 | 66 | case ENET_PEER_STATE_CONNECTED: 67 | if (enet_list_empty (& peer -> dispatchedCommands)) 68 | continue; 69 | 70 | event -> packet = enet_peer_receive (peer, & event -> channelID); 71 | if (event -> packet == NULL) 72 | continue; 73 | 74 | event -> type = ENET_EVENT_TYPE_RECEIVE; 75 | event -> peer = peer; 76 | 77 | if (! enet_list_empty (& peer -> dispatchedCommands)) 78 | { 79 | peer -> needsDispatch = 1; 80 | 81 | enet_list_insert (enet_list_end (& host -> dispatchQueue), & peer -> dispatchList); 82 | } 83 | 84 | return 1; 85 | } 86 | } 87 | 88 | return 0; 89 | } 90 | 91 | static void 92 | enet_protocol_dispatch_state (ENetHost * host, ENetPeer * peer, ENetPeerState state) 93 | { 94 | peer -> state = state; 95 | 96 | if (! peer -> needsDispatch) 97 | { 98 | enet_list_insert (enet_list_end (& host -> dispatchQueue), & peer -> dispatchList); 99 | 100 | peer -> needsDispatch = 1; 101 | } 102 | } 103 | 104 | static void 105 | enet_protocol_notify_connect (ENetHost * host, ENetPeer * peer, ENetEvent * event) 106 | { 107 | host -> recalculateBandwidthLimits = 1; 108 | 109 | if (event != NULL) 110 | { 111 | peer -> state = ENET_PEER_STATE_CONNECTED; 112 | 113 | event -> type = ENET_EVENT_TYPE_CONNECT; 114 | event -> peer = peer; 115 | event -> data = peer -> eventData; 116 | } 117 | else 118 | enet_protocol_dispatch_state (host, peer, peer -> state == ENET_PEER_STATE_CONNECTING ? ENET_PEER_STATE_CONNECTION_SUCCEEDED : ENET_PEER_STATE_CONNECTION_PENDING); 119 | } 120 | 121 | static void 122 | enet_protocol_notify_disconnect (ENetHost * host, ENetPeer * peer, ENetEvent * event) 123 | { 124 | if (peer -> state >= ENET_PEER_STATE_CONNECTION_PENDING) 125 | host -> recalculateBandwidthLimits = 1; 126 | 127 | if (peer -> state != ENET_PEER_STATE_CONNECTING && peer -> state < ENET_PEER_STATE_CONNECTION_SUCCEEDED) 128 | enet_peer_reset (peer); 129 | else 130 | if (event != NULL) 131 | { 132 | event -> type = ENET_EVENT_TYPE_DISCONNECT; 133 | event -> peer = peer; 134 | event -> data = 0; 135 | 136 | enet_peer_reset (peer); 137 | } 138 | else 139 | { 140 | peer -> eventData = 0; 141 | 142 | enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE); 143 | } 144 | } 145 | 146 | static void 147 | enet_protocol_remove_sent_unreliable_commands (ENetPeer * peer) 148 | { 149 | ENetOutgoingCommand * outgoingCommand; 150 | 151 | while (! enet_list_empty (& peer -> sentUnreliableCommands)) 152 | { 153 | outgoingCommand = (ENetOutgoingCommand *) enet_list_front (& peer -> sentUnreliableCommands); 154 | 155 | enet_list_remove (& outgoingCommand -> outgoingCommandList); 156 | 157 | if (outgoingCommand -> packet != NULL) 158 | { 159 | -- outgoingCommand -> packet -> referenceCount; 160 | 161 | if (outgoingCommand -> packet -> referenceCount == 0) 162 | enet_packet_destroy (outgoingCommand -> packet); 163 | } 164 | 165 | enet_free (outgoingCommand); 166 | } 167 | } 168 | 169 | static ENetProtocolCommand 170 | enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint16 reliableSequenceNumber, enet_uint8 channelID) 171 | { 172 | ENetOutgoingCommand * outgoingCommand; 173 | ENetListIterator currentCommand; 174 | ENetProtocolCommand commandNumber; 175 | 176 | for (currentCommand = enet_list_begin (& peer -> sentReliableCommands); 177 | currentCommand != enet_list_end (& peer -> sentReliableCommands); 178 | currentCommand = enet_list_next (currentCommand)) 179 | { 180 | outgoingCommand = (ENetOutgoingCommand *) currentCommand; 181 | 182 | if (outgoingCommand -> reliableSequenceNumber == reliableSequenceNumber && 183 | outgoingCommand -> command.header.channelID == channelID) 184 | break; 185 | } 186 | 187 | if (currentCommand == enet_list_end (& peer -> sentReliableCommands)) 188 | { 189 | for (currentCommand = enet_list_begin (& peer -> outgoingReliableCommands); 190 | currentCommand != enet_list_end (& peer -> outgoingReliableCommands); 191 | currentCommand = enet_list_next (currentCommand)) 192 | { 193 | outgoingCommand = (ENetOutgoingCommand *) currentCommand; 194 | 195 | if (outgoingCommand -> sendAttempts < 1) return ENET_PROTOCOL_COMMAND_NONE; 196 | 197 | if (outgoingCommand -> reliableSequenceNumber == reliableSequenceNumber && 198 | outgoingCommand -> command.header.channelID == channelID) 199 | break; 200 | } 201 | 202 | if (currentCommand == enet_list_end (& peer -> outgoingReliableCommands)) 203 | return ENET_PROTOCOL_COMMAND_NONE; 204 | } 205 | 206 | if (channelID < peer -> channelCount) 207 | { 208 | ENetChannel * channel = & peer -> channels [channelID]; 209 | enet_uint16 reliableWindow = reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; 210 | if (channel -> reliableWindows [reliableWindow] > 0) 211 | { 212 | -- channel -> reliableWindows [reliableWindow]; 213 | if (! channel -> reliableWindows [reliableWindow]) 214 | channel -> usedReliableWindows &= ~ (1 << reliableWindow); 215 | } 216 | } 217 | 218 | commandNumber = (ENetProtocolCommand) (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK); 219 | 220 | enet_list_remove (& outgoingCommand -> outgoingCommandList); 221 | 222 | if (outgoingCommand -> packet != NULL) 223 | { 224 | peer -> reliableDataInTransit -= outgoingCommand -> fragmentLength; 225 | 226 | -- outgoingCommand -> packet -> referenceCount; 227 | 228 | if (outgoingCommand -> packet -> referenceCount == 0) 229 | enet_packet_destroy (outgoingCommand -> packet); 230 | } 231 | 232 | enet_free (outgoingCommand); 233 | 234 | if (enet_list_empty (& peer -> sentReliableCommands)) 235 | return commandNumber; 236 | 237 | outgoingCommand = (ENetOutgoingCommand *) enet_list_front (& peer -> sentReliableCommands); 238 | 239 | peer -> nextTimeout = outgoingCommand -> sentTime + outgoingCommand -> roundTripTimeout; 240 | 241 | return commandNumber; 242 | } 243 | 244 | static ENetPeer * 245 | enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENetProtocol * command) 246 | { 247 | enet_uint8 incomingSessionID, outgoingSessionID; 248 | enet_uint32 mtu, windowSize; 249 | ENetChannel * channel; 250 | size_t channelCount; 251 | ENetPeer * currentPeer; 252 | ENetProtocol verifyCommand; 253 | 254 | channelCount = ENET_NET_TO_HOST_32 (command -> connect.channelCount); 255 | 256 | if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT || 257 | channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT) 258 | return NULL; 259 | 260 | for (currentPeer = host -> peers; 261 | currentPeer < & host -> peers [host -> peerCount]; 262 | ++ currentPeer) 263 | { 264 | if (currentPeer -> state != ENET_PEER_STATE_DISCONNECTED && 265 | currentPeer -> address.host == host -> receivedAddress.host && 266 | currentPeer -> address.port == host -> receivedAddress.port && 267 | currentPeer -> connectID == command -> connect.connectID) 268 | return NULL; 269 | } 270 | 271 | for (currentPeer = host -> peers; 272 | currentPeer < & host -> peers [host -> peerCount]; 273 | ++ currentPeer) 274 | { 275 | if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED) 276 | break; 277 | } 278 | 279 | if (currentPeer >= & host -> peers [host -> peerCount]) 280 | return NULL; 281 | 282 | if (channelCount > host -> channelLimit) 283 | channelCount = host -> channelLimit; 284 | currentPeer -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel)); 285 | if (currentPeer -> channels == NULL) 286 | return NULL; 287 | currentPeer -> channelCount = channelCount; 288 | currentPeer -> state = ENET_PEER_STATE_ACKNOWLEDGING_CONNECT; 289 | currentPeer -> connectID = command -> connect.connectID; 290 | currentPeer -> address = host -> receivedAddress; 291 | currentPeer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> connect.outgoingPeerID); 292 | currentPeer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.incomingBandwidth); 293 | currentPeer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.outgoingBandwidth); 294 | currentPeer -> packetThrottleInterval = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleInterval); 295 | currentPeer -> packetThrottleAcceleration = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleAcceleration); 296 | currentPeer -> packetThrottleDeceleration = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleDeceleration); 297 | currentPeer -> eventData = ENET_NET_TO_HOST_32 (command -> connect.data); 298 | 299 | incomingSessionID = command -> connect.incomingSessionID == 0xFF ? currentPeer -> outgoingSessionID : command -> connect.incomingSessionID; 300 | incomingSessionID = (incomingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT); 301 | if (incomingSessionID == currentPeer -> outgoingSessionID) 302 | incomingSessionID = (incomingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT); 303 | currentPeer -> outgoingSessionID = incomingSessionID; 304 | 305 | outgoingSessionID = command -> connect.outgoingSessionID == 0xFF ? currentPeer -> incomingSessionID : command -> connect.outgoingSessionID; 306 | outgoingSessionID = (outgoingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT); 307 | if (outgoingSessionID == currentPeer -> incomingSessionID) 308 | outgoingSessionID = (outgoingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT); 309 | currentPeer -> incomingSessionID = outgoingSessionID; 310 | 311 | for (channel = currentPeer -> channels; 312 | channel < & currentPeer -> channels [channelCount]; 313 | ++ channel) 314 | { 315 | channel -> outgoingReliableSequenceNumber = 0; 316 | channel -> outgoingUnreliableSequenceNumber = 0; 317 | channel -> incomingReliableSequenceNumber = 0; 318 | 319 | enet_list_clear (& channel -> incomingReliableCommands); 320 | enet_list_clear (& channel -> incomingUnreliableCommands); 321 | 322 | channel -> usedReliableWindows = 0; 323 | memset (channel -> reliableWindows, 0, sizeof (channel -> reliableWindows)); 324 | } 325 | 326 | mtu = ENET_NET_TO_HOST_32 (command -> connect.mtu); 327 | 328 | if (mtu < ENET_PROTOCOL_MINIMUM_MTU) 329 | mtu = ENET_PROTOCOL_MINIMUM_MTU; 330 | else 331 | if (mtu > ENET_PROTOCOL_MAXIMUM_MTU) 332 | mtu = ENET_PROTOCOL_MAXIMUM_MTU; 333 | 334 | currentPeer -> mtu = mtu; 335 | 336 | if (host -> outgoingBandwidth == 0 && 337 | currentPeer -> incomingBandwidth == 0) 338 | currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; 339 | else 340 | if (host -> outgoingBandwidth == 0 || 341 | currentPeer -> incomingBandwidth == 0) 342 | currentPeer -> windowSize = (ENET_MAX (host -> outgoingBandwidth, currentPeer -> incomingBandwidth) / 343 | ENET_PEER_WINDOW_SIZE_SCALE) * 344 | ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; 345 | else 346 | currentPeer -> windowSize = (ENET_MIN (host -> outgoingBandwidth, currentPeer -> incomingBandwidth) / 347 | ENET_PEER_WINDOW_SIZE_SCALE) * 348 | ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; 349 | 350 | if (currentPeer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) 351 | currentPeer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; 352 | else 353 | if (currentPeer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) 354 | currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; 355 | 356 | if (host -> incomingBandwidth == 0) 357 | windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; 358 | else 359 | windowSize = (host -> incomingBandwidth / ENET_PEER_WINDOW_SIZE_SCALE) * 360 | ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; 361 | 362 | if (windowSize > ENET_NET_TO_HOST_32 (command -> connect.windowSize)) 363 | windowSize = ENET_NET_TO_HOST_32 (command -> connect.windowSize); 364 | 365 | if (windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) 366 | windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; 367 | else 368 | if (windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) 369 | windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; 370 | 371 | verifyCommand.header.command = ENET_PROTOCOL_COMMAND_VERIFY_CONNECT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; 372 | verifyCommand.header.channelID = 0xFF; 373 | verifyCommand.verifyConnect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID); 374 | verifyCommand.verifyConnect.incomingSessionID = incomingSessionID; 375 | verifyCommand.verifyConnect.outgoingSessionID = outgoingSessionID; 376 | verifyCommand.verifyConnect.mtu = ENET_HOST_TO_NET_16 (currentPeer -> mtu); 377 | verifyCommand.verifyConnect.windowSize = ENET_HOST_TO_NET_32 (windowSize); 378 | verifyCommand.verifyConnect.channelCount = ENET_HOST_TO_NET_32 (channelCount); 379 | verifyCommand.verifyConnect.incomingBandwidth = ENET_HOST_TO_NET_32 (host -> incomingBandwidth); 380 | verifyCommand.verifyConnect.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth); 381 | verifyCommand.verifyConnect.packetThrottleInterval = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleInterval); 382 | verifyCommand.verifyConnect.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleAcceleration); 383 | verifyCommand.verifyConnect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleDeceleration); 384 | verifyCommand.verifyConnect.connectID = currentPeer -> connectID; 385 | 386 | enet_peer_queue_outgoing_command (currentPeer, & verifyCommand, NULL, 0, 0); 387 | 388 | return currentPeer; 389 | } 390 | 391 | static int 392 | enet_protocol_handle_send_reliable (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData) 393 | { 394 | ENetPacket * packet; 395 | size_t dataLength; 396 | 397 | if (command -> header.channelID >= peer -> channelCount || 398 | (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)) 399 | return -1; 400 | 401 | dataLength = ENET_NET_TO_HOST_16 (command -> sendReliable.dataLength); 402 | * currentData += dataLength; 403 | if (* currentData > & host -> receivedData [host -> receivedDataLength]) 404 | return -1; 405 | 406 | packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendReliable), 407 | dataLength, 408 | ENET_PACKET_FLAG_RELIABLE); 409 | if (packet == NULL || 410 | enet_peer_queue_incoming_command (peer, command, packet, 0) == NULL) 411 | return -1; 412 | 413 | return 0; 414 | } 415 | 416 | static int 417 | enet_protocol_handle_send_unsequenced (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData) 418 | { 419 | ENetPacket * packet; 420 | enet_uint32 unsequencedGroup, index; 421 | size_t dataLength; 422 | 423 | if (command -> header.channelID >= peer -> channelCount || 424 | (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)) 425 | return -1; 426 | 427 | dataLength = ENET_NET_TO_HOST_16 (command -> sendUnsequenced.dataLength); 428 | * currentData += dataLength; 429 | if (* currentData > & host -> receivedData [host -> receivedDataLength]) 430 | return -1; 431 | 432 | unsequencedGroup = ENET_NET_TO_HOST_16 (command -> sendUnsequenced.unsequencedGroup); 433 | index = unsequencedGroup % ENET_PEER_UNSEQUENCED_WINDOW_SIZE; 434 | 435 | if (unsequencedGroup < peer -> incomingUnsequencedGroup) 436 | unsequencedGroup += 0x10000; 437 | 438 | if (unsequencedGroup >= (enet_uint32) peer -> incomingUnsequencedGroup + ENET_PEER_FREE_UNSEQUENCED_WINDOWS * ENET_PEER_UNSEQUENCED_WINDOW_SIZE) 439 | return 0; 440 | 441 | unsequencedGroup &= 0xFFFF; 442 | 443 | if (unsequencedGroup - index != peer -> incomingUnsequencedGroup) 444 | { 445 | peer -> incomingUnsequencedGroup = unsequencedGroup - index; 446 | 447 | memset (peer -> unsequencedWindow, 0, sizeof (peer -> unsequencedWindow)); 448 | } 449 | else 450 | if (peer -> unsequencedWindow [index / 32] & (1 << (index % 32))) 451 | return 0; 452 | 453 | packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendUnsequenced), 454 | dataLength, 455 | ENET_PACKET_FLAG_UNSEQUENCED); 456 | if (packet == NULL || 457 | enet_peer_queue_incoming_command (peer, command, packet, 0) == NULL) 458 | return -1; 459 | 460 | peer -> unsequencedWindow [index / 32] |= 1 << (index % 32); 461 | 462 | return 0; 463 | } 464 | 465 | static int 466 | enet_protocol_handle_send_unreliable (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData) 467 | { 468 | ENetPacket * packet; 469 | size_t dataLength; 470 | 471 | if (command -> header.channelID >= peer -> channelCount || 472 | (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)) 473 | return -1; 474 | 475 | dataLength = ENET_NET_TO_HOST_16 (command -> sendUnreliable.dataLength); 476 | * currentData += dataLength; 477 | if (* currentData > & host -> receivedData [host -> receivedDataLength]) 478 | return -1; 479 | 480 | packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendUnreliable), 481 | dataLength, 482 | 0); 483 | if (packet == NULL || 484 | enet_peer_queue_incoming_command (peer, command, packet, 0) == NULL) 485 | return -1; 486 | 487 | return 0; 488 | } 489 | 490 | static int 491 | enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData) 492 | { 493 | enet_uint32 fragmentNumber, 494 | fragmentCount, 495 | fragmentOffset, 496 | fragmentLength, 497 | startSequenceNumber, 498 | totalLength; 499 | ENetChannel * channel; 500 | enet_uint16 startWindow, currentWindow; 501 | ENetListIterator currentCommand; 502 | ENetIncomingCommand * startCommand = NULL; 503 | 504 | if (command -> header.channelID >= peer -> channelCount || 505 | (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)) 506 | return -1; 507 | 508 | fragmentLength = ENET_NET_TO_HOST_16 (command -> sendFragment.dataLength); 509 | * currentData += fragmentLength; 510 | if (* currentData > & host -> receivedData [host -> receivedDataLength]) 511 | return -1; 512 | 513 | channel = & peer -> channels [command -> header.channelID]; 514 | startSequenceNumber = ENET_NET_TO_HOST_16 (command -> sendFragment.startSequenceNumber); 515 | startWindow = startSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; 516 | currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; 517 | 518 | if (startSequenceNumber < channel -> incomingReliableSequenceNumber) 519 | startWindow += ENET_PEER_RELIABLE_WINDOWS; 520 | 521 | if (startWindow < currentWindow || startWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1) 522 | return 0; 523 | 524 | fragmentNumber = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentNumber); 525 | fragmentCount = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentCount); 526 | fragmentOffset = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentOffset); 527 | totalLength = ENET_NET_TO_HOST_32 (command -> sendFragment.totalLength); 528 | 529 | if (fragmentOffset >= totalLength || 530 | fragmentOffset + fragmentLength > totalLength || 531 | fragmentNumber >= fragmentCount) 532 | return -1; 533 | 534 | for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands)); 535 | currentCommand != enet_list_end (& channel -> incomingReliableCommands); 536 | currentCommand = enet_list_previous (currentCommand)) 537 | { 538 | ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand; 539 | 540 | if (startSequenceNumber >= channel -> incomingReliableSequenceNumber) 541 | { 542 | if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber) 543 | continue; 544 | } 545 | else 546 | if (incomingCommand -> reliableSequenceNumber >= channel -> incomingReliableSequenceNumber) 547 | break; 548 | 549 | if (incomingCommand -> reliableSequenceNumber <= startSequenceNumber) 550 | { 551 | if (incomingCommand -> reliableSequenceNumber < startSequenceNumber) 552 | break; 553 | 554 | if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_FRAGMENT || 555 | totalLength != incomingCommand -> packet -> dataLength || 556 | fragmentCount != incomingCommand -> fragmentCount) 557 | return -1; 558 | 559 | startCommand = incomingCommand; 560 | break; 561 | } 562 | } 563 | 564 | if (startCommand == NULL) 565 | { 566 | ENetProtocol hostCommand = * command; 567 | ENetPacket * packet = enet_packet_create (NULL, totalLength, ENET_PACKET_FLAG_RELIABLE); 568 | if (packet == NULL) 569 | return -1; 570 | 571 | hostCommand.header.reliableSequenceNumber = startSequenceNumber; 572 | hostCommand.sendFragment.startSequenceNumber = startSequenceNumber; 573 | hostCommand.sendFragment.dataLength = fragmentLength; 574 | hostCommand.sendFragment.fragmentNumber = fragmentNumber; 575 | hostCommand.sendFragment.fragmentCount = fragmentCount; 576 | hostCommand.sendFragment.fragmentOffset = fragmentOffset; 577 | hostCommand.sendFragment.totalLength = totalLength; 578 | 579 | startCommand = enet_peer_queue_incoming_command (peer, & hostCommand, packet, fragmentCount); 580 | if (startCommand == NULL) 581 | return -1; 582 | } 583 | 584 | if ((startCommand -> fragments [fragmentNumber / 32] & (1 << (fragmentNumber % 32))) == 0) 585 | { 586 | -- startCommand -> fragmentsRemaining; 587 | 588 | startCommand -> fragments [fragmentNumber / 32] |= (1 << (fragmentNumber % 32)); 589 | 590 | if (fragmentOffset + fragmentLength > startCommand -> packet -> dataLength) 591 | fragmentLength = startCommand -> packet -> dataLength - fragmentOffset; 592 | 593 | memcpy (startCommand -> packet -> data + fragmentOffset, 594 | (enet_uint8 *) command + sizeof (ENetProtocolSendFragment), 595 | fragmentLength); 596 | 597 | if (startCommand -> fragmentsRemaining <= 0) 598 | enet_peer_dispatch_incoming_reliable_commands (peer, channel); 599 | } 600 | 601 | return 0; 602 | } 603 | 604 | static int 605 | enet_protocol_handle_ping (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) 606 | { 607 | return 0; 608 | } 609 | 610 | static int 611 | enet_protocol_handle_bandwidth_limit (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) 612 | { 613 | peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> bandwidthLimit.incomingBandwidth); 614 | peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> bandwidthLimit.outgoingBandwidth); 615 | 616 | if (peer -> incomingBandwidth == 0 && host -> outgoingBandwidth == 0) 617 | peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; 618 | else 619 | peer -> windowSize = (ENET_MIN (peer -> incomingBandwidth, host -> outgoingBandwidth) / 620 | ENET_PEER_WINDOW_SIZE_SCALE) * ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; 621 | 622 | if (peer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) 623 | peer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; 624 | else 625 | if (peer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) 626 | peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; 627 | 628 | return 0; 629 | } 630 | 631 | static int 632 | enet_protocol_handle_throttle_configure (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) 633 | { 634 | peer -> packetThrottleInterval = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleInterval); 635 | peer -> packetThrottleAcceleration = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleAcceleration); 636 | peer -> packetThrottleDeceleration = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleDeceleration); 637 | 638 | return 0; 639 | } 640 | 641 | static int 642 | enet_protocol_handle_disconnect (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) 643 | { 644 | if (peer -> state == ENET_PEER_STATE_ZOMBIE || peer -> state == ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT) 645 | return 0; 646 | 647 | enet_peer_reset_queues (peer); 648 | 649 | if (peer -> state == ENET_PEER_STATE_CONNECTION_SUCCEEDED) 650 | enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE); 651 | else 652 | if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) 653 | { 654 | if (peer -> state == ENET_PEER_STATE_CONNECTION_PENDING) host -> recalculateBandwidthLimits = 1; 655 | 656 | enet_peer_reset (peer); 657 | } 658 | else 659 | if (command -> header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) 660 | peer -> state = ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT; 661 | else 662 | enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE); 663 | 664 | if (peer -> state != ENET_PEER_STATE_DISCONNECTED) 665 | peer -> eventData = ENET_NET_TO_HOST_32 (command -> disconnect.data); 666 | 667 | return 0; 668 | } 669 | 670 | static int 671 | enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer * peer, const ENetProtocol * command) 672 | { 673 | enet_uint32 roundTripTime, 674 | receivedSentTime, 675 | receivedReliableSequenceNumber; 676 | ENetProtocolCommand commandNumber; 677 | 678 | receivedSentTime = ENET_NET_TO_HOST_16 (command -> acknowledge.receivedSentTime); 679 | receivedSentTime |= host -> serviceTime & 0xFFFF0000; 680 | if ((receivedSentTime & 0x8000) > (host -> serviceTime & 0x8000)) 681 | receivedSentTime -= 0x10000; 682 | 683 | if (ENET_TIME_LESS (host -> serviceTime, receivedSentTime)) 684 | return 0; 685 | 686 | peer -> lastReceiveTime = host -> serviceTime; 687 | peer -> earliestTimeout = 0; 688 | 689 | roundTripTime = ENET_TIME_DIFFERENCE (host -> serviceTime, receivedSentTime); 690 | 691 | enet_peer_throttle (peer, roundTripTime); 692 | 693 | peer -> roundTripTimeVariance -= peer -> roundTripTimeVariance / 4; 694 | 695 | if (roundTripTime >= peer -> roundTripTime) 696 | { 697 | peer -> roundTripTime += (roundTripTime - peer -> roundTripTime) / 8; 698 | peer -> roundTripTimeVariance += (roundTripTime - peer -> roundTripTime) / 4; 699 | } 700 | else 701 | { 702 | peer -> roundTripTime -= (peer -> roundTripTime - roundTripTime) / 8; 703 | peer -> roundTripTimeVariance += (peer -> roundTripTime - roundTripTime) / 4; 704 | } 705 | 706 | if (peer -> roundTripTime < peer -> lowestRoundTripTime) 707 | peer -> lowestRoundTripTime = peer -> roundTripTime; 708 | 709 | if (peer -> roundTripTimeVariance > peer -> highestRoundTripTimeVariance) 710 | peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance; 711 | 712 | if (peer -> packetThrottleEpoch == 0 || 713 | ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> packetThrottleEpoch) >= peer -> packetThrottleInterval) 714 | { 715 | peer -> lastRoundTripTime = peer -> lowestRoundTripTime; 716 | peer -> lastRoundTripTimeVariance = peer -> highestRoundTripTimeVariance; 717 | peer -> lowestRoundTripTime = peer -> roundTripTime; 718 | peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance; 719 | peer -> packetThrottleEpoch = host -> serviceTime; 720 | } 721 | 722 | receivedReliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> acknowledge.receivedReliableSequenceNumber); 723 | 724 | commandNumber = enet_protocol_remove_sent_reliable_command (peer, receivedReliableSequenceNumber, command -> header.channelID); 725 | 726 | switch (peer -> state) 727 | { 728 | case ENET_PEER_STATE_ACKNOWLEDGING_CONNECT: 729 | if (commandNumber != ENET_PROTOCOL_COMMAND_VERIFY_CONNECT) 730 | return -1; 731 | 732 | enet_protocol_notify_connect (host, peer, event); 733 | break; 734 | 735 | case ENET_PEER_STATE_DISCONNECTING: 736 | if (commandNumber != ENET_PROTOCOL_COMMAND_DISCONNECT) 737 | return -1; 738 | 739 | enet_protocol_notify_disconnect (host, peer, event); 740 | break; 741 | 742 | case ENET_PEER_STATE_DISCONNECT_LATER: 743 | if (enet_list_empty (& peer -> outgoingReliableCommands) && 744 | enet_list_empty (& peer -> outgoingUnreliableCommands) && 745 | enet_list_empty (& peer -> sentReliableCommands)) 746 | enet_peer_disconnect (peer, peer -> eventData); 747 | break; 748 | } 749 | 750 | return 0; 751 | } 752 | 753 | static int 754 | enet_protocol_handle_verify_connect (ENetHost * host, ENetEvent * event, ENetPeer * peer, const ENetProtocol * command) 755 | { 756 | enet_uint32 mtu, windowSize; 757 | size_t channelCount; 758 | 759 | if (peer -> state != ENET_PEER_STATE_CONNECTING) 760 | return 0; 761 | 762 | channelCount = ENET_NET_TO_HOST_32 (command -> verifyConnect.channelCount); 763 | 764 | if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT || channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT || 765 | ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleInterval) != peer -> packetThrottleInterval || 766 | ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleAcceleration) != peer -> packetThrottleAcceleration || 767 | ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleDeceleration) != peer -> packetThrottleDeceleration || 768 | command -> verifyConnect.connectID != peer -> connectID) 769 | { 770 | peer -> eventData = 0; 771 | 772 | enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE); 773 | 774 | return -1; 775 | } 776 | 777 | enet_protocol_remove_sent_reliable_command (peer, 1, 0xFF); 778 | 779 | if (channelCount < peer -> channelCount) 780 | peer -> channelCount = channelCount; 781 | 782 | peer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> verifyConnect.outgoingPeerID); 783 | peer -> incomingSessionID = command -> verifyConnect.incomingSessionID; 784 | peer -> outgoingSessionID = command -> verifyConnect.outgoingSessionID; 785 | 786 | mtu = ENET_NET_TO_HOST_32 (command -> verifyConnect.mtu); 787 | 788 | if (mtu < ENET_PROTOCOL_MINIMUM_MTU) 789 | mtu = ENET_PROTOCOL_MINIMUM_MTU; 790 | else 791 | if (mtu > ENET_PROTOCOL_MAXIMUM_MTU) 792 | mtu = ENET_PROTOCOL_MAXIMUM_MTU; 793 | 794 | if (mtu < peer -> mtu) 795 | peer -> mtu = mtu; 796 | 797 | windowSize = ENET_NET_TO_HOST_32 (command -> verifyConnect.windowSize); 798 | 799 | if (windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) 800 | windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; 801 | 802 | if (windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) 803 | windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; 804 | 805 | if (windowSize < peer -> windowSize) 806 | peer -> windowSize = windowSize; 807 | 808 | peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> verifyConnect.incomingBandwidth); 809 | peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> verifyConnect.outgoingBandwidth); 810 | 811 | enet_protocol_notify_connect (host, peer, event); 812 | return 0; 813 | } 814 | 815 | static int 816 | enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event) 817 | { 818 | ENetProtocolHeader * header; 819 | ENetProtocol * command; 820 | ENetPeer * peer; 821 | enet_uint8 * currentData; 822 | size_t headerSize; 823 | enet_uint16 peerID, flags; 824 | enet_uint8 sessionID; 825 | 826 | if (host -> receivedDataLength < (size_t) & ((ENetProtocolHeader *) 0) -> sentTime) 827 | return 0; 828 | 829 | header = (ENetProtocolHeader *) host -> receivedData; 830 | 831 | peerID = ENET_NET_TO_HOST_16 (header -> peerID); 832 | sessionID = (peerID & ENET_PROTOCOL_HEADER_SESSION_MASK) >> ENET_PROTOCOL_HEADER_SESSION_SHIFT; 833 | flags = peerID & ENET_PROTOCOL_HEADER_FLAG_MASK; 834 | peerID &= ~ (ENET_PROTOCOL_HEADER_FLAG_MASK | ENET_PROTOCOL_HEADER_SESSION_MASK); 835 | 836 | headerSize = (flags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME ? sizeof (ENetProtocolHeader) : (size_t) & ((ENetProtocolHeader *) 0) -> sentTime); 837 | if (host -> checksum != NULL) 838 | headerSize += sizeof (enet_uint32); 839 | 840 | if (peerID == ENET_PROTOCOL_MAXIMUM_PEER_ID) 841 | peer = NULL; 842 | else 843 | if (peerID >= host -> peerCount) 844 | return 0; 845 | else 846 | { 847 | peer = & host -> peers [peerID]; 848 | 849 | if (peer -> state == ENET_PEER_STATE_DISCONNECTED || 850 | peer -> state == ENET_PEER_STATE_ZOMBIE || 851 | (host -> receivedAddress.host != peer -> address.host && 852 | peer -> address.host != ENET_HOST_BROADCAST) || 853 | (peer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID && 854 | sessionID != peer -> incomingSessionID)) 855 | return 0; 856 | } 857 | 858 | if (flags & ENET_PROTOCOL_HEADER_FLAG_COMPRESSED) 859 | { 860 | size_t originalSize; 861 | if (host -> compressor.context == NULL || host -> compressor.decompress == NULL) 862 | return 0; 863 | 864 | originalSize = host -> compressor.decompress (host -> compressor.context, 865 | host -> receivedData + headerSize, 866 | host -> receivedDataLength - headerSize, 867 | host -> packetData [1] + headerSize, 868 | sizeof (host -> packetData [1]) - headerSize); 869 | if (originalSize <= 0 || originalSize > sizeof (host -> packetData [1]) - headerSize) 870 | return 0; 871 | 872 | memcpy (host -> packetData [1], header, headerSize); 873 | host -> receivedData = host -> packetData [1]; 874 | host -> receivedDataLength = headerSize + originalSize; 875 | } 876 | 877 | if (host -> checksum != NULL) 878 | { 879 | enet_uint32 * checksum = (enet_uint32 *) & host -> receivedData [headerSize - sizeof (enet_uint32)], 880 | desiredChecksum = * checksum; 881 | ENetBuffer buffer; 882 | 883 | * checksum = peer != NULL ? peer -> connectID : 0; 884 | 885 | buffer.data = host -> receivedData; 886 | buffer.dataLength = host -> receivedDataLength; 887 | 888 | if (host -> checksum (& buffer, 1) != desiredChecksum) 889 | return 0; 890 | } 891 | 892 | if (peer != NULL) 893 | { 894 | peer -> address.host = host -> receivedAddress.host; 895 | peer -> address.port = host -> receivedAddress.port; 896 | peer -> incomingDataTotal += host -> receivedDataLength; 897 | } 898 | 899 | currentData = host -> receivedData + headerSize; 900 | 901 | while (currentData < & host -> receivedData [host -> receivedDataLength]) 902 | { 903 | enet_uint8 commandNumber; 904 | size_t commandSize; 905 | 906 | command = (ENetProtocol *) currentData; 907 | 908 | if (currentData + sizeof (ENetProtocolCommandHeader) > & host -> receivedData [host -> receivedDataLength]) 909 | break; 910 | 911 | commandNumber = command -> header.command & ENET_PROTOCOL_COMMAND_MASK; 912 | if (commandNumber >= ENET_PROTOCOL_COMMAND_COUNT) 913 | break; 914 | 915 | commandSize = commandSizes [commandNumber]; 916 | if (commandSize == 0 || currentData + commandSize > & host -> receivedData [host -> receivedDataLength]) 917 | break; 918 | 919 | currentData += commandSize; 920 | 921 | if (peer == NULL && commandNumber != ENET_PROTOCOL_COMMAND_CONNECT) 922 | break; 923 | 924 | command -> header.reliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> header.reliableSequenceNumber); 925 | 926 | switch (command -> header.command & ENET_PROTOCOL_COMMAND_MASK) 927 | { 928 | case ENET_PROTOCOL_COMMAND_ACKNOWLEDGE: 929 | if (enet_protocol_handle_acknowledge (host, event, peer, command)) 930 | goto commandError; 931 | break; 932 | 933 | case ENET_PROTOCOL_COMMAND_CONNECT: 934 | peer = enet_protocol_handle_connect (host, header, command); 935 | if (peer == NULL) 936 | goto commandError; 937 | break; 938 | 939 | case ENET_PROTOCOL_COMMAND_VERIFY_CONNECT: 940 | if (enet_protocol_handle_verify_connect (host, event, peer, command)) 941 | goto commandError; 942 | break; 943 | 944 | case ENET_PROTOCOL_COMMAND_DISCONNECT: 945 | if (enet_protocol_handle_disconnect (host, peer, command)) 946 | goto commandError; 947 | break; 948 | 949 | case ENET_PROTOCOL_COMMAND_PING: 950 | if (enet_protocol_handle_ping (host, peer, command)) 951 | goto commandError; 952 | break; 953 | 954 | case ENET_PROTOCOL_COMMAND_SEND_RELIABLE: 955 | if (enet_protocol_handle_send_reliable (host, peer, command, & currentData)) 956 | goto commandError; 957 | break; 958 | 959 | case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE: 960 | if (enet_protocol_handle_send_unreliable (host, peer, command, & currentData)) 961 | goto commandError; 962 | break; 963 | 964 | case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED: 965 | if (enet_protocol_handle_send_unsequenced (host, peer, command, & currentData)) 966 | goto commandError; 967 | break; 968 | 969 | case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT: 970 | if (enet_protocol_handle_send_fragment (host, peer, command, & currentData)) 971 | goto commandError; 972 | break; 973 | 974 | case ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT: 975 | if (enet_protocol_handle_bandwidth_limit (host, peer, command)) 976 | goto commandError; 977 | break; 978 | 979 | case ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE: 980 | if (enet_protocol_handle_throttle_configure (host, peer, command)) 981 | goto commandError; 982 | break; 983 | 984 | default: 985 | goto commandError; 986 | } 987 | 988 | if (peer != NULL && 989 | (command -> header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) != 0) 990 | { 991 | enet_uint16 sentTime; 992 | 993 | if (! (flags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME)) 994 | break; 995 | 996 | sentTime = ENET_NET_TO_HOST_16 (header -> sentTime); 997 | 998 | switch (peer -> state) 999 | { 1000 | case ENET_PEER_STATE_DISCONNECTING: 1001 | case ENET_PEER_STATE_ACKNOWLEDGING_CONNECT: 1002 | break; 1003 | 1004 | case ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT: 1005 | if ((command -> header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_DISCONNECT) 1006 | enet_peer_queue_acknowledgement (peer, command, sentTime); 1007 | break; 1008 | 1009 | default: 1010 | enet_peer_queue_acknowledgement (peer, command, sentTime); 1011 | break; 1012 | } 1013 | } 1014 | } 1015 | 1016 | commandError: 1017 | if (event != NULL && event -> type != ENET_EVENT_TYPE_NONE) 1018 | return 1; 1019 | 1020 | return 0; 1021 | } 1022 | 1023 | static int 1024 | enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event) 1025 | { 1026 | for (;;) 1027 | { 1028 | int receivedLength; 1029 | ENetBuffer buffer; 1030 | 1031 | buffer.data = host -> packetData [0]; 1032 | buffer.dataLength = sizeof (host -> packetData [0]); 1033 | 1034 | receivedLength = enet_socket_receive (host -> socket, 1035 | & host -> receivedAddress, 1036 | & buffer, 1037 | 1); 1038 | 1039 | if (receivedLength < 0) 1040 | return -1; 1041 | 1042 | if (receivedLength == 0) 1043 | return 0; 1044 | 1045 | host -> receivedData = host -> packetData [0]; 1046 | host -> receivedDataLength = receivedLength; 1047 | 1048 | host -> totalReceivedData += receivedLength; 1049 | host -> totalReceivedPackets ++; 1050 | 1051 | switch (enet_protocol_handle_incoming_commands (host, event)) 1052 | { 1053 | case 1: 1054 | return 1; 1055 | 1056 | case -1: 1057 | return -1; 1058 | 1059 | default: 1060 | break; 1061 | } 1062 | } 1063 | 1064 | return -1; 1065 | } 1066 | 1067 | static void 1068 | enet_protocol_send_acknowledgements (ENetHost * host, ENetPeer * peer) 1069 | { 1070 | ENetProtocol * command = & host -> commands [host -> commandCount]; 1071 | ENetBuffer * buffer = & host -> buffers [host -> bufferCount]; 1072 | ENetAcknowledgement * acknowledgement; 1073 | ENetListIterator currentAcknowledgement; 1074 | 1075 | currentAcknowledgement = enet_list_begin (& peer -> acknowledgements); 1076 | 1077 | while (currentAcknowledgement != enet_list_end (& peer -> acknowledgements)) 1078 | { 1079 | if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] || 1080 | buffer >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] || 1081 | peer -> mtu - host -> packetSize < sizeof (ENetProtocolAcknowledge)) 1082 | { 1083 | host -> continueSending = 1; 1084 | 1085 | break; 1086 | } 1087 | 1088 | acknowledgement = (ENetAcknowledgement *) currentAcknowledgement; 1089 | 1090 | currentAcknowledgement = enet_list_next (currentAcknowledgement); 1091 | 1092 | buffer -> data = command; 1093 | buffer -> dataLength = sizeof (ENetProtocolAcknowledge); 1094 | 1095 | host -> packetSize += buffer -> dataLength; 1096 | 1097 | command -> header.command = ENET_PROTOCOL_COMMAND_ACKNOWLEDGE; 1098 | command -> header.channelID = acknowledgement -> command.header.channelID; 1099 | command -> acknowledge.receivedReliableSequenceNumber = ENET_HOST_TO_NET_16 (acknowledgement -> command.header.reliableSequenceNumber); 1100 | command -> acknowledge.receivedSentTime = ENET_HOST_TO_NET_16 (acknowledgement -> sentTime); 1101 | 1102 | if ((acknowledgement -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_DISCONNECT) 1103 | enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE); 1104 | 1105 | enet_list_remove (& acknowledgement -> acknowledgementList); 1106 | enet_free (acknowledgement); 1107 | 1108 | ++ command; 1109 | ++ buffer; 1110 | } 1111 | 1112 | host -> commandCount = command - host -> commands; 1113 | host -> bufferCount = buffer - host -> buffers; 1114 | } 1115 | 1116 | static void 1117 | enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * peer) 1118 | { 1119 | ENetProtocol * command = & host -> commands [host -> commandCount]; 1120 | ENetBuffer * buffer = & host -> buffers [host -> bufferCount]; 1121 | ENetOutgoingCommand * outgoingCommand; 1122 | ENetListIterator currentCommand; 1123 | 1124 | currentCommand = enet_list_begin (& peer -> outgoingUnreliableCommands); 1125 | 1126 | while (currentCommand != enet_list_end (& peer -> outgoingUnreliableCommands)) 1127 | { 1128 | size_t commandSize; 1129 | 1130 | outgoingCommand = (ENetOutgoingCommand *) currentCommand; 1131 | commandSize = commandSizes [outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK]; 1132 | 1133 | if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] || 1134 | buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] || 1135 | peer -> mtu - host -> packetSize < commandSize || 1136 | (outgoingCommand -> packet != NULL && 1137 | peer -> mtu - host -> packetSize < commandSize + outgoingCommand -> packet -> dataLength)) 1138 | { 1139 | host -> continueSending = 1; 1140 | 1141 | break; 1142 | } 1143 | 1144 | currentCommand = enet_list_next (currentCommand); 1145 | 1146 | if (outgoingCommand -> packet != NULL) 1147 | { 1148 | peer -> packetThrottleCounter += ENET_PEER_PACKET_THROTTLE_COUNTER; 1149 | peer -> packetThrottleCounter %= ENET_PEER_PACKET_THROTTLE_SCALE; 1150 | 1151 | if (peer -> packetThrottleCounter > peer -> packetThrottle) 1152 | { 1153 | -- outgoingCommand -> packet -> referenceCount; 1154 | 1155 | if (outgoingCommand -> packet -> referenceCount == 0) 1156 | enet_packet_destroy (outgoingCommand -> packet); 1157 | 1158 | enet_list_remove (& outgoingCommand -> outgoingCommandList); 1159 | enet_free (outgoingCommand); 1160 | 1161 | continue; 1162 | } 1163 | } 1164 | 1165 | buffer -> data = command; 1166 | buffer -> dataLength = commandSize; 1167 | 1168 | host -> packetSize += buffer -> dataLength; 1169 | 1170 | * command = outgoingCommand -> command; 1171 | 1172 | enet_list_remove (& outgoingCommand -> outgoingCommandList); 1173 | 1174 | if (outgoingCommand -> packet != NULL) 1175 | { 1176 | ++ buffer; 1177 | 1178 | buffer -> data = outgoingCommand -> packet -> data; 1179 | buffer -> dataLength = outgoingCommand -> packet -> dataLength; 1180 | 1181 | host -> packetSize += buffer -> dataLength; 1182 | 1183 | enet_list_insert (enet_list_end (& peer -> sentUnreliableCommands), outgoingCommand); 1184 | } 1185 | else 1186 | enet_free (outgoingCommand); 1187 | 1188 | ++ command; 1189 | ++ buffer; 1190 | } 1191 | 1192 | host -> commandCount = command - host -> commands; 1193 | host -> bufferCount = buffer - host -> buffers; 1194 | 1195 | if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER && 1196 | enet_list_empty (& peer -> outgoingReliableCommands) && 1197 | enet_list_empty (& peer -> outgoingUnreliableCommands) && 1198 | enet_list_empty (& peer -> sentReliableCommands)) 1199 | enet_peer_disconnect (peer, peer -> eventData); 1200 | } 1201 | 1202 | static int 1203 | enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * event) 1204 | { 1205 | ENetOutgoingCommand * outgoingCommand; 1206 | ENetListIterator currentCommand, insertPosition; 1207 | 1208 | currentCommand = enet_list_begin (& peer -> sentReliableCommands); 1209 | insertPosition = enet_list_begin (& peer -> outgoingReliableCommands); 1210 | 1211 | while (currentCommand != enet_list_end (& peer -> sentReliableCommands)) 1212 | { 1213 | outgoingCommand = (ENetOutgoingCommand *) currentCommand; 1214 | 1215 | currentCommand = enet_list_next (currentCommand); 1216 | 1217 | if (ENET_TIME_DIFFERENCE (host -> serviceTime, outgoingCommand -> sentTime) < outgoingCommand -> roundTripTimeout) 1218 | continue; 1219 | 1220 | if (peer -> earliestTimeout == 0 || 1221 | ENET_TIME_LESS (outgoingCommand -> sentTime, peer -> earliestTimeout)) 1222 | peer -> earliestTimeout = outgoingCommand -> sentTime; 1223 | 1224 | if (peer -> earliestTimeout != 0 && 1225 | (ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> earliestTimeout) >= ENET_PEER_TIMEOUT_MAXIMUM || 1226 | (outgoingCommand -> roundTripTimeout >= outgoingCommand -> roundTripTimeoutLimit && 1227 | ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> earliestTimeout) >= ENET_PEER_TIMEOUT_MINIMUM))) 1228 | { 1229 | enet_protocol_notify_disconnect (host, peer, event); 1230 | 1231 | return 1; 1232 | } 1233 | 1234 | if (outgoingCommand -> packet != NULL) 1235 | peer -> reliableDataInTransit -= outgoingCommand -> fragmentLength; 1236 | 1237 | ++ peer -> packetsLost; 1238 | 1239 | outgoingCommand -> roundTripTimeout *= 2; 1240 | 1241 | enet_list_insert (insertPosition, enet_list_remove (& outgoingCommand -> outgoingCommandList)); 1242 | 1243 | if (currentCommand == enet_list_begin (& peer -> sentReliableCommands) && 1244 | ! enet_list_empty (& peer -> sentReliableCommands)) 1245 | { 1246 | outgoingCommand = (ENetOutgoingCommand *) currentCommand; 1247 | 1248 | peer -> nextTimeout = outgoingCommand -> sentTime + outgoingCommand -> roundTripTimeout; 1249 | } 1250 | } 1251 | 1252 | return 0; 1253 | } 1254 | 1255 | static void 1256 | enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer) 1257 | { 1258 | ENetProtocol * command = & host -> commands [host -> commandCount]; 1259 | ENetBuffer * buffer = & host -> buffers [host -> bufferCount]; 1260 | ENetOutgoingCommand * outgoingCommand; 1261 | ENetListIterator currentCommand; 1262 | ENetChannel *channel; 1263 | enet_uint16 reliableWindow; 1264 | size_t commandSize; 1265 | 1266 | currentCommand = enet_list_begin (& peer -> outgoingReliableCommands); 1267 | 1268 | while (currentCommand != enet_list_end (& peer -> outgoingReliableCommands)) 1269 | { 1270 | outgoingCommand = (ENetOutgoingCommand *) currentCommand; 1271 | 1272 | channel = outgoingCommand -> command.header.channelID < peer -> channelCount ? & peer -> channels [outgoingCommand -> command.header.channelID] : NULL; 1273 | reliableWindow = outgoingCommand -> reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; 1274 | if (channel != NULL && 1275 | outgoingCommand -> sendAttempts < 1 && 1276 | ! (outgoingCommand -> reliableSequenceNumber % ENET_PEER_RELIABLE_WINDOW_SIZE) && 1277 | (channel -> reliableWindows [(reliableWindow + ENET_PEER_RELIABLE_WINDOWS - 1) % ENET_PEER_RELIABLE_WINDOWS] >= ENET_PEER_RELIABLE_WINDOW_SIZE || 1278 | channel -> usedReliableWindows & ((((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) << reliableWindow) | 1279 | (((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) >> (ENET_PEER_RELIABLE_WINDOW_SIZE - reliableWindow))))) 1280 | break; 1281 | 1282 | commandSize = commandSizes [outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK]; 1283 | if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] || 1284 | buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] || 1285 | peer -> mtu - host -> packetSize < commandSize) 1286 | { 1287 | host -> continueSending = 1; 1288 | 1289 | break; 1290 | } 1291 | 1292 | if (outgoingCommand -> packet != NULL) 1293 | { 1294 | if (peer -> reliableDataInTransit + outgoingCommand -> fragmentLength > peer -> windowSize) 1295 | break; 1296 | 1297 | if ((enet_uint16) (peer -> mtu - host -> packetSize) < (enet_uint16) (commandSize + outgoingCommand -> fragmentLength)) 1298 | { 1299 | host -> continueSending = 1; 1300 | 1301 | break; 1302 | } 1303 | } 1304 | 1305 | currentCommand = enet_list_next (currentCommand); 1306 | 1307 | if (channel != NULL && outgoingCommand -> sendAttempts < 1) 1308 | { 1309 | channel -> usedReliableWindows |= 1 << reliableWindow; 1310 | ++ channel -> reliableWindows [reliableWindow]; 1311 | } 1312 | 1313 | ++ outgoingCommand -> sendAttempts; 1314 | 1315 | if (outgoingCommand -> roundTripTimeout == 0) 1316 | { 1317 | outgoingCommand -> roundTripTimeout = peer -> roundTripTime + 4 * peer -> roundTripTimeVariance; 1318 | outgoingCommand -> roundTripTimeoutLimit = ENET_PEER_TIMEOUT_LIMIT * outgoingCommand -> roundTripTimeout; 1319 | } 1320 | 1321 | if (enet_list_empty (& peer -> sentReliableCommands)) 1322 | peer -> nextTimeout = host -> serviceTime + outgoingCommand -> roundTripTimeout; 1323 | 1324 | enet_list_insert (enet_list_end (& peer -> sentReliableCommands), 1325 | enet_list_remove (& outgoingCommand -> outgoingCommandList)); 1326 | 1327 | outgoingCommand -> sentTime = host -> serviceTime; 1328 | 1329 | buffer -> data = command; 1330 | buffer -> dataLength = commandSize; 1331 | 1332 | host -> packetSize += buffer -> dataLength; 1333 | host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_SENT_TIME; 1334 | 1335 | * command = outgoingCommand -> command; 1336 | 1337 | if (outgoingCommand -> packet != NULL) 1338 | { 1339 | ++ buffer; 1340 | 1341 | buffer -> data = outgoingCommand -> packet -> data + outgoingCommand -> fragmentOffset; 1342 | buffer -> dataLength = outgoingCommand -> fragmentLength; 1343 | 1344 | host -> packetSize += outgoingCommand -> fragmentLength; 1345 | 1346 | peer -> reliableDataInTransit += outgoingCommand -> fragmentLength; 1347 | } 1348 | 1349 | ++ peer -> packetsSent; 1350 | 1351 | ++ command; 1352 | ++ buffer; 1353 | } 1354 | 1355 | host -> commandCount = command - host -> commands; 1356 | host -> bufferCount = buffer - host -> buffers; 1357 | } 1358 | 1359 | static int 1360 | enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int checkForTimeouts) 1361 | { 1362 | enet_uint8 headerData [sizeof (ENetProtocolHeader) + sizeof (enet_uint32)]; 1363 | ENetProtocolHeader * header = (ENetProtocolHeader *) headerData; 1364 | ENetPeer * currentPeer; 1365 | int sentLength; 1366 | size_t shouldCompress = 0; 1367 | 1368 | host -> continueSending = 1; 1369 | 1370 | while (host -> continueSending) 1371 | for (host -> continueSending = 0, 1372 | currentPeer = host -> peers; 1373 | currentPeer < & host -> peers [host -> peerCount]; 1374 | ++ currentPeer) 1375 | { 1376 | if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED || 1377 | currentPeer -> state == ENET_PEER_STATE_ZOMBIE) 1378 | continue; 1379 | 1380 | host -> headerFlags = 0; 1381 | host -> commandCount = 0; 1382 | host -> bufferCount = 1; 1383 | host -> packetSize = sizeof (ENetProtocolHeader); 1384 | 1385 | if (! enet_list_empty (& currentPeer -> acknowledgements)) 1386 | enet_protocol_send_acknowledgements (host, currentPeer); 1387 | 1388 | if (checkForTimeouts != 0 && 1389 | ! enet_list_empty (& currentPeer -> sentReliableCommands) && 1390 | ENET_TIME_GREATER_EQUAL (host -> serviceTime, currentPeer -> nextTimeout) && 1391 | enet_protocol_check_timeouts (host, currentPeer, event) == 1) 1392 | return 1; 1393 | 1394 | if (! enet_list_empty (& currentPeer -> outgoingReliableCommands)) 1395 | enet_protocol_send_reliable_outgoing_commands (host, currentPeer); 1396 | else 1397 | if (enet_list_empty (& currentPeer -> sentReliableCommands) && 1398 | ENET_TIME_DIFFERENCE (host -> serviceTime, currentPeer -> lastReceiveTime) >= ENET_PEER_PING_INTERVAL && 1399 | currentPeer -> mtu - host -> packetSize >= sizeof (ENetProtocolPing)) 1400 | { 1401 | enet_peer_ping (currentPeer); 1402 | enet_protocol_send_reliable_outgoing_commands (host, currentPeer); 1403 | } 1404 | 1405 | if (! enet_list_empty (& currentPeer -> outgoingUnreliableCommands)) 1406 | enet_protocol_send_unreliable_outgoing_commands (host, currentPeer); 1407 | 1408 | if (host -> commandCount == 0) 1409 | continue; 1410 | 1411 | if (currentPeer -> packetLossEpoch == 0) 1412 | currentPeer -> packetLossEpoch = host -> serviceTime; 1413 | else 1414 | if (ENET_TIME_DIFFERENCE (host -> serviceTime, currentPeer -> packetLossEpoch) >= ENET_PEER_PACKET_LOSS_INTERVAL && 1415 | currentPeer -> packetsSent > 0) 1416 | { 1417 | enet_uint32 packetLoss = currentPeer -> packetsLost * ENET_PEER_PACKET_LOSS_SCALE / currentPeer -> packetsSent; 1418 | 1419 | #ifdef ENET_DEBUG 1420 | #ifdef WIN32 1421 | printf ( 1422 | #else 1423 | fprintf (stderr, 1424 | #endif 1425 | "peer %u: %f%%+-%f%% packet loss, %u+-%u ms round trip time, %f%% throttle, %u/%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 -> outgoingReliableCommands), enet_list_size (& currentPeer -> outgoingUnreliableCommands), currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingReliableCommands) : 0, currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingUnreliableCommands) : 0); 1426 | #endif 1427 | 1428 | currentPeer -> packetLossVariance -= currentPeer -> packetLossVariance / 4; 1429 | 1430 | if (packetLoss >= currentPeer -> packetLoss) 1431 | { 1432 | currentPeer -> packetLoss += (packetLoss - currentPeer -> packetLoss) / 8; 1433 | currentPeer -> packetLossVariance += (packetLoss - currentPeer -> packetLoss) / 4; 1434 | } 1435 | else 1436 | { 1437 | currentPeer -> packetLoss -= (currentPeer -> packetLoss - packetLoss) / 8; 1438 | currentPeer -> packetLossVariance += (currentPeer -> packetLoss - packetLoss) / 4; 1439 | } 1440 | 1441 | currentPeer -> packetLossEpoch = host -> serviceTime; 1442 | currentPeer -> packetsSent = 0; 1443 | currentPeer -> packetsLost = 0; 1444 | } 1445 | 1446 | host -> buffers -> data = headerData; 1447 | if (host -> headerFlags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME) 1448 | { 1449 | header -> sentTime = ENET_HOST_TO_NET_16 (host -> serviceTime & 0xFFFF); 1450 | 1451 | host -> buffers -> dataLength = sizeof (ENetProtocolHeader); 1452 | } 1453 | else 1454 | host -> buffers -> dataLength = (size_t) & ((ENetProtocolHeader *) 0) -> sentTime; 1455 | 1456 | shouldCompress = 0; 1457 | if (host -> compressor.context != NULL && host -> compressor.compress != NULL) 1458 | { 1459 | size_t originalSize = host -> packetSize - sizeof(ENetProtocolHeader), 1460 | compressedSize = host -> compressor.compress (host -> compressor.context, 1461 | & host -> buffers [1], host -> bufferCount - 1, 1462 | originalSize, 1463 | host -> packetData [1], 1464 | originalSize); 1465 | if (compressedSize > 0 && compressedSize < originalSize) 1466 | { 1467 | host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_COMPRESSED; 1468 | shouldCompress = compressedSize; 1469 | #ifdef ENET_DEBUG_COMPRESS 1470 | #ifdef WIN32 1471 | printf ( 1472 | #else 1473 | fprintf (stderr, 1474 | #endif 1475 | "peer %u: compressed %u -> %u (%u%%)\n", currentPeer -> incomingPeerID, originalSize, compressedSize, (compressedSize * 100) / originalSize); 1476 | #endif 1477 | } 1478 | } 1479 | 1480 | if (currentPeer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID) 1481 | host -> headerFlags |= currentPeer -> outgoingSessionID << ENET_PROTOCOL_HEADER_SESSION_SHIFT; 1482 | header -> peerID = ENET_HOST_TO_NET_16 (currentPeer -> outgoingPeerID | host -> headerFlags); 1483 | if (host -> checksum != NULL) 1484 | { 1485 | enet_uint32 * checksum = (enet_uint32 *) & headerData [host -> buffers -> dataLength]; 1486 | * checksum = currentPeer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID ? currentPeer -> connectID : 0; 1487 | host -> buffers -> dataLength += sizeof (enet_uint32); 1488 | * checksum = host -> checksum (host -> buffers, host -> bufferCount); 1489 | } 1490 | 1491 | if (shouldCompress > 0) 1492 | { 1493 | host -> buffers [1].data = host -> packetData [1]; 1494 | host -> buffers [1].dataLength = shouldCompress; 1495 | host -> bufferCount = 2; 1496 | } 1497 | 1498 | currentPeer -> lastSendTime = host -> serviceTime; 1499 | 1500 | sentLength = enet_socket_send (host -> socket, & currentPeer -> address, host -> buffers, host -> bufferCount); 1501 | 1502 | enet_protocol_remove_sent_unreliable_commands (currentPeer); 1503 | 1504 | if (sentLength < 0) 1505 | return -1; 1506 | 1507 | host -> totalSentData += sentLength; 1508 | host -> totalSentPackets ++; 1509 | } 1510 | 1511 | return 0; 1512 | } 1513 | 1514 | /** Sends any queued packets on the host specified to its designated peers. 1515 | 1516 | @param host host to flush 1517 | @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(). 1518 | @ingroup host 1519 | */ 1520 | void 1521 | enet_host_flush (ENetHost * host) 1522 | { 1523 | host -> serviceTime = enet_time_get (); 1524 | 1525 | enet_protocol_send_outgoing_commands (host, NULL, 0); 1526 | } 1527 | 1528 | /** Checks for any queued events on the host and dispatches one if available. 1529 | 1530 | @param host host to check for events 1531 | @param event an event structure where event details will be placed if available 1532 | @retval > 0 if an event was dispatched 1533 | @retval 0 if no events are available 1534 | @retval < 0 on failure 1535 | @ingroup host 1536 | */ 1537 | int 1538 | enet_host_check_events (ENetHost * host, ENetEvent * event) 1539 | { 1540 | if (event == NULL) return -1; 1541 | 1542 | event -> type = ENET_EVENT_TYPE_NONE; 1543 | event -> peer = NULL; 1544 | event -> packet = NULL; 1545 | 1546 | return enet_protocol_dispatch_incoming_commands (host, event); 1547 | } 1548 | 1549 | /** Waits for events on the host specified and shuttles packets between 1550 | the host and its peers. 1551 | 1552 | @param host host to service 1553 | @param event an event structure where event details will be placed if one occurs 1554 | if event == NULL then no events will be delivered 1555 | @param timeout number of milliseconds that ENet should wait for events 1556 | @retval > 0 if an event occurred within the specified time limit 1557 | @retval 0 if no event occurred 1558 | @retval < 0 on failure 1559 | @remarks enet_host_service should be called fairly regularly for adequate performance 1560 | @ingroup host 1561 | */ 1562 | int 1563 | enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout) 1564 | { 1565 | enet_uint32 waitCondition; 1566 | 1567 | if (event != NULL) 1568 | { 1569 | event -> type = ENET_EVENT_TYPE_NONE; 1570 | event -> peer = NULL; 1571 | event -> packet = NULL; 1572 | 1573 | switch (enet_protocol_dispatch_incoming_commands (host, event)) 1574 | { 1575 | case 1: 1576 | return 1; 1577 | 1578 | case -1: 1579 | perror ("Error dispatching incoming packets"); 1580 | 1581 | return -1; 1582 | 1583 | default: 1584 | break; 1585 | } 1586 | } 1587 | 1588 | host -> serviceTime = enet_time_get (); 1589 | 1590 | timeout += host -> serviceTime; 1591 | 1592 | do 1593 | { 1594 | if (ENET_TIME_DIFFERENCE (host -> serviceTime, host -> bandwidthThrottleEpoch) >= ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL) 1595 | enet_host_bandwidth_throttle (host); 1596 | 1597 | switch (enet_protocol_send_outgoing_commands (host, event, 1)) 1598 | { 1599 | case 1: 1600 | return 1; 1601 | 1602 | case -1: 1603 | perror ("Error sending outgoing packets"); 1604 | 1605 | return -1; 1606 | 1607 | default: 1608 | break; 1609 | } 1610 | 1611 | switch (enet_protocol_receive_incoming_commands (host, event)) 1612 | { 1613 | case 1: 1614 | return 1; 1615 | 1616 | case -1: 1617 | perror ("Error receiving incoming packets"); 1618 | 1619 | return -1; 1620 | 1621 | default: 1622 | break; 1623 | } 1624 | 1625 | switch (enet_protocol_send_outgoing_commands (host, event, 1)) 1626 | { 1627 | case 1: 1628 | return 1; 1629 | 1630 | case -1: 1631 | perror ("Error sending outgoing packets"); 1632 | 1633 | return -1; 1634 | 1635 | default: 1636 | break; 1637 | } 1638 | 1639 | if (event != NULL) 1640 | { 1641 | switch (enet_protocol_dispatch_incoming_commands (host, event)) 1642 | { 1643 | case 1: 1644 | return 1; 1645 | 1646 | case -1: 1647 | perror ("Error dispatching incoming packets"); 1648 | 1649 | return -1; 1650 | 1651 | default: 1652 | break; 1653 | } 1654 | } 1655 | 1656 | host -> serviceTime = enet_time_get (); 1657 | 1658 | if (ENET_TIME_GREATER_EQUAL (host -> serviceTime, timeout)) 1659 | return 0; 1660 | 1661 | waitCondition = ENET_SOCKET_WAIT_RECEIVE; 1662 | 1663 | if (enet_socket_wait (host -> socket, & waitCondition, ENET_TIME_DIFFERENCE (timeout, host -> serviceTime)) != 0) 1664 | return -1; 1665 | 1666 | host -> serviceTime = enet_time_get (); 1667 | } while (waitCondition == ENET_SOCKET_WAIT_RECEIVE); 1668 | 1669 | return 0; 1670 | } 1671 | 1672 | -------------------------------------------------------------------------------- /jni/unix.c: -------------------------------------------------------------------------------- 1 | /** 2 | @file unix.c 3 | @brief ENet Unix system specific functions 4 | */ 5 | #ifndef WIN32 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #define ENET_BUILDING_LIB 1 19 | #include "enet/enet.h" 20 | 21 | #ifdef HAS_FCNTL 22 | #include 23 | #endif 24 | 25 | #ifdef __APPLE__ 26 | #undef HAS_POLL 27 | #endif 28 | 29 | #ifdef HAS_POLL 30 | #include 31 | #endif 32 | 33 | #ifndef HAS_SOCKLEN_T 34 | typedef int socklen_t; 35 | #endif 36 | 37 | #ifndef MSG_NOSIGNAL 38 | #define MSG_NOSIGNAL 0 39 | #endif 40 | 41 | static enet_uint32 timeBase = 0; 42 | 43 | int 44 | enet_initialize (void) 45 | { 46 | return 0; 47 | } 48 | 49 | void 50 | enet_deinitialize (void) 51 | { 52 | } 53 | 54 | enet_uint32 55 | enet_time_get (void) 56 | { 57 | struct timeval timeVal; 58 | 59 | gettimeofday (& timeVal, NULL); 60 | 61 | return timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - timeBase; 62 | } 63 | 64 | void 65 | enet_time_set (enet_uint32 newTimeBase) 66 | { 67 | struct timeval timeVal; 68 | 69 | gettimeofday (& timeVal, NULL); 70 | 71 | timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase; 72 | } 73 | 74 | int 75 | enet_address_set_host (ENetAddress * address, const char * name) 76 | { 77 | struct hostent * hostEntry = NULL; 78 | #ifdef HAS_GETHOSTBYNAME_R 79 | struct hostent hostData; 80 | char buffer [2048]; 81 | int errnum; 82 | 83 | #if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 84 | gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum); 85 | #else 86 | hostEntry = gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & errnum); 87 | #endif 88 | #else 89 | hostEntry = gethostbyname (name); 90 | #endif 91 | 92 | if (hostEntry == NULL || 93 | hostEntry -> h_addrtype != AF_INET) 94 | { 95 | #ifdef HAS_INET_PTON 96 | if (! inet_pton (AF_INET, name, & address -> host)) 97 | #else 98 | if (! inet_aton (name, (struct in_addr *) & address -> host)) 99 | #endif 100 | return -1; 101 | return 0; 102 | } 103 | 104 | address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0]; 105 | 106 | return 0; 107 | } 108 | 109 | int 110 | enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength) 111 | { 112 | #ifdef HAS_INET_NTOP 113 | if (inet_ntop (AF_INET, & address -> host, name, nameLength) == NULL) 114 | #else 115 | char * addr = inet_ntoa (* (struct in_addr *) & address -> host); 116 | if (addr != NULL) 117 | strncpy (name, addr, nameLength); 118 | else 119 | #endif 120 | return -1; 121 | return 0; 122 | } 123 | 124 | int 125 | enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength) 126 | { 127 | struct in_addr in; 128 | struct hostent * hostEntry = NULL; 129 | #ifdef HAS_GETHOSTBYADDR_R 130 | struct hostent hostData; 131 | char buffer [2048]; 132 | int errnum; 133 | 134 | in.s_addr = address -> host; 135 | 136 | #if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 137 | gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum); 138 | #else 139 | hostEntry = gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & errnum); 140 | #endif 141 | #else 142 | in.s_addr = address -> host; 143 | 144 | hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET); 145 | #endif 146 | 147 | if (hostEntry == NULL) 148 | return enet_address_get_host_ip (address, name, nameLength); 149 | 150 | strncpy (name, hostEntry -> h_name, nameLength); 151 | 152 | return 0; 153 | } 154 | 155 | int 156 | enet_socket_bind (ENetSocket socket, const ENetAddress * address) 157 | { 158 | struct sockaddr_in sin; 159 | 160 | memset (& sin, 0, sizeof (struct sockaddr_in)); 161 | 162 | sin.sin_family = AF_INET; 163 | 164 | if (address != NULL) 165 | { 166 | sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); 167 | sin.sin_addr.s_addr = address -> host; 168 | } 169 | else 170 | { 171 | sin.sin_port = 0; 172 | sin.sin_addr.s_addr = INADDR_ANY; 173 | } 174 | 175 | return bind (socket, 176 | (struct sockaddr *) & sin, 177 | sizeof (struct sockaddr_in)); 178 | } 179 | 180 | int 181 | enet_socket_listen (ENetSocket socket, int backlog) 182 | { 183 | return listen (socket, backlog < 0 ? SOMAXCONN : backlog); 184 | } 185 | 186 | ENetSocket 187 | enet_socket_create (ENetSocketType type) 188 | { 189 | return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0); 190 | } 191 | 192 | int 193 | enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value) 194 | { 195 | int result = -1; 196 | switch (option) 197 | { 198 | case ENET_SOCKOPT_NONBLOCK: 199 | #ifdef HAS_FCNTL 200 | result = fcntl (socket, F_SETFL, O_NONBLOCK | fcntl (socket, F_GETFL)); 201 | #else 202 | result = ioctl (socket, FIONBIO, & value); 203 | #endif 204 | break; 205 | 206 | case ENET_SOCKOPT_BROADCAST: 207 | result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int)); 208 | break; 209 | 210 | case ENET_SOCKOPT_REUSEADDR: 211 | result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int)); 212 | break; 213 | 214 | case ENET_SOCKOPT_RCVBUF: 215 | result = setsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) & value, sizeof (int)); 216 | break; 217 | 218 | case ENET_SOCKOPT_SNDBUF: 219 | result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int)); 220 | break; 221 | 222 | default: 223 | break; 224 | } 225 | return result == -1 ? -1 : 0; 226 | } 227 | 228 | int 229 | enet_socket_connect (ENetSocket socket, const ENetAddress * address) 230 | { 231 | struct sockaddr_in sin; 232 | 233 | memset (& sin, 0, sizeof (struct sockaddr_in)); 234 | 235 | sin.sin_family = AF_INET; 236 | sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); 237 | sin.sin_addr.s_addr = address -> host; 238 | 239 | return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in)); 240 | } 241 | 242 | ENetSocket 243 | enet_socket_accept (ENetSocket socket, ENetAddress * address) 244 | { 245 | int result; 246 | struct sockaddr_in sin; 247 | socklen_t sinLength = sizeof (struct sockaddr_in); 248 | 249 | result = accept (socket, 250 | address != NULL ? (struct sockaddr *) & sin : NULL, 251 | address != NULL ? & sinLength : NULL); 252 | 253 | if (result == -1) 254 | return ENET_SOCKET_NULL; 255 | 256 | if (address != NULL) 257 | { 258 | address -> host = (enet_uint32) sin.sin_addr.s_addr; 259 | address -> port = ENET_NET_TO_HOST_16 (sin.sin_port); 260 | } 261 | 262 | return result; 263 | } 264 | 265 | void 266 | enet_socket_destroy (ENetSocket socket) 267 | { 268 | close (socket); 269 | } 270 | 271 | int 272 | enet_socket_send (ENetSocket socket, 273 | const ENetAddress * address, 274 | const ENetBuffer * buffers, 275 | size_t bufferCount) 276 | { 277 | struct msghdr msgHdr; 278 | struct sockaddr_in sin; 279 | int sentLength; 280 | 281 | memset (& msgHdr, 0, sizeof (struct msghdr)); 282 | 283 | if (address != NULL) 284 | { 285 | memset (& sin, 0, sizeof (struct sockaddr_in)); 286 | 287 | sin.sin_family = AF_INET; 288 | sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); 289 | sin.sin_addr.s_addr = address -> host; 290 | 291 | msgHdr.msg_name = & sin; 292 | msgHdr.msg_namelen = sizeof (struct sockaddr_in); 293 | } 294 | 295 | msgHdr.msg_iov = (struct iovec *) buffers; 296 | msgHdr.msg_iovlen = bufferCount; 297 | 298 | sentLength = sendmsg (socket, & msgHdr, MSG_NOSIGNAL); 299 | 300 | if (sentLength == -1) 301 | { 302 | if (errno == EWOULDBLOCK) 303 | return 0; 304 | 305 | return -1; 306 | } 307 | 308 | return sentLength; 309 | } 310 | 311 | int 312 | enet_socket_receive (ENetSocket socket, 313 | ENetAddress * address, 314 | ENetBuffer * buffers, 315 | size_t bufferCount) 316 | { 317 | struct msghdr msgHdr; 318 | struct sockaddr_in sin; 319 | int recvLength; 320 | 321 | memset (& msgHdr, 0, sizeof (struct msghdr)); 322 | 323 | if (address != NULL) 324 | { 325 | msgHdr.msg_name = & sin; 326 | msgHdr.msg_namelen = sizeof (struct sockaddr_in); 327 | } 328 | 329 | msgHdr.msg_iov = (struct iovec *) buffers; 330 | msgHdr.msg_iovlen = bufferCount; 331 | 332 | recvLength = recvmsg (socket, & msgHdr, MSG_NOSIGNAL); 333 | 334 | if (recvLength == -1) 335 | { 336 | if (errno == EWOULDBLOCK) 337 | return 0; 338 | 339 | return -1; 340 | } 341 | 342 | #ifdef HAS_MSGHDR_FLAGS 343 | if (msgHdr.msg_flags & MSG_TRUNC) 344 | return -1; 345 | #endif 346 | 347 | if (address != NULL) 348 | { 349 | address -> host = (enet_uint32) sin.sin_addr.s_addr; 350 | address -> port = ENET_NET_TO_HOST_16 (sin.sin_port); 351 | } 352 | 353 | return recvLength; 354 | } 355 | 356 | int 357 | enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocketSet * writeSet, enet_uint32 timeout) 358 | { 359 | struct timeval timeVal; 360 | 361 | timeVal.tv_sec = timeout / 1000; 362 | timeVal.tv_usec = (timeout % 1000) * 1000; 363 | 364 | return select (maxSocket + 1, readSet, writeSet, NULL, & timeVal); 365 | } 366 | 367 | int 368 | enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout) 369 | { 370 | #ifdef HAS_POLL 371 | struct pollfd pollSocket; 372 | int pollCount; 373 | 374 | pollSocket.fd = socket; 375 | pollSocket.events = 0; 376 | 377 | if (* condition & ENET_SOCKET_WAIT_SEND) 378 | pollSocket.events |= POLLOUT; 379 | 380 | if (* condition & ENET_SOCKET_WAIT_RECEIVE) 381 | pollSocket.events |= POLLIN; 382 | 383 | pollCount = poll (& pollSocket, 1, timeout); 384 | 385 | if (pollCount < 0) 386 | return -1; 387 | 388 | * condition = ENET_SOCKET_WAIT_NONE; 389 | 390 | if (pollCount == 0) 391 | return 0; 392 | 393 | if (pollSocket.revents & POLLOUT) 394 | * condition |= ENET_SOCKET_WAIT_SEND; 395 | 396 | if (pollSocket.revents & POLLIN) 397 | * condition |= ENET_SOCKET_WAIT_RECEIVE; 398 | 399 | return 0; 400 | #else 401 | fd_set readSet, writeSet; 402 | struct timeval timeVal; 403 | int selectCount; 404 | 405 | timeVal.tv_sec = timeout / 1000; 406 | timeVal.tv_usec = (timeout % 1000) * 1000; 407 | 408 | FD_ZERO (& readSet); 409 | FD_ZERO (& writeSet); 410 | 411 | if (* condition & ENET_SOCKET_WAIT_SEND) 412 | FD_SET (socket, & writeSet); 413 | 414 | if (* condition & ENET_SOCKET_WAIT_RECEIVE) 415 | FD_SET (socket, & readSet); 416 | 417 | selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal); 418 | 419 | if (selectCount < 0) 420 | return -1; 421 | 422 | * condition = ENET_SOCKET_WAIT_NONE; 423 | 424 | if (selectCount == 0) 425 | return 0; 426 | 427 | if (FD_ISSET (socket, & writeSet)) 428 | * condition |= ENET_SOCKET_WAIT_SEND; 429 | 430 | if (FD_ISSET (socket, & readSet)) 431 | * condition |= ENET_SOCKET_WAIT_RECEIVE; 432 | 433 | return 0; 434 | #endif 435 | } 436 | 437 | #endif 438 | 439 | -------------------------------------------------------------------------------- /jni/win32.c: -------------------------------------------------------------------------------- 1 | /** 2 | @file win32.c 3 | @brief ENet Win32 system specific functions 4 | */ 5 | #ifdef WIN32 6 | 7 | #include 8 | #define ENET_BUILDING_LIB 1 9 | #include "enet/enet.h" 10 | 11 | static enet_uint32 timeBase = 0; 12 | 13 | int 14 | enet_initialize (void) 15 | { 16 | WORD versionRequested = MAKEWORD (1, 1); 17 | WSADATA wsaData; 18 | 19 | if (WSAStartup (versionRequested, & wsaData)) 20 | return -1; 21 | 22 | if (LOBYTE (wsaData.wVersion) != 1|| 23 | HIBYTE (wsaData.wVersion) != 1) 24 | { 25 | WSACleanup (); 26 | 27 | return -1; 28 | } 29 | 30 | timeBeginPeriod (1); 31 | 32 | return 0; 33 | } 34 | 35 | void 36 | enet_deinitialize (void) 37 | { 38 | timeEndPeriod (1); 39 | 40 | WSACleanup (); 41 | } 42 | 43 | enet_uint32 44 | enet_time_get (void) 45 | { 46 | return (enet_uint32) timeGetTime () - timeBase; 47 | } 48 | 49 | void 50 | enet_time_set (enet_uint32 newTimeBase) 51 | { 52 | timeBase = (enet_uint32) timeGetTime () - newTimeBase; 53 | } 54 | 55 | int 56 | enet_address_set_host (ENetAddress * address, const char * name) 57 | { 58 | struct hostent * hostEntry; 59 | 60 | hostEntry = gethostbyname (name); 61 | if (hostEntry == NULL || 62 | hostEntry -> h_addrtype != AF_INET) 63 | { 64 | unsigned long host = inet_addr (name); 65 | if (host == INADDR_NONE) 66 | return -1; 67 | address -> host = host; 68 | return 0; 69 | } 70 | 71 | address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0]; 72 | 73 | return 0; 74 | } 75 | 76 | int 77 | enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength) 78 | { 79 | char * addr = inet_ntoa (* (struct in_addr *) & address -> host); 80 | if (addr == NULL) 81 | return -1; 82 | strncpy (name, addr, nameLength); 83 | return 0; 84 | } 85 | 86 | int 87 | enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength) 88 | { 89 | struct in_addr in; 90 | struct hostent * hostEntry; 91 | 92 | in.s_addr = address -> host; 93 | 94 | hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET); 95 | if (hostEntry == NULL) 96 | return enet_address_get_host_ip (address, name, nameLength); 97 | 98 | strncpy (name, hostEntry -> h_name, nameLength); 99 | 100 | return 0; 101 | } 102 | 103 | int 104 | enet_socket_bind (ENetSocket socket, const ENetAddress * address) 105 | { 106 | struct sockaddr_in sin; 107 | 108 | memset (& sin, 0, sizeof (struct sockaddr_in)); 109 | 110 | sin.sin_family = AF_INET; 111 | 112 | if (address != NULL) 113 | { 114 | sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); 115 | sin.sin_addr.s_addr = address -> host; 116 | } 117 | else 118 | { 119 | sin.sin_port = 0; 120 | sin.sin_addr.s_addr = INADDR_ANY; 121 | } 122 | 123 | return bind (socket, 124 | (struct sockaddr *) & sin, 125 | sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0; 126 | } 127 | 128 | int 129 | enet_socket_listen (ENetSocket socket, int backlog) 130 | { 131 | return listen (socket, backlog < 0 ? SOMAXCONN : backlog) == SOCKET_ERROR ? -1 : 0; 132 | } 133 | 134 | ENetSocket 135 | enet_socket_create (ENetSocketType type) 136 | { 137 | return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0); 138 | } 139 | 140 | int 141 | enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value) 142 | { 143 | int result = SOCKET_ERROR; 144 | switch (option) 145 | { 146 | case ENET_SOCKOPT_NONBLOCK: 147 | { 148 | u_long nonBlocking = (u_long) value; 149 | result = ioctlsocket (socket, FIONBIO, & nonBlocking); 150 | break; 151 | } 152 | 153 | case ENET_SOCKOPT_BROADCAST: 154 | result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int)); 155 | break; 156 | 157 | case ENET_SOCKOPT_REUSEADDR: 158 | result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int)); 159 | break; 160 | 161 | case ENET_SOCKOPT_RCVBUF: 162 | result = setsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) & value, sizeof (int)); 163 | break; 164 | 165 | case ENET_SOCKOPT_SNDBUF: 166 | result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int)); 167 | break; 168 | 169 | default: 170 | break; 171 | } 172 | return result == SOCKET_ERROR ? -1 : 0; 173 | } 174 | 175 | int 176 | enet_socket_connect (ENetSocket socket, const ENetAddress * address) 177 | { 178 | struct sockaddr_in sin; 179 | 180 | memset (& sin, 0, sizeof (struct sockaddr_in)); 181 | 182 | sin.sin_family = AF_INET; 183 | sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); 184 | sin.sin_addr.s_addr = address -> host; 185 | 186 | return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0; 187 | } 188 | 189 | ENetSocket 190 | enet_socket_accept (ENetSocket socket, ENetAddress * address) 191 | { 192 | SOCKET result; 193 | struct sockaddr_in sin; 194 | int sinLength = sizeof (struct sockaddr_in); 195 | 196 | result = accept (socket, 197 | address != NULL ? (struct sockaddr *) & sin : NULL, 198 | address != NULL ? & sinLength : NULL); 199 | 200 | if (result == INVALID_SOCKET) 201 | return ENET_SOCKET_NULL; 202 | 203 | if (address != NULL) 204 | { 205 | address -> host = (enet_uint32) sin.sin_addr.s_addr; 206 | address -> port = ENET_NET_TO_HOST_16 (sin.sin_port); 207 | } 208 | 209 | return result; 210 | } 211 | 212 | void 213 | enet_socket_destroy (ENetSocket socket) 214 | { 215 | closesocket (socket); 216 | } 217 | 218 | int 219 | enet_socket_send (ENetSocket socket, 220 | const ENetAddress * address, 221 | const ENetBuffer * buffers, 222 | size_t bufferCount) 223 | { 224 | struct sockaddr_in sin; 225 | DWORD sentLength; 226 | 227 | if (address != NULL) 228 | { 229 | memset (& sin, 0, sizeof (struct sockaddr_in)); 230 | 231 | sin.sin_family = AF_INET; 232 | sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); 233 | sin.sin_addr.s_addr = address -> host; 234 | } 235 | 236 | if (WSASendTo (socket, 237 | (LPWSABUF) buffers, 238 | (DWORD) bufferCount, 239 | & sentLength, 240 | 0, 241 | address != NULL ? (struct sockaddr *) & sin : 0, 242 | address != NULL ? sizeof (struct sockaddr_in) : 0, 243 | NULL, 244 | NULL) == SOCKET_ERROR) 245 | { 246 | if (WSAGetLastError () == WSAEWOULDBLOCK) 247 | return 0; 248 | 249 | return -1; 250 | } 251 | 252 | return (int) sentLength; 253 | } 254 | 255 | int 256 | enet_socket_receive (ENetSocket socket, 257 | ENetAddress * address, 258 | ENetBuffer * buffers, 259 | size_t bufferCount) 260 | { 261 | INT sinLength = sizeof (struct sockaddr_in); 262 | DWORD flags = 0, 263 | recvLength; 264 | struct sockaddr_in sin; 265 | 266 | if (WSARecvFrom (socket, 267 | (LPWSABUF) buffers, 268 | (DWORD) bufferCount, 269 | & recvLength, 270 | & flags, 271 | address != NULL ? (struct sockaddr *) & sin : NULL, 272 | address != NULL ? & sinLength : NULL, 273 | NULL, 274 | NULL) == SOCKET_ERROR) 275 | { 276 | switch (WSAGetLastError ()) 277 | { 278 | case WSAEWOULDBLOCK: 279 | case WSAECONNRESET: 280 | return 0; 281 | } 282 | 283 | return -1; 284 | } 285 | 286 | if (flags & MSG_PARTIAL) 287 | return -1; 288 | 289 | if (address != NULL) 290 | { 291 | address -> host = (enet_uint32) sin.sin_addr.s_addr; 292 | address -> port = ENET_NET_TO_HOST_16 (sin.sin_port); 293 | } 294 | 295 | return (int) recvLength; 296 | } 297 | 298 | int 299 | enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocketSet * writeSet, enet_uint32 timeout) 300 | { 301 | struct timeval timeVal; 302 | 303 | timeVal.tv_sec = timeout / 1000; 304 | timeVal.tv_usec = (timeout % 1000) * 1000; 305 | 306 | return select (maxSocket + 1, readSet, writeSet, NULL, & timeVal); 307 | } 308 | 309 | int 310 | enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout) 311 | { 312 | fd_set readSet, writeSet; 313 | struct timeval timeVal; 314 | int selectCount; 315 | 316 | timeVal.tv_sec = timeout / 1000; 317 | timeVal.tv_usec = (timeout % 1000) * 1000; 318 | 319 | FD_ZERO (& readSet); 320 | FD_ZERO (& writeSet); 321 | 322 | if (* condition & ENET_SOCKET_WAIT_SEND) 323 | FD_SET (socket, & writeSet); 324 | 325 | if (* condition & ENET_SOCKET_WAIT_RECEIVE) 326 | FD_SET (socket, & readSet); 327 | 328 | selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal); 329 | 330 | if (selectCount < 0) 331 | return -1; 332 | 333 | * condition = ENET_SOCKET_WAIT_NONE; 334 | 335 | if (selectCount == 0) 336 | return 0; 337 | 338 | if (FD_ISSET (socket, & writeSet)) 339 | * condition |= ENET_SOCKET_WAIT_SEND; 340 | 341 | if (FD_ISSET (socket, & readSet)) 342 | * condition |= ENET_SOCKET_WAIT_RECEIVE; 343 | 344 | return 0; 345 | } 346 | 347 | #endif 348 | 349 | --------------------------------------------------------------------------------