Browse Source

Upgraded to ENet 1.3.1.
Disabled buffer security checks for smaller executable size.
Removed deprecated ODE files.

Lasse Öörni 14 years ago
parent
commit
6098409700

+ 2 - 2
CMakeLists.txt

@@ -28,10 +28,10 @@ add_definitions (-DENABLE_PROFILING)
 if (MSVC)
     add_definitions (-D_CRT_SECURE_NO_WARNINGS)
     set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MTd")
-    set (CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELEASE} /MT /fp:fast /Zi")
+    set (CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELEASE} /MT /fp:fast /Zi /GS-")
     set (CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELWITHDEBINFO} /GL")
     set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
-    set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE} /MT /fp:fast /Zi /D _SECURE_SCL=0")
+    set (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE} /MT /fp:fast /Zi /GS- /D _SECURE_SCL=0")
     set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /GL")
     set (CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /OPT:REF /OPT:ICF /DEBUG")
     set (CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /OPT:REF /OPT:ICF /LTCG")

+ 16 - 16
Docs/GettingStarted.dox

@@ -14,7 +14,7 @@ After the build is complete, the programs can be run from the Bin directory.
 
 To run Urho3D from the Visual Studio debugger, set it as a startup project and enter its relative path and filename into Properties -> Debugging -> Command: ..\\Bin\\Urho3D.exe (release) or ..\\Bin\\Urho3D_d.exe (debug.) Entering -w into Debugging -> Command Arguments is highly recommended. This enables startup in windowed mode: without it running into an exception or breakpoint will be obnoxious as the mouse cursor will most probably be hidden.
 
-To actually make Urho3D.exe do something useful, it must be supplied with the name of the script file it should load and run. See \subpage Running "Running Urho3D" for more information, but for a quick test you can try the following arguments: Scripts/TestScene.as -w
+To actually make Urho3D.exe do something useful, it must be supplied with the name of the script file it should load and run. See \ref Running "Running Urho3D" for more information, but for a quick test you can try the following arguments: Scripts/TestScene.as -w
 
 Note: some SM2.0 shaders in Urho3D reach exactly the arithmetic instruction count limit. The fxc.exe in newer DirectX SDK's may fail to compile them. At least the February 2010 SDK is known to work.
 
@@ -27,7 +27,7 @@ The main executable Urho3D.exe in the Bin directory contains all the engine runt
 
 Urho3D.exe <scriptfilename> [options]
 
-The scripting language used is AngelScript (http://www.angelcode.com/angelscript); the script files have .as extension and need to be placed under either the Data or CoreData subdirectories so that Urho3D.exe can find them. An application script is required to have the function void Start(), which will be executed before starting the engine main loop. It is this function's responsibility to initialize the application and to hook up to any necessary \subpage Events "events", such as the update that happens every frame.
+The scripting language used is AngelScript (http://www.angelcode.com/angelscript); the script files have .as extension and need to be placed under either the Data or CoreData subdirectories so that Urho3D.exe can find them. An application script is required to have the function void Start(), which will be executed before starting the engine main loop. It is this function's responsibility to initialize the application and to hook up to any necessary \ref Events "events", such as the update that happens every frame.
 
 Currently, two example application scripts exist:
 
@@ -94,17 +94,17 @@ Urho3D consists of several static libraries that are independent where possible:
 The libraries are the following:
 
 - Math. Provides vector & quaternion types and geometric shapes used in intersection tests.
-- Core. Provides the execution Context, the base class Object for typed objects, object factories, \subpage Event "event handling", threading and profiling.
+- Core. Provides the execution Context, the base class Object for typed objects, object factories, \ref Event "event handling", threading and profiling.
 - IO. Provides file system access, stream input/output and logging.
-- Resource. Provides the ResourceCache and the base resource types, including XML documents.
-- Scene. Provides Node and Component classes, from which Urho3D scenes (or worlds, maps, levels) are built.
-- Graphics. Provides application window handling and 3D rendering capabilities.
-- Input. Provides mouse & keyboard input in both polled and event-based mode.
-- Network. Provides low-level client-server networking functionality.
-- Audio. Provides the audio subsystem and playback of .wav & .ogg sounds in either 2D or 3D.
+- %Resource. Provides the ResourceCache and the base resource types, including XML documents.
+- %Scene. Provides Node and Component classes, from which Urho3D scenes are built.
+- %Graphics. Provides application window handling and 3D rendering capabilities.
+- %Input. Provides mouse & keyboard input in both polled and event-based mode.
+- %Network. Provides low-level client-server networking functionality.
+- %Audio. Provides the audio subsystem and playback of .wav & .ogg sounds in either 2D or 3D.
 - Physics. Provides physics simulation.
-- Script. Provides scripting support using the AngelScript language.
-- Engine. Instantiates the subsystems from the libraries above, and manages the main loop iteration.
+- %Script. Provides scripting support using the AngelScript language.
+- %Engine. Instantiates the subsystems from the libraries above, and manages the main loop iteration.
 
 Urho3D.exe uses just the Engine & Script libraries to start up the subsystems and to load the script file specified on the command line; however due to the cmake build process all the libraries above get automatically linked (as Engine library depends on all of them.)
 
@@ -116,7 +116,7 @@ The third-party libraries are used for the following functionality:
 - ENet: UDP networking
 - FreeType: font rendering
 - Open Asset Import Library: reading various 3D file formats
-- Open Dynamics Engine: physics simulation implementation
+- Open Dynamics %Engine: physics simulation implementation
 - StanHull: convex hull generation from triangle meshes, used for physics collision shapes
 - stb_image: image loading
 - stb_vorbis: Ogg Vorbis decoding
@@ -133,7 +133,7 @@ Urho3D uses the following conventions:
 
 - Clockwise vertices define a front face.
 
-- Audio volume is specified from 0.0 (silence) to 1.0 (full volume)
+- %Audio volume is specified from 0.0 (silence) to 1.0 (full volume)
 
 - Axis aligned bounding boxes are used in all bounding tests, except for raycast into bone collision boxes, and testing whether a Camera is inside a Zone; in those cases oriented bounding boxes are used instead.
 
@@ -145,7 +145,7 @@ Urho3D uses the following conventions:
 
 - In the script API, properties are used whenever appropriate instead of Set... and Get... functions. If the setter and getter require index parameters, the property will use array-style indexing, and its name will be in plural. For example model->SetMaterial(0, myMaterial) in C++ would become model.materials[0] = myMaterial in script.
 
-For more details related to the C++ coding style, see also \subpage CodingConventions "Coding conventions".
+For more details related to the C++ coding style, see also \ref CodingConventions "Coding conventions".
 
 
 \page ScriptQuickstart Quickstart in script
@@ -257,7 +257,7 @@ To try out the application, save it as HelloWorld.as in the Bin/Data/Scripts dir
 
 \page CppQuickstart Quickstart in C++
 
-This example shows how to create an Urho3D C++ application from the ground up. The actual functionality will be the same as in \subpage ScriptQuickstart "Quickstart in script"; it is strongly recommended that you familiarize yourself with it first.
+This example shows how to create an Urho3D C++ application from the ground up. The actual functionality will be the same as in \ref ScriptQuickstart "Quickstart in script"; it is strongly recommended that you familiarize yourself with it first.
 
 To start with, create a subdirectory "HelloWorld" into the Urho3D root directory, and add the following line to the root directory's CMakeLists.txt file:
 
@@ -435,7 +435,7 @@ void HelloWorld::SubscribeToEvents()
 }
 \endcode
 
-Unlike in script, in C++ there is no choice - the event handler function must always have the signature "void HandleEvent(StringHash eventType, VariantMap& eventData)". Note that to prevent name clashes, the event's name is used as a namespace for the event parameter hashes:
+Unlike in script, in C++ the event handler function must always have the signature "void HandleEvent(StringHash eventType, VariantMap& eventData)". Note that when accessing event parameters, the event's name is used as a namespace to prevent name clashes:
 
 \code
 void HelloWorld::HandleUpdate(StringHash eventType, VariantMap& eventData)

+ 30 - 30
Docs/Urho3D.dox

@@ -6,34 +6,34 @@ Urho3D is a lightweight, object-oriented Win32 / Direct3D9 rendering and game en
 
 For getting started, see:
 
-\subpage Building "Building Urho3D" <br>
-\subpage Running "Running Urho3D" <br>
-\subpage Structure "Overall structure" <br>
-\subpage Conventions "Conventions" <br>
-\subpage ScriptQuickstart "Quickstart in script" <br>
-\subpage CppQuickstart "Quickstart in C++" <br>
+\ref Building "Building Urho3D" <br>
+\ref Running "Running Urho3D" <br>
+\ref Structure "Overall structure" <br>
+\ref Conventions "Conventions" <br>
+\ref ScriptQuickstart "Quickstart in script" <br>
+\ref CppQuickstart "Quickstart in C++" <br>
 
 For further reference, see:
 
-\subpage ObjectTypes "Object types and factories" <br>
-\subpage Subsystems "Subsystems" <br>
-\subpage Events "Events" <br>
-\subpage MainLoop "Main loop and frame update" <br>
-\subpage SceneModel "Scene model" <br>
-\subpage Resources "Resources" <br>
-\subpage Scripting "Scripting" <br>
-\subpage Rendering "Rendering" <br>
-\subpage Input "Input" <br>
-\subpage Audio "Audio" <br>
-\subpage Physics "Physics" <br>
-\subpage UI "User interface" <br>
-\subpage Serialization "Serialization" <br>
-\subpage Network "Networking" <br>
-\subpage Tools "Tools" <br>
-\subpage FileFormats "Custom file formats" <br>
-\subpage CodingConventions "Coding conventions" <br>
-
-For credits, copyright and licensing information, see \subpage Credits & \subpage License.
+\ref ObjectTypes "Object types and factories" <br>
+\ref Subsystems "Subsystems" <br>
+\ref Events "Events" <br>
+\ref MainLoop "Main loop and frame update" <br>
+\ref SceneModel "Scene model" <br>
+\ref Resources "Resources" <br>
+\ref Scripting "Scripting" <br>
+\ref Rendering "Rendering" <br>
+\ref Input "Input" <br>
+\ref Audio "Audio" <br>
+\ref Physics "Physics" <br>
+\ref UI "User interface" <br>
+\ref Serialization "Serialization" <br>
+\ref Network "Networking" <br>
+\ref Tools "Tools" <br>
+\ref FileFormats "Custom file formats" <br>
+\ref CodingConventions "Coding conventions" <br>
+
+For credits, copyright and licensing information, see \ref Credits & \ref License.
 
 
 \page Credits Credits
@@ -46,17 +46,17 @@ Urho3D is greatly inspired by OGRE (http://www.ogre3d.org/) and Horde3D (http://
 - Tangent generation from Terathon (http://www.terathon.com/code/tangent.html)
 - Fast, Minimum Storage Ray/Triangle Intersection by M&ouml;ller & Trumbore (http://www.graphics.cornell.edu/pubs/1997/MT97.pdf)
 - Linear-Speed Vertex Cache Optimisation by Tom Forsyth (http://home.comcast.net/~tom_forsyth/papers/fast_vert_cache_opt.html)
-- Software rasterization of triangles based on Chris Hecker's Perspective Texture Mapping series in the Game Developer magazine (http://chrishecker.com/Miscellaneous_Technical_Articles)
+- Software rasterization of triangles based on Chris Hecker's Perspective %Texture Mapping series in the Game Developer magazine (http://chrishecker.com/Miscellaneous_Technical_Articles)
 - Networked Physics by Glenn Fiedler (http://gafferongames.com/game-physics/networked-physics/)
 - Euler Angle Formulas by David Eberly (http://www.geometrictools.com/Documentation/EulerAngles.pdf)
 
 Urho3D uses the following third-party libraries:
 
 - AngelScript 2.20.2 (http://www.angelcode.com/angelscript/)
-- ENet 1.3.0 (http://enet.bespin.org/)
+- ENet 1.3.1 (http://enet.bespin.org/)
 - FreeType 2.3.12 (http://www.freetype.org/)
 - Open Asset Import Library 2.0.863 (http://assimp.sourceforge.net/)
-- Open Dynamics Engine, svn rev 1770 (http://www.ode.org/)
+- Open Dynamics %Engine, svn rev 1770 (http://www.ode.org/)
 - StanHull (http://codesuppository.blogspot.com/2006/03/john-ratcliffs-code-suppository-blog.html)
 - stb_image 1.29 (http://nothings.org/)
 - stb_vorbis 0.99996 (http://nothings.org/)
@@ -64,14 +64,14 @@ Urho3D uses the following third-party libraries:
 
 Ninja model, BlueHighway font and smoke/flare/status bar textures are from OGRE.
 
-Jack and mushroom models are from the realXtend project (http:///www.realxtend.org/).
+Jack and mushroom models are from the realXtend project (http://www.realxtend.org/).
 
 NinjaSnowWar sounds by Veli-Pekka T&auml;til&auml;.
 
 
 \page License
 
-Urho3D Engine
+Urho3D %Engine
 Copyright (c) 2008-2011 Lasse &Ouml;&ouml;rni
 
 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:

+ 92 - 0
ThirdParty/ENet/ChangeLog

@@ -0,0 +1,92 @@
+ENet 1.3.1 (February 10, 2011):
+
+* fixed bug in tracking of reliable data in transit
+* reliable data window size now scales with the throttle
+* fixed bug in fragment length calculation when checksums are used
+
+ENet 1.3.0 (June 5, 2010):
+
+* enet_host_create() now requires the channel limit to be specified as
+a parameter
+* enet_host_connect() now accepts a data parameter which is supplied 
+to the receiving receiving host in the event data field for a connect event
+* added an adaptive order-2 PPM range coder as a built-in compressor option
+which can be set with enet_host_compress_with_range_coder()
+* added support for packet compression configurable with a callback
+* improved session number handling to not rely on the packet checksum
+field, saving 4 bytes per packet unless the checksum option is used
+* removed the dependence on the rand callback for session number handling
+
+Caveats: This version is not protocol compatible with the 1.2 series or 
+earlier. The enet_host_connect and enet_host_create API functions require
+supplying additional parameters.
+
+ENet 1.2.2 (June 5, 2010):
+
+* checksum functionality is now enabled by setting a checksum callback
+inside ENetHost instead of being a configure script option
+* added totalSentData, totalSentPackets, totalReceivedData, and
+totalReceivedPackets counters inside ENetHost for getting usage
+statistics
+* added enet_host_channel_limit() for limiting the maximum number of
+channels allowed by connected peers
+* now uses dispatch queues for event dispatch rather than potentially
+unscalable array walking
+* added no_memory callback that is called when a malloc attempt fails,
+such that if no_memory returns rather than aborts (the default behavior),
+then the error is propagated to the return value of the API calls
+* now uses packed attribute for protocol structures on platforms with 
+strange alignment rules
+* improved autoconf build system contributed by Nathan Brink allowing 
+for easier building as a shared library
+
+Caveats: If you were using the compile-time option that enabled checksums,
+make sure to set the checksum callback inside ENetHost to enet_crc32 to
+regain the old behavior. The ENetCallbacks structure has added new fields,
+so make sure to clear the structure to zero before use if 
+using enet_initialize_with_callbacks().
+
+ENet 1.2.1 (November 12, 2009):
+
+* fixed bug that could cause disconnect events to be dropped
+* added thin wrapper around select() for portable usage
+* added ENET_SOCKOPT_REUSEADDR socket option
+* factored enet_socket_bind()/enet_socket_listen() out of enet_socket_create()
+* added contributed Code::Blocks build file
+
+ENet 1.2 (February 12, 2008):
+
+* fixed bug in VERIFY_CONNECT acknowledgement that could cause connect
+attempts to occasionally timeout
+* fixed acknowledgements to check both the outgoing and sent queues
+when removing acknowledged packets
+* fixed accidental bit rot in the MSVC project file
+* revised sequence number overflow handling to address some possible
+disconnect bugs
+* added enet_host_check_events() for getting only local queued events
+* factored out socket option setting into enet_socket_set_option() so
+that socket options are now set separately from enet_socket_create()
+
+Caveats: While this release is superficially protocol compatible with 1.1,
+differences in the sequence number overflow handling can potentially cause
+random disconnects.
+
+ENet 1.1 (June 6, 2007):
+
+* optional CRC32 just in case someone needs a stronger checksum than UDP 
+provides (--enable-crc32 configure option)
+* the size of packet headers are half the size they used to be (so less 
+overhead when sending small packets)
+* enet_peer_disconnect_later() that waits till all queued outgoing 
+packets get sent before issuing an actual disconnect
+* freeCallback field in individual packets for notification of when a 
+packet is about to be freed
+* ENET_PACKET_FLAG_NO_ALLOCATE for supplying pre-allocated data to a 
+packet (can be used in concert with freeCallback to support some custom 
+allocation schemes that the normal memory allocation callbacks would 
+normally not allow)
+* enet_address_get_host_ip() for printing address numbers
+* promoted the enet_socket_*() functions to be part of the API now
+* a few stability/crash fixes
+
+

+ 7 - 7
ThirdParty/ENet/LICENSE

@@ -1,7 +1,7 @@
-Copyright (c) 2002-2010 Lee Salzman
-
-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:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
-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.
+Copyright (c) 2002-2011 Lee Salzman
+
+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:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+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.

+ 15 - 15
ThirdParty/ENet/README

@@ -1,15 +1,15 @@
-Please visit the ENet homepage at http://enet.bespin.org for installation
-and usage instructions.
-
-If you obtained this package from CVS, the quick description on how to build
-is:
-
-# Generate the build system.
-
-autoreconf -vfi
-
-# Compile and install the library.
-
-./configure && make && make install
-
-
+Please visit the ENet homepage at http://enet.bespin.org for installation
+and usage instructions.
+
+If you obtained this package from CVS, the quick description on how to build
+is:
+
+# Generate the build system.
+
+autoreconf -vfi
+
+# Compile and install the library.
+
+./configure && make && make install
+
+

+ 47 - 47
ThirdParty/ENet/callbacks.c

@@ -1,47 +1,47 @@
-/** 
- @file callbacks.c
- @brief ENet callback functions
-*/
-#define ENET_BUILDING_LIB 1
-#include "enet/enet.h"
-
-static ENetCallbacks callbacks = { malloc, free, abort };
-
-int
-enet_initialize_with_callbacks (ENetVersion version, const ENetCallbacks * inits)
-{
-   if (version < ENET_VERSION_CREATE (1, 3, 0))
-     return -1;
-
-   if (inits -> malloc != NULL || inits -> free != NULL)
-   {
-      if (inits -> malloc == NULL || inits -> free == NULL)
-        return -1;
-
-      callbacks.malloc = inits -> malloc;
-      callbacks.free = inits -> free;
-   }
-      
-   if (inits -> no_memory != NULL)
-     callbacks.no_memory = inits -> no_memory;
-
-   return enet_initialize ();
-}
-           
-void *
-enet_malloc (size_t size)
-{
-   void * memory = callbacks.malloc (size);
-
-   if (memory == NULL)
-     callbacks.no_memory ();
-
-   return memory;
-}
-
-void
-enet_free (void * memory)
-{
-   callbacks.free (memory);
-}
-
+/** 
+ @file callbacks.c
+ @brief ENet callback functions
+*/
+#define ENET_BUILDING_LIB 1
+#include "enet/enet.h"
+
+static ENetCallbacks callbacks = { malloc, free, abort };
+
+int
+enet_initialize_with_callbacks (ENetVersion version, const ENetCallbacks * inits)
+{
+   if (version < ENET_VERSION_CREATE (1, 3, 0))
+     return -1;
+
+   if (inits -> malloc != NULL || inits -> free != NULL)
+   {
+      if (inits -> malloc == NULL || inits -> free == NULL)
+        return -1;
+
+      callbacks.malloc = inits -> malloc;
+      callbacks.free = inits -> free;
+   }
+      
+   if (inits -> no_memory != NULL)
+     callbacks.no_memory = inits -> no_memory;
+
+   return enet_initialize ();
+}
+           
+void *
+enet_malloc (size_t size)
+{
+   void * memory = callbacks.malloc (size);
+
+   if (memory == NULL)
+     callbacks.no_memory ();
+
+   return memory;
+}
+
+void
+enet_free (void * memory)
+{
+   callbacks.free (memory);
+}
+

+ 654 - 654
ThirdParty/ENet/compress.c

@@ -1,654 +1,654 @@
-/** 
- @file compress.c
- @brief An adaptive order-2 PPM range coder
-*/
-#define ENET_BUILDING_LIB 1
-#include <string.h>
-#include "enet/enet.h"
-
-typedef struct _ENetSymbol
-{
-    /* binary indexed tree of symbols */
-    enet_uint8 value;
-    enet_uint8 count;
-    enet_uint16 under;
-    enet_uint16 left, right;
-
-    /* context defined by this symbol */
-    enet_uint16 symbols;
-    enet_uint16 escapes;
-    enet_uint16 total;
-    enet_uint16 parent; 
-} ENetSymbol;
-
-/* adaptation constants tuned aggressively for small packet sizes rather than large file compression */
-enum
-{
-    ENET_RANGE_CODER_TOP    = 1<<24,
-    ENET_RANGE_CODER_BOTTOM = 1<<16,
-
-    ENET_CONTEXT_SYMBOL_DELTA = 3,
-    ENET_CONTEXT_SYMBOL_MINIMUM = 1,
-    ENET_CONTEXT_ESCAPE_MINIMUM = 1,
-
-    ENET_SUBCONTEXT_ORDER = 2,
-    ENET_SUBCONTEXT_SYMBOL_DELTA = 2,
-    ENET_SUBCONTEXT_ESCAPE_DELTA = 5
-};
-
-/* context exclusion roughly halves compression speed, so disable for now */
-#undef ENET_CONTEXT_EXCLUSION
-
-typedef struct _ENetRangeCoder
-{
-    /* only allocate enough symbols for reasonable MTUs, would need to be larger for large file compression */
-    ENetSymbol symbols[4096];
-} ENetRangeCoder;
-
-void *
-enet_range_coder_create (void)
-{
-    ENetRangeCoder * rangeCoder = (ENetRangeCoder *) enet_malloc (sizeof (ENetRangeCoder));
-    if (rangeCoder == NULL)
-      return NULL;
-
-    return rangeCoder;
-}
-
-void
-enet_range_coder_destroy (void * context)
-{
-    ENetRangeCoder * rangeCoder = (ENetRangeCoder *) context;
-    if (rangeCoder == NULL)
-      return;
-
-    enet_free (rangeCoder);
-}
-
-#define ENET_SYMBOL_CREATE(symbol, value_, count_) \
-{ \
-    symbol = & rangeCoder -> symbols [nextSymbol ++]; \
-    symbol -> value = value_; \
-    symbol -> count = count_; \
-    symbol -> under = count_; \
-    symbol -> left = 0; \
-    symbol -> right = 0; \
-    symbol -> symbols = 0; \
-    symbol -> escapes = 0; \
-    symbol -> total = 0; \
-    symbol -> parent = 0; \
-}
-
-#define ENET_CONTEXT_CREATE(context, escapes_, minimum) \
-{ \
-    ENET_SYMBOL_CREATE (context, 0, 0); \
-    (context) -> escapes = escapes_; \
-    (context) -> total = escapes_ + 256*minimum; \
-    (context) -> symbols = 0; \
-}
-
-static enet_uint16
-enet_symbol_rescale (ENetSymbol * symbol)
-{
-    enet_uint16 total = 0;
-    for (;;)
-    {
-        symbol -> count -= symbol->count >> 1;
-        symbol -> under = symbol -> count;
-        if (symbol -> left)
-          symbol -> under += enet_symbol_rescale (symbol + symbol -> left);
-        total += symbol -> under;
-        if (! symbol -> right) break;
-        symbol += symbol -> right;
-    } 
-    return total;
-}
-
-#define ENET_CONTEXT_RESCALE(context, minimum) \
-{ \
-    (context) -> total = (context) -> symbols ? enet_symbol_rescale ((context) + (context) -> symbols) : 0; \
-    (context) -> escapes -= (context) -> escapes >> 1; \
-    (context) -> total += (context) -> escapes + 256*minimum; \
-}
-
-#define ENET_RANGE_CODER_OUTPUT(value) \
-{ \
-    if (outData >= outEnd) \
-      return 0; \
-    * outData ++ = value; \
-}
-
-#define ENET_RANGE_CODER_ENCODE(under, count, total) \
-{ \
-    encodeRange /= (total); \
-    encodeLow += (under) * encodeRange; \
-    encodeRange *= (count); \
-    for (;;) \
-    { \
-        if((encodeLow ^ (encodeLow + encodeRange)) >= ENET_RANGE_CODER_TOP) \
-        { \
-            if(encodeRange >= ENET_RANGE_CODER_BOTTOM) break; \
-            encodeRange = -encodeLow & (ENET_RANGE_CODER_BOTTOM - 1); \
-        } \
-        ENET_RANGE_CODER_OUTPUT (encodeLow >> 24); \
-        encodeRange <<= 8; \
-        encodeLow <<= 8; \
-    } \
-}
-
-#define ENET_RANGE_CODER_FLUSH \
-{ \
-    while (encodeLow) \
-    { \
-        ENET_RANGE_CODER_OUTPUT (encodeLow >> 24); \
-        encodeLow <<= 8; \
-    } \
-}
-
-#define ENET_RANGE_CODER_FREE_SYMBOLS \
-{ \
-    if (nextSymbol >= sizeof (rangeCoder -> symbols) / sizeof (ENetSymbol) - ENET_SUBCONTEXT_ORDER ) \
-    { \
-        nextSymbol = 0; \
-        ENET_CONTEXT_CREATE (root, ENET_CONTEXT_ESCAPE_MINIMUM, ENET_CONTEXT_SYMBOL_MINIMUM); \
-        predicted = 0; \
-        order = 0; \
-    } \
-}
-
-#define ENET_CONTEXT_ENCODE(context, symbol_, value_, under_, count_, update, minimum) \
-{ \
-    under_ = value*minimum; \
-    count_ = minimum; \
-    if (! (context) -> symbols) \
-    { \
-        ENET_SYMBOL_CREATE (symbol_, value_, update); \
-        (context) -> symbols = symbol_ - (context); \
-    } \
-    else \
-    { \
-        ENetSymbol * node = (context) + (context) -> symbols; \
-        for (;;) \
-        { \
-            if (value_ < node -> value) \
-            { \
-                node -> under += update; \
-                if (node -> left) { node += node -> left; continue; } \
-                ENET_SYMBOL_CREATE (symbol_, value_, update); \
-                node -> left = symbol_ - node; \
-            } \
-            else \
-            if (value_ > node -> value) \
-            { \
-                under_ += node -> under; \
-                if (node -> right) { node += node -> right; continue; } \
-                ENET_SYMBOL_CREATE (symbol_, value_, update); \
-                node -> right = symbol_ - node; \
-            } \
-            else \
-            { \
-                count_ += node -> count; \
-                under_ += node -> under - node -> count; \
-                node -> under += update; \
-                node -> count += update; \
-                symbol_ = node; \
-            } \
-            break; \
-        } \
-    } \
-}
-
-#ifdef ENET_CONTEXT_EXCLUSION
-static const ENetSymbol emptyContext = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
-
-#define ENET_CONTEXT_WALK(context, body) \
-{ \
-    const ENetSymbol * node = (context) + (context) -> symbols; \
-    const ENetSymbol * stack [256]; \
-    size_t stackSize = 0; \
-    while (node -> left) \
-    { \
-        stack [stackSize ++] = node; \
-        node += node -> left; \
-    } \
-    for (;;) \
-    { \
-        body; \
-        if (node -> right) \
-        { \
-            node += node -> right; \
-            while (node -> left) \
-            { \
-                stack [stackSize ++] = node; \
-                node += node -> left; \
-            } \
-        } \
-        else \
-        if (stackSize <= 0) \
-            break; \
-        else \
-            node = stack [-- stackSize]; \
-    } \
-}
-
-#define ENET_CONTEXT_ENCODE_EXCLUDE(context, value_, under, total, minimum) \
-ENET_CONTEXT_WALK(context, { \
-    if (node -> value != value_) \
-    { \
-        enet_uint16 parentCount = rangeCoder -> symbols [node -> parent].count + minimum; \
-        if (node -> value < value_) \
-          under -= parentCount; \
-        total -= parentCount; \
-    } \
-})
-#endif
-
-size_t
-enet_range_coder_compress (void * context, const ENetBuffer * inBuffers, size_t inBufferCount, size_t inLimit, enet_uint8 * outData, size_t outLimit)
-{
-    ENetRangeCoder * rangeCoder = (ENetRangeCoder *) context;
-    enet_uint8 * outStart = outData, * outEnd = & outData [outLimit];
-    const enet_uint8 * inData, * inEnd;
-    enet_uint32 encodeLow = 0, encodeRange = ~0;
-    ENetSymbol * root;
-    enet_uint16 predicted = 0;
-    size_t order = 0, nextSymbol = 0;
-
-    if (rangeCoder == NULL || inBufferCount <= 0 || inLimit <= 0)
-      return 0;
-
-    inData = (const enet_uint8 *) inBuffers -> data;
-    inEnd = & inData [inBuffers -> dataLength];
-    inBuffers ++;
-    inBufferCount --;
-
-    ENET_CONTEXT_CREATE (root, ENET_CONTEXT_ESCAPE_MINIMUM, ENET_CONTEXT_SYMBOL_MINIMUM);
-
-    for (;;)
-    {
-        ENetSymbol * subcontext, * symbol;
-#ifdef ENET_CONTEXT_EXCLUSION
-        const ENetSymbol * childContext = & emptyContext;
-#endif
-        enet_uint8 value;
-        enet_uint16 count, under, * parent = & predicted, total;
-        if (inData >= inEnd)
-        {
-            if (inBufferCount <= 0)
-              break;
-            inData = (const enet_uint8 *) inBuffers -> data;
-            inEnd = & inData [inBuffers -> dataLength];
-            inBuffers ++;
-            inBufferCount --;
-        }
-        value = * inData ++;
-    
-        for (subcontext = & rangeCoder -> symbols [predicted]; 
-             subcontext != root; 
-#ifdef ENET_CONTEXT_EXCLUSION
-             childContext = subcontext, 
-#endif
-                subcontext = & rangeCoder -> symbols [subcontext -> parent])
-        {
-            ENET_CONTEXT_ENCODE (subcontext, symbol, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0);
-            * parent = symbol - rangeCoder -> symbols;
-            parent = & symbol -> parent;
-            total = subcontext -> total;
-#ifdef ENET_CONTEXT_EXCLUSION
-            if (childContext -> total > ENET_SUBCONTEXT_SYMBOL_DELTA + ENET_SUBCONTEXT_ESCAPE_DELTA)
-              ENET_CONTEXT_ENCODE_EXCLUDE (childContext, value, under, total, 0);
-#endif
-            if (count > 0)
-            {
-                ENET_RANGE_CODER_ENCODE (subcontext -> escapes + under, count, total);
-            }
-            else
-            {
-                if (subcontext -> escapes > 0 && subcontext -> escapes < total) 
-                    ENET_RANGE_CODER_ENCODE (0, subcontext -> escapes, total); 
-                subcontext -> escapes += ENET_SUBCONTEXT_ESCAPE_DELTA;
-                subcontext -> total += ENET_SUBCONTEXT_ESCAPE_DELTA;
-            }
-            subcontext -> total += ENET_SUBCONTEXT_SYMBOL_DELTA;
-            if (count > 0xFF - 2*ENET_SUBCONTEXT_SYMBOL_DELTA || subcontext -> total > ENET_RANGE_CODER_BOTTOM - 0x100)
-              ENET_CONTEXT_RESCALE (subcontext, 0);
-            if (count > 0) goto nextInput;
-        }
-
-        ENET_CONTEXT_ENCODE (root, symbol, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM);
-        * parent = symbol - rangeCoder -> symbols;
-        parent = & symbol -> parent;
-        total = root -> total;
-#ifdef ENET_CONTEXT_EXCLUSION
-        if (childContext -> total > ENET_SUBCONTEXT_SYMBOL_DELTA + ENET_SUBCONTEXT_ESCAPE_DELTA)
-          ENET_CONTEXT_ENCODE_EXCLUDE (childContext, value, under, total, ENET_CONTEXT_SYMBOL_MINIMUM); 
-#endif
-        ENET_RANGE_CODER_ENCODE (root -> escapes + under, count, total);
-        root -> total += ENET_CONTEXT_SYMBOL_DELTA; 
-        if (count > 0xFF - 2*ENET_CONTEXT_SYMBOL_DELTA + ENET_CONTEXT_SYMBOL_MINIMUM || root -> total > ENET_RANGE_CODER_BOTTOM - 0x100)
-          ENET_CONTEXT_RESCALE (root, ENET_CONTEXT_SYMBOL_MINIMUM);
-
-    nextInput:
-        if (order >= ENET_SUBCONTEXT_ORDER) 
-          predicted = rangeCoder -> symbols [predicted].parent;
-        else 
-          order ++;
-        ENET_RANGE_CODER_FREE_SYMBOLS;
-    }
-
-    ENET_RANGE_CODER_FLUSH;
-
-    return (size_t) (outData - outStart);
-}
-
-#define ENET_RANGE_CODER_SEED \
-{ \
-    if (inData < inEnd) decodeCode |= * inData ++ << 24; \
-    if (inData < inEnd) decodeCode |= * inData ++ << 16; \
-    if (inData < inEnd) decodeCode |= * inData ++ << 8; \
-    if (inData < inEnd) decodeCode |= * inData ++; \
-}
-
-#define ENET_RANGE_CODER_READ(total) ((decodeCode - decodeLow) / (decodeRange /= (total)))
-
-#define ENET_RANGE_CODER_DECODE(under, count, total) \
-{ \
-    decodeLow += (under) * decodeRange; \
-    decodeRange *= (count); \
-    for (;;) \
-    { \
-        if((decodeLow ^ (decodeLow + decodeRange)) >= ENET_RANGE_CODER_TOP) \
-        { \
-            if(decodeRange >= ENET_RANGE_CODER_BOTTOM) break; \
-            decodeRange = -decodeLow & (ENET_RANGE_CODER_BOTTOM - 1); \
-        } \
-        decodeCode <<= 8; \
-        if (inData < inEnd) \
-          decodeCode |= * inData ++; \
-        decodeRange <<= 8; \
-        decodeLow <<= 8; \
-    } \
-}
-
-#define ENET_CONTEXT_DECODE(context, symbol_, code, value_, under_, count_, update, minimum, createRoot, visitNode, createRight, createLeft) \
-{ \
-    under_ = 0; \
-    count_ = minimum; \
-    if (! (context) -> symbols) \
-    { \
-        createRoot; \
-    } \
-    else \
-    { \
-        ENetSymbol * node = (context) + (context) -> symbols; \
-        for (;;) \
-        { \
-            enet_uint16 after = under_ + node -> under + (node -> value + 1)*minimum, before = node -> count + minimum; \
-            visitNode; \
-            if (code >= after) \
-            { \
-                under_ += node -> under; \
-                if (node -> right) { node += node -> right; continue; } \
-                createRight; \
-            } \
-            else \
-            if (code < after - before) \
-            { \
-                node -> under += update; \
-                if (node -> left) { node += node -> left; continue; } \
-                createLeft; \
-            } \
-            else \
-            { \
-                value_ = node -> value; \
-                count_ += node -> count; \
-                under_ = after - before; \
-                node -> under += update; \
-                node -> count += update; \
-                symbol_ = node; \
-            } \
-            break; \
-        } \
-    } \
-}
-
-#define ENET_CONTEXT_TRY_DECODE(context, symbol_, code, value_, under_, count_, update, minimum, exclude) \
-ENET_CONTEXT_DECODE (context, symbol_, code, value_, under_, count_, update, minimum, return 0, exclude (node -> value, after, before), return 0, return 0)
-
-#define ENET_CONTEXT_ROOT_DECODE(context, symbol_, code, value_, under_, count_, update, minimum, exclude) \
-ENET_CONTEXT_DECODE (context, symbol_, code, value_, under_, count_, update, minimum, \
-    { \
-        value_ = code / minimum; \
-        under_ = code - code%minimum; \
-        ENET_SYMBOL_CREATE (symbol_, value_, update); \
-        (context) -> symbols = symbol_ - (context); \
-    }, \
-    exclude (node -> value, after, before), \
-    { \
-        value_ = node->value + 1 + (code - after)/minimum; \
-        under_ = code - (code - after)%minimum; \
-        ENET_SYMBOL_CREATE (symbol_, value_, update); \
-        node -> right = symbol_ - node; \
-    }, \
-    { \
-        value_ = node->value - 1 - (after - before - code - 1)/minimum; \
-        under_ = code - (after - before - code - 1)%minimum; \
-        ENET_SYMBOL_CREATE (symbol_, value_, update); \
-        node -> left = symbol_ - node; \
-    }) \
-
-#ifdef ENET_CONTEXT_EXCLUSION
-typedef struct _ENetExclude
-{
-    enet_uint8 value;
-    enet_uint16 under;
-} ENetExclude;
-
-#define ENET_CONTEXT_DECODE_EXCLUDE(context, total, minimum) \
-{ \
-    enet_uint16 under = 0; \
-    nextExclude = excludes; \
-    ENET_CONTEXT_WALK (context, { \
-        under += rangeCoder -> symbols [node -> parent].count + minimum; \
-        nextExclude -> value = node -> value; \
-        nextExclude -> under = under; \
-        nextExclude ++; \
-    }); \
-    total -= under; \
-}
-
-#define ENET_CONTEXT_EXCLUDED(value_, after, before) \
-{ \
-    size_t low = 0, high = nextExclude - excludes; \
-    for(;;) \
-    { \
-        size_t mid = (low + high) >> 1; \
-        const ENetExclude * exclude = & excludes [mid]; \
-        if (value_ < exclude -> value) \
-        { \
-            if (low + 1 < high) \
-            { \
-                high = mid; \
-                continue; \
-            } \
-            if (exclude > excludes) \
-              after -= exclude [-1].under; \
-        } \
-        else \
-        { \
-            if (value_ > exclude -> value) \
-            { \
-                if (low + 1 < high) \
-                { \
-                    low = mid; \
-                    continue; \
-                } \
-            } \
-            else \
-              before = 0; \
-            after -= exclude -> under; \
-        } \
-        break; \
-    } \
-}
-#endif
-
-#define ENET_CONTEXT_NOT_EXCLUDED(value_, after, before)
-
-size_t
-enet_range_coder_decompress (void * context, const enet_uint8 * inData, size_t inLimit, enet_uint8 * outData, size_t outLimit)
-{
-    ENetRangeCoder * rangeCoder = (ENetRangeCoder *) context;
-    enet_uint8 * outStart = outData, * outEnd = & outData [outLimit];
-    const enet_uint8 * inEnd = & inData [inLimit];
-    enet_uint32 decodeLow = 0, decodeCode = 0, decodeRange = ~0;
-    ENetSymbol * root;
-    enet_uint16 predicted = 0;
-    size_t order = 0, nextSymbol = 0;
-#ifdef ENET_CONTEXT_EXCLUSION
-    ENetExclude excludes [256];
-    ENetExclude * nextExclude = excludes;
-#endif
-  
-    if (rangeCoder == NULL || inLimit <= 0)
-      return 0;
-
-    ENET_CONTEXT_CREATE (root, ENET_CONTEXT_ESCAPE_MINIMUM, ENET_CONTEXT_SYMBOL_MINIMUM);
-
-    ENET_RANGE_CODER_SEED;
-
-    for (;;)
-    {
-        ENetSymbol * subcontext, * symbol, * patch;
-#ifdef ENET_CONTEXT_EXCLUSION
-        const ENetSymbol * childContext = & emptyContext;
-#endif
-        enet_uint8 value = 0;
-        enet_uint16 code, under, count, bottom, * parent = & predicted, total;
-
-        for (subcontext = & rangeCoder -> symbols [predicted];
-             subcontext != root;
-#ifdef ENET_CONTEXT_EXCLUSION
-             childContext = subcontext, 
-#endif
-                subcontext = & rangeCoder -> symbols [subcontext -> parent])
-        {
-            if (subcontext -> escapes <= 0)
-              continue;
-            total = subcontext -> total;
-#ifdef ENET_CONTEXT_EXCLUSION
-            if (childContext -> total > 0) 
-              ENET_CONTEXT_DECODE_EXCLUDE (childContext, total, 0); 
-#endif
-            if (subcontext -> escapes >= total)
-              continue;
-            code = ENET_RANGE_CODER_READ (total);
-            if (code < subcontext -> escapes) 
-            {
-                ENET_RANGE_CODER_DECODE (0, subcontext -> escapes, total); 
-                continue;
-            }
-            code -= subcontext -> escapes;
-#ifdef ENET_CONTEXT_EXCLUSION
-            if (childContext -> total > 0)
-            {
-                ENET_CONTEXT_TRY_DECODE (subcontext, symbol, code, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0, ENET_CONTEXT_EXCLUDED); 
-            }
-            else
-#endif
-            {
-                ENET_CONTEXT_TRY_DECODE (subcontext, symbol, code, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0, ENET_CONTEXT_NOT_EXCLUDED); 
-            }
-            bottom = symbol - rangeCoder -> symbols;
-            ENET_RANGE_CODER_DECODE (subcontext -> escapes + under, count, total);
-            subcontext -> total += ENET_SUBCONTEXT_SYMBOL_DELTA;
-            if (count > 0xFF - 2*ENET_SUBCONTEXT_SYMBOL_DELTA || subcontext -> total > ENET_RANGE_CODER_BOTTOM - 0x100)
-              ENET_CONTEXT_RESCALE (subcontext, 0);
-            goto patchContexts;
-        }
-
-        total = root -> total;
-#ifdef ENET_CONTEXT_EXCLUSION
-        if (childContext -> total > 0)
-          ENET_CONTEXT_DECODE_EXCLUDE (childContext, total, ENET_CONTEXT_SYMBOL_MINIMUM);  
-#endif
-        code = ENET_RANGE_CODER_READ (total);
-        if (code < root -> escapes)
-        {
-            ENET_RANGE_CODER_DECODE (0, root -> escapes, total);
-            break;
-        }
-        code -= root -> escapes;
-#ifdef ENET_CONTEXT_EXCLUSION
-        if (childContext -> total > 0)
-        {
-            ENET_CONTEXT_ROOT_DECODE (root, symbol, code, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM, ENET_CONTEXT_EXCLUDED); 
-        }
-        else
-#endif
-        {
-            ENET_CONTEXT_ROOT_DECODE (root, symbol, code, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM, ENET_CONTEXT_NOT_EXCLUDED); 
-        }
-        bottom = symbol - rangeCoder -> symbols;
-        ENET_RANGE_CODER_DECODE (root -> escapes + under, count, total);
-        root -> total += ENET_CONTEXT_SYMBOL_DELTA;
-        if (count > 0xFF - 2*ENET_CONTEXT_SYMBOL_DELTA + ENET_CONTEXT_SYMBOL_MINIMUM || root -> total > ENET_RANGE_CODER_BOTTOM - 0x100)
-          ENET_CONTEXT_RESCALE (root, ENET_CONTEXT_SYMBOL_MINIMUM);
-
-    patchContexts:
-        for (patch = & rangeCoder -> symbols [predicted];
-             patch != subcontext;
-             patch = & rangeCoder -> symbols [patch -> parent])
-        {
-            ENET_CONTEXT_ENCODE (patch, symbol, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0);
-            * parent = symbol - rangeCoder -> symbols;
-            parent = & symbol -> parent;
-            if (count <= 0)
-            {
-                patch -> escapes += ENET_SUBCONTEXT_ESCAPE_DELTA;
-                patch -> total += ENET_SUBCONTEXT_ESCAPE_DELTA;
-            }
-            patch -> total += ENET_SUBCONTEXT_SYMBOL_DELTA; 
-            if (count > 0xFF - 2*ENET_SUBCONTEXT_SYMBOL_DELTA || patch -> total > ENET_RANGE_CODER_BOTTOM - 0x100)
-              ENET_CONTEXT_RESCALE (patch, 0);
-        }
-        * parent = bottom;
-
-        ENET_RANGE_CODER_OUTPUT (value);
-
-        if (order >= ENET_SUBCONTEXT_ORDER)
-          predicted = rangeCoder -> symbols [predicted].parent;
-        else
-          order ++;
-        ENET_RANGE_CODER_FREE_SYMBOLS;
-    }
-                        
-    return (size_t) (outData - outStart);
-}
-
-/** @defgroup host ENet host functions
-    @{
-*/
-
-/** Sets the packet compressor the host should use to the default range coder.
-    @param host host to enable the range coder for
-    @returns 0 on success, < 0 on failure
-*/
-int
-enet_host_compress_with_range_coder (ENetHost * host)
-{
-    ENetCompressor compressor;
-    memset (& compressor, 0, sizeof (compressor));
-    compressor.context = enet_range_coder_create();
-    if (compressor.context == NULL)
-      return -1;
-    compressor.compress = enet_range_coder_compress;
-    compressor.decompress = enet_range_coder_decompress;
-    compressor.destroy = enet_range_coder_destroy;
-    enet_host_compress (host, & compressor);
-    return 0;
-}
-    
-/** @} */
-    
-     
+/** 
+ @file compress.c
+ @brief An adaptive order-2 PPM range coder
+*/
+#define ENET_BUILDING_LIB 1
+#include <string.h>
+#include "enet/enet.h"
+
+typedef struct _ENetSymbol
+{
+    /* binary indexed tree of symbols */
+    enet_uint8 value;
+    enet_uint8 count;
+    enet_uint16 under;
+    enet_uint16 left, right;
+
+    /* context defined by this symbol */
+    enet_uint16 symbols;
+    enet_uint16 escapes;
+    enet_uint16 total;
+    enet_uint16 parent; 
+} ENetSymbol;
+
+/* adaptation constants tuned aggressively for small packet sizes rather than large file compression */
+enum
+{
+    ENET_RANGE_CODER_TOP    = 1<<24,
+    ENET_RANGE_CODER_BOTTOM = 1<<16,
+
+    ENET_CONTEXT_SYMBOL_DELTA = 3,
+    ENET_CONTEXT_SYMBOL_MINIMUM = 1,
+    ENET_CONTEXT_ESCAPE_MINIMUM = 1,
+
+    ENET_SUBCONTEXT_ORDER = 2,
+    ENET_SUBCONTEXT_SYMBOL_DELTA = 2,
+    ENET_SUBCONTEXT_ESCAPE_DELTA = 5
+};
+
+/* context exclusion roughly halves compression speed, so disable for now */
+#undef ENET_CONTEXT_EXCLUSION
+
+typedef struct _ENetRangeCoder
+{
+    /* only allocate enough symbols for reasonable MTUs, would need to be larger for large file compression */
+    ENetSymbol symbols[4096];
+} ENetRangeCoder;
+
+void *
+enet_range_coder_create (void)
+{
+    ENetRangeCoder * rangeCoder = (ENetRangeCoder *) enet_malloc (sizeof (ENetRangeCoder));
+    if (rangeCoder == NULL)
+      return NULL;
+
+    return rangeCoder;
+}
+
+void
+enet_range_coder_destroy (void * context)
+{
+    ENetRangeCoder * rangeCoder = (ENetRangeCoder *) context;
+    if (rangeCoder == NULL)
+      return;
+
+    enet_free (rangeCoder);
+}
+
+#define ENET_SYMBOL_CREATE(symbol, value_, count_) \
+{ \
+    symbol = & rangeCoder -> symbols [nextSymbol ++]; \
+    symbol -> value = value_; \
+    symbol -> count = count_; \
+    symbol -> under = count_; \
+    symbol -> left = 0; \
+    symbol -> right = 0; \
+    symbol -> symbols = 0; \
+    symbol -> escapes = 0; \
+    symbol -> total = 0; \
+    symbol -> parent = 0; \
+}
+
+#define ENET_CONTEXT_CREATE(context, escapes_, minimum) \
+{ \
+    ENET_SYMBOL_CREATE (context, 0, 0); \
+    (context) -> escapes = escapes_; \
+    (context) -> total = escapes_ + 256*minimum; \
+    (context) -> symbols = 0; \
+}
+
+static enet_uint16
+enet_symbol_rescale (ENetSymbol * symbol)
+{
+    enet_uint16 total = 0;
+    for (;;)
+    {
+        symbol -> count -= symbol->count >> 1;
+        symbol -> under = symbol -> count;
+        if (symbol -> left)
+          symbol -> under += enet_symbol_rescale (symbol + symbol -> left);
+        total += symbol -> under;
+        if (! symbol -> right) break;
+        symbol += symbol -> right;
+    } 
+    return total;
+}
+
+#define ENET_CONTEXT_RESCALE(context, minimum) \
+{ \
+    (context) -> total = (context) -> symbols ? enet_symbol_rescale ((context) + (context) -> symbols) : 0; \
+    (context) -> escapes -= (context) -> escapes >> 1; \
+    (context) -> total += (context) -> escapes + 256*minimum; \
+}
+
+#define ENET_RANGE_CODER_OUTPUT(value) \
+{ \
+    if (outData >= outEnd) \
+      return 0; \
+    * outData ++ = value; \
+}
+
+#define ENET_RANGE_CODER_ENCODE(under, count, total) \
+{ \
+    encodeRange /= (total); \
+    encodeLow += (under) * encodeRange; \
+    encodeRange *= (count); \
+    for (;;) \
+    { \
+        if((encodeLow ^ (encodeLow + encodeRange)) >= ENET_RANGE_CODER_TOP) \
+        { \
+            if(encodeRange >= ENET_RANGE_CODER_BOTTOM) break; \
+            encodeRange = -encodeLow & (ENET_RANGE_CODER_BOTTOM - 1); \
+        } \
+        ENET_RANGE_CODER_OUTPUT (encodeLow >> 24); \
+        encodeRange <<= 8; \
+        encodeLow <<= 8; \
+    } \
+}
+
+#define ENET_RANGE_CODER_FLUSH \
+{ \
+    while (encodeLow) \
+    { \
+        ENET_RANGE_CODER_OUTPUT (encodeLow >> 24); \
+        encodeLow <<= 8; \
+    } \
+}
+
+#define ENET_RANGE_CODER_FREE_SYMBOLS \
+{ \
+    if (nextSymbol >= sizeof (rangeCoder -> symbols) / sizeof (ENetSymbol) - ENET_SUBCONTEXT_ORDER ) \
+    { \
+        nextSymbol = 0; \
+        ENET_CONTEXT_CREATE (root, ENET_CONTEXT_ESCAPE_MINIMUM, ENET_CONTEXT_SYMBOL_MINIMUM); \
+        predicted = 0; \
+        order = 0; \
+    } \
+}
+
+#define ENET_CONTEXT_ENCODE(context, symbol_, value_, under_, count_, update, minimum) \
+{ \
+    under_ = value*minimum; \
+    count_ = minimum; \
+    if (! (context) -> symbols) \
+    { \
+        ENET_SYMBOL_CREATE (symbol_, value_, update); \
+        (context) -> symbols = symbol_ - (context); \
+    } \
+    else \
+    { \
+        ENetSymbol * node = (context) + (context) -> symbols; \
+        for (;;) \
+        { \
+            if (value_ < node -> value) \
+            { \
+                node -> under += update; \
+                if (node -> left) { node += node -> left; continue; } \
+                ENET_SYMBOL_CREATE (symbol_, value_, update); \
+                node -> left = symbol_ - node; \
+            } \
+            else \
+            if (value_ > node -> value) \
+            { \
+                under_ += node -> under; \
+                if (node -> right) { node += node -> right; continue; } \
+                ENET_SYMBOL_CREATE (symbol_, value_, update); \
+                node -> right = symbol_ - node; \
+            } \
+            else \
+            { \
+                count_ += node -> count; \
+                under_ += node -> under - node -> count; \
+                node -> under += update; \
+                node -> count += update; \
+                symbol_ = node; \
+            } \
+            break; \
+        } \
+    } \
+}
+
+#ifdef ENET_CONTEXT_EXCLUSION
+static const ENetSymbol emptyContext = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+
+#define ENET_CONTEXT_WALK(context, body) \
+{ \
+    const ENetSymbol * node = (context) + (context) -> symbols; \
+    const ENetSymbol * stack [256]; \
+    size_t stackSize = 0; \
+    while (node -> left) \
+    { \
+        stack [stackSize ++] = node; \
+        node += node -> left; \
+    } \
+    for (;;) \
+    { \
+        body; \
+        if (node -> right) \
+        { \
+            node += node -> right; \
+            while (node -> left) \
+            { \
+                stack [stackSize ++] = node; \
+                node += node -> left; \
+            } \
+        } \
+        else \
+        if (stackSize <= 0) \
+            break; \
+        else \
+            node = stack [-- stackSize]; \
+    } \
+}
+
+#define ENET_CONTEXT_ENCODE_EXCLUDE(context, value_, under, total, minimum) \
+ENET_CONTEXT_WALK(context, { \
+    if (node -> value != value_) \
+    { \
+        enet_uint16 parentCount = rangeCoder -> symbols [node -> parent].count + minimum; \
+        if (node -> value < value_) \
+          under -= parentCount; \
+        total -= parentCount; \
+    } \
+})
+#endif
+
+size_t
+enet_range_coder_compress (void * context, const ENetBuffer * inBuffers, size_t inBufferCount, size_t inLimit, enet_uint8 * outData, size_t outLimit)
+{
+    ENetRangeCoder * rangeCoder = (ENetRangeCoder *) context;
+    enet_uint8 * outStart = outData, * outEnd = & outData [outLimit];
+    const enet_uint8 * inData, * inEnd;
+    enet_uint32 encodeLow = 0, encodeRange = ~0;
+    ENetSymbol * root;
+    enet_uint16 predicted = 0;
+    size_t order = 0, nextSymbol = 0;
+
+    if (rangeCoder == NULL || inBufferCount <= 0 || inLimit <= 0)
+      return 0;
+
+    inData = (const enet_uint8 *) inBuffers -> data;
+    inEnd = & inData [inBuffers -> dataLength];
+    inBuffers ++;
+    inBufferCount --;
+
+    ENET_CONTEXT_CREATE (root, ENET_CONTEXT_ESCAPE_MINIMUM, ENET_CONTEXT_SYMBOL_MINIMUM);
+
+    for (;;)
+    {
+        ENetSymbol * subcontext, * symbol;
+#ifdef ENET_CONTEXT_EXCLUSION
+        const ENetSymbol * childContext = & emptyContext;
+#endif
+        enet_uint8 value;
+        enet_uint16 count, under, * parent = & predicted, total;
+        if (inData >= inEnd)
+        {
+            if (inBufferCount <= 0)
+              break;
+            inData = (const enet_uint8 *) inBuffers -> data;
+            inEnd = & inData [inBuffers -> dataLength];
+            inBuffers ++;
+            inBufferCount --;
+        }
+        value = * inData ++;
+    
+        for (subcontext = & rangeCoder -> symbols [predicted]; 
+             subcontext != root; 
+#ifdef ENET_CONTEXT_EXCLUSION
+             childContext = subcontext, 
+#endif
+                subcontext = & rangeCoder -> symbols [subcontext -> parent])
+        {
+            ENET_CONTEXT_ENCODE (subcontext, symbol, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0);
+            * parent = symbol - rangeCoder -> symbols;
+            parent = & symbol -> parent;
+            total = subcontext -> total;
+#ifdef ENET_CONTEXT_EXCLUSION
+            if (childContext -> total > ENET_SUBCONTEXT_SYMBOL_DELTA + ENET_SUBCONTEXT_ESCAPE_DELTA)
+              ENET_CONTEXT_ENCODE_EXCLUDE (childContext, value, under, total, 0);
+#endif
+            if (count > 0)
+            {
+                ENET_RANGE_CODER_ENCODE (subcontext -> escapes + under, count, total);
+            }
+            else
+            {
+                if (subcontext -> escapes > 0 && subcontext -> escapes < total) 
+                    ENET_RANGE_CODER_ENCODE (0, subcontext -> escapes, total); 
+                subcontext -> escapes += ENET_SUBCONTEXT_ESCAPE_DELTA;
+                subcontext -> total += ENET_SUBCONTEXT_ESCAPE_DELTA;
+            }
+            subcontext -> total += ENET_SUBCONTEXT_SYMBOL_DELTA;
+            if (count > 0xFF - 2*ENET_SUBCONTEXT_SYMBOL_DELTA || subcontext -> total > ENET_RANGE_CODER_BOTTOM - 0x100)
+              ENET_CONTEXT_RESCALE (subcontext, 0);
+            if (count > 0) goto nextInput;
+        }
+
+        ENET_CONTEXT_ENCODE (root, symbol, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM);
+        * parent = symbol - rangeCoder -> symbols;
+        parent = & symbol -> parent;
+        total = root -> total;
+#ifdef ENET_CONTEXT_EXCLUSION
+        if (childContext -> total > ENET_SUBCONTEXT_SYMBOL_DELTA + ENET_SUBCONTEXT_ESCAPE_DELTA)
+          ENET_CONTEXT_ENCODE_EXCLUDE (childContext, value, under, total, ENET_CONTEXT_SYMBOL_MINIMUM); 
+#endif
+        ENET_RANGE_CODER_ENCODE (root -> escapes + under, count, total);
+        root -> total += ENET_CONTEXT_SYMBOL_DELTA; 
+        if (count > 0xFF - 2*ENET_CONTEXT_SYMBOL_DELTA + ENET_CONTEXT_SYMBOL_MINIMUM || root -> total > ENET_RANGE_CODER_BOTTOM - 0x100)
+          ENET_CONTEXT_RESCALE (root, ENET_CONTEXT_SYMBOL_MINIMUM);
+
+    nextInput:
+        if (order >= ENET_SUBCONTEXT_ORDER) 
+          predicted = rangeCoder -> symbols [predicted].parent;
+        else 
+          order ++;
+        ENET_RANGE_CODER_FREE_SYMBOLS;
+    }
+
+    ENET_RANGE_CODER_FLUSH;
+
+    return (size_t) (outData - outStart);
+}
+
+#define ENET_RANGE_CODER_SEED \
+{ \
+    if (inData < inEnd) decodeCode |= * inData ++ << 24; \
+    if (inData < inEnd) decodeCode |= * inData ++ << 16; \
+    if (inData < inEnd) decodeCode |= * inData ++ << 8; \
+    if (inData < inEnd) decodeCode |= * inData ++; \
+}
+
+#define ENET_RANGE_CODER_READ(total) ((decodeCode - decodeLow) / (decodeRange /= (total)))
+
+#define ENET_RANGE_CODER_DECODE(under, count, total) \
+{ \
+    decodeLow += (under) * decodeRange; \
+    decodeRange *= (count); \
+    for (;;) \
+    { \
+        if((decodeLow ^ (decodeLow + decodeRange)) >= ENET_RANGE_CODER_TOP) \
+        { \
+            if(decodeRange >= ENET_RANGE_CODER_BOTTOM) break; \
+            decodeRange = -decodeLow & (ENET_RANGE_CODER_BOTTOM - 1); \
+        } \
+        decodeCode <<= 8; \
+        if (inData < inEnd) \
+          decodeCode |= * inData ++; \
+        decodeRange <<= 8; \
+        decodeLow <<= 8; \
+    } \
+}
+
+#define ENET_CONTEXT_DECODE(context, symbol_, code, value_, under_, count_, update, minimum, createRoot, visitNode, createRight, createLeft) \
+{ \
+    under_ = 0; \
+    count_ = minimum; \
+    if (! (context) -> symbols) \
+    { \
+        createRoot; \
+    } \
+    else \
+    { \
+        ENetSymbol * node = (context) + (context) -> symbols; \
+        for (;;) \
+        { \
+            enet_uint16 after = under_ + node -> under + (node -> value + 1)*minimum, before = node -> count + minimum; \
+            visitNode; \
+            if (code >= after) \
+            { \
+                under_ += node -> under; \
+                if (node -> right) { node += node -> right; continue; } \
+                createRight; \
+            } \
+            else \
+            if (code < after - before) \
+            { \
+                node -> under += update; \
+                if (node -> left) { node += node -> left; continue; } \
+                createLeft; \
+            } \
+            else \
+            { \
+                value_ = node -> value; \
+                count_ += node -> count; \
+                under_ = after - before; \
+                node -> under += update; \
+                node -> count += update; \
+                symbol_ = node; \
+            } \
+            break; \
+        } \
+    } \
+}
+
+#define ENET_CONTEXT_TRY_DECODE(context, symbol_, code, value_, under_, count_, update, minimum, exclude) \
+ENET_CONTEXT_DECODE (context, symbol_, code, value_, under_, count_, update, minimum, return 0, exclude (node -> value, after, before), return 0, return 0)
+
+#define ENET_CONTEXT_ROOT_DECODE(context, symbol_, code, value_, under_, count_, update, minimum, exclude) \
+ENET_CONTEXT_DECODE (context, symbol_, code, value_, under_, count_, update, minimum, \
+    { \
+        value_ = code / minimum; \
+        under_ = code - code%minimum; \
+        ENET_SYMBOL_CREATE (symbol_, value_, update); \
+        (context) -> symbols = symbol_ - (context); \
+    }, \
+    exclude (node -> value, after, before), \
+    { \
+        value_ = node->value + 1 + (code - after)/minimum; \
+        under_ = code - (code - after)%minimum; \
+        ENET_SYMBOL_CREATE (symbol_, value_, update); \
+        node -> right = symbol_ - node; \
+    }, \
+    { \
+        value_ = node->value - 1 - (after - before - code - 1)/minimum; \
+        under_ = code - (after - before - code - 1)%minimum; \
+        ENET_SYMBOL_CREATE (symbol_, value_, update); \
+        node -> left = symbol_ - node; \
+    }) \
+
+#ifdef ENET_CONTEXT_EXCLUSION
+typedef struct _ENetExclude
+{
+    enet_uint8 value;
+    enet_uint16 under;
+} ENetExclude;
+
+#define ENET_CONTEXT_DECODE_EXCLUDE(context, total, minimum) \
+{ \
+    enet_uint16 under = 0; \
+    nextExclude = excludes; \
+    ENET_CONTEXT_WALK (context, { \
+        under += rangeCoder -> symbols [node -> parent].count + minimum; \
+        nextExclude -> value = node -> value; \
+        nextExclude -> under = under; \
+        nextExclude ++; \
+    }); \
+    total -= under; \
+}
+
+#define ENET_CONTEXT_EXCLUDED(value_, after, before) \
+{ \
+    size_t low = 0, high = nextExclude - excludes; \
+    for(;;) \
+    { \
+        size_t mid = (low + high) >> 1; \
+        const ENetExclude * exclude = & excludes [mid]; \
+        if (value_ < exclude -> value) \
+        { \
+            if (low + 1 < high) \
+            { \
+                high = mid; \
+                continue; \
+            } \
+            if (exclude > excludes) \
+              after -= exclude [-1].under; \
+        } \
+        else \
+        { \
+            if (value_ > exclude -> value) \
+            { \
+                if (low + 1 < high) \
+                { \
+                    low = mid; \
+                    continue; \
+                } \
+            } \
+            else \
+              before = 0; \
+            after -= exclude -> under; \
+        } \
+        break; \
+    } \
+}
+#endif
+
+#define ENET_CONTEXT_NOT_EXCLUDED(value_, after, before)
+
+size_t
+enet_range_coder_decompress (void * context, const enet_uint8 * inData, size_t inLimit, enet_uint8 * outData, size_t outLimit)
+{
+    ENetRangeCoder * rangeCoder = (ENetRangeCoder *) context;
+    enet_uint8 * outStart = outData, * outEnd = & outData [outLimit];
+    const enet_uint8 * inEnd = & inData [inLimit];
+    enet_uint32 decodeLow = 0, decodeCode = 0, decodeRange = ~0;
+    ENetSymbol * root;
+    enet_uint16 predicted = 0;
+    size_t order = 0, nextSymbol = 0;
+#ifdef ENET_CONTEXT_EXCLUSION
+    ENetExclude excludes [256];
+    ENetExclude * nextExclude = excludes;
+#endif
+  
+    if (rangeCoder == NULL || inLimit <= 0)
+      return 0;
+
+    ENET_CONTEXT_CREATE (root, ENET_CONTEXT_ESCAPE_MINIMUM, ENET_CONTEXT_SYMBOL_MINIMUM);
+
+    ENET_RANGE_CODER_SEED;
+
+    for (;;)
+    {
+        ENetSymbol * subcontext, * symbol, * patch;
+#ifdef ENET_CONTEXT_EXCLUSION
+        const ENetSymbol * childContext = & emptyContext;
+#endif
+        enet_uint8 value = 0;
+        enet_uint16 code, under, count, bottom, * parent = & predicted, total;
+
+        for (subcontext = & rangeCoder -> symbols [predicted];
+             subcontext != root;
+#ifdef ENET_CONTEXT_EXCLUSION
+             childContext = subcontext, 
+#endif
+                subcontext = & rangeCoder -> symbols [subcontext -> parent])
+        {
+            if (subcontext -> escapes <= 0)
+              continue;
+            total = subcontext -> total;
+#ifdef ENET_CONTEXT_EXCLUSION
+            if (childContext -> total > 0) 
+              ENET_CONTEXT_DECODE_EXCLUDE (childContext, total, 0); 
+#endif
+            if (subcontext -> escapes >= total)
+              continue;
+            code = ENET_RANGE_CODER_READ (total);
+            if (code < subcontext -> escapes) 
+            {
+                ENET_RANGE_CODER_DECODE (0, subcontext -> escapes, total); 
+                continue;
+            }
+            code -= subcontext -> escapes;
+#ifdef ENET_CONTEXT_EXCLUSION
+            if (childContext -> total > 0)
+            {
+                ENET_CONTEXT_TRY_DECODE (subcontext, symbol, code, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0, ENET_CONTEXT_EXCLUDED); 
+            }
+            else
+#endif
+            {
+                ENET_CONTEXT_TRY_DECODE (subcontext, symbol, code, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0, ENET_CONTEXT_NOT_EXCLUDED); 
+            }
+            bottom = symbol - rangeCoder -> symbols;
+            ENET_RANGE_CODER_DECODE (subcontext -> escapes + under, count, total);
+            subcontext -> total += ENET_SUBCONTEXT_SYMBOL_DELTA;
+            if (count > 0xFF - 2*ENET_SUBCONTEXT_SYMBOL_DELTA || subcontext -> total > ENET_RANGE_CODER_BOTTOM - 0x100)
+              ENET_CONTEXT_RESCALE (subcontext, 0);
+            goto patchContexts;
+        }
+
+        total = root -> total;
+#ifdef ENET_CONTEXT_EXCLUSION
+        if (childContext -> total > 0)
+          ENET_CONTEXT_DECODE_EXCLUDE (childContext, total, ENET_CONTEXT_SYMBOL_MINIMUM);  
+#endif
+        code = ENET_RANGE_CODER_READ (total);
+        if (code < root -> escapes)
+        {
+            ENET_RANGE_CODER_DECODE (0, root -> escapes, total);
+            break;
+        }
+        code -= root -> escapes;
+#ifdef ENET_CONTEXT_EXCLUSION
+        if (childContext -> total > 0)
+        {
+            ENET_CONTEXT_ROOT_DECODE (root, symbol, code, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM, ENET_CONTEXT_EXCLUDED); 
+        }
+        else
+#endif
+        {
+            ENET_CONTEXT_ROOT_DECODE (root, symbol, code, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM, ENET_CONTEXT_NOT_EXCLUDED); 
+        }
+        bottom = symbol - rangeCoder -> symbols;
+        ENET_RANGE_CODER_DECODE (root -> escapes + under, count, total);
+        root -> total += ENET_CONTEXT_SYMBOL_DELTA;
+        if (count > 0xFF - 2*ENET_CONTEXT_SYMBOL_DELTA + ENET_CONTEXT_SYMBOL_MINIMUM || root -> total > ENET_RANGE_CODER_BOTTOM - 0x100)
+          ENET_CONTEXT_RESCALE (root, ENET_CONTEXT_SYMBOL_MINIMUM);
+
+    patchContexts:
+        for (patch = & rangeCoder -> symbols [predicted];
+             patch != subcontext;
+             patch = & rangeCoder -> symbols [patch -> parent])
+        {
+            ENET_CONTEXT_ENCODE (patch, symbol, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0);
+            * parent = symbol - rangeCoder -> symbols;
+            parent = & symbol -> parent;
+            if (count <= 0)
+            {
+                patch -> escapes += ENET_SUBCONTEXT_ESCAPE_DELTA;
+                patch -> total += ENET_SUBCONTEXT_ESCAPE_DELTA;
+            }
+            patch -> total += ENET_SUBCONTEXT_SYMBOL_DELTA; 
+            if (count > 0xFF - 2*ENET_SUBCONTEXT_SYMBOL_DELTA || patch -> total > ENET_RANGE_CODER_BOTTOM - 0x100)
+              ENET_CONTEXT_RESCALE (patch, 0);
+        }
+        * parent = bottom;
+
+        ENET_RANGE_CODER_OUTPUT (value);
+
+        if (order >= ENET_SUBCONTEXT_ORDER)
+          predicted = rangeCoder -> symbols [predicted].parent;
+        else
+          order ++;
+        ENET_RANGE_CODER_FREE_SYMBOLS;
+    }
+                        
+    return (size_t) (outData - outStart);
+}
+
+/** @defgroup host ENet host functions
+    @{
+*/
+
+/** Sets the packet compressor the host should use to the default range coder.
+    @param host host to enable the range coder for
+    @returns 0 on success, < 0 on failure
+*/
+int
+enet_host_compress_with_range_coder (ENetHost * host)
+{
+    ENetCompressor compressor;
+    memset (& compressor, 0, sizeof (compressor));
+    compressor.context = enet_range_coder_create();
+    if (compressor.context == NULL)
+      return -1;
+    compressor.compress = enet_range_coder_compress;
+    compressor.decompress = enet_range_coder_decompress;
+    compressor.destroy = enet_range_coder_destroy;
+    enet_host_compress (host, & compressor);
+    return 0;
+}
+    
+/** @} */
+    
+     

+ 479 - 479
ThirdParty/ENet/host.c

@@ -1,479 +1,479 @@
-/** 
- @file host.c
- @brief ENet host management functions
-*/
-#define ENET_BUILDING_LIB 1
-#include <string.h>
-#include <time.h>
-#include "enet/enet.h"
-
-/** @defgroup host ENet host functions
-    @{
-*/
-
-/** Creates a host for communicating to peers.  
-
-    @param address   the address at which other peers may connect to this host.  If NULL, then no peers may connect to the host.
-    @param peerCount the maximum number of peers that should be allocated for the host.
-    @param channelLimit the maximum number of channels allowed; if 0, then this is equivalent to ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT
-    @param incomingBandwidth downstream bandwidth of the host in bytes/second; if 0, ENet will assume unlimited bandwidth.
-    @param outgoingBandwidth upstream bandwidth of the host in bytes/second; if 0, ENet will assume unlimited bandwidth.
-
-    @returns the host on success and NULL on failure
-
-    @remarks ENet will strategically drop packets on specific sides of a connection between hosts
-    to ensure the host's bandwidth is not overwhelmed.  The bandwidth parameters also determine
-    the window size of a connection which limits the amount of reliable packets that may be in transit
-    at any given time.
-*/
-ENetHost *
-enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelLimit, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth)
-{
-    ENetHost * host;
-    ENetPeer * currentPeer;
-
-    if (peerCount > ENET_PROTOCOL_MAXIMUM_PEER_ID)
-      return NULL;
-
-    host = (ENetHost *) enet_malloc (sizeof (ENetHost));
-    if (host == NULL)
-      return NULL;
-
-    host -> peers = (ENetPeer *) enet_malloc (peerCount * sizeof (ENetPeer));
-    if (host -> peers == NULL)
-    {
-       enet_free (host);
-
-       return NULL;
-    }
-    memset (host -> peers, 0, peerCount * sizeof (ENetPeer));
-
-    host -> socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM);
-    if (host -> socket == ENET_SOCKET_NULL || (address != NULL && enet_socket_bind (host -> socket, address) < 0))
-    {
-       if (host -> socket != ENET_SOCKET_NULL)
-         enet_socket_destroy (host -> socket);
-
-       enet_free (host -> peers);
-       enet_free (host);
-
-       return NULL;
-    }
-
-    enet_socket_set_option (host -> socket, ENET_SOCKOPT_NONBLOCK, 1);
-    enet_socket_set_option (host -> socket, ENET_SOCKOPT_BROADCAST, 1);
-    enet_socket_set_option (host -> socket, ENET_SOCKOPT_RCVBUF, ENET_HOST_RECEIVE_BUFFER_SIZE);
-    enet_socket_set_option (host -> socket, ENET_SOCKOPT_SNDBUF, ENET_HOST_SEND_BUFFER_SIZE);
-
-    if (address != NULL)
-      host -> address = * address;
-
-    if (! channelLimit || channelLimit > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
-      channelLimit = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT;
-    else
-    if (channelLimit < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT)
-      channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
-
-    host -> randomSeed = (enet_uint32) time(NULL) + (enet_uint32) (size_t) host;
-    host -> randomSeed = (host -> randomSeed << 16) | (host -> randomSeed >> 16);
-    host -> channelLimit = channelLimit;
-    host -> incomingBandwidth = incomingBandwidth;
-    host -> outgoingBandwidth = outgoingBandwidth;
-    host -> bandwidthThrottleEpoch = 0;
-    host -> recalculateBandwidthLimits = 0;
-    host -> mtu = ENET_HOST_DEFAULT_MTU;
-    host -> peerCount = peerCount;
-    host -> commandCount = 0;
-    host -> bufferCount = 0;
-    host -> checksum = NULL;
-    host -> receivedAddress.host = ENET_HOST_ANY;
-    host -> receivedAddress.port = 0;
-    host -> receivedData = NULL;
-    host -> receivedDataLength = 0;
-     
-    host -> totalSentData = 0;
-    host -> totalSentPackets = 0;
-    host -> totalReceivedData = 0;
-    host -> totalReceivedPackets = 0;
-
-    host -> compressor.context = NULL;
-    host -> compressor.compress = NULL;
-    host -> compressor.decompress = NULL;
-    host -> compressor.destroy = NULL;
-
-    enet_list_clear (& host -> dispatchQueue);
-
-    for (currentPeer = host -> peers;
-         currentPeer < & host -> peers [host -> peerCount];
-         ++ currentPeer)
-    {
-       currentPeer -> host = host;
-       currentPeer -> incomingPeerID = currentPeer - host -> peers;
-       currentPeer -> outgoingSessionID = currentPeer -> incomingSessionID = 0xFF;
-       currentPeer -> data = NULL;
-
-       enet_list_clear (& currentPeer -> acknowledgements);
-       enet_list_clear (& currentPeer -> sentReliableCommands);
-       enet_list_clear (& currentPeer -> sentUnreliableCommands);
-       enet_list_clear (& currentPeer -> outgoingReliableCommands);
-       enet_list_clear (& currentPeer -> outgoingUnreliableCommands);
-       enet_list_clear (& currentPeer -> dispatchedCommands);
-
-       enet_peer_reset (currentPeer);
-    }
-
-    return host;
-}
-
-/** Destroys the host and all resources associated with it.
-    @param host pointer to the host to destroy
-*/
-void
-enet_host_destroy (ENetHost * host)
-{
-    ENetPeer * currentPeer;
-
-    enet_socket_destroy (host -> socket);
-
-    for (currentPeer = host -> peers;
-         currentPeer < & host -> peers [host -> peerCount];
-         ++ currentPeer)
-    {
-       enet_peer_reset (currentPeer);
-    }
-
-    if (host -> compressor.context != NULL && host -> compressor.destroy)
-      (* host -> compressor.destroy) (host -> compressor.context);
-
-    enet_free (host -> peers);
-    enet_free (host);
-}
-
-/** Initiates a connection to a foreign host.
-    @param host host seeking the connection
-    @param address destination for the connection
-    @param channelCount number of channels to allocate
-    @param data user data supplied to the receiving host 
-    @returns a peer representing the foreign host on success, NULL on failure
-    @remarks The peer returned will have not completed the connection until enet_host_service()
-    notifies of an ENET_EVENT_TYPE_CONNECT event for the peer.
-*/
-ENetPeer *
-enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelCount, enet_uint32 data)
-{
-    ENetPeer * currentPeer;
-    ENetChannel * channel;
-    ENetProtocol command;
-
-    if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT)
-      channelCount = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
-    else
-    if (channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
-      channelCount = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT;
-
-    for (currentPeer = host -> peers;
-         currentPeer < & host -> peers [host -> peerCount];
-         ++ currentPeer)
-    {
-       if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED)
-         break;
-    }
-
-    if (currentPeer >= & host -> peers [host -> peerCount])
-      return NULL;
-
-    currentPeer -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel));
-    if (currentPeer -> channels == NULL)
-      return NULL;
-    currentPeer -> channelCount = channelCount;
-    currentPeer -> state = ENET_PEER_STATE_CONNECTING;
-    currentPeer -> address = * address;
-    currentPeer -> connectID = ++ host -> randomSeed;
-
-    if (host -> outgoingBandwidth == 0)
-      currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
-    else
-      currentPeer -> windowSize = (host -> outgoingBandwidth /
-                                    ENET_PEER_WINDOW_SIZE_SCALE) * 
-                                      ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
-
-    if (currentPeer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE)
-      currentPeer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
-    else
-    if (currentPeer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
-      currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
-         
-    for (channel = currentPeer -> channels;
-         channel < & currentPeer -> channels [channelCount];
-         ++ channel)
-    {
-        channel -> outgoingReliableSequenceNumber = 0;
-        channel -> outgoingUnreliableSequenceNumber = 0;
-        channel -> incomingReliableSequenceNumber = 0;
-
-        enet_list_clear (& channel -> incomingReliableCommands);
-        enet_list_clear (& channel -> incomingUnreliableCommands);
-
-        channel -> usedReliableWindows = 0;
-        memset (channel -> reliableWindows, 0, sizeof (channel -> reliableWindows));
-    }
-        
-    command.header.command = ENET_PROTOCOL_COMMAND_CONNECT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
-    command.header.channelID = 0xFF;
-    command.connect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID);
-    command.connect.incomingSessionID = currentPeer -> incomingSessionID;
-    command.connect.outgoingSessionID = currentPeer -> outgoingSessionID;
-    command.connect.mtu = ENET_HOST_TO_NET_32 (currentPeer -> mtu);
-    command.connect.windowSize = ENET_HOST_TO_NET_32 (currentPeer -> windowSize);
-    command.connect.channelCount = ENET_HOST_TO_NET_32 (channelCount);
-    command.connect.incomingBandwidth = ENET_HOST_TO_NET_32 (host -> incomingBandwidth);
-    command.connect.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
-    command.connect.packetThrottleInterval = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleInterval);
-    command.connect.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleAcceleration);
-    command.connect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleDeceleration);
-    command.connect.connectID = currentPeer -> connectID;
-    command.connect.data = ENET_HOST_TO_NET_32 (data);
- 
-    enet_peer_queue_outgoing_command (currentPeer, & command, NULL, 0, 0);
-
-    return currentPeer;
-}
-
-/** Queues a packet to be sent to all peers associated with the host.
-    @param host host on which to broadcast the packet
-    @param channelID channel on which to broadcast
-    @param packet packet to broadcast
-*/
-void
-enet_host_broadcast (ENetHost * host, enet_uint8 channelID, ENetPacket * packet)
-{
-    ENetPeer * currentPeer;
-
-    for (currentPeer = host -> peers;
-         currentPeer < & host -> peers [host -> peerCount];
-         ++ currentPeer)
-    {
-       if (currentPeer -> state != ENET_PEER_STATE_CONNECTED)
-         continue;
-
-       enet_peer_send (currentPeer, channelID, packet);
-    }
-
-    if (packet -> referenceCount == 0)
-      enet_packet_destroy (packet);
-}
-
-/** Sets the packet compressor the host should use to compress and decompress packets.
-    @param host host to enable or disable compression for
-    @param compressor callbacks for for the packet compressor; if NULL, then compression is disabled
-*/
-void
-enet_host_compress (ENetHost * host, const ENetCompressor * compressor)
-{
-    if (host -> compressor.context != NULL && host -> compressor.destroy)
-      (* host -> compressor.destroy) (host -> compressor.context);
-
-    if (compressor)
-      host -> compressor = * compressor;
-    else
-      host -> compressor.context = NULL;
-}
-
-/** Limits the maximum allowed channels of future incoming connections.
-    @param host host to limit
-    @param channelLimit the maximum number of channels allowed; if 0, then this is equivalent to ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT
-*/
-void
-enet_host_channel_limit (ENetHost * host, size_t channelLimit)
-{
-    if (! channelLimit || channelLimit > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
-      channelLimit = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT;
-    else
-    if (channelLimit < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT)
-      channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
-
-    host -> channelLimit = channelLimit;
-}
-
-
-/** Adjusts the bandwidth limits of a host.
-    @param host host to adjust
-    @param incomingBandwidth new incoming bandwidth
-    @param outgoingBandwidth new outgoing bandwidth
-    @remarks the incoming and outgoing bandwidth parameters are identical in function to those
-    specified in enet_host_create().
-*/
-void
-enet_host_bandwidth_limit (ENetHost * host, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth)
-{
-    host -> incomingBandwidth = incomingBandwidth;
-    host -> outgoingBandwidth = outgoingBandwidth;
-    host -> recalculateBandwidthLimits = 1;
-}
-
-void
-enet_host_bandwidth_throttle (ENetHost * host)
-{
-    enet_uint32 timeCurrent = enet_time_get (),
-           elapsedTime = timeCurrent - host -> bandwidthThrottleEpoch,
-           peersTotal = 0,
-           dataTotal = 0,
-           peersRemaining,
-           bandwidth,
-           throttle = 0,
-           bandwidthLimit = 0;
-    int needsAdjustment;
-    ENetPeer * peer;
-    ENetProtocol command;
-
-    if (elapsedTime < ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL)
-      return;
-
-    for (peer = host -> peers;
-         peer < & host -> peers [host -> peerCount];
-         ++ peer)
-    {
-        if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
-          continue;
-
-        ++ peersTotal;
-        dataTotal += peer -> outgoingDataTotal;
-    }
-
-    if (peersTotal == 0)
-      return;
-
-    peersRemaining = peersTotal;
-    needsAdjustment = 1;
-
-    if (host -> outgoingBandwidth == 0)
-      bandwidth = ~0;
-    else
-      bandwidth = (host -> outgoingBandwidth * elapsedTime) / 1000;
-
-    while (peersRemaining > 0 && needsAdjustment != 0)
-    {
-        needsAdjustment = 0;
-        
-        if (dataTotal < bandwidth)
-          throttle = ENET_PEER_PACKET_THROTTLE_SCALE;
-        else
-          throttle = (bandwidth * ENET_PEER_PACKET_THROTTLE_SCALE) / dataTotal;
-
-        for (peer = host -> peers;
-             peer < & host -> peers [host -> peerCount];
-             ++ peer)
-        {
-            enet_uint32 peerBandwidth;
-            
-            if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) ||
-                peer -> incomingBandwidth == 0 ||
-                peer -> outgoingBandwidthThrottleEpoch == timeCurrent)
-              continue;
-
-            peerBandwidth = (peer -> incomingBandwidth * elapsedTime) / 1000;
-            if ((throttle * peer -> outgoingDataTotal) / ENET_PEER_PACKET_THROTTLE_SCALE <= peerBandwidth)
-              continue;
-
-            peer -> packetThrottleLimit = (peerBandwidth * 
-                                            ENET_PEER_PACKET_THROTTLE_SCALE) / peer -> outgoingDataTotal;
-            
-            if (peer -> packetThrottleLimit == 0)
-              peer -> packetThrottleLimit = 1;
-            
-            if (peer -> packetThrottle > peer -> packetThrottleLimit)
-              peer -> packetThrottle = peer -> packetThrottleLimit;
-
-            peer -> outgoingBandwidthThrottleEpoch = timeCurrent;
-
-            
-            needsAdjustment = 1;
-            -- peersRemaining;
-            bandwidth -= peerBandwidth;
-            dataTotal -= peerBandwidth;
-        }
-    }
-
-    if (peersRemaining > 0)
-    for (peer = host -> peers;
-         peer < & host -> peers [host -> peerCount];
-         ++ peer)
-    {
-        if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) ||
-            peer -> outgoingBandwidthThrottleEpoch == timeCurrent)
-          continue;
-
-        peer -> packetThrottleLimit = throttle;
-
-        if (peer -> packetThrottle > peer -> packetThrottleLimit)
-          peer -> packetThrottle = peer -> packetThrottleLimit;
-    }
-    
-    if (host -> recalculateBandwidthLimits)
-    {
-       host -> recalculateBandwidthLimits = 0;
-
-       peersRemaining = peersTotal;
-       bandwidth = host -> incomingBandwidth;
-       needsAdjustment = 1;
-
-       if (bandwidth == 0)
-         bandwidthLimit = 0;
-       else
-       while (peersRemaining > 0 && needsAdjustment != 0)
-       {
-           needsAdjustment = 0;
-           bandwidthLimit = bandwidth / peersRemaining;
-
-           for (peer = host -> peers;
-                peer < & host -> peers [host -> peerCount];
-                ++ peer)
-           {
-               if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) ||
-                   peer -> incomingBandwidthThrottleEpoch == timeCurrent)
-                 continue;
-
-               if (peer -> outgoingBandwidth > 0 &&
-                   peer -> outgoingBandwidth >= bandwidthLimit)
-                 continue;
-
-               peer -> incomingBandwidthThrottleEpoch = timeCurrent;
- 
-               needsAdjustment = 1;
-               -- peersRemaining;
-               bandwidth -= peer -> outgoingBandwidth;
-           }
-       }
-
-       for (peer = host -> peers;
-            peer < & host -> peers [host -> peerCount];
-            ++ peer)
-       {
-           if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
-             continue;
-
-           command.header.command = ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
-           command.header.channelID = 0xFF;
-           command.bandwidthLimit.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
-
-           if (peer -> incomingBandwidthThrottleEpoch == timeCurrent)
-             command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (peer -> outgoingBandwidth);
-           else
-             command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (bandwidthLimit);
-
-           enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
-       } 
-    }
-
-    host -> bandwidthThrottleEpoch = timeCurrent;
-
-    for (peer = host -> peers;
-         peer < & host -> peers [host -> peerCount];
-         ++ peer)
-    {
-        peer -> incomingDataTotal = 0;
-        peer -> outgoingDataTotal = 0;
-    }
-}
-    
-/** @} */
+/** 
+ @file host.c
+ @brief ENet host management functions
+*/
+#define ENET_BUILDING_LIB 1
+#include <string.h>
+#include <time.h>
+#include "enet/enet.h"
+
+/** @defgroup host ENet host functions
+    @{
+*/
+
+/** Creates a host for communicating to peers.  
+
+    @param address   the address at which other peers may connect to this host.  If NULL, then no peers may connect to the host.
+    @param peerCount the maximum number of peers that should be allocated for the host.
+    @param channelLimit the maximum number of channels allowed; if 0, then this is equivalent to ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT
+    @param incomingBandwidth downstream bandwidth of the host in bytes/second; if 0, ENet will assume unlimited bandwidth.
+    @param outgoingBandwidth upstream bandwidth of the host in bytes/second; if 0, ENet will assume unlimited bandwidth.
+
+    @returns the host on success and NULL on failure
+
+    @remarks ENet will strategically drop packets on specific sides of a connection between hosts
+    to ensure the host's bandwidth is not overwhelmed.  The bandwidth parameters also determine
+    the window size of a connection which limits the amount of reliable packets that may be in transit
+    at any given time.
+*/
+ENetHost *
+enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelLimit, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth)
+{
+    ENetHost * host;
+    ENetPeer * currentPeer;
+
+    if (peerCount > ENET_PROTOCOL_MAXIMUM_PEER_ID)
+      return NULL;
+
+    host = (ENetHost *) enet_malloc (sizeof (ENetHost));
+    if (host == NULL)
+      return NULL;
+
+    host -> peers = (ENetPeer *) enet_malloc (peerCount * sizeof (ENetPeer));
+    if (host -> peers == NULL)
+    {
+       enet_free (host);
+
+       return NULL;
+    }
+    memset (host -> peers, 0, peerCount * sizeof (ENetPeer));
+
+    host -> socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM);
+    if (host -> socket == ENET_SOCKET_NULL || (address != NULL && enet_socket_bind (host -> socket, address) < 0))
+    {
+       if (host -> socket != ENET_SOCKET_NULL)
+         enet_socket_destroy (host -> socket);
+
+       enet_free (host -> peers);
+       enet_free (host);
+
+       return NULL;
+    }
+
+    enet_socket_set_option (host -> socket, ENET_SOCKOPT_NONBLOCK, 1);
+    enet_socket_set_option (host -> socket, ENET_SOCKOPT_BROADCAST, 1);
+    enet_socket_set_option (host -> socket, ENET_SOCKOPT_RCVBUF, ENET_HOST_RECEIVE_BUFFER_SIZE);
+    enet_socket_set_option (host -> socket, ENET_SOCKOPT_SNDBUF, ENET_HOST_SEND_BUFFER_SIZE);
+
+    if (address != NULL)
+      host -> address = * address;
+
+    if (! channelLimit || channelLimit > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
+      channelLimit = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT;
+    else
+    if (channelLimit < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT)
+      channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
+
+    host -> randomSeed = (enet_uint32) time(NULL) + (enet_uint32) (size_t) host;
+    host -> randomSeed = (host -> randomSeed << 16) | (host -> randomSeed >> 16);
+    host -> channelLimit = channelLimit;
+    host -> incomingBandwidth = incomingBandwidth;
+    host -> outgoingBandwidth = outgoingBandwidth;
+    host -> bandwidthThrottleEpoch = 0;
+    host -> recalculateBandwidthLimits = 0;
+    host -> mtu = ENET_HOST_DEFAULT_MTU;
+    host -> peerCount = peerCount;
+    host -> commandCount = 0;
+    host -> bufferCount = 0;
+    host -> checksum = NULL;
+    host -> receivedAddress.host = ENET_HOST_ANY;
+    host -> receivedAddress.port = 0;
+    host -> receivedData = NULL;
+    host -> receivedDataLength = 0;
+     
+    host -> totalSentData = 0;
+    host -> totalSentPackets = 0;
+    host -> totalReceivedData = 0;
+    host -> totalReceivedPackets = 0;
+
+    host -> compressor.context = NULL;
+    host -> compressor.compress = NULL;
+    host -> compressor.decompress = NULL;
+    host -> compressor.destroy = NULL;
+
+    enet_list_clear (& host -> dispatchQueue);
+
+    for (currentPeer = host -> peers;
+         currentPeer < & host -> peers [host -> peerCount];
+         ++ currentPeer)
+    {
+       currentPeer -> host = host;
+       currentPeer -> incomingPeerID = currentPeer - host -> peers;
+       currentPeer -> outgoingSessionID = currentPeer -> incomingSessionID = 0xFF;
+       currentPeer -> data = NULL;
+
+       enet_list_clear (& currentPeer -> acknowledgements);
+       enet_list_clear (& currentPeer -> sentReliableCommands);
+       enet_list_clear (& currentPeer -> sentUnreliableCommands);
+       enet_list_clear (& currentPeer -> outgoingReliableCommands);
+       enet_list_clear (& currentPeer -> outgoingUnreliableCommands);
+       enet_list_clear (& currentPeer -> dispatchedCommands);
+
+       enet_peer_reset (currentPeer);
+    }
+
+    return host;
+}
+
+/** Destroys the host and all resources associated with it.
+    @param host pointer to the host to destroy
+*/
+void
+enet_host_destroy (ENetHost * host)
+{
+    ENetPeer * currentPeer;
+
+    enet_socket_destroy (host -> socket);
+
+    for (currentPeer = host -> peers;
+         currentPeer < & host -> peers [host -> peerCount];
+         ++ currentPeer)
+    {
+       enet_peer_reset (currentPeer);
+    }
+
+    if (host -> compressor.context != NULL && host -> compressor.destroy)
+      (* host -> compressor.destroy) (host -> compressor.context);
+
+    enet_free (host -> peers);
+    enet_free (host);
+}
+
+/** Initiates a connection to a foreign host.
+    @param host host seeking the connection
+    @param address destination for the connection
+    @param channelCount number of channels to allocate
+    @param data user data supplied to the receiving host 
+    @returns a peer representing the foreign host on success, NULL on failure
+    @remarks The peer returned will have not completed the connection until enet_host_service()
+    notifies of an ENET_EVENT_TYPE_CONNECT event for the peer.
+*/
+ENetPeer *
+enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelCount, enet_uint32 data)
+{
+    ENetPeer * currentPeer;
+    ENetChannel * channel;
+    ENetProtocol command;
+
+    if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT)
+      channelCount = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
+    else
+    if (channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
+      channelCount = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT;
+
+    for (currentPeer = host -> peers;
+         currentPeer < & host -> peers [host -> peerCount];
+         ++ currentPeer)
+    {
+       if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED)
+         break;
+    }
+
+    if (currentPeer >= & host -> peers [host -> peerCount])
+      return NULL;
+
+    currentPeer -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel));
+    if (currentPeer -> channels == NULL)
+      return NULL;
+    currentPeer -> channelCount = channelCount;
+    currentPeer -> state = ENET_PEER_STATE_CONNECTING;
+    currentPeer -> address = * address;
+    currentPeer -> connectID = ++ host -> randomSeed;
+
+    if (host -> outgoingBandwidth == 0)
+      currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
+    else
+      currentPeer -> windowSize = (host -> outgoingBandwidth /
+                                    ENET_PEER_WINDOW_SIZE_SCALE) * 
+                                      ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
+
+    if (currentPeer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE)
+      currentPeer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
+    else
+    if (currentPeer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
+      currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
+         
+    for (channel = currentPeer -> channels;
+         channel < & currentPeer -> channels [channelCount];
+         ++ channel)
+    {
+        channel -> outgoingReliableSequenceNumber = 0;
+        channel -> outgoingUnreliableSequenceNumber = 0;
+        channel -> incomingReliableSequenceNumber = 0;
+
+        enet_list_clear (& channel -> incomingReliableCommands);
+        enet_list_clear (& channel -> incomingUnreliableCommands);
+
+        channel -> usedReliableWindows = 0;
+        memset (channel -> reliableWindows, 0, sizeof (channel -> reliableWindows));
+    }
+        
+    command.header.command = ENET_PROTOCOL_COMMAND_CONNECT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
+    command.header.channelID = 0xFF;
+    command.connect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID);
+    command.connect.incomingSessionID = currentPeer -> incomingSessionID;
+    command.connect.outgoingSessionID = currentPeer -> outgoingSessionID;
+    command.connect.mtu = ENET_HOST_TO_NET_32 (currentPeer -> mtu);
+    command.connect.windowSize = ENET_HOST_TO_NET_32 (currentPeer -> windowSize);
+    command.connect.channelCount = ENET_HOST_TO_NET_32 (channelCount);
+    command.connect.incomingBandwidth = ENET_HOST_TO_NET_32 (host -> incomingBandwidth);
+    command.connect.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
+    command.connect.packetThrottleInterval = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleInterval);
+    command.connect.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleAcceleration);
+    command.connect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleDeceleration);
+    command.connect.connectID = currentPeer -> connectID;
+    command.connect.data = ENET_HOST_TO_NET_32 (data);
+ 
+    enet_peer_queue_outgoing_command (currentPeer, & command, NULL, 0, 0);
+
+    return currentPeer;
+}
+
+/** Queues a packet to be sent to all peers associated with the host.
+    @param host host on which to broadcast the packet
+    @param channelID channel on which to broadcast
+    @param packet packet to broadcast
+*/
+void
+enet_host_broadcast (ENetHost * host, enet_uint8 channelID, ENetPacket * packet)
+{
+    ENetPeer * currentPeer;
+
+    for (currentPeer = host -> peers;
+         currentPeer < & host -> peers [host -> peerCount];
+         ++ currentPeer)
+    {
+       if (currentPeer -> state != ENET_PEER_STATE_CONNECTED)
+         continue;
+
+       enet_peer_send (currentPeer, channelID, packet);
+    }
+
+    if (packet -> referenceCount == 0)
+      enet_packet_destroy (packet);
+}
+
+/** Sets the packet compressor the host should use to compress and decompress packets.
+    @param host host to enable or disable compression for
+    @param compressor callbacks for for the packet compressor; if NULL, then compression is disabled
+*/
+void
+enet_host_compress (ENetHost * host, const ENetCompressor * compressor)
+{
+    if (host -> compressor.context != NULL && host -> compressor.destroy)
+      (* host -> compressor.destroy) (host -> compressor.context);
+
+    if (compressor)
+      host -> compressor = * compressor;
+    else
+      host -> compressor.context = NULL;
+}
+
+/** Limits the maximum allowed channels of future incoming connections.
+    @param host host to limit
+    @param channelLimit the maximum number of channels allowed; if 0, then this is equivalent to ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT
+*/
+void
+enet_host_channel_limit (ENetHost * host, size_t channelLimit)
+{
+    if (! channelLimit || channelLimit > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
+      channelLimit = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT;
+    else
+    if (channelLimit < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT)
+      channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
+
+    host -> channelLimit = channelLimit;
+}
+
+
+/** Adjusts the bandwidth limits of a host.
+    @param host host to adjust
+    @param incomingBandwidth new incoming bandwidth
+    @param outgoingBandwidth new outgoing bandwidth
+    @remarks the incoming and outgoing bandwidth parameters are identical in function to those
+    specified in enet_host_create().
+*/
+void
+enet_host_bandwidth_limit (ENetHost * host, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth)
+{
+    host -> incomingBandwidth = incomingBandwidth;
+    host -> outgoingBandwidth = outgoingBandwidth;
+    host -> recalculateBandwidthLimits = 1;
+}
+
+void
+enet_host_bandwidth_throttle (ENetHost * host)
+{
+    enet_uint32 timeCurrent = enet_time_get (),
+           elapsedTime = timeCurrent - host -> bandwidthThrottleEpoch,
+           peersTotal = 0,
+           dataTotal = 0,
+           peersRemaining,
+           bandwidth,
+           throttle = 0,
+           bandwidthLimit = 0;
+    int needsAdjustment;
+    ENetPeer * peer;
+    ENetProtocol command;
+
+    if (elapsedTime < ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL)
+      return;
+
+    for (peer = host -> peers;
+         peer < & host -> peers [host -> peerCount];
+         ++ peer)
+    {
+        if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
+          continue;
+
+        ++ peersTotal;
+        dataTotal += peer -> outgoingDataTotal;
+    }
+
+    if (peersTotal == 0)
+      return;
+
+    peersRemaining = peersTotal;
+    needsAdjustment = 1;
+
+    if (host -> outgoingBandwidth == 0)
+      bandwidth = ~0;
+    else
+      bandwidth = (host -> outgoingBandwidth * elapsedTime) / 1000;
+
+    while (peersRemaining > 0 && needsAdjustment != 0)
+    {
+        needsAdjustment = 0;
+        
+        if (dataTotal < bandwidth)
+          throttle = ENET_PEER_PACKET_THROTTLE_SCALE;
+        else
+          throttle = (bandwidth * ENET_PEER_PACKET_THROTTLE_SCALE) / dataTotal;
+
+        for (peer = host -> peers;
+             peer < & host -> peers [host -> peerCount];
+             ++ peer)
+        {
+            enet_uint32 peerBandwidth;
+            
+            if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) ||
+                peer -> incomingBandwidth == 0 ||
+                peer -> outgoingBandwidthThrottleEpoch == timeCurrent)
+              continue;
+
+            peerBandwidth = (peer -> incomingBandwidth * elapsedTime) / 1000;
+            if ((throttle * peer -> outgoingDataTotal) / ENET_PEER_PACKET_THROTTLE_SCALE <= peerBandwidth)
+              continue;
+
+            peer -> packetThrottleLimit = (peerBandwidth * 
+                                            ENET_PEER_PACKET_THROTTLE_SCALE) / peer -> outgoingDataTotal;
+            
+            if (peer -> packetThrottleLimit == 0)
+              peer -> packetThrottleLimit = 1;
+            
+            if (peer -> packetThrottle > peer -> packetThrottleLimit)
+              peer -> packetThrottle = peer -> packetThrottleLimit;
+
+            peer -> outgoingBandwidthThrottleEpoch = timeCurrent;
+
+            
+            needsAdjustment = 1;
+            -- peersRemaining;
+            bandwidth -= peerBandwidth;
+            dataTotal -= peerBandwidth;
+        }
+    }
+
+    if (peersRemaining > 0)
+    for (peer = host -> peers;
+         peer < & host -> peers [host -> peerCount];
+         ++ peer)
+    {
+        if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) ||
+            peer -> outgoingBandwidthThrottleEpoch == timeCurrent)
+          continue;
+
+        peer -> packetThrottleLimit = throttle;
+
+        if (peer -> packetThrottle > peer -> packetThrottleLimit)
+          peer -> packetThrottle = peer -> packetThrottleLimit;
+    }
+    
+    if (host -> recalculateBandwidthLimits)
+    {
+       host -> recalculateBandwidthLimits = 0;
+
+       peersRemaining = peersTotal;
+       bandwidth = host -> incomingBandwidth;
+       needsAdjustment = 1;
+
+       if (bandwidth == 0)
+         bandwidthLimit = 0;
+       else
+       while (peersRemaining > 0 && needsAdjustment != 0)
+       {
+           needsAdjustment = 0;
+           bandwidthLimit = bandwidth / peersRemaining;
+
+           for (peer = host -> peers;
+                peer < & host -> peers [host -> peerCount];
+                ++ peer)
+           {
+               if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) ||
+                   peer -> incomingBandwidthThrottleEpoch == timeCurrent)
+                 continue;
+
+               if (peer -> outgoingBandwidth > 0 &&
+                   peer -> outgoingBandwidth >= bandwidthLimit)
+                 continue;
+
+               peer -> incomingBandwidthThrottleEpoch = timeCurrent;
+ 
+               needsAdjustment = 1;
+               -- peersRemaining;
+               bandwidth -= peer -> outgoingBandwidth;
+           }
+       }
+
+       for (peer = host -> peers;
+            peer < & host -> peers [host -> peerCount];
+            ++ peer)
+       {
+           if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
+             continue;
+
+           command.header.command = ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
+           command.header.channelID = 0xFF;
+           command.bandwidthLimit.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
+
+           if (peer -> incomingBandwidthThrottleEpoch == timeCurrent)
+             command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (peer -> outgoingBandwidth);
+           else
+             command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (bandwidthLimit);
+
+           enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
+       } 
+    }
+
+    host -> bandwidthThrottleEpoch = timeCurrent;
+
+    for (peer = host -> peers;
+         peer < & host -> peers [host -> peerCount];
+         ++ peer)
+    {
+        peer -> incomingDataTotal = 0;
+        peer -> outgoingDataTotal = 0;
+    }
+}
+    
+/** @} */

+ 27 - 27
ThirdParty/ENet/include/enet/callbacks.h

@@ -1,27 +1,27 @@
-/** 
- @file  callbacks.h
- @brief ENet callbacks
-*/
-#ifndef __ENET_CALLBACKS_H__
-#define __ENET_CALLBACKS_H__
-
-#include <stdlib.h>
-
-typedef struct _ENetCallbacks
-{
-    void * (ENET_CALLBACK * malloc) (size_t size);
-    void (ENET_CALLBACK * free) (void * memory);
-    void (ENET_CALLBACK * no_memory) (void);
-} ENetCallbacks;
-
-/** @defgroup callbacks ENet internal callbacks
-    @{
-    @ingroup private
-*/
-extern void * enet_malloc (size_t);
-extern void   enet_free (void *);
-
-/** @} */
-
-#endif /* __ENET_CALLBACKS_H__ */
-
+/** 
+ @file  callbacks.h
+ @brief ENet callbacks
+*/
+#ifndef __ENET_CALLBACKS_H__
+#define __ENET_CALLBACKS_H__
+
+#include <stdlib.h>
+
+typedef struct _ENetCallbacks
+{
+    void * (ENET_CALLBACK * malloc) (size_t size);
+    void (ENET_CALLBACK * free) (void * memory);
+    void (ENET_CALLBACK * no_memory) (void);
+} ENetCallbacks;
+
+/** @defgroup callbacks ENet internal callbacks
+    @{
+    @ingroup private
+*/
+extern void * enet_malloc (size_t);
+extern void   enet_free (void *);
+
+/** @} */
+
+#endif /* __ENET_CALLBACKS_H__ */
+

+ 540 - 540
ThirdParty/ENet/include/enet/enet.h

@@ -1,540 +1,540 @@
-/** 
- @file  enet.h
- @brief ENet public header file
-*/
-#ifndef __ENET_ENET_H__
-#define __ENET_ENET_H__
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-#include <stdlib.h>
-
-#ifdef WIN32
-#include "enet/win32.h"
-#else
-#include "enet/unix.h"
-#endif
-
-#include "enet/types.h"
-#include "enet/protocol.h"
-#include "enet/list.h"
-#include "enet/callbacks.h"
-
-#define ENET_VERSION_MAJOR 1
-#define ENET_VERSION_MINOR 3
-#define ENET_VERSION_PATCH 0
-#define ENET_VERSION_CREATE(major, minor, patch) (((major)<<16) | ((minor)<<8) | (patch))
-#define ENET_VERSION ENET_VERSION_CREATE(ENET_VERSION_MAJOR, ENET_VERSION_MINOR, ENET_VERSION_PATCH)
-
-typedef enet_uint32 ENetVersion;
-
-typedef enum _ENetSocketType
-{
-   ENET_SOCKET_TYPE_STREAM   = 1,
-   ENET_SOCKET_TYPE_DATAGRAM = 2
-} ENetSocketType;
-
-typedef enum _ENetSocketWait
-{
-   ENET_SOCKET_WAIT_NONE    = 0,
-   ENET_SOCKET_WAIT_SEND    = (1 << 0),
-   ENET_SOCKET_WAIT_RECEIVE = (1 << 1)
-} ENetSocketWait;
-
-typedef enum _ENetSocketOption
-{
-   ENET_SOCKOPT_NONBLOCK  = 1,
-   ENET_SOCKOPT_BROADCAST = 2,
-   ENET_SOCKOPT_RCVBUF    = 3,
-   ENET_SOCKOPT_SNDBUF    = 4,
-   ENET_SOCKOPT_REUSEADDR = 5
-} ENetSocketOption;
-
-enum
-{
-   ENET_HOST_ANY       = 0,            /**< specifies the default server host */
-   ENET_HOST_BROADCAST = 0xFFFFFFFF,   /**< specifies a subnet-wide broadcast */
-
-   ENET_PORT_ANY       = 0             /**< specifies that a port should be automatically chosen */
-};
-
-/**
- * Portable internet address structure. 
- *
- * The host must be specified in network byte-order, and the port must be in host 
- * byte-order. The constant ENET_HOST_ANY may be used to specify the default 
- * server host. The constant ENET_HOST_BROADCAST may be used to specify the
- * broadcast address (255.255.255.255).  This makes sense for enet_host_connect,
- * but not for enet_host_create.  Once a server responds to a broadcast, the
- * address is updated from ENET_HOST_BROADCAST to the server's actual IP address.
- */
-typedef struct _ENetAddress
-{
-   enet_uint32 host;
-   enet_uint16 port;
-} ENetAddress;
-
-/**
- * Packet flag bit constants.
- *
- * The host must be specified in network byte-order, and the port must be in
- * host byte-order. The constant ENET_HOST_ANY may be used to specify the
- * default server host.
- 
-   @sa ENetPacket
-*/
-typedef enum _ENetPacketFlag
-{
-   /** packet must be received by the target peer and resend attempts should be
-     * made until the packet is delivered */
-   ENET_PACKET_FLAG_RELIABLE    = (1 << 0),
-   /** packet will not be sequenced with other packets
-     * not supported for reliable packets
-     */
-   ENET_PACKET_FLAG_UNSEQUENCED = (1 << 1),
-   /** packet will not allocate data, and user must supply it instead */
-   ENET_PACKET_FLAG_NO_ALLOCATE = (1 << 2)
-} ENetPacketFlag;
-
-struct _ENetPacket;
-typedef void (ENET_CALLBACK * ENetPacketFreeCallback) (struct _ENetPacket *);
-
-/**
- * ENet packet structure.
- *
- * An ENet data packet that may be sent to or received from a peer. The shown 
- * fields should only be read and never modified. The data field contains the 
- * allocated data for the packet. The dataLength fields specifies the length 
- * of the allocated data.  The flags field is either 0 (specifying no flags), 
- * or a bitwise-or of any combination of the following flags:
- *
- *    ENET_PACKET_FLAG_RELIABLE - packet must be received by the target peer
- *    and resend attempts should be made until the packet is delivered
- *
- *    ENET_PACKET_FLAG_UNSEQUENCED - packet will not be sequenced with other packets 
- *    (not supported for reliable packets)
- *
- *    ENET_PACKET_FLAG_NO_ALLOCATE - packet will not allocate data, and user must supply it instead
- 
-   @sa ENetPacketFlag
- */
-typedef struct _ENetPacket
-{
-   size_t                   referenceCount;  /**< internal use only */
-   enet_uint32              flags;           /**< bitwise-or of ENetPacketFlag constants */
-   enet_uint8 *             data;            /**< allocated data for packet */
-   size_t                   dataLength;      /**< length of data */
-   ENetPacketFreeCallback   freeCallback;    /**< function to be called when the packet is no longer in use */
-} ENetPacket;
-
-typedef struct _ENetAcknowledgement
-{
-   ENetListNode acknowledgementList;
-   enet_uint32  sentTime;
-   ENetProtocol command;
-} ENetAcknowledgement;
-
-typedef struct _ENetOutgoingCommand
-{
-   ENetListNode outgoingCommandList;
-   enet_uint16  reliableSequenceNumber;
-   enet_uint16  unreliableSequenceNumber;
-   enet_uint32  sentTime;
-   enet_uint32  roundTripTimeout;
-   enet_uint32  roundTripTimeoutLimit;
-   enet_uint32  fragmentOffset;
-   enet_uint16  fragmentLength;
-   enet_uint16  sendAttempts;
-   ENetProtocol command;
-   ENetPacket * packet;
-} ENetOutgoingCommand;
-
-typedef struct _ENetIncomingCommand
-{  
-   ENetListNode     incomingCommandList;
-   enet_uint16      reliableSequenceNumber;
-   enet_uint16      unreliableSequenceNumber;
-   ENetProtocol     command;
-   enet_uint32      fragmentCount;
-   enet_uint32      fragmentsRemaining;
-   enet_uint32 *    fragments;
-   ENetPacket *     packet;
-} ENetIncomingCommand;
-
-typedef enum _ENetPeerState
-{
-   ENET_PEER_STATE_DISCONNECTED                = 0,
-   ENET_PEER_STATE_CONNECTING                  = 1,
-   ENET_PEER_STATE_ACKNOWLEDGING_CONNECT       = 2,
-   ENET_PEER_STATE_CONNECTION_PENDING          = 3,
-   ENET_PEER_STATE_CONNECTION_SUCCEEDED        = 4,
-   ENET_PEER_STATE_CONNECTED                   = 5,
-   ENET_PEER_STATE_DISCONNECT_LATER            = 6,
-   ENET_PEER_STATE_DISCONNECTING               = 7,
-   ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT    = 8,
-   ENET_PEER_STATE_ZOMBIE                      = 9 
-} ENetPeerState;
-
-#ifndef ENET_BUFFER_MAXIMUM
-#define ENET_BUFFER_MAXIMUM (1 + 2 * ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS)
-#endif
-
-enum
-{
-   ENET_HOST_RECEIVE_BUFFER_SIZE          = 256 * 1024,
-   ENET_HOST_SEND_BUFFER_SIZE             = 256 * 1024,
-   ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL  = 1000,
-   ENET_HOST_DEFAULT_MTU                  = 1400,
-
-   ENET_PEER_DEFAULT_ROUND_TRIP_TIME      = 500,
-   ENET_PEER_DEFAULT_PACKET_THROTTLE      = 32,
-   ENET_PEER_PACKET_THROTTLE_SCALE        = 32,
-   ENET_PEER_PACKET_THROTTLE_COUNTER      = 7, 
-   ENET_PEER_PACKET_THROTTLE_ACCELERATION = 2,
-   ENET_PEER_PACKET_THROTTLE_DECELERATION = 2,
-   ENET_PEER_PACKET_THROTTLE_INTERVAL     = 5000,
-   ENET_PEER_PACKET_LOSS_SCALE            = (1 << 16),
-   ENET_PEER_PACKET_LOSS_INTERVAL         = 10000,
-   ENET_PEER_WINDOW_SIZE_SCALE            = 64 * 1024,
-   ENET_PEER_TIMEOUT_LIMIT                = 32,
-   ENET_PEER_TIMEOUT_MINIMUM              = 5000,
-   ENET_PEER_TIMEOUT_MAXIMUM              = 30000,
-   ENET_PEER_PING_INTERVAL                = 500,
-   ENET_PEER_UNSEQUENCED_WINDOWS          = 64,
-   ENET_PEER_UNSEQUENCED_WINDOW_SIZE      = 1024,
-   ENET_PEER_FREE_UNSEQUENCED_WINDOWS     = 32,
-   ENET_PEER_RELIABLE_WINDOWS             = 16,
-   ENET_PEER_RELIABLE_WINDOW_SIZE         = 0x1000,
-   ENET_PEER_FREE_RELIABLE_WINDOWS        = 8
-};
-
-typedef struct _ENetChannel
-{
-   enet_uint16  outgoingReliableSequenceNumber;
-   enet_uint16  outgoingUnreliableSequenceNumber;
-   enet_uint16  usedReliableWindows;
-   enet_uint16  reliableWindows [ENET_PEER_RELIABLE_WINDOWS];
-   enet_uint16  incomingReliableSequenceNumber;
-   ENetList     incomingReliableCommands;
-   ENetList     incomingUnreliableCommands;
-} ENetChannel;
-
-/**
- * An ENet peer which data packets may be sent or received from. 
- *
- * No fields should be modified unless otherwise specified. 
- */
-typedef struct _ENetPeer
-{ 
-   ENetListNode  dispatchList;
-   struct _ENetHost * host;
-   enet_uint16   outgoingPeerID;
-   enet_uint16   incomingPeerID;
-   enet_uint32   connectID;
-   enet_uint8    outgoingSessionID;
-   enet_uint8    incomingSessionID;
-   ENetAddress   address;            /**< Internet address of the peer */
-   void *        data;               /**< Application private data, may be freely modified */
-   ENetPeerState state;
-   ENetChannel * channels;
-   size_t        channelCount;       /**< Number of channels allocated for communication with peer */
-   enet_uint32   incomingBandwidth;  /**< Downstream bandwidth of the client in bytes/second */
-   enet_uint32   outgoingBandwidth;  /**< Upstream bandwidth of the client in bytes/second */
-   enet_uint32   incomingBandwidthThrottleEpoch;
-   enet_uint32   outgoingBandwidthThrottleEpoch;
-   enet_uint32   incomingDataTotal;
-   enet_uint32   outgoingDataTotal;
-   enet_uint32   lastSendTime;
-   enet_uint32   lastReceiveTime;
-   enet_uint32   nextTimeout;
-   enet_uint32   earliestTimeout;
-   enet_uint32   packetLossEpoch;
-   enet_uint32   packetsSent;
-   enet_uint32   packetsLost;
-   enet_uint32   packetLoss;          /**< mean packet loss of reliable packets as a ratio with respect to the constant ENET_PEER_PACKET_LOSS_SCALE */
-   enet_uint32   packetLossVariance;
-   enet_uint32   packetThrottle;
-   enet_uint32   packetThrottleLimit;
-   enet_uint32   packetThrottleCounter;
-   enet_uint32   packetThrottleEpoch;
-   enet_uint32   packetThrottleAcceleration;
-   enet_uint32   packetThrottleDeceleration;
-   enet_uint32   packetThrottleInterval;
-   enet_uint32   lastRoundTripTime;
-   enet_uint32   lowestRoundTripTime;
-   enet_uint32   lastRoundTripTimeVariance;
-   enet_uint32   highestRoundTripTimeVariance;
-   enet_uint32   roundTripTime;            /**< mean round trip time (RTT), in milliseconds, between sending a reliable packet and receiving its acknowledgement */
-   enet_uint32   roundTripTimeVariance;
-   enet_uint32   mtu;
-   enet_uint32   windowSize;
-   enet_uint32   reliableDataInTransit;
-   enet_uint16   outgoingReliableSequenceNumber;
-   ENetList      acknowledgements;
-   ENetList      sentReliableCommands;
-   ENetList      sentUnreliableCommands;
-   ENetList      outgoingReliableCommands;
-   ENetList      outgoingUnreliableCommands;
-   ENetList      dispatchedCommands;
-   int           needsDispatch;
-   enet_uint16   incomingUnsequencedGroup;
-   enet_uint16   outgoingUnsequencedGroup;
-   enet_uint32   unsequencedWindow [ENET_PEER_UNSEQUENCED_WINDOW_SIZE / 32]; 
-   enet_uint32   eventData;
-} ENetPeer;
-
-/** An ENet packet compressor for compressing UDP packets before socket sends or receives.
- */
-typedef struct _ENetCompressor
-{
-   /** Context data for the compressor. Must be non-NULL. */
-   void * context;
-   /** Compresses from inBuffers[0:inBufferCount-1], containing inLimit bytes, to outData, outputting at most outLimit bytes. Should return 0 on failure. */
-   size_t (ENET_CALLBACK * compress) (void * context, const ENetBuffer * inBuffers, size_t inBufferCount, size_t inLimit, enet_uint8 * outData, size_t outLimit);
-   /** Decompresses from inData, containing inLimit bytes, to outData, outputting at most outLimit bytes. Should return 0 on failure. */
-   size_t (ENET_CALLBACK * decompress) (void * context, const enet_uint8 * inData, size_t inLimit, enet_uint8 * outData, size_t outLimit);
-   /** Destroys the context when compression is disabled or the host is destroyed. May be NULL. */
-   void (ENET_CALLBACK * destroy) (void * context);
-} ENetCompressor;
-
-/** Callback that computes the checksum of the data held in buffers[0:bufferCount-1] */
-typedef enet_uint32 (ENET_CALLBACK * ENetChecksumCallback) (const ENetBuffer * buffers, size_t bufferCount);
- 
-/** An ENet host for communicating with peers.
-  *
-  * No fields should be modified unless otherwise stated.
-
-    @sa enet_host_create()
-    @sa enet_host_destroy()
-    @sa enet_host_connect()
-    @sa enet_host_service()
-    @sa enet_host_flush()
-    @sa enet_host_broadcast()
-    @sa enet_host_compress()
-    @sa enet_host_compress_with_range_coder()
-    @sa enet_host_channel_limit()
-    @sa enet_host_bandwidth_limit()
-    @sa enet_host_bandwidth_throttle()
-  */
-typedef struct _ENetHost
-{
-   ENetSocket           socket;
-   ENetAddress          address;                     /**< Internet address of the host */
-   enet_uint32          incomingBandwidth;           /**< downstream bandwidth of the host */
-   enet_uint32          outgoingBandwidth;           /**< upstream bandwidth of the host */
-   enet_uint32          bandwidthThrottleEpoch;
-   enet_uint32          mtu;
-   enet_uint32          randomSeed;
-   int                  recalculateBandwidthLimits;
-   ENetPeer *           peers;                       /**< array of peers allocated for this host */
-   size_t               peerCount;                   /**< number of peers allocated for this host */
-   size_t               channelLimit;                /**< maximum number of channels allowed for connected peers */
-   enet_uint32          serviceTime;
-   ENetList             dispatchQueue;
-   int                  continueSending;
-   size_t               packetSize;
-   enet_uint16          headerFlags;
-   ENetProtocol         commands [ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS];
-   size_t               commandCount;
-   ENetBuffer           buffers [ENET_BUFFER_MAXIMUM];
-   size_t               bufferCount;
-   ENetChecksumCallback checksum;                    /**< callback the user can set to enable packet checksums for this host */
-   ENetCompressor       compressor;
-   enet_uint8           packetData [2][ENET_PROTOCOL_MAXIMUM_MTU];
-   ENetAddress          receivedAddress;
-   enet_uint8 *         receivedData;
-   size_t               receivedDataLength;
-   enet_uint32          totalSentData;               /**< total data sent, user should reset to 0 as needed to prevent overflow */
-   enet_uint32          totalSentPackets;            /**< total UDP packets sent, user should reset to 0 as needed to prevent overflow */
-   enet_uint32          totalReceivedData;           /**< total data received, user should reset to 0 as needed to prevent overflow */
-   enet_uint32          totalReceivedPackets;        /**< total UDP packets received, user should reset to 0 as needed to prevent overflow */
-} ENetHost;
-
-/**
- * An ENet event type, as specified in @ref ENetEvent.
- */
-typedef enum _ENetEventType
-{
-   /** no event occurred within the specified time limit */
-   ENET_EVENT_TYPE_NONE       = 0,  
-
-   /** a connection request initiated by enet_host_connect has completed.  
-     * The peer field contains the peer which successfully connected. 
-     */
-   ENET_EVENT_TYPE_CONNECT    = 1,  
-
-   /** a peer has disconnected.  This event is generated on a successful 
-     * completion of a disconnect initiated by enet_pper_disconnect, if 
-     * a peer has timed out, or if a connection request intialized by 
-     * enet_host_connect has timed out.  The peer field contains the peer 
-     * which disconnected. The data field contains user supplied data 
-     * describing the disconnection, or 0, if none is available.
-     */
-   ENET_EVENT_TYPE_DISCONNECT = 2,  
-
-   /** a packet has been received from a peer.  The peer field specifies the
-     * peer which sent the packet.  The channelID field specifies the channel
-     * number upon which the packet was received.  The packet field contains
-     * the packet that was received; this packet must be destroyed with
-     * enet_packet_destroy after use.
-     */
-   ENET_EVENT_TYPE_RECEIVE    = 3
-} ENetEventType;
-
-/**
- * An ENet event as returned by enet_host_service().
-   
-   @sa enet_host_service
- */
-typedef struct _ENetEvent 
-{
-   ENetEventType        type;      /**< type of the event */
-   ENetPeer *           peer;      /**< peer that generated a connect, disconnect or receive event */
-   enet_uint8           channelID; /**< channel on the peer that generated the event, if appropriate */
-   enet_uint32          data;      /**< data associated with the event, if appropriate */
-   ENetPacket *         packet;    /**< packet associated with the event, if appropriate */
-} ENetEvent;
-
-/** @defgroup global ENet global functions
-    @{ 
-*/
-
-/** 
-  Initializes ENet globally.  Must be called prior to using any functions in
-  ENet.
-  @returns 0 on success, < 0 on failure
-*/
-ENET_API int enet_initialize (void);
-
-/** 
-  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.
-
-  @param version the constant ENET_VERSION should be supplied so ENet knows which version of ENetCallbacks struct to use
-  @param inits user-overriden callbacks where any NULL callbacks will use ENet's defaults
-  @returns 0 on success, < 0 on failure
-*/
-ENET_API int enet_initialize_with_callbacks (ENetVersion version, const ENetCallbacks * inits);
-
-/** 
-  Shuts down ENet globally.  Should be called when a program that has
-  initialized ENet exits.
-*/
-ENET_API void enet_deinitialize (void);
-
-/** @} */
-
-/** @defgroup private ENet private implementation functions */
-
-/**
-  Returns the wall-time in milliseconds.  Its initial value is unspecified
-  unless otherwise set.
-  */
-ENET_API enet_uint32 enet_time_get (void);
-/**
-  Sets the current wall-time in milliseconds.
-  */
-ENET_API void enet_time_set (enet_uint32);
-
-/** @defgroup socket ENet socket functions
-    @{
-*/
-ENET_API ENetSocket enet_socket_create (ENetSocketType);
-ENET_API int        enet_socket_bind (ENetSocket, const ENetAddress *);
-ENET_API int        enet_socket_listen (ENetSocket, int);
-ENET_API ENetSocket enet_socket_accept (ENetSocket, ENetAddress *);
-ENET_API int        enet_socket_connect (ENetSocket, const ENetAddress *);
-ENET_API int        enet_socket_send (ENetSocket, const ENetAddress *, const ENetBuffer *, size_t);
-ENET_API int        enet_socket_receive (ENetSocket, ENetAddress *, ENetBuffer *, size_t);
-ENET_API int        enet_socket_wait (ENetSocket, enet_uint32 *, enet_uint32);
-ENET_API int        enet_socket_set_option (ENetSocket, ENetSocketOption, int);
-ENET_API void       enet_socket_destroy (ENetSocket);
-ENET_API int        enet_socketset_select (ENetSocket, ENetSocketSet *, ENetSocketSet *, enet_uint32);
-
-/** @} */
-
-/** @defgroup Address ENet address functions
-    @{
-*/
-/** Attempts to resolve the host named by the parameter hostName and sets
-    the host field in the address parameter if successful.
-    @param address destination to store resolved address
-    @param hostName host name to lookup
-    @retval 0 on success
-    @retval < 0 on failure
-    @returns the address of the given hostName in address on success
-*/
-ENET_API int enet_address_set_host (ENetAddress * address, const char * hostName);
-
-/** Gives the printable form of the ip address specified in the address parameter.
-    @param address    address printed
-    @param hostName   destination for name, must not be NULL
-    @param nameLength maximum length of hostName.
-    @returns the null-terminated name of the host in hostName on success
-    @retval 0 on success
-    @retval < 0 on failure
-*/
-ENET_API int enet_address_get_host_ip (const ENetAddress * address, char * hostName, size_t nameLength);
-
-/** Attempts to do a reverse lookup of the host field in the address parameter.
-    @param address    address used for reverse lookup
-    @param hostName   destination for name, must not be NULL
-    @param nameLength maximum length of hostName.
-    @returns the null-terminated name of the host in hostName on success
-    @retval 0 on success
-    @retval < 0 on failure
-*/
-ENET_API int enet_address_get_host (const ENetAddress * address, char * hostName, size_t nameLength);
-
-/** @} */
-
-ENET_API ENetPacket * enet_packet_create (const void *, size_t, enet_uint32);
-ENET_API void         enet_packet_destroy (ENetPacket *);
-ENET_API int          enet_packet_resize  (ENetPacket *, size_t);
-extern enet_uint32    enet_crc32 (const ENetBuffer *, size_t);
-                
-ENET_API ENetHost * enet_host_create (const ENetAddress *, size_t, size_t, enet_uint32, enet_uint32);
-ENET_API void       enet_host_destroy (ENetHost *);
-ENET_API ENetPeer * enet_host_connect (ENetHost *, const ENetAddress *, size_t, enet_uint32);
-ENET_API int        enet_host_check_events (ENetHost *, ENetEvent *);
-ENET_API int        enet_host_service (ENetHost *, ENetEvent *, enet_uint32);
-ENET_API void       enet_host_flush (ENetHost *);
-ENET_API void       enet_host_broadcast (ENetHost *, enet_uint8, ENetPacket *);
-ENET_API void       enet_host_compress (ENetHost *, const ENetCompressor *);
-ENET_API int        enet_host_compress_with_range_coder (ENetHost * host);
-ENET_API void       enet_host_channel_limit (ENetHost *, size_t);
-ENET_API void       enet_host_bandwidth_limit (ENetHost *, enet_uint32, enet_uint32);
-extern   void       enet_host_bandwidth_throttle (ENetHost *);
-
-ENET_API int                 enet_peer_send (ENetPeer *, enet_uint8, ENetPacket *);
-ENET_API ENetPacket *        enet_peer_receive (ENetPeer *, enet_uint8 * channelID);
-ENET_API void                enet_peer_ping (ENetPeer *);
-ENET_API void                enet_peer_reset (ENetPeer *);
-ENET_API void                enet_peer_disconnect (ENetPeer *, enet_uint32);
-ENET_API void                enet_peer_disconnect_now (ENetPeer *, enet_uint32);
-ENET_API void                enet_peer_disconnect_later (ENetPeer *, enet_uint32);
-ENET_API void                enet_peer_throttle_configure (ENetPeer *, enet_uint32, enet_uint32, enet_uint32);
-extern int                   enet_peer_throttle (ENetPeer *, enet_uint32);
-extern void                  enet_peer_reset_queues (ENetPeer *);
-extern void                  enet_peer_setup_outgoing_command (ENetPeer *, ENetOutgoingCommand *);
-extern ENetOutgoingCommand * enet_peer_queue_outgoing_command (ENetPeer *, const ENetProtocol *, ENetPacket *, enet_uint32, enet_uint16);
-extern ENetIncomingCommand * enet_peer_queue_incoming_command (ENetPeer *, const ENetProtocol *, ENetPacket *, enet_uint32);
-extern ENetAcknowledgement * enet_peer_queue_acknowledgement (ENetPeer *, const ENetProtocol *, enet_uint16);
-extern void                  enet_peer_dispatch_incoming_unreliable_commands (ENetPeer *, ENetChannel *);
-extern void                  enet_peer_dispatch_incoming_reliable_commands (ENetPeer *, ENetChannel *);
-
-ENET_API void * enet_range_coder_create (void);
-ENET_API void   enet_range_coder_destroy (void *);
-ENET_API size_t enet_range_coder_compress (void *, const ENetBuffer *, size_t, size_t, enet_uint8 *, size_t);
-ENET_API size_t enet_range_coder_decompress (void *, const enet_uint8 *, size_t, enet_uint8 *, size_t);
-   
-extern size_t enet_protocol_command_size (enet_uint8);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __ENET_ENET_H__ */
-
+/** 
+ @file  enet.h
+ @brief ENet public header file
+*/
+#ifndef __ENET_ENET_H__
+#define __ENET_ENET_H__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdlib.h>
+
+#ifdef WIN32
+#include "enet/win32.h"
+#else
+#include "enet/unix.h"
+#endif
+
+#include "enet/types.h"
+#include "enet/protocol.h"
+#include "enet/list.h"
+#include "enet/callbacks.h"
+
+#define ENET_VERSION_MAJOR 1
+#define ENET_VERSION_MINOR 3
+#define ENET_VERSION_PATCH 1
+#define ENET_VERSION_CREATE(major, minor, patch) (((major)<<16) | ((minor)<<8) | (patch))
+#define ENET_VERSION ENET_VERSION_CREATE(ENET_VERSION_MAJOR, ENET_VERSION_MINOR, ENET_VERSION_PATCH)
+
+typedef enet_uint32 ENetVersion;
+
+typedef enum _ENetSocketType
+{
+   ENET_SOCKET_TYPE_STREAM   = 1,
+   ENET_SOCKET_TYPE_DATAGRAM = 2
+} ENetSocketType;
+
+typedef enum _ENetSocketWait
+{
+   ENET_SOCKET_WAIT_NONE    = 0,
+   ENET_SOCKET_WAIT_SEND    = (1 << 0),
+   ENET_SOCKET_WAIT_RECEIVE = (1 << 1)
+} ENetSocketWait;
+
+typedef enum _ENetSocketOption
+{
+   ENET_SOCKOPT_NONBLOCK  = 1,
+   ENET_SOCKOPT_BROADCAST = 2,
+   ENET_SOCKOPT_RCVBUF    = 3,
+   ENET_SOCKOPT_SNDBUF    = 4,
+   ENET_SOCKOPT_REUSEADDR = 5
+} ENetSocketOption;
+
+enum
+{
+   ENET_HOST_ANY       = 0,            /**< specifies the default server host */
+   ENET_HOST_BROADCAST = 0xFFFFFFFF,   /**< specifies a subnet-wide broadcast */
+
+   ENET_PORT_ANY       = 0             /**< specifies that a port should be automatically chosen */
+};
+
+/**
+ * Portable internet address structure. 
+ *
+ * The host must be specified in network byte-order, and the port must be in host 
+ * byte-order. The constant ENET_HOST_ANY may be used to specify the default 
+ * server host. The constant ENET_HOST_BROADCAST may be used to specify the
+ * broadcast address (255.255.255.255).  This makes sense for enet_host_connect,
+ * but not for enet_host_create.  Once a server responds to a broadcast, the
+ * address is updated from ENET_HOST_BROADCAST to the server's actual IP address.
+ */
+typedef struct _ENetAddress
+{
+   enet_uint32 host;
+   enet_uint16 port;
+} ENetAddress;
+
+/**
+ * Packet flag bit constants.
+ *
+ * The host must be specified in network byte-order, and the port must be in
+ * host byte-order. The constant ENET_HOST_ANY may be used to specify the
+ * default server host.
+ 
+   @sa ENetPacket
+*/
+typedef enum _ENetPacketFlag
+{
+   /** packet must be received by the target peer and resend attempts should be
+     * made until the packet is delivered */
+   ENET_PACKET_FLAG_RELIABLE    = (1 << 0),
+   /** packet will not be sequenced with other packets
+     * not supported for reliable packets
+     */
+   ENET_PACKET_FLAG_UNSEQUENCED = (1 << 1),
+   /** packet will not allocate data, and user must supply it instead */
+   ENET_PACKET_FLAG_NO_ALLOCATE = (1 << 2)
+} ENetPacketFlag;
+
+struct _ENetPacket;
+typedef void (ENET_CALLBACK * ENetPacketFreeCallback) (struct _ENetPacket *);
+
+/**
+ * ENet packet structure.
+ *
+ * An ENet data packet that may be sent to or received from a peer. The shown 
+ * fields should only be read and never modified. The data field contains the 
+ * allocated data for the packet. The dataLength fields specifies the length 
+ * of the allocated data.  The flags field is either 0 (specifying no flags), 
+ * or a bitwise-or of any combination of the following flags:
+ *
+ *    ENET_PACKET_FLAG_RELIABLE - packet must be received by the target peer
+ *    and resend attempts should be made until the packet is delivered
+ *
+ *    ENET_PACKET_FLAG_UNSEQUENCED - packet will not be sequenced with other packets 
+ *    (not supported for reliable packets)
+ *
+ *    ENET_PACKET_FLAG_NO_ALLOCATE - packet will not allocate data, and user must supply it instead
+ 
+   @sa ENetPacketFlag
+ */
+typedef struct _ENetPacket
+{
+   size_t                   referenceCount;  /**< internal use only */
+   enet_uint32              flags;           /**< bitwise-or of ENetPacketFlag constants */
+   enet_uint8 *             data;            /**< allocated data for packet */
+   size_t                   dataLength;      /**< length of data */
+   ENetPacketFreeCallback   freeCallback;    /**< function to be called when the packet is no longer in use */
+} ENetPacket;
+
+typedef struct _ENetAcknowledgement
+{
+   ENetListNode acknowledgementList;
+   enet_uint32  sentTime;
+   ENetProtocol command;
+} ENetAcknowledgement;
+
+typedef struct _ENetOutgoingCommand
+{
+   ENetListNode outgoingCommandList;
+   enet_uint16  reliableSequenceNumber;
+   enet_uint16  unreliableSequenceNumber;
+   enet_uint32  sentTime;
+   enet_uint32  roundTripTimeout;
+   enet_uint32  roundTripTimeoutLimit;
+   enet_uint32  fragmentOffset;
+   enet_uint16  fragmentLength;
+   enet_uint16  sendAttempts;
+   ENetProtocol command;
+   ENetPacket * packet;
+} ENetOutgoingCommand;
+
+typedef struct _ENetIncomingCommand
+{  
+   ENetListNode     incomingCommandList;
+   enet_uint16      reliableSequenceNumber;
+   enet_uint16      unreliableSequenceNumber;
+   ENetProtocol     command;
+   enet_uint32      fragmentCount;
+   enet_uint32      fragmentsRemaining;
+   enet_uint32 *    fragments;
+   ENetPacket *     packet;
+} ENetIncomingCommand;
+
+typedef enum _ENetPeerState
+{
+   ENET_PEER_STATE_DISCONNECTED                = 0,
+   ENET_PEER_STATE_CONNECTING                  = 1,
+   ENET_PEER_STATE_ACKNOWLEDGING_CONNECT       = 2,
+   ENET_PEER_STATE_CONNECTION_PENDING          = 3,
+   ENET_PEER_STATE_CONNECTION_SUCCEEDED        = 4,
+   ENET_PEER_STATE_CONNECTED                   = 5,
+   ENET_PEER_STATE_DISCONNECT_LATER            = 6,
+   ENET_PEER_STATE_DISCONNECTING               = 7,
+   ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT    = 8,
+   ENET_PEER_STATE_ZOMBIE                      = 9 
+} ENetPeerState;
+
+#ifndef ENET_BUFFER_MAXIMUM
+#define ENET_BUFFER_MAXIMUM (1 + 2 * ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS)
+#endif
+
+enum
+{
+   ENET_HOST_RECEIVE_BUFFER_SIZE          = 256 * 1024,
+   ENET_HOST_SEND_BUFFER_SIZE             = 256 * 1024,
+   ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL  = 1000,
+   ENET_HOST_DEFAULT_MTU                  = 1400,
+
+   ENET_PEER_DEFAULT_ROUND_TRIP_TIME      = 500,
+   ENET_PEER_DEFAULT_PACKET_THROTTLE      = 32,
+   ENET_PEER_PACKET_THROTTLE_SCALE        = 32,
+   ENET_PEER_PACKET_THROTTLE_COUNTER      = 7, 
+   ENET_PEER_PACKET_THROTTLE_ACCELERATION = 2,
+   ENET_PEER_PACKET_THROTTLE_DECELERATION = 2,
+   ENET_PEER_PACKET_THROTTLE_INTERVAL     = 5000,
+   ENET_PEER_PACKET_LOSS_SCALE            = (1 << 16),
+   ENET_PEER_PACKET_LOSS_INTERVAL         = 10000,
+   ENET_PEER_WINDOW_SIZE_SCALE            = 64 * 1024,
+   ENET_PEER_TIMEOUT_LIMIT                = 32,
+   ENET_PEER_TIMEOUT_MINIMUM              = 5000,
+   ENET_PEER_TIMEOUT_MAXIMUM              = 30000,
+   ENET_PEER_PING_INTERVAL                = 500,
+   ENET_PEER_UNSEQUENCED_WINDOWS          = 64,
+   ENET_PEER_UNSEQUENCED_WINDOW_SIZE      = 1024,
+   ENET_PEER_FREE_UNSEQUENCED_WINDOWS     = 32,
+   ENET_PEER_RELIABLE_WINDOWS             = 16,
+   ENET_PEER_RELIABLE_WINDOW_SIZE         = 0x1000,
+   ENET_PEER_FREE_RELIABLE_WINDOWS        = 8
+};
+
+typedef struct _ENetChannel
+{
+   enet_uint16  outgoingReliableSequenceNumber;
+   enet_uint16  outgoingUnreliableSequenceNumber;
+   enet_uint16  usedReliableWindows;
+   enet_uint16  reliableWindows [ENET_PEER_RELIABLE_WINDOWS];
+   enet_uint16  incomingReliableSequenceNumber;
+   ENetList     incomingReliableCommands;
+   ENetList     incomingUnreliableCommands;
+} ENetChannel;
+
+/**
+ * An ENet peer which data packets may be sent or received from. 
+ *
+ * No fields should be modified unless otherwise specified. 
+ */
+typedef struct _ENetPeer
+{ 
+   ENetListNode  dispatchList;
+   struct _ENetHost * host;
+   enet_uint16   outgoingPeerID;
+   enet_uint16   incomingPeerID;
+   enet_uint32   connectID;
+   enet_uint8    outgoingSessionID;
+   enet_uint8    incomingSessionID;
+   ENetAddress   address;            /**< Internet address of the peer */
+   void *        data;               /**< Application private data, may be freely modified */
+   ENetPeerState state;
+   ENetChannel * channels;
+   size_t        channelCount;       /**< Number of channels allocated for communication with peer */
+   enet_uint32   incomingBandwidth;  /**< Downstream bandwidth of the client in bytes/second */
+   enet_uint32   outgoingBandwidth;  /**< Upstream bandwidth of the client in bytes/second */
+   enet_uint32   incomingBandwidthThrottleEpoch;
+   enet_uint32   outgoingBandwidthThrottleEpoch;
+   enet_uint32   incomingDataTotal;
+   enet_uint32   outgoingDataTotal;
+   enet_uint32   lastSendTime;
+   enet_uint32   lastReceiveTime;
+   enet_uint32   nextTimeout;
+   enet_uint32   earliestTimeout;
+   enet_uint32   packetLossEpoch;
+   enet_uint32   packetsSent;
+   enet_uint32   packetsLost;
+   enet_uint32   packetLoss;          /**< mean packet loss of reliable packets as a ratio with respect to the constant ENET_PEER_PACKET_LOSS_SCALE */
+   enet_uint32   packetLossVariance;
+   enet_uint32   packetThrottle;
+   enet_uint32   packetThrottleLimit;
+   enet_uint32   packetThrottleCounter;
+   enet_uint32   packetThrottleEpoch;
+   enet_uint32   packetThrottleAcceleration;
+   enet_uint32   packetThrottleDeceleration;
+   enet_uint32   packetThrottleInterval;
+   enet_uint32   lastRoundTripTime;
+   enet_uint32   lowestRoundTripTime;
+   enet_uint32   lastRoundTripTimeVariance;
+   enet_uint32   highestRoundTripTimeVariance;
+   enet_uint32   roundTripTime;            /**< mean round trip time (RTT), in milliseconds, between sending a reliable packet and receiving its acknowledgement */
+   enet_uint32   roundTripTimeVariance;
+   enet_uint32   mtu;
+   enet_uint32   windowSize;
+   enet_uint32   reliableDataInTransit;
+   enet_uint16   outgoingReliableSequenceNumber;
+   ENetList      acknowledgements;
+   ENetList      sentReliableCommands;
+   ENetList      sentUnreliableCommands;
+   ENetList      outgoingReliableCommands;
+   ENetList      outgoingUnreliableCommands;
+   ENetList      dispatchedCommands;
+   int           needsDispatch;
+   enet_uint16   incomingUnsequencedGroup;
+   enet_uint16   outgoingUnsequencedGroup;
+   enet_uint32   unsequencedWindow [ENET_PEER_UNSEQUENCED_WINDOW_SIZE / 32]; 
+   enet_uint32   eventData;
+} ENetPeer;
+
+/** An ENet packet compressor for compressing UDP packets before socket sends or receives.
+ */
+typedef struct _ENetCompressor
+{
+   /** Context data for the compressor. Must be non-NULL. */
+   void * context;
+   /** Compresses from inBuffers[0:inBufferCount-1], containing inLimit bytes, to outData, outputting at most outLimit bytes. Should return 0 on failure. */
+   size_t (ENET_CALLBACK * compress) (void * context, const ENetBuffer * inBuffers, size_t inBufferCount, size_t inLimit, enet_uint8 * outData, size_t outLimit);
+   /** Decompresses from inData, containing inLimit bytes, to outData, outputting at most outLimit bytes. Should return 0 on failure. */
+   size_t (ENET_CALLBACK * decompress) (void * context, const enet_uint8 * inData, size_t inLimit, enet_uint8 * outData, size_t outLimit);
+   /** Destroys the context when compression is disabled or the host is destroyed. May be NULL. */
+   void (ENET_CALLBACK * destroy) (void * context);
+} ENetCompressor;
+
+/** Callback that computes the checksum of the data held in buffers[0:bufferCount-1] */
+typedef enet_uint32 (ENET_CALLBACK * ENetChecksumCallback) (const ENetBuffer * buffers, size_t bufferCount);
+ 
+/** An ENet host for communicating with peers.
+  *
+  * No fields should be modified unless otherwise stated.
+
+    @sa enet_host_create()
+    @sa enet_host_destroy()
+    @sa enet_host_connect()
+    @sa enet_host_service()
+    @sa enet_host_flush()
+    @sa enet_host_broadcast()
+    @sa enet_host_compress()
+    @sa enet_host_compress_with_range_coder()
+    @sa enet_host_channel_limit()
+    @sa enet_host_bandwidth_limit()
+    @sa enet_host_bandwidth_throttle()
+  */
+typedef struct _ENetHost
+{
+   ENetSocket           socket;
+   ENetAddress          address;                     /**< Internet address of the host */
+   enet_uint32          incomingBandwidth;           /**< downstream bandwidth of the host */
+   enet_uint32          outgoingBandwidth;           /**< upstream bandwidth of the host */
+   enet_uint32          bandwidthThrottleEpoch;
+   enet_uint32          mtu;
+   enet_uint32          randomSeed;
+   int                  recalculateBandwidthLimits;
+   ENetPeer *           peers;                       /**< array of peers allocated for this host */
+   size_t               peerCount;                   /**< number of peers allocated for this host */
+   size_t               channelLimit;                /**< maximum number of channels allowed for connected peers */
+   enet_uint32          serviceTime;
+   ENetList             dispatchQueue;
+   int                  continueSending;
+   size_t               packetSize;
+   enet_uint16          headerFlags;
+   ENetProtocol         commands [ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS];
+   size_t               commandCount;
+   ENetBuffer           buffers [ENET_BUFFER_MAXIMUM];
+   size_t               bufferCount;
+   ENetChecksumCallback checksum;                    /**< callback the user can set to enable packet checksums for this host */
+   ENetCompressor       compressor;
+   enet_uint8           packetData [2][ENET_PROTOCOL_MAXIMUM_MTU];
+   ENetAddress          receivedAddress;
+   enet_uint8 *         receivedData;
+   size_t               receivedDataLength;
+   enet_uint32          totalSentData;               /**< total data sent, user should reset to 0 as needed to prevent overflow */
+   enet_uint32          totalSentPackets;            /**< total UDP packets sent, user should reset to 0 as needed to prevent overflow */
+   enet_uint32          totalReceivedData;           /**< total data received, user should reset to 0 as needed to prevent overflow */
+   enet_uint32          totalReceivedPackets;        /**< total UDP packets received, user should reset to 0 as needed to prevent overflow */
+} ENetHost;
+
+/**
+ * An ENet event type, as specified in @ref ENetEvent.
+ */
+typedef enum _ENetEventType
+{
+   /** no event occurred within the specified time limit */
+   ENET_EVENT_TYPE_NONE       = 0,  
+
+   /** a connection request initiated by enet_host_connect has completed.  
+     * The peer field contains the peer which successfully connected. 
+     */
+   ENET_EVENT_TYPE_CONNECT    = 1,  
+
+   /** a peer has disconnected.  This event is generated on a successful 
+     * completion of a disconnect initiated by enet_pper_disconnect, if 
+     * a peer has timed out, or if a connection request intialized by 
+     * enet_host_connect has timed out.  The peer field contains the peer 
+     * which disconnected. The data field contains user supplied data 
+     * describing the disconnection, or 0, if none is available.
+     */
+   ENET_EVENT_TYPE_DISCONNECT = 2,  
+
+   /** a packet has been received from a peer.  The peer field specifies the
+     * peer which sent the packet.  The channelID field specifies the channel
+     * number upon which the packet was received.  The packet field contains
+     * the packet that was received; this packet must be destroyed with
+     * enet_packet_destroy after use.
+     */
+   ENET_EVENT_TYPE_RECEIVE    = 3
+} ENetEventType;
+
+/**
+ * An ENet event as returned by enet_host_service().
+   
+   @sa enet_host_service
+ */
+typedef struct _ENetEvent 
+{
+   ENetEventType        type;      /**< type of the event */
+   ENetPeer *           peer;      /**< peer that generated a connect, disconnect or receive event */
+   enet_uint8           channelID; /**< channel on the peer that generated the event, if appropriate */
+   enet_uint32          data;      /**< data associated with the event, if appropriate */
+   ENetPacket *         packet;    /**< packet associated with the event, if appropriate */
+} ENetEvent;
+
+/** @defgroup global ENet global functions
+    @{ 
+*/
+
+/** 
+  Initializes ENet globally.  Must be called prior to using any functions in
+  ENet.
+  @returns 0 on success, < 0 on failure
+*/
+ENET_API int enet_initialize (void);
+
+/** 
+  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.
+
+  @param version the constant ENET_VERSION should be supplied so ENet knows which version of ENetCallbacks struct to use
+  @param inits user-overriden callbacks where any NULL callbacks will use ENet's defaults
+  @returns 0 on success, < 0 on failure
+*/
+ENET_API int enet_initialize_with_callbacks (ENetVersion version, const ENetCallbacks * inits);
+
+/** 
+  Shuts down ENet globally.  Should be called when a program that has
+  initialized ENet exits.
+*/
+ENET_API void enet_deinitialize (void);
+
+/** @} */
+
+/** @defgroup private ENet private implementation functions */
+
+/**
+  Returns the wall-time in milliseconds.  Its initial value is unspecified
+  unless otherwise set.
+  */
+ENET_API enet_uint32 enet_time_get (void);
+/**
+  Sets the current wall-time in milliseconds.
+  */
+ENET_API void enet_time_set (enet_uint32);
+
+/** @defgroup socket ENet socket functions
+    @{
+*/
+ENET_API ENetSocket enet_socket_create (ENetSocketType);
+ENET_API int        enet_socket_bind (ENetSocket, const ENetAddress *);
+ENET_API int        enet_socket_listen (ENetSocket, int);
+ENET_API ENetSocket enet_socket_accept (ENetSocket, ENetAddress *);
+ENET_API int        enet_socket_connect (ENetSocket, const ENetAddress *);
+ENET_API int        enet_socket_send (ENetSocket, const ENetAddress *, const ENetBuffer *, size_t);
+ENET_API int        enet_socket_receive (ENetSocket, ENetAddress *, ENetBuffer *, size_t);
+ENET_API int        enet_socket_wait (ENetSocket, enet_uint32 *, enet_uint32);
+ENET_API int        enet_socket_set_option (ENetSocket, ENetSocketOption, int);
+ENET_API void       enet_socket_destroy (ENetSocket);
+ENET_API int        enet_socketset_select (ENetSocket, ENetSocketSet *, ENetSocketSet *, enet_uint32);
+
+/** @} */
+
+/** @defgroup Address ENet address functions
+    @{
+*/
+/** Attempts to resolve the host named by the parameter hostName and sets
+    the host field in the address parameter if successful.
+    @param address destination to store resolved address
+    @param hostName host name to lookup
+    @retval 0 on success
+    @retval < 0 on failure
+    @returns the address of the given hostName in address on success
+*/
+ENET_API int enet_address_set_host (ENetAddress * address, const char * hostName);
+
+/** Gives the printable form of the ip address specified in the address parameter.
+    @param address    address printed
+    @param hostName   destination for name, must not be NULL
+    @param nameLength maximum length of hostName.
+    @returns the null-terminated name of the host in hostName on success
+    @retval 0 on success
+    @retval < 0 on failure
+*/
+ENET_API int enet_address_get_host_ip (const ENetAddress * address, char * hostName, size_t nameLength);
+
+/** Attempts to do a reverse lookup of the host field in the address parameter.
+    @param address    address used for reverse lookup
+    @param hostName   destination for name, must not be NULL
+    @param nameLength maximum length of hostName.
+    @returns the null-terminated name of the host in hostName on success
+    @retval 0 on success
+    @retval < 0 on failure
+*/
+ENET_API int enet_address_get_host (const ENetAddress * address, char * hostName, size_t nameLength);
+
+/** @} */
+
+ENET_API ENetPacket * enet_packet_create (const void *, size_t, enet_uint32);
+ENET_API void         enet_packet_destroy (ENetPacket *);
+ENET_API int          enet_packet_resize  (ENetPacket *, size_t);
+extern enet_uint32    enet_crc32 (const ENetBuffer *, size_t);
+                
+ENET_API ENetHost * enet_host_create (const ENetAddress *, size_t, size_t, enet_uint32, enet_uint32);
+ENET_API void       enet_host_destroy (ENetHost *);
+ENET_API ENetPeer * enet_host_connect (ENetHost *, const ENetAddress *, size_t, enet_uint32);
+ENET_API int        enet_host_check_events (ENetHost *, ENetEvent *);
+ENET_API int        enet_host_service (ENetHost *, ENetEvent *, enet_uint32);
+ENET_API void       enet_host_flush (ENetHost *);
+ENET_API void       enet_host_broadcast (ENetHost *, enet_uint8, ENetPacket *);
+ENET_API void       enet_host_compress (ENetHost *, const ENetCompressor *);
+ENET_API int        enet_host_compress_with_range_coder (ENetHost * host);
+ENET_API void       enet_host_channel_limit (ENetHost *, size_t);
+ENET_API void       enet_host_bandwidth_limit (ENetHost *, enet_uint32, enet_uint32);
+extern   void       enet_host_bandwidth_throttle (ENetHost *);
+
+ENET_API int                 enet_peer_send (ENetPeer *, enet_uint8, ENetPacket *);
+ENET_API ENetPacket *        enet_peer_receive (ENetPeer *, enet_uint8 * channelID);
+ENET_API void                enet_peer_ping (ENetPeer *);
+ENET_API void                enet_peer_reset (ENetPeer *);
+ENET_API void                enet_peer_disconnect (ENetPeer *, enet_uint32);
+ENET_API void                enet_peer_disconnect_now (ENetPeer *, enet_uint32);
+ENET_API void                enet_peer_disconnect_later (ENetPeer *, enet_uint32);
+ENET_API void                enet_peer_throttle_configure (ENetPeer *, enet_uint32, enet_uint32, enet_uint32);
+extern int                   enet_peer_throttle (ENetPeer *, enet_uint32);
+extern void                  enet_peer_reset_queues (ENetPeer *);
+extern void                  enet_peer_setup_outgoing_command (ENetPeer *, ENetOutgoingCommand *);
+extern ENetOutgoingCommand * enet_peer_queue_outgoing_command (ENetPeer *, const ENetProtocol *, ENetPacket *, enet_uint32, enet_uint16);
+extern ENetIncomingCommand * enet_peer_queue_incoming_command (ENetPeer *, const ENetProtocol *, ENetPacket *, enet_uint32);
+extern ENetAcknowledgement * enet_peer_queue_acknowledgement (ENetPeer *, const ENetProtocol *, enet_uint16);
+extern void                  enet_peer_dispatch_incoming_unreliable_commands (ENetPeer *, ENetChannel *);
+extern void                  enet_peer_dispatch_incoming_reliable_commands (ENetPeer *, ENetChannel *);
+
+ENET_API void * enet_range_coder_create (void);
+ENET_API void   enet_range_coder_destroy (void *);
+ENET_API size_t enet_range_coder_compress (void *, const ENetBuffer *, size_t, size_t, enet_uint8 *, size_t);
+ENET_API size_t enet_range_coder_decompress (void *, const enet_uint8 *, size_t, enet_uint8 *, size_t);
+   
+extern size_t enet_protocol_command_size (enet_uint8);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ENET_ENET_H__ */
+

+ 43 - 43
ThirdParty/ENet/include/enet/list.h

@@ -1,43 +1,43 @@
-/** 
- @file  list.h
- @brief ENet list management 
-*/
-#ifndef __ENET_LIST_H__
-#define __ENET_LIST_H__
-
-#include <stdlib.h>
-
-typedef struct _ENetListNode
-{
-   struct _ENetListNode * next;
-   struct _ENetListNode * previous;
-} ENetListNode;
-
-typedef ENetListNode * ENetListIterator;
-
-typedef struct _ENetList
-{
-   ENetListNode sentinel;
-} ENetList;
-
-extern void enet_list_clear (ENetList *);
-
-extern ENetListIterator enet_list_insert (ENetListIterator, void *);
-extern void * enet_list_remove (ENetListIterator);
-extern ENetListIterator enet_list_move (ENetListIterator, void *, void *);
-
-extern size_t enet_list_size (ENetList *);
-
-#define enet_list_begin(list) ((list) -> sentinel.next)
-#define enet_list_end(list) (& (list) -> sentinel)
-
-#define enet_list_empty(list) (enet_list_begin (list) == enet_list_end (list))
-
-#define enet_list_next(iterator) ((iterator) -> next)
-#define enet_list_previous(iterator) ((iterator) -> previous)
-
-#define enet_list_front(list) ((void *) (list) -> sentinel.next)
-#define enet_list_back(list) ((void *) (list) -> sentinel.previous)
-
-#endif /* __ENET_LIST_H__ */
-
+/** 
+ @file  list.h
+ @brief ENet list management 
+*/
+#ifndef __ENET_LIST_H__
+#define __ENET_LIST_H__
+
+#include <stdlib.h>
+
+typedef struct _ENetListNode
+{
+   struct _ENetListNode * next;
+   struct _ENetListNode * previous;
+} ENetListNode;
+
+typedef ENetListNode * ENetListIterator;
+
+typedef struct _ENetList
+{
+   ENetListNode sentinel;
+} ENetList;
+
+extern void enet_list_clear (ENetList *);
+
+extern ENetListIterator enet_list_insert (ENetListIterator, void *);
+extern void * enet_list_remove (ENetListIterator);
+extern ENetListIterator enet_list_move (ENetListIterator, void *, void *);
+
+extern size_t enet_list_size (ENetList *);
+
+#define enet_list_begin(list) ((list) -> sentinel.next)
+#define enet_list_end(list) (& (list) -> sentinel)
+
+#define enet_list_empty(list) (enet_list_begin (list) == enet_list_end (list))
+
+#define enet_list_next(iterator) ((iterator) -> next)
+#define enet_list_previous(iterator) ((iterator) -> previous)
+
+#define enet_list_front(list) ((void *) (list) -> sentinel.next)
+#define enet_list_back(list) ((void *) (list) -> sentinel.previous)
+
+#endif /* __ENET_LIST_H__ */
+

+ 196 - 196
ThirdParty/ENet/include/enet/protocol.h

@@ -1,196 +1,196 @@
-/** 
- @file  protocol.h
- @brief ENet protocol
-*/
-#ifndef __ENET_PROTOCOL_H__
-#define __ENET_PROTOCOL_H__
-
-#include "enet/types.h"
-
-enum
-{
-   ENET_PROTOCOL_MINIMUM_MTU             = 576,
-   ENET_PROTOCOL_MAXIMUM_MTU             = 4096,
-   ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS = 32,
-   ENET_PROTOCOL_MINIMUM_WINDOW_SIZE     = 4096,
-   ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE     = 32768,
-   ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT   = 1,
-   ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT   = 255,
-   ENET_PROTOCOL_MAXIMUM_PEER_ID         = 0xFFF
-};
-
-typedef enum _ENetProtocolCommand
-{
-   ENET_PROTOCOL_COMMAND_NONE               = 0,
-   ENET_PROTOCOL_COMMAND_ACKNOWLEDGE        = 1,
-   ENET_PROTOCOL_COMMAND_CONNECT            = 2,
-   ENET_PROTOCOL_COMMAND_VERIFY_CONNECT     = 3,
-   ENET_PROTOCOL_COMMAND_DISCONNECT         = 4,
-   ENET_PROTOCOL_COMMAND_PING               = 5,
-   ENET_PROTOCOL_COMMAND_SEND_RELIABLE      = 6,
-   ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE    = 7,
-   ENET_PROTOCOL_COMMAND_SEND_FRAGMENT      = 8,
-   ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED   = 9,
-   ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT    = 10,
-   ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE = 11,
-   ENET_PROTOCOL_COMMAND_COUNT              = 12,
-
-   ENET_PROTOCOL_COMMAND_MASK               = 0x0F
-} ENetProtocolCommand;
-
-typedef enum _ENetProtocolFlag
-{
-   ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE = (1 << 7),
-   ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED = (1 << 6),
-
-   ENET_PROTOCOL_HEADER_FLAG_COMPRESSED = (1 << 14),
-   ENET_PROTOCOL_HEADER_FLAG_SENT_TIME  = (1 << 15),
-   ENET_PROTOCOL_HEADER_FLAG_MASK       = ENET_PROTOCOL_HEADER_FLAG_COMPRESSED | ENET_PROTOCOL_HEADER_FLAG_SENT_TIME,
-
-   ENET_PROTOCOL_HEADER_SESSION_MASK    = (3 << 12),
-   ENET_PROTOCOL_HEADER_SESSION_SHIFT   = 12
-} ENetProtocolFlag;
-
-#ifdef _MSC_VER_
-#pragma pack(push, 1)
-#define ENET_PACKED
-#elif defined(__GNUC__)
-#define ENET_PACKED __attribute__ ((packed))
-#else
-#define ENET_PACKED
-#endif
-
-typedef struct _ENetProtocolHeader
-{
-   enet_uint16 peerID;
-   enet_uint16 sentTime;
-} ENET_PACKED ENetProtocolHeader;
-
-typedef struct _ENetProtocolCommandHeader
-{
-   enet_uint8 command;
-   enet_uint8 channelID;
-   enet_uint16 reliableSequenceNumber;
-} ENET_PACKED ENetProtocolCommandHeader;
-
-typedef struct _ENetProtocolAcknowledge
-{
-   ENetProtocolCommandHeader header;
-   enet_uint16 receivedReliableSequenceNumber;
-   enet_uint16 receivedSentTime;
-} ENET_PACKED ENetProtocolAcknowledge;
-
-typedef struct _ENetProtocolConnect
-{
-   ENetProtocolCommandHeader header;
-   enet_uint16 outgoingPeerID;
-   enet_uint8  incomingSessionID;
-   enet_uint8  outgoingSessionID;
-   enet_uint32 mtu;
-   enet_uint32 windowSize;
-   enet_uint32 channelCount;
-   enet_uint32 incomingBandwidth;
-   enet_uint32 outgoingBandwidth;
-   enet_uint32 packetThrottleInterval;
-   enet_uint32 packetThrottleAcceleration;
-   enet_uint32 packetThrottleDeceleration;
-   enet_uint32 connectID;
-   enet_uint32 data;
-} ENET_PACKED ENetProtocolConnect;
-
-typedef struct _ENetProtocolVerifyConnect
-{
-   ENetProtocolCommandHeader header;
-   enet_uint16 outgoingPeerID;
-   enet_uint8  incomingSessionID;
-   enet_uint8  outgoingSessionID;
-   enet_uint32 mtu;
-   enet_uint32 windowSize;
-   enet_uint32 channelCount;
-   enet_uint32 incomingBandwidth;
-   enet_uint32 outgoingBandwidth;
-   enet_uint32 packetThrottleInterval;
-   enet_uint32 packetThrottleAcceleration;
-   enet_uint32 packetThrottleDeceleration;
-   enet_uint32 connectID;
-} ENET_PACKED ENetProtocolVerifyConnect;
-
-typedef struct _ENetProtocolBandwidthLimit
-{
-   ENetProtocolCommandHeader header;
-   enet_uint32 incomingBandwidth;
-   enet_uint32 outgoingBandwidth;
-} ENET_PACKED ENetProtocolBandwidthLimit;
-
-typedef struct _ENetProtocolThrottleConfigure
-{
-   ENetProtocolCommandHeader header;
-   enet_uint32 packetThrottleInterval;
-   enet_uint32 packetThrottleAcceleration;
-   enet_uint32 packetThrottleDeceleration;
-} ENET_PACKED ENetProtocolThrottleConfigure;
-
-typedef struct _ENetProtocolDisconnect
-{
-   ENetProtocolCommandHeader header;
-   enet_uint32 data;
-} ENET_PACKED ENetProtocolDisconnect;
-
-typedef struct _ENetProtocolPing
-{
-   ENetProtocolCommandHeader header;
-} ENET_PACKED ENetProtocolPing;
-
-typedef struct _ENetProtocolSendReliable
-{
-   ENetProtocolCommandHeader header;
-   enet_uint16 dataLength;
-} ENET_PACKED ENetProtocolSendReliable;
-
-typedef struct _ENetProtocolSendUnreliable
-{
-   ENetProtocolCommandHeader header;
-   enet_uint16 unreliableSequenceNumber;
-   enet_uint16 dataLength;
-} ENET_PACKED ENetProtocolSendUnreliable;
-
-typedef struct _ENetProtocolSendUnsequenced
-{
-   ENetProtocolCommandHeader header;
-   enet_uint16 unsequencedGroup;
-   enet_uint16 dataLength;
-} ENET_PACKED ENetProtocolSendUnsequenced;
-
-typedef struct _ENetProtocolSendFragment
-{
-   ENetProtocolCommandHeader header;
-   enet_uint16 startSequenceNumber;
-   enet_uint16 dataLength;
-   enet_uint32 fragmentCount;
-   enet_uint32 fragmentNumber;
-   enet_uint32 totalLength;
-   enet_uint32 fragmentOffset;
-} ENET_PACKED ENetProtocolSendFragment;
-
-typedef union _ENetProtocol
-{
-   ENetProtocolCommandHeader header;
-   ENetProtocolAcknowledge acknowledge;
-   ENetProtocolConnect connect;
-   ENetProtocolVerifyConnect verifyConnect;
-   ENetProtocolDisconnect disconnect;
-   ENetProtocolPing ping;
-   ENetProtocolSendReliable sendReliable;
-   ENetProtocolSendUnreliable sendUnreliable;
-   ENetProtocolSendUnsequenced sendUnsequenced;
-   ENetProtocolSendFragment sendFragment;
-   ENetProtocolBandwidthLimit bandwidthLimit;
-   ENetProtocolThrottleConfigure throttleConfigure;
-} ENET_PACKED ENetProtocol;
-
-#ifdef _MSC_VER_
-#pragma pack(pop)
-#endif
-
-#endif /* __ENET_PROTOCOL_H__ */
-
+/** 
+ @file  protocol.h
+ @brief ENet protocol
+*/
+#ifndef __ENET_PROTOCOL_H__
+#define __ENET_PROTOCOL_H__
+
+#include "enet/types.h"
+
+enum
+{
+   ENET_PROTOCOL_MINIMUM_MTU             = 576,
+   ENET_PROTOCOL_MAXIMUM_MTU             = 4096,
+   ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS = 32,
+   ENET_PROTOCOL_MINIMUM_WINDOW_SIZE     = 4096,
+   ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE     = 32768,
+   ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT   = 1,
+   ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT   = 255,
+   ENET_PROTOCOL_MAXIMUM_PEER_ID         = 0xFFF
+};
+
+typedef enum _ENetProtocolCommand
+{
+   ENET_PROTOCOL_COMMAND_NONE               = 0,
+   ENET_PROTOCOL_COMMAND_ACKNOWLEDGE        = 1,
+   ENET_PROTOCOL_COMMAND_CONNECT            = 2,
+   ENET_PROTOCOL_COMMAND_VERIFY_CONNECT     = 3,
+   ENET_PROTOCOL_COMMAND_DISCONNECT         = 4,
+   ENET_PROTOCOL_COMMAND_PING               = 5,
+   ENET_PROTOCOL_COMMAND_SEND_RELIABLE      = 6,
+   ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE    = 7,
+   ENET_PROTOCOL_COMMAND_SEND_FRAGMENT      = 8,
+   ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED   = 9,
+   ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT    = 10,
+   ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE = 11,
+   ENET_PROTOCOL_COMMAND_COUNT              = 12,
+
+   ENET_PROTOCOL_COMMAND_MASK               = 0x0F
+} ENetProtocolCommand;
+
+typedef enum _ENetProtocolFlag
+{
+   ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE = (1 << 7),
+   ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED = (1 << 6),
+
+   ENET_PROTOCOL_HEADER_FLAG_COMPRESSED = (1 << 14),
+   ENET_PROTOCOL_HEADER_FLAG_SENT_TIME  = (1 << 15),
+   ENET_PROTOCOL_HEADER_FLAG_MASK       = ENET_PROTOCOL_HEADER_FLAG_COMPRESSED | ENET_PROTOCOL_HEADER_FLAG_SENT_TIME,
+
+   ENET_PROTOCOL_HEADER_SESSION_MASK    = (3 << 12),
+   ENET_PROTOCOL_HEADER_SESSION_SHIFT   = 12
+} ENetProtocolFlag;
+
+#ifdef _MSC_VER_
+#pragma pack(push, 1)
+#define ENET_PACKED
+#elif defined(__GNUC__)
+#define ENET_PACKED __attribute__ ((packed))
+#else
+#define ENET_PACKED
+#endif
+
+typedef struct _ENetProtocolHeader
+{
+   enet_uint16 peerID;
+   enet_uint16 sentTime;
+} ENET_PACKED ENetProtocolHeader;
+
+typedef struct _ENetProtocolCommandHeader
+{
+   enet_uint8 command;
+   enet_uint8 channelID;
+   enet_uint16 reliableSequenceNumber;
+} ENET_PACKED ENetProtocolCommandHeader;
+
+typedef struct _ENetProtocolAcknowledge
+{
+   ENetProtocolCommandHeader header;
+   enet_uint16 receivedReliableSequenceNumber;
+   enet_uint16 receivedSentTime;
+} ENET_PACKED ENetProtocolAcknowledge;
+
+typedef struct _ENetProtocolConnect
+{
+   ENetProtocolCommandHeader header;
+   enet_uint16 outgoingPeerID;
+   enet_uint8  incomingSessionID;
+   enet_uint8  outgoingSessionID;
+   enet_uint32 mtu;
+   enet_uint32 windowSize;
+   enet_uint32 channelCount;
+   enet_uint32 incomingBandwidth;
+   enet_uint32 outgoingBandwidth;
+   enet_uint32 packetThrottleInterval;
+   enet_uint32 packetThrottleAcceleration;
+   enet_uint32 packetThrottleDeceleration;
+   enet_uint32 connectID;
+   enet_uint32 data;
+} ENET_PACKED ENetProtocolConnect;
+
+typedef struct _ENetProtocolVerifyConnect
+{
+   ENetProtocolCommandHeader header;
+   enet_uint16 outgoingPeerID;
+   enet_uint8  incomingSessionID;
+   enet_uint8  outgoingSessionID;
+   enet_uint32 mtu;
+   enet_uint32 windowSize;
+   enet_uint32 channelCount;
+   enet_uint32 incomingBandwidth;
+   enet_uint32 outgoingBandwidth;
+   enet_uint32 packetThrottleInterval;
+   enet_uint32 packetThrottleAcceleration;
+   enet_uint32 packetThrottleDeceleration;
+   enet_uint32 connectID;
+} ENET_PACKED ENetProtocolVerifyConnect;
+
+typedef struct _ENetProtocolBandwidthLimit
+{
+   ENetProtocolCommandHeader header;
+   enet_uint32 incomingBandwidth;
+   enet_uint32 outgoingBandwidth;
+} ENET_PACKED ENetProtocolBandwidthLimit;
+
+typedef struct _ENetProtocolThrottleConfigure
+{
+   ENetProtocolCommandHeader header;
+   enet_uint32 packetThrottleInterval;
+   enet_uint32 packetThrottleAcceleration;
+   enet_uint32 packetThrottleDeceleration;
+} ENET_PACKED ENetProtocolThrottleConfigure;
+
+typedef struct _ENetProtocolDisconnect
+{
+   ENetProtocolCommandHeader header;
+   enet_uint32 data;
+} ENET_PACKED ENetProtocolDisconnect;
+
+typedef struct _ENetProtocolPing
+{
+   ENetProtocolCommandHeader header;
+} ENET_PACKED ENetProtocolPing;
+
+typedef struct _ENetProtocolSendReliable
+{
+   ENetProtocolCommandHeader header;
+   enet_uint16 dataLength;
+} ENET_PACKED ENetProtocolSendReliable;
+
+typedef struct _ENetProtocolSendUnreliable
+{
+   ENetProtocolCommandHeader header;
+   enet_uint16 unreliableSequenceNumber;
+   enet_uint16 dataLength;
+} ENET_PACKED ENetProtocolSendUnreliable;
+
+typedef struct _ENetProtocolSendUnsequenced
+{
+   ENetProtocolCommandHeader header;
+   enet_uint16 unsequencedGroup;
+   enet_uint16 dataLength;
+} ENET_PACKED ENetProtocolSendUnsequenced;
+
+typedef struct _ENetProtocolSendFragment
+{
+   ENetProtocolCommandHeader header;
+   enet_uint16 startSequenceNumber;
+   enet_uint16 dataLength;
+   enet_uint32 fragmentCount;
+   enet_uint32 fragmentNumber;
+   enet_uint32 totalLength;
+   enet_uint32 fragmentOffset;
+} ENET_PACKED ENetProtocolSendFragment;
+
+typedef union _ENetProtocol
+{
+   ENetProtocolCommandHeader header;
+   ENetProtocolAcknowledge acknowledge;
+   ENetProtocolConnect connect;
+   ENetProtocolVerifyConnect verifyConnect;
+   ENetProtocolDisconnect disconnect;
+   ENetProtocolPing ping;
+   ENetProtocolSendReliable sendReliable;
+   ENetProtocolSendUnreliable sendUnreliable;
+   ENetProtocolSendUnsequenced sendUnsequenced;
+   ENetProtocolSendFragment sendFragment;
+   ENetProtocolBandwidthLimit bandwidthLimit;
+   ENetProtocolThrottleConfigure throttleConfigure;
+} ENET_PACKED ENetProtocol;
+
+#ifdef _MSC_VER_
+#pragma pack(pop)
+#endif
+
+#endif /* __ENET_PROTOCOL_H__ */
+

+ 18 - 18
ThirdParty/ENet/include/enet/time.h

@@ -1,18 +1,18 @@
-/** 
- @file  time.h
- @brief ENet time constants and macros
-*/
-#ifndef __ENET_TIME_H__
-#define __ENET_TIME_H__
-
-#define ENET_TIME_OVERFLOW 86400000
-
-#define ENET_TIME_LESS(a, b) ((a) - (b) >= ENET_TIME_OVERFLOW)
-#define ENET_TIME_GREATER(a, b) ((b) - (a) >= ENET_TIME_OVERFLOW)
-#define ENET_TIME_LESS_EQUAL(a, b) (! ENET_TIME_GREATER (a, b))
-#define ENET_TIME_GREATER_EQUAL(a, b) (! ENET_TIME_LESS (a, b))
-
-#define ENET_TIME_DIFFERENCE(a, b) ((a) - (b) >= ENET_TIME_OVERFLOW ? (b) - (a) : (a) - (b))
-
-#endif /* __ENET_TIME_H__ */
-
+/** 
+ @file  time.h
+ @brief ENet time constants and macros
+*/
+#ifndef __ENET_TIME_H__
+#define __ENET_TIME_H__
+
+#define ENET_TIME_OVERFLOW 86400000
+
+#define ENET_TIME_LESS(a, b) ((a) - (b) >= ENET_TIME_OVERFLOW)
+#define ENET_TIME_GREATER(a, b) ((b) - (a) >= ENET_TIME_OVERFLOW)
+#define ENET_TIME_LESS_EQUAL(a, b) (! ENET_TIME_GREATER (a, b))
+#define ENET_TIME_GREATER_EQUAL(a, b) (! ENET_TIME_LESS (a, b))
+
+#define ENET_TIME_DIFFERENCE(a, b) ((a) - (b) >= ENET_TIME_OVERFLOW ? (b) - (a) : (a) - (b))
+
+#endif /* __ENET_TIME_H__ */
+

+ 13 - 13
ThirdParty/ENet/include/enet/types.h

@@ -1,13 +1,13 @@
-/** 
- @file  types.h
- @brief type definitions for ENet
-*/
-#ifndef __ENET_TYPES_H__
-#define __ENET_TYPES_H__
-
-typedef unsigned char enet_uint8;       /**< unsigned 8-bit type  */
-typedef unsigned short enet_uint16;     /**< unsigned 16-bit type */
-typedef unsigned int enet_uint32;      /**< unsigned 32-bit type */
-
-#endif /* __ENET_TYPES_H__ */
-
+/** 
+ @file  types.h
+ @brief type definitions for ENet
+*/
+#ifndef __ENET_TYPES_H__
+#define __ENET_TYPES_H__
+
+typedef unsigned char enet_uint8;       /**< unsigned 8-bit type  */
+typedef unsigned short enet_uint16;     /**< unsigned 16-bit type */
+typedef unsigned int enet_uint32;      /**< unsigned 32-bit type */
+
+#endif /* __ENET_TYPES_H__ */
+

+ 45 - 45
ThirdParty/ENet/include/enet/unix.h

@@ -1,45 +1,45 @@
-/** 
- @file  unix.h
- @brief ENet Unix header
-*/
-#ifndef __ENET_UNIX_H__
-#define __ENET_UNIX_H__
-
-#include <stdlib.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <unistd.h>
-
-typedef int ENetSocket;
-
-enum
-{
-    ENET_SOCKET_NULL = -1
-};
-
-#define ENET_HOST_TO_NET_16(value) (htons (value)) /**< macro that converts host to net byte-order of a 16-bit value */
-#define ENET_HOST_TO_NET_32(value) (htonl (value)) /**< macro that converts host to net byte-order of a 32-bit value */
-
-#define ENET_NET_TO_HOST_16(value) (ntohs (value)) /**< macro that converts net to host byte-order of a 16-bit value */
-#define ENET_NET_TO_HOST_32(value) (ntohl (value)) /**< macro that converts net to host byte-order of a 32-bit value */
-
-typedef struct
-{
-    void * data;
-    size_t dataLength;
-} ENetBuffer;
-
-#define ENET_CALLBACK
-
-#define ENET_API extern
-
-typedef fd_set ENetSocketSet;
-
-#define ENET_SOCKETSET_EMPTY(sockset)          FD_ZERO (& (sockset))
-#define ENET_SOCKETSET_ADD(sockset, socket)    FD_SET (socket, & (sockset))
-#define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLEAR (socket, & (sockset))
-#define ENET_SOCKETSET_CHECK(sockset, socket)  FD_ISSET (socket, & (sockset))
-    
-#endif /* __ENET_UNIX_H__ */
-
+/** 
+ @file  unix.h
+ @brief ENet Unix header
+*/
+#ifndef __ENET_UNIX_H__
+#define __ENET_UNIX_H__
+
+#include <stdlib.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <unistd.h>
+
+typedef int ENetSocket;
+
+enum
+{
+    ENET_SOCKET_NULL = -1
+};
+
+#define ENET_HOST_TO_NET_16(value) (htons (value)) /**< macro that converts host to net byte-order of a 16-bit value */
+#define ENET_HOST_TO_NET_32(value) (htonl (value)) /**< macro that converts host to net byte-order of a 32-bit value */
+
+#define ENET_NET_TO_HOST_16(value) (ntohs (value)) /**< macro that converts net to host byte-order of a 16-bit value */
+#define ENET_NET_TO_HOST_32(value) (ntohl (value)) /**< macro that converts net to host byte-order of a 32-bit value */
+
+typedef struct
+{
+    void * data;
+    size_t dataLength;
+} ENetBuffer;
+
+#define ENET_CALLBACK
+
+#define ENET_API extern
+
+typedef fd_set ENetSocketSet;
+
+#define ENET_SOCKETSET_EMPTY(sockset)          FD_ZERO (& (sockset))
+#define ENET_SOCKETSET_ADD(sockset, socket)    FD_SET (socket, & (sockset))
+#define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLEAR (socket, & (sockset))
+#define ENET_SOCKETSET_CHECK(sockset, socket)  FD_ISSET (socket, & (sockset))
+    
+#endif /* __ENET_UNIX_H__ */
+

+ 12 - 12
ThirdParty/ENet/include/enet/utility.h

@@ -1,12 +1,12 @@
-/** 
- @file  utility.h
- @brief ENet utility header
-*/
-#ifndef __ENET_UTILITY_H__
-#define __ENET_UTILITY_H__
-
-#define ENET_MAX(x, y) ((x) > (y) ? (x) : (y))
-#define ENET_MIN(x, y) ((x) < (y) ? (x) : (y))
-
-#endif /* __ENET_UTILITY_H__ */
-
+/** 
+ @file  utility.h
+ @brief ENet utility header
+*/
+#ifndef __ENET_UTILITY_H__
+#define __ENET_UTILITY_H__
+
+#define ENET_MAX(x, y) ((x) > (y) ? (x) : (y))
+#define ENET_MIN(x, y) ((x) < (y) ? (x) : (y))
+
+#endif /* __ENET_UTILITY_H__ */
+

+ 58 - 58
ThirdParty/ENet/include/enet/win32.h

@@ -1,58 +1,58 @@
-/** 
- @file  win32.h
- @brief ENet Win32 header
-*/
-#ifndef __ENET_WIN32_H__
-#define __ENET_WIN32_H__
-
-#ifdef ENET_BUILDING_LIB
-#pragma warning (disable: 4996) // 'strncpy' was declared deprecated
-#pragma warning (disable: 4267) // size_t to int conversion
-#pragma warning (disable: 4244) // 64bit to 32bit int
-#pragma warning (disable: 4018) // signed/unsigned mismatch
-#endif
-
-#include <stdlib.h>
-#include <winsock2.h>
-
-typedef SOCKET ENetSocket;
-
-enum
-{
-    ENET_SOCKET_NULL = INVALID_SOCKET
-};
-
-#define ENET_HOST_TO_NET_16(value) (htons (value))
-#define ENET_HOST_TO_NET_32(value) (htonl (value))
-
-#define ENET_NET_TO_HOST_16(value) (ntohs (value))
-#define ENET_NET_TO_HOST_32(value) (ntohl (value))
-
-typedef struct
-{
-    size_t dataLength;
-    void * data;
-} ENetBuffer;
-
-#define ENET_CALLBACK __cdecl
-
-#if defined ENET_DLL
-#if defined ENET_BUILDING_LIB
-#define ENET_API __declspec( dllexport )
-#else
-#define ENET_API __declspec( dllimport )
-#endif /* ENET_BUILDING_LIB */
-#else /* !ENET_DLL */
-#define ENET_API extern
-#endif /* ENET_DLL */
-
-typedef fd_set ENetSocketSet;
-
-#define ENET_SOCKETSET_EMPTY(sockset)          FD_ZERO (& (sockset))
-#define ENET_SOCKETSET_ADD(sockset, socket)    FD_SET (socket, & (sockset))
-#define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLEAR (socket, & (sockset))
-#define ENET_SOCKETSET_CHECK(sockset, socket)  FD_ISSET (socket, & (sockset))
-
-#endif /* __ENET_WIN32_H__ */
-
-
+/** 
+ @file  win32.h
+ @brief ENet Win32 header
+*/
+#ifndef __ENET_WIN32_H__
+#define __ENET_WIN32_H__
+
+#ifdef ENET_BUILDING_LIB
+#pragma warning (disable: 4996) // 'strncpy' was declared deprecated
+#pragma warning (disable: 4267) // size_t to int conversion
+#pragma warning (disable: 4244) // 64bit to 32bit int
+#pragma warning (disable: 4018) // signed/unsigned mismatch
+#endif
+
+#include <stdlib.h>
+#include <winsock2.h>
+
+typedef SOCKET ENetSocket;
+
+enum
+{
+    ENET_SOCKET_NULL = INVALID_SOCKET
+};
+
+#define ENET_HOST_TO_NET_16(value) (htons (value))
+#define ENET_HOST_TO_NET_32(value) (htonl (value))
+
+#define ENET_NET_TO_HOST_16(value) (ntohs (value))
+#define ENET_NET_TO_HOST_32(value) (ntohl (value))
+
+typedef struct
+{
+    size_t dataLength;
+    void * data;
+} ENetBuffer;
+
+#define ENET_CALLBACK __cdecl
+
+#if defined ENET_DLL
+#if defined ENET_BUILDING_LIB
+#define ENET_API __declspec( dllexport )
+#else
+#define ENET_API __declspec( dllimport )
+#endif /* ENET_BUILDING_LIB */
+#else /* !ENET_DLL */
+#define ENET_API extern
+#endif /* ENET_DLL */
+
+typedef fd_set ENetSocketSet;
+
+#define ENET_SOCKETSET_EMPTY(sockset)          FD_ZERO (& (sockset))
+#define ENET_SOCKETSET_ADD(sockset, socket)    FD_SET (socket, & (sockset))
+#define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLEAR (socket, & (sockset))
+#define ENET_SOCKETSET_CHECK(sockset, socket)  FD_ISSET (socket, & (sockset))
+
+#endif /* __ENET_WIN32_H__ */
+
+

+ 75 - 75
ThirdParty/ENet/list.c

@@ -1,75 +1,75 @@
-/** 
- @file list.c
- @brief ENet linked list functions
-*/
-#define ENET_BUILDING_LIB 1
-#include "enet/list.h"
-
-/** 
-    @defgroup list ENet linked list utility functions
-    @ingroup private
-    @{
-*/
-void
-enet_list_clear (ENetList * list)
-{
-   list -> sentinel.next = & list -> sentinel;
-   list -> sentinel.previous = & list -> sentinel;
-}
-
-ENetListIterator
-enet_list_insert (ENetListIterator position, void * data)
-{
-   ENetListIterator result = (ENetListIterator) data;
-
-   result -> previous = position -> previous;
-   result -> next = position;
-
-   result -> previous -> next = result;
-   position -> previous = result;
-
-   return result;
-}
-
-void *
-enet_list_remove (ENetListIterator position)
-{
-   position -> previous -> next = position -> next;
-   position -> next -> previous = position -> previous;
-
-   return position;
-}
-
-ENetListIterator
-enet_list_move (ENetListIterator position, void * dataFirst, void * dataLast)
-{
-   ENetListIterator first = (ENetListIterator) dataFirst,
-                    last = (ENetListIterator) dataLast;
-
-   first -> previous -> next = last -> next;
-   last -> next -> previous = first -> previous;
-
-   first -> previous = position -> previous;
-   last -> next = position;
-
-   first -> previous -> next = first;
-   position -> previous = last;
-    
-   return first;
-}
-
-size_t
-enet_list_size (ENetList * list)
-{
-   size_t size = 0;
-   ENetListIterator position;
-
-   for (position = enet_list_begin (list);
-        position != enet_list_end (list);
-        position = enet_list_next (position))
-     ++ size;
-   
-   return size;
-}
-
-/** @} */
+/** 
+ @file list.c
+ @brief ENet linked list functions
+*/
+#define ENET_BUILDING_LIB 1
+#include "enet/enet.h"
+
+/** 
+    @defgroup list ENet linked list utility functions
+    @ingroup private
+    @{
+*/
+void
+enet_list_clear (ENetList * list)
+{
+   list -> sentinel.next = & list -> sentinel;
+   list -> sentinel.previous = & list -> sentinel;
+}
+
+ENetListIterator
+enet_list_insert (ENetListIterator position, void * data)
+{
+   ENetListIterator result = (ENetListIterator) data;
+
+   result -> previous = position -> previous;
+   result -> next = position;
+
+   result -> previous -> next = result;
+   position -> previous = result;
+
+   return result;
+}
+
+void *
+enet_list_remove (ENetListIterator position)
+{
+   position -> previous -> next = position -> next;
+   position -> next -> previous = position -> previous;
+
+   return position;
+}
+
+ENetListIterator
+enet_list_move (ENetListIterator position, void * dataFirst, void * dataLast)
+{
+   ENetListIterator first = (ENetListIterator) dataFirst,
+                    last = (ENetListIterator) dataLast;
+
+   first -> previous -> next = last -> next;
+   last -> next -> previous = first -> previous;
+
+   first -> previous = position -> previous;
+   last -> next = position;
+
+   first -> previous -> next = first;
+   position -> previous = last;
+    
+   return first;
+}
+
+size_t
+enet_list_size (ENetList * list)
+{
+   size_t size = 0;
+   ENetListIterator position;
+
+   for (position = enet_list_begin (list);
+        position != enet_list_end (list);
+        position = enet_list_next (position))
+     ++ size;
+   
+   return size;
+}
+
+/** @} */

+ 157 - 157
ThirdParty/ENet/packet.c

@@ -1,157 +1,157 @@
-/** 
- @file  packet.c
- @brief ENet packet management functions
-*/
-#include <string.h>
-#define ENET_BUILDING_LIB 1
-#include "enet/enet.h"
-
-/** @defgroup Packet ENet packet functions 
-    @{ 
-*/
-
-/** Creates a packet that may be sent to a peer.
-    @param dataContents initial contents of the packet's data; the packet's data will remain uninitialized if dataContents is NULL.
-    @param dataLength   size of the data allocated for this packet
-    @param flags        flags for this packet as described for the ENetPacket structure.
-    @returns the packet on success, NULL on failure
-*/
-ENetPacket *
-enet_packet_create (const void * data, size_t dataLength, enet_uint32 flags)
-{
-    ENetPacket * packet = (ENetPacket *) enet_malloc (sizeof (ENetPacket));
-    if (packet == NULL)
-      return NULL;
-
-    if (flags & ENET_PACKET_FLAG_NO_ALLOCATE)
-      packet -> data = (enet_uint8 *) data;
-    else
-    {
-       packet -> data = (enet_uint8 *) enet_malloc (dataLength);
-       if (packet -> data == NULL)
-       {
-          enet_free (packet);
-          return NULL;
-       }
-
-       if (data != NULL)
-         memcpy (packet -> data, data, dataLength);
-    }
-
-    packet -> referenceCount = 0;
-    packet -> flags = flags;
-    packet -> dataLength = dataLength;
-    packet -> freeCallback = NULL;
-
-    return packet;
-}
-
-/** Destroys the packet and deallocates its data.
-    @param packet packet to be destroyed
-*/
-void
-enet_packet_destroy (ENetPacket * packet)
-{
-    if (packet -> freeCallback != NULL)
-      (* packet -> freeCallback) (packet);
-    if (! (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE))
-      enet_free (packet -> data);
-    enet_free (packet);
-}
-
-/** Attempts to resize the data in the packet to length specified in the 
-    dataLength parameter 
-    @param packet packet to resize
-    @param dataLength new size for the packet data
-    @returns 0 on success, < 0 on failure
-*/
-int
-enet_packet_resize (ENetPacket * packet, size_t dataLength)
-{
-    enet_uint8 * newData;
-   
-    if (dataLength <= packet -> dataLength || (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE))
-    {
-       packet -> dataLength = dataLength;
-
-       return 0;
-    }
-
-    newData = (enet_uint8 *) enet_malloc (dataLength);
-    if (newData == NULL)
-      return -1;
-
-    memcpy (newData, packet -> data, packet -> dataLength);
-    enet_free (packet -> data);
-    
-    packet -> data = newData;
-    packet -> dataLength = dataLength;
-
-    return 0;
-}
-
-static int initializedCRC32 = 0;
-static enet_uint32 crcTable [256];
-
-static enet_uint32 
-reflect_crc (int val, int bits)
-{
-    int result = 0, bit;
-
-    for (bit = 0; bit < bits; bit ++)
-    {
-        if(val & 1) result |= 1 << (bits - 1 - bit); 
-        val >>= 1;
-    }
-
-    return result;
-}
-
-static void 
-initialize_crc32 ()
-{
-    int byte;
-
-    for (byte = 0; byte < 256; ++ byte)
-    {
-        enet_uint32 crc = reflect_crc (byte, 8) << 24;
-        int offset;
-
-        for(offset = 0; offset < 8; ++ offset)
-        {
-            if (crc & 0x80000000)
-                crc = (crc << 1) ^ 0x04c11db7;
-            else
-                crc <<= 1;
-        }
-
-        crcTable [byte] = reflect_crc (crc, 32);
-    }
-
-    initializedCRC32 = 1;
-}
-    
-enet_uint32
-enet_crc32 (const ENetBuffer * buffers, size_t bufferCount)
-{
-    enet_uint32 crc = 0xFFFFFFFF;
-    
-    if (! initializedCRC32) initialize_crc32 ();
-
-    while (bufferCount -- > 0)
-    {
-        const enet_uint8 * data = (const enet_uint8 *) buffers -> data,
-                         * dataEnd = & data [buffers -> dataLength];
-
-        while (data < dataEnd)
-        {
-            crc = (crc >> 8) ^ crcTable [(crc & 0xFF) ^ *data++];        
-        }
-
-        ++ buffers;
-    }
-
-    return ENET_HOST_TO_NET_32 (~ crc);
-}
-
-/** @} */
+/** 
+ @file  packet.c
+ @brief ENet packet management functions
+*/
+#include <string.h>
+#define ENET_BUILDING_LIB 1
+#include "enet/enet.h"
+
+/** @defgroup Packet ENet packet functions 
+    @{ 
+*/
+
+/** Creates a packet that may be sent to a peer.
+    @param dataContents initial contents of the packet's data; the packet's data will remain uninitialized if dataContents is NULL.
+    @param dataLength   size of the data allocated for this packet
+    @param flags        flags for this packet as described for the ENetPacket structure.
+    @returns the packet on success, NULL on failure
+*/
+ENetPacket *
+enet_packet_create (const void * data, size_t dataLength, enet_uint32 flags)
+{
+    ENetPacket * packet = (ENetPacket *) enet_malloc (sizeof (ENetPacket));
+    if (packet == NULL)
+      return NULL;
+
+    if (flags & ENET_PACKET_FLAG_NO_ALLOCATE)
+      packet -> data = (enet_uint8 *) data;
+    else
+    {
+       packet -> data = (enet_uint8 *) enet_malloc (dataLength);
+       if (packet -> data == NULL)
+       {
+          enet_free (packet);
+          return NULL;
+       }
+
+       if (data != NULL)
+         memcpy (packet -> data, data, dataLength);
+    }
+
+    packet -> referenceCount = 0;
+    packet -> flags = flags;
+    packet -> dataLength = dataLength;
+    packet -> freeCallback = NULL;
+
+    return packet;
+}
+
+/** Destroys the packet and deallocates its data.
+    @param packet packet to be destroyed
+*/
+void
+enet_packet_destroy (ENetPacket * packet)
+{
+    if (packet -> freeCallback != NULL)
+      (* packet -> freeCallback) (packet);
+    if (! (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE))
+      enet_free (packet -> data);
+    enet_free (packet);
+}
+
+/** Attempts to resize the data in the packet to length specified in the 
+    dataLength parameter 
+    @param packet packet to resize
+    @param dataLength new size for the packet data
+    @returns 0 on success, < 0 on failure
+*/
+int
+enet_packet_resize (ENetPacket * packet, size_t dataLength)
+{
+    enet_uint8 * newData;
+   
+    if (dataLength <= packet -> dataLength || (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE))
+    {
+       packet -> dataLength = dataLength;
+
+       return 0;
+    }
+
+    newData = (enet_uint8 *) enet_malloc (dataLength);
+    if (newData == NULL)
+      return -1;
+
+    memcpy (newData, packet -> data, packet -> dataLength);
+    enet_free (packet -> data);
+    
+    packet -> data = newData;
+    packet -> dataLength = dataLength;
+
+    return 0;
+}
+
+static int initializedCRC32 = 0;
+static enet_uint32 crcTable [256];
+
+static enet_uint32 
+reflect_crc (int val, int bits)
+{
+    int result = 0, bit;
+
+    for (bit = 0; bit < bits; bit ++)
+    {
+        if(val & 1) result |= 1 << (bits - 1 - bit); 
+        val >>= 1;
+    }
+
+    return result;
+}
+
+static void 
+initialize_crc32 ()
+{
+    int byte;
+
+    for (byte = 0; byte < 256; ++ byte)
+    {
+        enet_uint32 crc = reflect_crc (byte, 8) << 24;
+        int offset;
+
+        for(offset = 0; offset < 8; ++ offset)
+        {
+            if (crc & 0x80000000)
+                crc = (crc << 1) ^ 0x04c11db7;
+            else
+                crc <<= 1;
+        }
+
+        crcTable [byte] = reflect_crc (crc, 32);
+    }
+
+    initializedCRC32 = 1;
+}
+    
+enet_uint32
+enet_crc32 (const ENetBuffer * buffers, size_t bufferCount)
+{
+    enet_uint32 crc = 0xFFFFFFFF;
+    
+    if (! initializedCRC32) initialize_crc32 ();
+
+    while (bufferCount -- > 0)
+    {
+        const enet_uint8 * data = (const enet_uint8 *) buffers -> data,
+                         * dataEnd = & data [buffers -> dataLength];
+
+        while (data < dataEnd)
+        {
+            crc = (crc >> 8) ^ crcTable [(crc & 0xFF) ^ *data++];        
+        }
+
+        ++ buffers;
+    }
+
+    return ENET_HOST_TO_NET_32 (~ crc);
+}
+
+/** @} */

+ 818 - 816
ThirdParty/ENet/peer.c

@@ -1,816 +1,818 @@
-/** 
- @file  peer.c
- @brief ENet peer management functions
-*/
-#include <string.h>
-#define ENET_BUILDING_LIB 1
-#include "enet/enet.h"
-
-/** @defgroup peer ENet peer functions 
-    @{
-*/
-
-/** Configures throttle parameter for a peer.
-
-    Unreliable packets are dropped by ENet in response to the varying conditions
-    of the Internet connection to the peer.  The throttle represents a probability
-    that an unreliable packet should not be dropped and thus sent by ENet to the peer.
-    The lowest mean round trip time from the sending of a reliable packet to the
-    receipt of its acknowledgement is measured over an amount of time specified by
-    the interval parameter in milliseconds.  If a measured round trip time happens to
-    be significantly less than the mean round trip time measured over the interval, 
-    then the throttle probability is increased to allow more traffic by an amount
-    specified in the acceleration parameter, which is a ratio to the ENET_PEER_PACKET_THROTTLE_SCALE
-    constant.  If a measured round trip time happens to be significantly greater than
-    the mean round trip time measured over the interval, then the throttle probability
-    is decreased to limit traffic by an amount specified in the deceleration parameter, which
-    is a ratio to the ENET_PEER_PACKET_THROTTLE_SCALE constant.  When the throttle has
-    a value of ENET_PEER_PACKET_THROTTLE_SCALE, on unreliable packets are dropped by 
-    ENet, and so 100% of all unreliable packets will be sent.  When the throttle has a
-    value of 0, all unreliable packets are dropped by ENet, and so 0% of all unreliable
-    packets will be sent.  Intermediate values for the throttle represent intermediate
-    probabilities between 0% and 100% of unreliable packets being sent.  The bandwidth
-    limits of the local and foreign hosts are taken into account to determine a 
-    sensible limit for the throttle probability above which it should not raise even in
-    the best of conditions.
-
-    @param peer peer to configure 
-    @param interval interval, in milliseconds, over which to measure lowest mean RTT; the default value is ENET_PEER_PACKET_THROTTLE_INTERVAL.
-    @param acceleration rate at which to increase the throttle probability as mean RTT declines
-    @param deceleration rate at which to decrease the throttle probability as mean RTT increases
-*/
-void
-enet_peer_throttle_configure (ENetPeer * peer, enet_uint32 interval, enet_uint32 acceleration, enet_uint32 deceleration)
-{
-    ENetProtocol command;
-
-    peer -> packetThrottleInterval = interval;
-    peer -> packetThrottleAcceleration = acceleration;
-    peer -> packetThrottleDeceleration = deceleration;
-
-    command.header.command = ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
-    command.header.channelID = 0xFF;
-
-    command.throttleConfigure.packetThrottleInterval = ENET_HOST_TO_NET_32 (interval);
-    command.throttleConfigure.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (acceleration);
-    command.throttleConfigure.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (deceleration);
-
-    enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
-}
-
-int
-enet_peer_throttle (ENetPeer * peer, enet_uint32 rtt)
-{
-    if (peer -> lastRoundTripTime <= peer -> lastRoundTripTimeVariance)
-    {
-        peer -> packetThrottle = peer -> packetThrottleLimit;
-    }
-    else
-    if (rtt < peer -> lastRoundTripTime)
-    {
-        peer -> packetThrottle += peer -> packetThrottleAcceleration;
-
-        if (peer -> packetThrottle > peer -> packetThrottleLimit)
-          peer -> packetThrottle = peer -> packetThrottleLimit;
-
-        return 1;
-    }
-    else
-    if (rtt > peer -> lastRoundTripTime + 2 * peer -> lastRoundTripTimeVariance)
-    {
-        if (peer -> packetThrottle > peer -> packetThrottleDeceleration)
-          peer -> packetThrottle -= peer -> packetThrottleDeceleration;
-        else
-          peer -> packetThrottle = 0;
-
-        return -1;
-    }
-
-    return 0;
-}
-
-/** Queues a packet to be sent.
-    @param peer destination for the packet
-    @param channelID channel on which to send
-    @param packet packet to send
-    @retval 0 on success
-    @retval < 0 on failure
-*/
-int
-enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
-{
-   ENetChannel * channel = & peer -> channels [channelID];
-   ENetProtocol command;
-   size_t fragmentLength;
-
-   if (peer -> state != ENET_PEER_STATE_CONNECTED ||
-       channelID >= peer -> channelCount)
-     return -1;
-
-   fragmentLength = peer -> mtu - sizeof (ENetProtocolHeader) - sizeof (ENetProtocolSendFragment);
-
-   if (packet -> dataLength > fragmentLength)
-   {
-      enet_uint16 startSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingReliableSequenceNumber + 1);
-      enet_uint32 fragmentCount = ENET_HOST_TO_NET_32 ((packet -> dataLength + fragmentLength - 1) / fragmentLength),
-             fragmentNumber,
-             fragmentOffset;
-      ENetList fragments;
-      ENetOutgoingCommand * fragment;
-
-      enet_list_clear (& fragments);
-
-      for (fragmentNumber = 0,
-             fragmentOffset = 0;
-           fragmentOffset < packet -> dataLength;
-           ++ fragmentNumber,
-             fragmentOffset += fragmentLength)
-      {
-         if (packet -> dataLength - fragmentOffset < fragmentLength)
-           fragmentLength = packet -> dataLength - fragmentOffset;
-
-         fragment = (ENetOutgoingCommand *) enet_malloc (sizeof (ENetOutgoingCommand));
-         if (fragment == NULL)
-         {
-            while (! enet_list_empty (& fragments))
-            {
-               fragment = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (& fragments));
-               
-               enet_free (fragment);
-            }
-            
-            return -1;
-         }
-         
-         fragment -> fragmentOffset = fragmentOffset;
-         fragment -> fragmentLength = fragmentLength;
-         fragment -> packet = packet;
-         fragment -> command.header.command = ENET_PROTOCOL_COMMAND_SEND_FRAGMENT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
-         fragment -> command.header.channelID = channelID;
-         fragment -> command.sendFragment.startSequenceNumber = startSequenceNumber;
-         fragment -> command.sendFragment.dataLength = ENET_HOST_TO_NET_16 (fragmentLength);
-         fragment -> command.sendFragment.fragmentCount = fragmentCount;
-         fragment -> command.sendFragment.fragmentNumber = ENET_HOST_TO_NET_32 (fragmentNumber);
-         fragment -> command.sendFragment.totalLength = ENET_HOST_TO_NET_32 (packet -> dataLength);
-         fragment -> command.sendFragment.fragmentOffset = ENET_NET_TO_HOST_32 (fragmentOffset);
-        
-         enet_list_insert (enet_list_end (& fragments), fragment);
-      }
-
-      packet -> referenceCount += fragmentNumber;
-
-      while (! enet_list_empty (& fragments))
-      {
-         fragment = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (& fragments));
- 
-         enet_peer_setup_outgoing_command (peer, fragment);
-      }
-
-      return 0;
-   }
-
-   command.header.channelID = channelID;
-
-   if (packet -> flags & ENET_PACKET_FLAG_RELIABLE)
-   {
-      command.header.command = ENET_PROTOCOL_COMMAND_SEND_RELIABLE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
-      command.sendReliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
-   }
-   else
-   if (packet -> flags & ENET_PACKET_FLAG_UNSEQUENCED)
-   {
-      command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED | ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED;
-      command.sendUnsequenced.unsequencedGroup = ENET_HOST_TO_NET_16 (peer -> outgoingUnsequencedGroup + 1);
-      command.sendUnsequenced.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
-   }
-   else 
-   if (channel -> outgoingUnreliableSequenceNumber >= 0xFFFF)
-   {
-      command.header.command = ENET_PROTOCOL_COMMAND_SEND_RELIABLE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
-      command.sendReliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
-   }
-   else
-   {
-      command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE;
-      command.sendUnreliable.unreliableSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingUnreliableSequenceNumber + 1);
-      command.sendUnreliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
-   }
-
-   if (enet_peer_queue_outgoing_command (peer, & command, packet, 0, packet -> dataLength) == NULL)
-     return -1;
-
-   return 0;
-}
-
-/** Attempts to dequeue any incoming queued packet.
-    @param peer peer to dequeue packets from
-    @param channelID holds the channel ID of the channel the packet was received on success
-    @returns a pointer to the packet, or NULL if there are no available incoming queued packets
-*/
-ENetPacket *
-enet_peer_receive (ENetPeer * peer, enet_uint8 * channelID)
-{
-   ENetIncomingCommand * incomingCommand;
-   ENetPacket * packet;
-   
-   if (enet_list_empty (& peer -> dispatchedCommands))
-     return NULL;
-
-   incomingCommand = (ENetIncomingCommand *) enet_list_remove (enet_list_begin (& peer -> dispatchedCommands));
-
-   if (channelID != NULL)
-     * channelID = incomingCommand -> command.header.channelID;
-
-   packet = incomingCommand -> packet;
-
-   -- packet -> referenceCount;
-
-   if (incomingCommand -> fragments != NULL)
-     enet_free (incomingCommand -> fragments);
-
-   enet_free (incomingCommand);
-
-   return packet;
-}
-
-static void
-enet_peer_reset_outgoing_commands (ENetList * queue)
-{
-    ENetOutgoingCommand * outgoingCommand;
-
-    while (! enet_list_empty (queue))
-    {
-       outgoingCommand = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (queue));
-
-       if (outgoingCommand -> packet != NULL)
-       {
-          -- outgoingCommand -> packet -> referenceCount;
-
-          if (outgoingCommand -> packet -> referenceCount == 0)
-            enet_packet_destroy (outgoingCommand -> packet);
-       }
-
-       enet_free (outgoingCommand);
-    }
-}
-
-static void
-enet_peer_reset_incoming_commands (ENetList * queue)
-{
-    ENetIncomingCommand * incomingCommand;
-
-    while (! enet_list_empty (queue))
-    {
-       incomingCommand = (ENetIncomingCommand *) enet_list_remove (enet_list_begin (queue));
-
-       if (incomingCommand -> packet != NULL)
-       {
-          -- incomingCommand -> packet -> referenceCount;
-
-          if (incomingCommand -> packet -> referenceCount == 0)
-            enet_packet_destroy (incomingCommand -> packet);
-       }
-
-       if (incomingCommand -> fragments != NULL)
-         enet_free (incomingCommand -> fragments);
-
-       enet_free (incomingCommand);
-    }
-}
-
-void
-enet_peer_reset_queues (ENetPeer * peer)
-{
-    ENetChannel * channel;
-
-    if (peer -> needsDispatch)
-    {
-       enet_list_remove (& peer -> dispatchList);
-
-       peer -> needsDispatch = 0;
-    }
-
-    while (! enet_list_empty (& peer -> acknowledgements))
-      enet_free (enet_list_remove (enet_list_begin (& peer -> acknowledgements)));
-
-    enet_peer_reset_outgoing_commands (& peer -> sentReliableCommands);
-    enet_peer_reset_outgoing_commands (& peer -> sentUnreliableCommands);
-    enet_peer_reset_outgoing_commands (& peer -> outgoingReliableCommands);
-    enet_peer_reset_outgoing_commands (& peer -> outgoingUnreliableCommands);
-    enet_peer_reset_incoming_commands (& peer -> dispatchedCommands);
-
-    if (peer -> channels != NULL && peer -> channelCount > 0)
-    {
-        for (channel = peer -> channels;
-             channel < & peer -> channels [peer -> channelCount];
-             ++ channel)
-        {
-            enet_peer_reset_incoming_commands (& channel -> incomingReliableCommands);
-            enet_peer_reset_incoming_commands (& channel -> incomingUnreliableCommands);
-        }
-
-        enet_free (peer -> channels);
-    }
-
-    peer -> channels = NULL;
-    peer -> channelCount = 0;
-}
-
-/** Forcefully disconnects a peer.
-    @param peer peer to forcefully disconnect
-    @remarks The foreign host represented by the peer is not notified of the disconnection and will timeout
-    on its connection to the local host.
-*/
-void
-enet_peer_reset (ENetPeer * peer)
-{
-    peer -> outgoingPeerID = ENET_PROTOCOL_MAXIMUM_PEER_ID;
-    peer -> connectID = 0;
-
-    peer -> state = ENET_PEER_STATE_DISCONNECTED;
-
-    peer -> incomingBandwidth = 0;
-    peer -> outgoingBandwidth = 0;
-    peer -> incomingBandwidthThrottleEpoch = 0;
-    peer -> outgoingBandwidthThrottleEpoch = 0;
-    peer -> incomingDataTotal = 0;
-    peer -> outgoingDataTotal = 0;
-    peer -> lastSendTime = 0;
-    peer -> lastReceiveTime = 0;
-    peer -> nextTimeout = 0;
-    peer -> earliestTimeout = 0;
-    peer -> packetLossEpoch = 0;
-    peer -> packetsSent = 0;
-    peer -> packetsLost = 0;
-    peer -> packetLoss = 0;
-    peer -> packetLossVariance = 0;
-    peer -> packetThrottle = ENET_PEER_DEFAULT_PACKET_THROTTLE;
-    peer -> packetThrottleLimit = ENET_PEER_PACKET_THROTTLE_SCALE;
-    peer -> packetThrottleCounter = 0;
-    peer -> packetThrottleEpoch = 0;
-    peer -> packetThrottleAcceleration = ENET_PEER_PACKET_THROTTLE_ACCELERATION;
-    peer -> packetThrottleDeceleration = ENET_PEER_PACKET_THROTTLE_DECELERATION;
-    peer -> packetThrottleInterval = ENET_PEER_PACKET_THROTTLE_INTERVAL;
-    peer -> lastRoundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME;
-    peer -> lowestRoundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME;
-    peer -> lastRoundTripTimeVariance = 0;
-    peer -> highestRoundTripTimeVariance = 0;
-    peer -> roundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME;
-    peer -> roundTripTimeVariance = 0;
-    peer -> mtu = peer -> host -> mtu;
-    peer -> reliableDataInTransit = 0;
-    peer -> outgoingReliableSequenceNumber = 0;
-    peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
-    peer -> incomingUnsequencedGroup = 0;
-    peer -> outgoingUnsequencedGroup = 0;
-    peer -> eventData = 0;
-
-    memset (peer -> unsequencedWindow, 0, sizeof (peer -> unsequencedWindow));
-    
-    enet_peer_reset_queues (peer);
-}
-
-/** Sends a ping request to a peer.
-    @param peer destination for the ping request
-    @remarks ping requests factor into the mean round trip time as designated by the 
-    roundTripTime field in the ENetPeer structure.  Enet automatically pings all connected
-    peers at regular intervals, however, this function may be called to ensure more
-    frequent ping requests.
-*/
-void
-enet_peer_ping (ENetPeer * peer)
-{
-    ENetProtocol command;
-
-    if (peer -> state != ENET_PEER_STATE_CONNECTED)
-      return;
-
-    command.header.command = ENET_PROTOCOL_COMMAND_PING | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
-    command.header.channelID = 0xFF;
-   
-    enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
-}
-
-/** Force an immediate disconnection from a peer.
-    @param peer peer to disconnect
-    @param data data describing the disconnection
-    @remarks No ENET_EVENT_DISCONNECT event will be generated. The foreign peer is not
-    guarenteed to receive the disconnect notification, and is reset immediately upon
-    return from this function.
-*/
-void
-enet_peer_disconnect_now (ENetPeer * peer, enet_uint32 data)
-{
-    ENetProtocol command;
-
-    if (peer -> state == ENET_PEER_STATE_DISCONNECTED)
-      return;
-
-    if (peer -> state != ENET_PEER_STATE_ZOMBIE &&
-        peer -> state != ENET_PEER_STATE_DISCONNECTING)
-    {
-        enet_peer_reset_queues (peer);
-
-        command.header.command = ENET_PROTOCOL_COMMAND_DISCONNECT | ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED;
-        command.header.channelID = 0xFF;
-        command.disconnect.data = ENET_HOST_TO_NET_32 (data);
-
-        enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
-
-        enet_host_flush (peer -> host);
-    }
-
-    enet_peer_reset (peer);
-}
-
-/** Request a disconnection from a peer.
-    @param peer peer to request a disconnection
-    @param data data describing the disconnection
-    @remarks An ENET_EVENT_DISCONNECT event will be generated by enet_host_service()
-    once the disconnection is complete.
-*/
-void
-enet_peer_disconnect (ENetPeer * peer, enet_uint32 data)
-{
-    ENetProtocol command;
-
-    if (peer -> state == ENET_PEER_STATE_DISCONNECTING ||
-        peer -> state == ENET_PEER_STATE_DISCONNECTED ||
-        peer -> state == ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT ||
-        peer -> state == ENET_PEER_STATE_ZOMBIE)
-      return;
-
-    enet_peer_reset_queues (peer);
-
-    command.header.command = ENET_PROTOCOL_COMMAND_DISCONNECT;
-    command.header.channelID = 0xFF;
-    command.disconnect.data = ENET_HOST_TO_NET_32 (data);
-
-    if (peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER)
-      command.header.command |= ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
-    else
-      command.header.command |= ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED;      
-    
-    enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
-
-    if (peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER)
-      peer -> state = ENET_PEER_STATE_DISCONNECTING;
-    else
-    {
-        enet_host_flush (peer -> host);
-        enet_peer_reset (peer);
-    }
-}
-
-/** Request a disconnection from a peer, but only after all queued outgoing packets are sent.
-    @param peer peer to request a disconnection
-    @param data data describing the disconnection
-    @remarks An ENET_EVENT_DISCONNECT event will be generated by enet_host_service()
-    once the disconnection is complete.
-*/
-void
-enet_peer_disconnect_later (ENetPeer * peer, enet_uint32 data)
-{   
-    if ((peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER) && 
-        ! (enet_list_empty (& peer -> outgoingReliableCommands) &&
-           enet_list_empty (& peer -> outgoingUnreliableCommands) && 
-           enet_list_empty (& peer -> sentReliableCommands)))
-    {
-        peer -> state = ENET_PEER_STATE_DISCONNECT_LATER;
-        peer -> eventData = data;
-    }
-    else
-      enet_peer_disconnect (peer, data);
-}
-
-ENetAcknowledgement *
-enet_peer_queue_acknowledgement (ENetPeer * peer, const ENetProtocol * command, enet_uint16 sentTime)
-{
-    ENetAcknowledgement * acknowledgement;
-
-    if (command -> header.channelID < peer -> channelCount)
-    {
-        ENetChannel * channel = & peer -> channels [command -> header.channelID];
-        enet_uint16 reliableWindow = command -> header.reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE,
-                    currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
-
-        if (command -> header.reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
-           reliableWindow += ENET_PEER_RELIABLE_WINDOWS;
-
-        if (reliableWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1 && reliableWindow <= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS)
-          return NULL;
-    }
-
-    acknowledgement = (ENetAcknowledgement *) enet_malloc (sizeof (ENetAcknowledgement));
-    if (acknowledgement == NULL)
-      return NULL;
-
-    peer -> outgoingDataTotal += sizeof (ENetProtocolAcknowledge);
-
-    acknowledgement -> sentTime = sentTime;
-    acknowledgement -> command = * command;
-    
-    enet_list_insert (enet_list_end (& peer -> acknowledgements), acknowledgement);
-    
-    return acknowledgement;
-}
-
-void
-enet_peer_setup_outgoing_command (ENetPeer * peer, ENetOutgoingCommand * outgoingCommand)
-{
-    ENetChannel * channel = & peer -> channels [outgoingCommand -> command.header.channelID];
-
-    peer -> outgoingDataTotal += enet_protocol_command_size (outgoingCommand -> command.header.command) + outgoingCommand -> fragmentLength;
-
-    if (outgoingCommand -> command.header.channelID == 0xFF)
-    {
-       ++ peer -> outgoingReliableSequenceNumber;
-
-       outgoingCommand -> reliableSequenceNumber = peer -> outgoingReliableSequenceNumber;
-       outgoingCommand -> unreliableSequenceNumber = 0;
-    }
-    else
-    if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
-    {
-       ++ channel -> outgoingReliableSequenceNumber;
-       channel -> outgoingUnreliableSequenceNumber = 0;
-
-       outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber;
-       outgoingCommand -> unreliableSequenceNumber = 0;
-    }
-    else
-    if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED)
-    {
-       ++ peer -> outgoingUnsequencedGroup;
-
-       outgoingCommand -> reliableSequenceNumber = 0;
-       outgoingCommand -> unreliableSequenceNumber = 0;
-    }
-    else
-    {
-       ++ channel -> outgoingUnreliableSequenceNumber;
-        
-       outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber;
-       outgoingCommand -> unreliableSequenceNumber = channel -> outgoingUnreliableSequenceNumber;
-    }
-   
-    outgoingCommand -> sendAttempts = 0;
-    outgoingCommand -> sentTime = 0;
-    outgoingCommand -> roundTripTimeout = 0;
-    outgoingCommand -> roundTripTimeoutLimit = 0;
-    outgoingCommand -> command.header.reliableSequenceNumber = ENET_HOST_TO_NET_16 (outgoingCommand -> reliableSequenceNumber);
-
-    if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
-      enet_list_insert (enet_list_end (& peer -> outgoingReliableCommands), outgoingCommand);
-    else
-      enet_list_insert (enet_list_end (& peer -> outgoingUnreliableCommands), outgoingCommand);
-}
-
-ENetOutgoingCommand *
-enet_peer_queue_outgoing_command (ENetPeer * peer, const ENetProtocol * command, ENetPacket * packet, enet_uint32 offset, enet_uint16 length)
-{
-    ENetOutgoingCommand * outgoingCommand = (ENetOutgoingCommand *) enet_malloc (sizeof (ENetOutgoingCommand));
-    if (outgoingCommand == NULL)
-      return NULL;
-
-    outgoingCommand -> command = * command;
-    outgoingCommand -> fragmentOffset = offset;
-    outgoingCommand -> fragmentLength = length;
-    outgoingCommand -> packet = packet;
-    if (packet != NULL)
-      ++ packet -> referenceCount;
-
-    enet_peer_setup_outgoing_command (peer, outgoingCommand);
-
-    return outgoingCommand;
-}
-
-void
-enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel * channel)
-{
-    ENetListIterator currentCommand;
-
-    for (currentCommand = enet_list_begin (& channel -> incomingUnreliableCommands);
-         currentCommand != enet_list_end (& channel -> incomingUnreliableCommands);
-         currentCommand = enet_list_next (currentCommand))
-    {
-       ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand;
-
-       if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE &&
-           incomingCommand -> reliableSequenceNumber != channel -> incomingReliableSequenceNumber)
-         break;
-    }
-
-    if (currentCommand == enet_list_begin (& channel -> incomingUnreliableCommands))
-      return;
-
-    enet_list_move (enet_list_end (& peer -> dispatchedCommands), enet_list_begin (& channel -> incomingUnreliableCommands), enet_list_previous (currentCommand));
-
-    if (! peer -> needsDispatch)
-    {
-       enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList);
-
-       peer -> needsDispatch = 1;
-    }
-}
-
-void
-enet_peer_dispatch_incoming_reliable_commands (ENetPeer * peer, ENetChannel * channel)
-{
-    ENetListIterator currentCommand;
-
-    for (currentCommand = enet_list_begin (& channel -> incomingReliableCommands);
-         currentCommand != enet_list_end (& channel -> incomingReliableCommands);
-         currentCommand = enet_list_next (currentCommand))
-    {
-       ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand;
-         
-       if (incomingCommand -> fragmentsRemaining > 0 ||
-           incomingCommand -> reliableSequenceNumber != (enet_uint16) (channel -> incomingReliableSequenceNumber + 1))
-         break;
-
-       channel -> incomingReliableSequenceNumber = incomingCommand -> reliableSequenceNumber;
-
-       if (incomingCommand -> fragmentCount > 0)
-         channel -> incomingReliableSequenceNumber += incomingCommand -> fragmentCount - 1;
-    } 
-
-    if (currentCommand == enet_list_begin (& channel -> incomingReliableCommands))
-      return;
-
-    enet_list_move (enet_list_end (& peer -> dispatchedCommands), enet_list_begin (& channel -> incomingReliableCommands), enet_list_previous (currentCommand));
-
-    if (! peer -> needsDispatch)
-    {
-       enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList);
-
-       peer -> needsDispatch = 1;
-    }
-
-    enet_peer_dispatch_incoming_unreliable_commands (peer, channel);
-}
-
-ENetIncomingCommand *
-enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command, ENetPacket * packet, enet_uint32 fragmentCount)
-{
-    static ENetIncomingCommand dummyCommand;
-
-    ENetChannel * channel = & peer -> channels [command -> header.channelID];
-    enet_uint32 unreliableSequenceNumber = 0, reliableSequenceNumber;
-    enet_uint16 reliableWindow, currentWindow;
-    ENetIncomingCommand * incomingCommand;
-    ENetListIterator currentCommand;
-
-    if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER)
-      goto freePacket;
-
-    if ((command -> header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED)
-    {
-        reliableSequenceNumber = command -> header.reliableSequenceNumber;
-        reliableWindow = reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
-        currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
-
-        if (reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
-           reliableWindow += ENET_PEER_RELIABLE_WINDOWS;
-
-        if (reliableWindow < currentWindow || reliableWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1)
-          goto freePacket;
-    }
-                    
-    switch (command -> header.command & ENET_PROTOCOL_COMMAND_MASK)
-    {
-    case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT:
-    case ENET_PROTOCOL_COMMAND_SEND_RELIABLE:
-       if (reliableSequenceNumber == channel -> incomingReliableSequenceNumber)
-           goto freePacket;
-       
-       for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands));
-            currentCommand != enet_list_end (& channel -> incomingReliableCommands);
-            currentCommand = enet_list_previous (currentCommand))
-       {
-          incomingCommand = (ENetIncomingCommand *) currentCommand;
-
-          if (reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
-          {
-             if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
-               continue;
-          }
-          else
-          if (incomingCommand -> reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
-            break;
-
-          if (incomingCommand -> reliableSequenceNumber <= reliableSequenceNumber)
-          {
-             if (incomingCommand -> reliableSequenceNumber < reliableSequenceNumber)
-               break;
-
-             goto freePacket;
-          }
-       }
-       break;
-
-    case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE:
-       unreliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> sendUnreliable.unreliableSequenceNumber);
-
-       for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingUnreliableCommands));
-            currentCommand != enet_list_end (& channel -> incomingUnreliableCommands);
-            currentCommand = enet_list_previous (currentCommand))
-       {
-          incomingCommand = (ENetIncomingCommand *) currentCommand;
-
-          if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE)
-            continue;
-
-          if (reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
-          {
-             if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
-               continue;
-          }
-          else
-          if (incomingCommand -> reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
-            break;
-
-          if (incomingCommand -> reliableSequenceNumber < reliableSequenceNumber)
-            break;
-
-          if (incomingCommand -> reliableSequenceNumber > reliableSequenceNumber)
-            continue;
-
-          if (incomingCommand -> unreliableSequenceNumber <= unreliableSequenceNumber)
-          {
-             if (incomingCommand -> unreliableSequenceNumber < unreliableSequenceNumber)
-               break;
-
-             goto freePacket;
-          }
-       }
-       break;
-
-    case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED:
-       currentCommand = enet_list_end (& channel -> incomingUnreliableCommands);
-       break;
-
-    default:
-       goto freePacket;
-    }
-
-    incomingCommand = (ENetIncomingCommand *) enet_malloc (sizeof (ENetIncomingCommand));
-    if (incomingCommand == NULL)
-      goto notifyError;
-
-    incomingCommand -> reliableSequenceNumber = command -> header.reliableSequenceNumber;
-    incomingCommand -> unreliableSequenceNumber = unreliableSequenceNumber & 0xFFFF;
-    incomingCommand -> command = * command;
-    incomingCommand -> fragmentCount = fragmentCount;
-    incomingCommand -> fragmentsRemaining = fragmentCount;
-    incomingCommand -> packet = packet;
-    incomingCommand -> fragments = NULL;
-    
-    if (fragmentCount > 0)
-    { 
-       incomingCommand -> fragments = (enet_uint32 *) enet_malloc ((fragmentCount + 31) / 32 * sizeof (enet_uint32));
-       if (incomingCommand -> fragments == NULL)
-       {
-          enet_free (incomingCommand);
-
-          goto notifyError;
-       }
-       memset (incomingCommand -> fragments, 0, (fragmentCount + 31) / 32 * sizeof (enet_uint32));
-    }
-
-    if (packet != NULL)
-      ++ packet -> referenceCount;
-
-    enet_list_insert (enet_list_next (currentCommand), incomingCommand);
-
-    switch (command -> header.command & ENET_PROTOCOL_COMMAND_MASK)
-    {
-    case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT:
-    case ENET_PROTOCOL_COMMAND_SEND_RELIABLE:
-       enet_peer_dispatch_incoming_reliable_commands (peer, channel);
-       break;
-
-    default:
-       enet_peer_dispatch_incoming_unreliable_commands (peer, channel);
-       break;
-    }
-
-    return incomingCommand;
-
-freePacket:
-    if (fragmentCount > 0)
-      goto notifyError;
-
-    if (packet != NULL && packet -> referenceCount == 0)
-      enet_packet_destroy (packet);
-
-    return & dummyCommand;
-
-notifyError:
-    if (packet != NULL && packet -> referenceCount == 0)
-      enet_packet_destroy (packet);
-
-    return NULL;
-}
-
-/** @} */
+/** 
+ @file  peer.c
+ @brief ENet peer management functions
+*/
+#include <string.h>
+#define ENET_BUILDING_LIB 1
+#include "enet/enet.h"
+
+/** @defgroup peer ENet peer functions 
+    @{
+*/
+
+/** Configures throttle parameter for a peer.
+
+    Unreliable packets are dropped by ENet in response to the varying conditions
+    of the Internet connection to the peer.  The throttle represents a probability
+    that an unreliable packet should not be dropped and thus sent by ENet to the peer.
+    The lowest mean round trip time from the sending of a reliable packet to the
+    receipt of its acknowledgement is measured over an amount of time specified by
+    the interval parameter in milliseconds.  If a measured round trip time happens to
+    be significantly less than the mean round trip time measured over the interval, 
+    then the throttle probability is increased to allow more traffic by an amount
+    specified in the acceleration parameter, which is a ratio to the ENET_PEER_PACKET_THROTTLE_SCALE
+    constant.  If a measured round trip time happens to be significantly greater than
+    the mean round trip time measured over the interval, then the throttle probability
+    is decreased to limit traffic by an amount specified in the deceleration parameter, which
+    is a ratio to the ENET_PEER_PACKET_THROTTLE_SCALE constant.  When the throttle has
+    a value of ENET_PEER_PACKET_THROTTLE_SCALE, on unreliable packets are dropped by 
+    ENet, and so 100% of all unreliable packets will be sent.  When the throttle has a
+    value of 0, all unreliable packets are dropped by ENet, and so 0% of all unreliable
+    packets will be sent.  Intermediate values for the throttle represent intermediate
+    probabilities between 0% and 100% of unreliable packets being sent.  The bandwidth
+    limits of the local and foreign hosts are taken into account to determine a 
+    sensible limit for the throttle probability above which it should not raise even in
+    the best of conditions.
+
+    @param peer peer to configure 
+    @param interval interval, in milliseconds, over which to measure lowest mean RTT; the default value is ENET_PEER_PACKET_THROTTLE_INTERVAL.
+    @param acceleration rate at which to increase the throttle probability as mean RTT declines
+    @param deceleration rate at which to decrease the throttle probability as mean RTT increases
+*/
+void
+enet_peer_throttle_configure (ENetPeer * peer, enet_uint32 interval, enet_uint32 acceleration, enet_uint32 deceleration)
+{
+    ENetProtocol command;
+
+    peer -> packetThrottleInterval = interval;
+    peer -> packetThrottleAcceleration = acceleration;
+    peer -> packetThrottleDeceleration = deceleration;
+
+    command.header.command = ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
+    command.header.channelID = 0xFF;
+
+    command.throttleConfigure.packetThrottleInterval = ENET_HOST_TO_NET_32 (interval);
+    command.throttleConfigure.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (acceleration);
+    command.throttleConfigure.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (deceleration);
+
+    enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
+}
+
+int
+enet_peer_throttle (ENetPeer * peer, enet_uint32 rtt)
+{
+    if (peer -> lastRoundTripTime <= peer -> lastRoundTripTimeVariance)
+    {
+        peer -> packetThrottle = peer -> packetThrottleLimit;
+    }
+    else
+    if (rtt < peer -> lastRoundTripTime)
+    {
+        peer -> packetThrottle += peer -> packetThrottleAcceleration;
+
+        if (peer -> packetThrottle > peer -> packetThrottleLimit)
+          peer -> packetThrottle = peer -> packetThrottleLimit;
+
+        return 1;
+    }
+    else
+    if (rtt > peer -> lastRoundTripTime + 2 * peer -> lastRoundTripTimeVariance)
+    {
+        if (peer -> packetThrottle > peer -> packetThrottleDeceleration)
+          peer -> packetThrottle -= peer -> packetThrottleDeceleration;
+        else
+          peer -> packetThrottle = 0;
+
+        return -1;
+    }
+
+    return 0;
+}
+
+/** Queues a packet to be sent.
+    @param peer destination for the packet
+    @param channelID channel on which to send
+    @param packet packet to send
+    @retval 0 on success
+    @retval < 0 on failure
+*/
+int
+enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet)
+{
+   ENetChannel * channel = & peer -> channels [channelID];
+   ENetProtocol command;
+   size_t fragmentLength;
+
+   if (peer -> state != ENET_PEER_STATE_CONNECTED ||
+       channelID >= peer -> channelCount)
+     return -1;
+
+   fragmentLength = peer -> mtu - sizeof (ENetProtocolHeader) - sizeof (ENetProtocolSendFragment);
+   if (peer -> host -> checksum != NULL)
+     fragmentLength -= sizeof(enet_uint32);
+
+   if (packet -> dataLength > fragmentLength)
+   {
+      enet_uint16 startSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingReliableSequenceNumber + 1);
+      enet_uint32 fragmentCount = ENET_HOST_TO_NET_32 ((packet -> dataLength + fragmentLength - 1) / fragmentLength),
+             fragmentNumber,
+             fragmentOffset;
+      ENetList fragments;
+      ENetOutgoingCommand * fragment;
+
+      enet_list_clear (& fragments);
+
+      for (fragmentNumber = 0,
+             fragmentOffset = 0;
+           fragmentOffset < packet -> dataLength;
+           ++ fragmentNumber,
+             fragmentOffset += fragmentLength)
+      {
+         if (packet -> dataLength - fragmentOffset < fragmentLength)
+           fragmentLength = packet -> dataLength - fragmentOffset;
+
+         fragment = (ENetOutgoingCommand *) enet_malloc (sizeof (ENetOutgoingCommand));
+         if (fragment == NULL)
+         {
+            while (! enet_list_empty (& fragments))
+            {
+               fragment = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (& fragments));
+               
+               enet_free (fragment);
+            }
+            
+            return -1;
+         }
+         
+         fragment -> fragmentOffset = fragmentOffset;
+         fragment -> fragmentLength = fragmentLength;
+         fragment -> packet = packet;
+         fragment -> command.header.command = ENET_PROTOCOL_COMMAND_SEND_FRAGMENT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
+         fragment -> command.header.channelID = channelID;
+         fragment -> command.sendFragment.startSequenceNumber = startSequenceNumber;
+         fragment -> command.sendFragment.dataLength = ENET_HOST_TO_NET_16 (fragmentLength);
+         fragment -> command.sendFragment.fragmentCount = fragmentCount;
+         fragment -> command.sendFragment.fragmentNumber = ENET_HOST_TO_NET_32 (fragmentNumber);
+         fragment -> command.sendFragment.totalLength = ENET_HOST_TO_NET_32 (packet -> dataLength);
+         fragment -> command.sendFragment.fragmentOffset = ENET_NET_TO_HOST_32 (fragmentOffset);
+        
+         enet_list_insert (enet_list_end (& fragments), fragment);
+      }
+
+      packet -> referenceCount += fragmentNumber;
+
+      while (! enet_list_empty (& fragments))
+      {
+         fragment = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (& fragments));
+ 
+         enet_peer_setup_outgoing_command (peer, fragment);
+      }
+
+      return 0;
+   }
+
+   command.header.channelID = channelID;
+
+   if (packet -> flags & ENET_PACKET_FLAG_RELIABLE)
+   {
+      command.header.command = ENET_PROTOCOL_COMMAND_SEND_RELIABLE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
+      command.sendReliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
+   }
+   else
+   if (packet -> flags & ENET_PACKET_FLAG_UNSEQUENCED)
+   {
+      command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED | ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED;
+      command.sendUnsequenced.unsequencedGroup = ENET_HOST_TO_NET_16 (peer -> outgoingUnsequencedGroup + 1);
+      command.sendUnsequenced.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
+   }
+   else 
+   if (channel -> outgoingUnreliableSequenceNumber >= 0xFFFF)
+   {
+      command.header.command = ENET_PROTOCOL_COMMAND_SEND_RELIABLE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
+      command.sendReliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
+   }
+   else
+   {
+      command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE;
+      command.sendUnreliable.unreliableSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingUnreliableSequenceNumber + 1);
+      command.sendUnreliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength);
+   }
+
+   if (enet_peer_queue_outgoing_command (peer, & command, packet, 0, packet -> dataLength) == NULL)
+     return -1;
+
+   return 0;
+}
+
+/** Attempts to dequeue any incoming queued packet.
+    @param peer peer to dequeue packets from
+    @param channelID holds the channel ID of the channel the packet was received on success
+    @returns a pointer to the packet, or NULL if there are no available incoming queued packets
+*/
+ENetPacket *
+enet_peer_receive (ENetPeer * peer, enet_uint8 * channelID)
+{
+   ENetIncomingCommand * incomingCommand;
+   ENetPacket * packet;
+   
+   if (enet_list_empty (& peer -> dispatchedCommands))
+     return NULL;
+
+   incomingCommand = (ENetIncomingCommand *) enet_list_remove (enet_list_begin (& peer -> dispatchedCommands));
+
+   if (channelID != NULL)
+     * channelID = incomingCommand -> command.header.channelID;
+
+   packet = incomingCommand -> packet;
+
+   -- packet -> referenceCount;
+
+   if (incomingCommand -> fragments != NULL)
+     enet_free (incomingCommand -> fragments);
+
+   enet_free (incomingCommand);
+
+   return packet;
+}
+
+static void
+enet_peer_reset_outgoing_commands (ENetList * queue)
+{
+    ENetOutgoingCommand * outgoingCommand;
+
+    while (! enet_list_empty (queue))
+    {
+       outgoingCommand = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (queue));
+
+       if (outgoingCommand -> packet != NULL)
+       {
+          -- outgoingCommand -> packet -> referenceCount;
+
+          if (outgoingCommand -> packet -> referenceCount == 0)
+            enet_packet_destroy (outgoingCommand -> packet);
+       }
+
+       enet_free (outgoingCommand);
+    }
+}
+
+static void
+enet_peer_reset_incoming_commands (ENetList * queue)
+{
+    ENetIncomingCommand * incomingCommand;
+
+    while (! enet_list_empty (queue))
+    {
+       incomingCommand = (ENetIncomingCommand *) enet_list_remove (enet_list_begin (queue));
+
+       if (incomingCommand -> packet != NULL)
+       {
+          -- incomingCommand -> packet -> referenceCount;
+
+          if (incomingCommand -> packet -> referenceCount == 0)
+            enet_packet_destroy (incomingCommand -> packet);
+       }
+
+       if (incomingCommand -> fragments != NULL)
+         enet_free (incomingCommand -> fragments);
+
+       enet_free (incomingCommand);
+    }
+}
+
+void
+enet_peer_reset_queues (ENetPeer * peer)
+{
+    ENetChannel * channel;
+
+    if (peer -> needsDispatch)
+    {
+       enet_list_remove (& peer -> dispatchList);
+
+       peer -> needsDispatch = 0;
+    }
+
+    while (! enet_list_empty (& peer -> acknowledgements))
+      enet_free (enet_list_remove (enet_list_begin (& peer -> acknowledgements)));
+
+    enet_peer_reset_outgoing_commands (& peer -> sentReliableCommands);
+    enet_peer_reset_outgoing_commands (& peer -> sentUnreliableCommands);
+    enet_peer_reset_outgoing_commands (& peer -> outgoingReliableCommands);
+    enet_peer_reset_outgoing_commands (& peer -> outgoingUnreliableCommands);
+    enet_peer_reset_incoming_commands (& peer -> dispatchedCommands);
+
+    if (peer -> channels != NULL && peer -> channelCount > 0)
+    {
+        for (channel = peer -> channels;
+             channel < & peer -> channels [peer -> channelCount];
+             ++ channel)
+        {
+            enet_peer_reset_incoming_commands (& channel -> incomingReliableCommands);
+            enet_peer_reset_incoming_commands (& channel -> incomingUnreliableCommands);
+        }
+
+        enet_free (peer -> channels);
+    }
+
+    peer -> channels = NULL;
+    peer -> channelCount = 0;
+}
+
+/** Forcefully disconnects a peer.
+    @param peer peer to forcefully disconnect
+    @remarks The foreign host represented by the peer is not notified of the disconnection and will timeout
+    on its connection to the local host.
+*/
+void
+enet_peer_reset (ENetPeer * peer)
+{
+    peer -> outgoingPeerID = ENET_PROTOCOL_MAXIMUM_PEER_ID;
+    peer -> connectID = 0;
+
+    peer -> state = ENET_PEER_STATE_DISCONNECTED;
+
+    peer -> incomingBandwidth = 0;
+    peer -> outgoingBandwidth = 0;
+    peer -> incomingBandwidthThrottleEpoch = 0;
+    peer -> outgoingBandwidthThrottleEpoch = 0;
+    peer -> incomingDataTotal = 0;
+    peer -> outgoingDataTotal = 0;
+    peer -> lastSendTime = 0;
+    peer -> lastReceiveTime = 0;
+    peer -> nextTimeout = 0;
+    peer -> earliestTimeout = 0;
+    peer -> packetLossEpoch = 0;
+    peer -> packetsSent = 0;
+    peer -> packetsLost = 0;
+    peer -> packetLoss = 0;
+    peer -> packetLossVariance = 0;
+    peer -> packetThrottle = ENET_PEER_DEFAULT_PACKET_THROTTLE;
+    peer -> packetThrottleLimit = ENET_PEER_PACKET_THROTTLE_SCALE;
+    peer -> packetThrottleCounter = 0;
+    peer -> packetThrottleEpoch = 0;
+    peer -> packetThrottleAcceleration = ENET_PEER_PACKET_THROTTLE_ACCELERATION;
+    peer -> packetThrottleDeceleration = ENET_PEER_PACKET_THROTTLE_DECELERATION;
+    peer -> packetThrottleInterval = ENET_PEER_PACKET_THROTTLE_INTERVAL;
+    peer -> lastRoundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME;
+    peer -> lowestRoundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME;
+    peer -> lastRoundTripTimeVariance = 0;
+    peer -> highestRoundTripTimeVariance = 0;
+    peer -> roundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME;
+    peer -> roundTripTimeVariance = 0;
+    peer -> mtu = peer -> host -> mtu;
+    peer -> reliableDataInTransit = 0;
+    peer -> outgoingReliableSequenceNumber = 0;
+    peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
+    peer -> incomingUnsequencedGroup = 0;
+    peer -> outgoingUnsequencedGroup = 0;
+    peer -> eventData = 0;
+
+    memset (peer -> unsequencedWindow, 0, sizeof (peer -> unsequencedWindow));
+    
+    enet_peer_reset_queues (peer);
+}
+
+/** Sends a ping request to a peer.
+    @param peer destination for the ping request
+    @remarks ping requests factor into the mean round trip time as designated by the 
+    roundTripTime field in the ENetPeer structure.  Enet automatically pings all connected
+    peers at regular intervals, however, this function may be called to ensure more
+    frequent ping requests.
+*/
+void
+enet_peer_ping (ENetPeer * peer)
+{
+    ENetProtocol command;
+
+    if (peer -> state != ENET_PEER_STATE_CONNECTED)
+      return;
+
+    command.header.command = ENET_PROTOCOL_COMMAND_PING | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
+    command.header.channelID = 0xFF;
+   
+    enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
+}
+
+/** Force an immediate disconnection from a peer.
+    @param peer peer to disconnect
+    @param data data describing the disconnection
+    @remarks No ENET_EVENT_DISCONNECT event will be generated. The foreign peer is not
+    guarenteed to receive the disconnect notification, and is reset immediately upon
+    return from this function.
+*/
+void
+enet_peer_disconnect_now (ENetPeer * peer, enet_uint32 data)
+{
+    ENetProtocol command;
+
+    if (peer -> state == ENET_PEER_STATE_DISCONNECTED)
+      return;
+
+    if (peer -> state != ENET_PEER_STATE_ZOMBIE &&
+        peer -> state != ENET_PEER_STATE_DISCONNECTING)
+    {
+        enet_peer_reset_queues (peer);
+
+        command.header.command = ENET_PROTOCOL_COMMAND_DISCONNECT | ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED;
+        command.header.channelID = 0xFF;
+        command.disconnect.data = ENET_HOST_TO_NET_32 (data);
+
+        enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
+
+        enet_host_flush (peer -> host);
+    }
+
+    enet_peer_reset (peer);
+}
+
+/** Request a disconnection from a peer.
+    @param peer peer to request a disconnection
+    @param data data describing the disconnection
+    @remarks An ENET_EVENT_DISCONNECT event will be generated by enet_host_service()
+    once the disconnection is complete.
+*/
+void
+enet_peer_disconnect (ENetPeer * peer, enet_uint32 data)
+{
+    ENetProtocol command;
+
+    if (peer -> state == ENET_PEER_STATE_DISCONNECTING ||
+        peer -> state == ENET_PEER_STATE_DISCONNECTED ||
+        peer -> state == ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT ||
+        peer -> state == ENET_PEER_STATE_ZOMBIE)
+      return;
+
+    enet_peer_reset_queues (peer);
+
+    command.header.command = ENET_PROTOCOL_COMMAND_DISCONNECT;
+    command.header.channelID = 0xFF;
+    command.disconnect.data = ENET_HOST_TO_NET_32 (data);
+
+    if (peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER)
+      command.header.command |= ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
+    else
+      command.header.command |= ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED;      
+    
+    enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
+
+    if (peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER)
+      peer -> state = ENET_PEER_STATE_DISCONNECTING;
+    else
+    {
+        enet_host_flush (peer -> host);
+        enet_peer_reset (peer);
+    }
+}
+
+/** Request a disconnection from a peer, but only after all queued outgoing packets are sent.
+    @param peer peer to request a disconnection
+    @param data data describing the disconnection
+    @remarks An ENET_EVENT_DISCONNECT event will be generated by enet_host_service()
+    once the disconnection is complete.
+*/
+void
+enet_peer_disconnect_later (ENetPeer * peer, enet_uint32 data)
+{   
+    if ((peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER) && 
+        ! (enet_list_empty (& peer -> outgoingReliableCommands) &&
+           enet_list_empty (& peer -> outgoingUnreliableCommands) && 
+           enet_list_empty (& peer -> sentReliableCommands)))
+    {
+        peer -> state = ENET_PEER_STATE_DISCONNECT_LATER;
+        peer -> eventData = data;
+    }
+    else
+      enet_peer_disconnect (peer, data);
+}
+
+ENetAcknowledgement *
+enet_peer_queue_acknowledgement (ENetPeer * peer, const ENetProtocol * command, enet_uint16 sentTime)
+{
+    ENetAcknowledgement * acknowledgement;
+
+    if (command -> header.channelID < peer -> channelCount)
+    {
+        ENetChannel * channel = & peer -> channels [command -> header.channelID];
+        enet_uint16 reliableWindow = command -> header.reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE,
+                    currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
+
+        if (command -> header.reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
+           reliableWindow += ENET_PEER_RELIABLE_WINDOWS;
+
+        if (reliableWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1 && reliableWindow <= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS)
+          return NULL;
+    }
+
+    acknowledgement = (ENetAcknowledgement *) enet_malloc (sizeof (ENetAcknowledgement));
+    if (acknowledgement == NULL)
+      return NULL;
+
+    peer -> outgoingDataTotal += sizeof (ENetProtocolAcknowledge);
+
+    acknowledgement -> sentTime = sentTime;
+    acknowledgement -> command = * command;
+    
+    enet_list_insert (enet_list_end (& peer -> acknowledgements), acknowledgement);
+    
+    return acknowledgement;
+}
+
+void
+enet_peer_setup_outgoing_command (ENetPeer * peer, ENetOutgoingCommand * outgoingCommand)
+{
+    ENetChannel * channel = & peer -> channels [outgoingCommand -> command.header.channelID];
+
+    peer -> outgoingDataTotal += enet_protocol_command_size (outgoingCommand -> command.header.command) + outgoingCommand -> fragmentLength;
+
+    if (outgoingCommand -> command.header.channelID == 0xFF)
+    {
+       ++ peer -> outgoingReliableSequenceNumber;
+
+       outgoingCommand -> reliableSequenceNumber = peer -> outgoingReliableSequenceNumber;
+       outgoingCommand -> unreliableSequenceNumber = 0;
+    }
+    else
+    if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
+    {
+       ++ channel -> outgoingReliableSequenceNumber;
+       channel -> outgoingUnreliableSequenceNumber = 0;
+
+       outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber;
+       outgoingCommand -> unreliableSequenceNumber = 0;
+    }
+    else
+    if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED)
+    {
+       ++ peer -> outgoingUnsequencedGroup;
+
+       outgoingCommand -> reliableSequenceNumber = 0;
+       outgoingCommand -> unreliableSequenceNumber = 0;
+    }
+    else
+    {
+       ++ channel -> outgoingUnreliableSequenceNumber;
+        
+       outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber;
+       outgoingCommand -> unreliableSequenceNumber = channel -> outgoingUnreliableSequenceNumber;
+    }
+   
+    outgoingCommand -> sendAttempts = 0;
+    outgoingCommand -> sentTime = 0;
+    outgoingCommand -> roundTripTimeout = 0;
+    outgoingCommand -> roundTripTimeoutLimit = 0;
+    outgoingCommand -> command.header.reliableSequenceNumber = ENET_HOST_TO_NET_16 (outgoingCommand -> reliableSequenceNumber);
+
+    if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE)
+      enet_list_insert (enet_list_end (& peer -> outgoingReliableCommands), outgoingCommand);
+    else
+      enet_list_insert (enet_list_end (& peer -> outgoingUnreliableCommands), outgoingCommand);
+}
+
+ENetOutgoingCommand *
+enet_peer_queue_outgoing_command (ENetPeer * peer, const ENetProtocol * command, ENetPacket * packet, enet_uint32 offset, enet_uint16 length)
+{
+    ENetOutgoingCommand * outgoingCommand = (ENetOutgoingCommand *) enet_malloc (sizeof (ENetOutgoingCommand));
+    if (outgoingCommand == NULL)
+      return NULL;
+
+    outgoingCommand -> command = * command;
+    outgoingCommand -> fragmentOffset = offset;
+    outgoingCommand -> fragmentLength = length;
+    outgoingCommand -> packet = packet;
+    if (packet != NULL)
+      ++ packet -> referenceCount;
+
+    enet_peer_setup_outgoing_command (peer, outgoingCommand);
+
+    return outgoingCommand;
+}
+
+void
+enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel * channel)
+{
+    ENetListIterator currentCommand;
+
+    for (currentCommand = enet_list_begin (& channel -> incomingUnreliableCommands);
+         currentCommand != enet_list_end (& channel -> incomingUnreliableCommands);
+         currentCommand = enet_list_next (currentCommand))
+    {
+       ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand;
+
+       if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE &&
+           incomingCommand -> reliableSequenceNumber != channel -> incomingReliableSequenceNumber)
+         break;
+    }
+
+    if (currentCommand == enet_list_begin (& channel -> incomingUnreliableCommands))
+      return;
+
+    enet_list_move (enet_list_end (& peer -> dispatchedCommands), enet_list_begin (& channel -> incomingUnreliableCommands), enet_list_previous (currentCommand));
+
+    if (! peer -> needsDispatch)
+    {
+       enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList);
+
+       peer -> needsDispatch = 1;
+    }
+}
+
+void
+enet_peer_dispatch_incoming_reliable_commands (ENetPeer * peer, ENetChannel * channel)
+{
+    ENetListIterator currentCommand;
+
+    for (currentCommand = enet_list_begin (& channel -> incomingReliableCommands);
+         currentCommand != enet_list_end (& channel -> incomingReliableCommands);
+         currentCommand = enet_list_next (currentCommand))
+    {
+       ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand;
+         
+       if (incomingCommand -> fragmentsRemaining > 0 ||
+           incomingCommand -> reliableSequenceNumber != (enet_uint16) (channel -> incomingReliableSequenceNumber + 1))
+         break;
+
+       channel -> incomingReliableSequenceNumber = incomingCommand -> reliableSequenceNumber;
+
+       if (incomingCommand -> fragmentCount > 0)
+         channel -> incomingReliableSequenceNumber += incomingCommand -> fragmentCount - 1;
+    } 
+
+    if (currentCommand == enet_list_begin (& channel -> incomingReliableCommands))
+      return;
+
+    enet_list_move (enet_list_end (& peer -> dispatchedCommands), enet_list_begin (& channel -> incomingReliableCommands), enet_list_previous (currentCommand));
+
+    if (! peer -> needsDispatch)
+    {
+       enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList);
+
+       peer -> needsDispatch = 1;
+    }
+
+    enet_peer_dispatch_incoming_unreliable_commands (peer, channel);
+}
+
+ENetIncomingCommand *
+enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command, ENetPacket * packet, enet_uint32 fragmentCount)
+{
+    static ENetIncomingCommand dummyCommand;
+
+    ENetChannel * channel = & peer -> channels [command -> header.channelID];
+    enet_uint32 unreliableSequenceNumber = 0, reliableSequenceNumber;
+    enet_uint16 reliableWindow, currentWindow;
+    ENetIncomingCommand * incomingCommand;
+    ENetListIterator currentCommand;
+
+    if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER)
+      goto freePacket;
+
+    if ((command -> header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED)
+    {
+        reliableSequenceNumber = command -> header.reliableSequenceNumber;
+        reliableWindow = reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
+        currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE;
+
+        if (reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
+           reliableWindow += ENET_PEER_RELIABLE_WINDOWS;
+
+        if (reliableWindow < currentWindow || reliableWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1)
+          goto freePacket;
+    }
+                    
+    switch (command -> header.command & ENET_PROTOCOL_COMMAND_MASK)
+    {
+    case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT:
+    case ENET_PROTOCOL_COMMAND_SEND_RELIABLE:
+       if (reliableSequenceNumber == channel -> incomingReliableSequenceNumber)
+           goto freePacket;
+       
+       for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands));
+            currentCommand != enet_list_end (& channel -> incomingReliableCommands);
+            currentCommand = enet_list_previous (currentCommand))
+       {
+          incomingCommand = (ENetIncomingCommand *) currentCommand;
+
+          if (reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
+          {
+             if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
+               continue;
+          }
+          else
+          if (incomingCommand -> reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
+            break;
+
+          if (incomingCommand -> reliableSequenceNumber <= reliableSequenceNumber)
+          {
+             if (incomingCommand -> reliableSequenceNumber < reliableSequenceNumber)
+               break;
+
+             goto freePacket;
+          }
+       }
+       break;
+
+    case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE:
+       unreliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> sendUnreliable.unreliableSequenceNumber);
+
+       for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingUnreliableCommands));
+            currentCommand != enet_list_end (& channel -> incomingUnreliableCommands);
+            currentCommand = enet_list_previous (currentCommand))
+       {
+          incomingCommand = (ENetIncomingCommand *) currentCommand;
+
+          if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE)
+            continue;
+
+          if (reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
+          {
+             if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber)
+               continue;
+          }
+          else
+          if (incomingCommand -> reliableSequenceNumber >= channel -> incomingReliableSequenceNumber)
+            break;
+
+          if (incomingCommand -> reliableSequenceNumber < reliableSequenceNumber)
+            break;
+
+          if (incomingCommand -> reliableSequenceNumber > reliableSequenceNumber)
+            continue;
+
+          if (incomingCommand -> unreliableSequenceNumber <= unreliableSequenceNumber)
+          {
+             if (incomingCommand -> unreliableSequenceNumber < unreliableSequenceNumber)
+               break;
+
+             goto freePacket;
+          }
+       }
+       break;
+
+    case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED:
+       currentCommand = enet_list_end (& channel -> incomingUnreliableCommands);
+       break;
+
+    default:
+       goto freePacket;
+    }
+
+    incomingCommand = (ENetIncomingCommand *) enet_malloc (sizeof (ENetIncomingCommand));
+    if (incomingCommand == NULL)
+      goto notifyError;
+
+    incomingCommand -> reliableSequenceNumber = command -> header.reliableSequenceNumber;
+    incomingCommand -> unreliableSequenceNumber = unreliableSequenceNumber & 0xFFFF;
+    incomingCommand -> command = * command;
+    incomingCommand -> fragmentCount = fragmentCount;
+    incomingCommand -> fragmentsRemaining = fragmentCount;
+    incomingCommand -> packet = packet;
+    incomingCommand -> fragments = NULL;
+    
+    if (fragmentCount > 0)
+    { 
+       incomingCommand -> fragments = (enet_uint32 *) enet_malloc ((fragmentCount + 31) / 32 * sizeof (enet_uint32));
+       if (incomingCommand -> fragments == NULL)
+       {
+          enet_free (incomingCommand);
+
+          goto notifyError;
+       }
+       memset (incomingCommand -> fragments, 0, (fragmentCount + 31) / 32 * sizeof (enet_uint32));
+    }
+
+    if (packet != NULL)
+      ++ packet -> referenceCount;
+
+    enet_list_insert (enet_list_next (currentCommand), incomingCommand);
+
+    switch (command -> header.command & ENET_PROTOCOL_COMMAND_MASK)
+    {
+    case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT:
+    case ENET_PROTOCOL_COMMAND_SEND_RELIABLE:
+       enet_peer_dispatch_incoming_reliable_commands (peer, channel);
+       break;
+
+    default:
+       enet_peer_dispatch_incoming_unreliable_commands (peer, channel);
+       break;
+    }
+
+    return incomingCommand;
+
+freePacket:
+    if (fragmentCount > 0)
+      goto notifyError;
+
+    if (packet != NULL && packet -> referenceCount == 0)
+      enet_packet_destroy (packet);
+
+    return & dummyCommand;
+
+notifyError:
+    if (packet != NULL && packet -> referenceCount == 0)
+      enet_packet_destroy (packet);
+
+    return NULL;
+}
+
+/** @} */

+ 1694 - 1671
ThirdParty/ENet/protocol.c

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

+ 438 - 438
ThirdParty/ENet/unix.c

@@ -1,438 +1,438 @@
-/** 
- @file  unix.c
- @brief ENet Unix system specific functions
-*/
-#ifndef WIN32
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <sys/time.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <time.h>
-
-#define ENET_BUILDING_LIB 1
-#include "enet/enet.h"
-
-#ifdef HAS_FCNTL
-#include <fcntl.h>
-#endif
-
-#ifdef __APPLE__
-#undef HAS_POLL
-#endif
-
-#ifdef HAS_POLL
-#include <sys/poll.h>
-#endif
-
-#ifndef HAS_SOCKLEN_T
-typedef int socklen_t;
-#endif
-
-#ifndef MSG_NOSIGNAL
-#define MSG_NOSIGNAL 0
-#endif
-
-static enet_uint32 timeBase = 0;
-
-int
-enet_initialize (void)
-{
-    return 0;
-}
-
-void
-enet_deinitialize (void)
-{
-}
-
-enet_uint32
-enet_time_get (void)
-{
-    struct timeval timeVal;
-
-    gettimeofday (& timeVal, NULL);
-
-    return timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - timeBase;
-}
-
-void
-enet_time_set (enet_uint32 newTimeBase)
-{
-    struct timeval timeVal;
-
-    gettimeofday (& timeVal, NULL);
-    
-    timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase;
-}
-
-int
-enet_address_set_host (ENetAddress * address, const char * name)
-{
-    struct hostent * hostEntry = NULL;
-#ifdef HAS_GETHOSTBYNAME_R
-    struct hostent hostData;
-    char buffer [2048];
-    int errnum;
-
-#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-    gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
-#else
-    hostEntry = gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & errnum);
-#endif
-#else
-    hostEntry = gethostbyname (name);
-#endif
-
-    if (hostEntry == NULL ||
-        hostEntry -> h_addrtype != AF_INET)
-    {
-#ifdef HAS_INET_PTON
-        if (! inet_pton (AF_INET, name, & address -> host))
-#else
-        if (! inet_aton (name, (struct in_addr *) & address -> host))
-#endif
-            return -1;
-        return 0;
-    }
-
-    address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
-
-    return 0;
-}
-
-int
-enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
-{
-#ifdef HAS_INET_NTOP
-    if (inet_ntop (AF_INET, & address -> host, name, nameLength) == NULL)
-#else
-    char * addr = inet_ntoa (* (struct in_addr *) & address -> host);
-    if (addr != NULL)
-        strncpy (name, addr, nameLength);
-    else
-#endif
-        return -1;
-    return 0;
-}
-
-int
-enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
-{
-    struct in_addr in;
-    struct hostent * hostEntry = NULL;
-#ifdef HAS_GETHOSTBYADDR_R
-    struct hostent hostData;
-    char buffer [2048];
-    int errnum;
-
-    in.s_addr = address -> host;
-
-#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-    gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
-#else
-    hostEntry = gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & errnum);
-#endif
-#else
-    in.s_addr = address -> host;
-
-    hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
-#endif
-
-    if (hostEntry == NULL)
-      return enet_address_get_host_ip (address, name, nameLength);
-
-    strncpy (name, hostEntry -> h_name, nameLength);
-
-    return 0;
-}
-
-int
-enet_socket_bind (ENetSocket socket, const ENetAddress * address)
-{
-    struct sockaddr_in sin;
-
-    memset (& sin, 0, sizeof (struct sockaddr_in));
-
-    sin.sin_family = AF_INET;
-
-    if (address != NULL)
-    {
-       sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
-       sin.sin_addr.s_addr = address -> host;
-    }
-    else
-    {
-       sin.sin_port = 0;
-       sin.sin_addr.s_addr = INADDR_ANY;
-    }
-
-    return bind (socket,
-                 (struct sockaddr *) & sin,
-                 sizeof (struct sockaddr_in)); 
-}
-
-int 
-enet_socket_listen (ENetSocket socket, int backlog)
-{
-    return listen (socket, backlog < 0 ? SOMAXCONN : backlog);
-}
-
-ENetSocket
-enet_socket_create (ENetSocketType type)
-{
-    return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
-}
-
-int
-enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
-{
-    int result = -1;
-    switch (option)
-    {
-        case ENET_SOCKOPT_NONBLOCK:
-#ifdef HAS_FCNTL
-            result = fcntl (socket, F_SETFL, O_NONBLOCK | fcntl (socket, F_GETFL));
-#else
-            result = ioctl (socket, FIONBIO, & value);
-#endif
-            break;
-
-        case ENET_SOCKOPT_BROADCAST:
-            result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int));
-            break;
-
-        case ENET_SOCKOPT_REUSEADDR:
-            result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int));
-            break;
-
-        case ENET_SOCKOPT_RCVBUF:
-            result = setsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) & value, sizeof (int));
-            break;
-
-        case ENET_SOCKOPT_SNDBUF:
-            result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int));
-            break;
-
-        default:
-            break;
-    }
-    return result == -1 ? -1 : 0;
-}
-
-int
-enet_socket_connect (ENetSocket socket, const ENetAddress * address)
-{
-    struct sockaddr_in sin;
-
-    memset (& sin, 0, sizeof (struct sockaddr_in));
-
-    sin.sin_family = AF_INET;
-    sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
-    sin.sin_addr.s_addr = address -> host;
-
-    return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in));
-}
-
-ENetSocket
-enet_socket_accept (ENetSocket socket, ENetAddress * address)
-{
-    int result;
-    struct sockaddr_in sin;
-    socklen_t sinLength = sizeof (struct sockaddr_in);
-
-    result = accept (socket, 
-                     address != NULL ? (struct sockaddr *) & sin : NULL, 
-                     address != NULL ? & sinLength : NULL);
-    
-    if (result == -1)
-      return ENET_SOCKET_NULL;
-
-    if (address != NULL)
-    {
-        address -> host = (enet_uint32) sin.sin_addr.s_addr;
-        address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
-    }
-
-    return result;
-} 
-    
-void
-enet_socket_destroy (ENetSocket socket)
-{
-    close (socket);
-}
-
-int
-enet_socket_send (ENetSocket socket,
-                  const ENetAddress * address,
-                  const ENetBuffer * buffers,
-                  size_t bufferCount)
-{
-    struct msghdr msgHdr;
-    struct sockaddr_in sin;
-    int sentLength;
-
-    memset (& msgHdr, 0, sizeof (struct msghdr));
-
-    if (address != NULL)
-    {
-        memset (& sin, 0, sizeof (struct sockaddr_in));
-
-        sin.sin_family = AF_INET;
-        sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
-        sin.sin_addr.s_addr = address -> host;
-
-        msgHdr.msg_name = & sin;
-        msgHdr.msg_namelen = sizeof (struct sockaddr_in);
-    }
-
-    msgHdr.msg_iov = (struct iovec *) buffers;
-    msgHdr.msg_iovlen = bufferCount;
-
-    sentLength = sendmsg (socket, & msgHdr, MSG_NOSIGNAL);
-    
-    if (sentLength == -1)
-    {
-       if (errno == EWOULDBLOCK)
-         return 0;
-
-       return -1;
-    }
-
-    return sentLength;
-}
-
-int
-enet_socket_receive (ENetSocket socket,
-                     ENetAddress * address,
-                     ENetBuffer * buffers,
-                     size_t bufferCount)
-{
-    struct msghdr msgHdr;
-    struct sockaddr_in sin;
-    int recvLength;
-
-    memset (& msgHdr, 0, sizeof (struct msghdr));
-
-    if (address != NULL)
-    {
-        msgHdr.msg_name = & sin;
-        msgHdr.msg_namelen = sizeof (struct sockaddr_in);
-    }
-
-    msgHdr.msg_iov = (struct iovec *) buffers;
-    msgHdr.msg_iovlen = bufferCount;
-
-    recvLength = recvmsg (socket, & msgHdr, MSG_NOSIGNAL);
-
-    if (recvLength == -1)
-    {
-       if (errno == EWOULDBLOCK)
-         return 0;
-
-       return -1;
-    }
-
-#ifdef HAS_MSGHDR_FLAGS
-    if (msgHdr.msg_flags & MSG_TRUNC)
-      return -1;
-#endif
-
-    if (address != NULL)
-    {
-        address -> host = (enet_uint32) sin.sin_addr.s_addr;
-        address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
-    }
-
-    return recvLength;
-}
-
-int
-enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocketSet * writeSet, enet_uint32 timeout)
-{
-    struct timeval timeVal;
-
-    timeVal.tv_sec = timeout / 1000;
-    timeVal.tv_usec = (timeout % 1000) * 1000;
-
-    return select (maxSocket + 1, readSet, writeSet, NULL, & timeVal);
-}
-
-int
-enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout)
-{
-#ifdef HAS_POLL
-    struct pollfd pollSocket;
-    int pollCount;
-    
-    pollSocket.fd = socket;
-    pollSocket.events = 0;
-
-    if (* condition & ENET_SOCKET_WAIT_SEND)
-      pollSocket.events |= POLLOUT;
-
-    if (* condition & ENET_SOCKET_WAIT_RECEIVE)
-      pollSocket.events |= POLLIN;
-
-    pollCount = poll (& pollSocket, 1, timeout);
-
-    if (pollCount < 0)
-      return -1;
-
-    * condition = ENET_SOCKET_WAIT_NONE;
-
-    if (pollCount == 0)
-      return 0;
-
-    if (pollSocket.revents & POLLOUT)
-      * condition |= ENET_SOCKET_WAIT_SEND;
-    
-    if (pollSocket.revents & POLLIN)
-      * condition |= ENET_SOCKET_WAIT_RECEIVE;
-
-    return 0;
-#else
-    fd_set readSet, writeSet;
-    struct timeval timeVal;
-    int selectCount;
-
-    timeVal.tv_sec = timeout / 1000;
-    timeVal.tv_usec = (timeout % 1000) * 1000;
-
-    FD_ZERO (& readSet);
-    FD_ZERO (& writeSet);
-
-    if (* condition & ENET_SOCKET_WAIT_SEND)
-      FD_SET (socket, & writeSet);
-
-    if (* condition & ENET_SOCKET_WAIT_RECEIVE)
-      FD_SET (socket, & readSet);
-
-    selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
-
-    if (selectCount < 0)
-      return -1;
-
-    * condition = ENET_SOCKET_WAIT_NONE;
-
-    if (selectCount == 0)
-      return 0;
-
-    if (FD_ISSET (socket, & writeSet))
-      * condition |= ENET_SOCKET_WAIT_SEND;
-
-    if (FD_ISSET (socket, & readSet))
-      * condition |= ENET_SOCKET_WAIT_RECEIVE;
-
-    return 0;
-#endif
-}
-
-#endif
-
+/** 
+ @file  unix.c
+ @brief ENet Unix system specific functions
+*/
+#ifndef WIN32
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <time.h>
+
+#define ENET_BUILDING_LIB 1
+#include "enet/enet.h"
+
+#ifdef HAS_FCNTL
+#include <fcntl.h>
+#endif
+
+#ifdef __APPLE__
+#undef HAS_POLL
+#endif
+
+#ifdef HAS_POLL
+#include <sys/poll.h>
+#endif
+
+#ifndef HAS_SOCKLEN_T
+typedef int socklen_t;
+#endif
+
+#ifndef MSG_NOSIGNAL
+#define MSG_NOSIGNAL 0
+#endif
+
+static enet_uint32 timeBase = 0;
+
+int
+enet_initialize (void)
+{
+    return 0;
+}
+
+void
+enet_deinitialize (void)
+{
+}
+
+enet_uint32
+enet_time_get (void)
+{
+    struct timeval timeVal;
+
+    gettimeofday (& timeVal, NULL);
+
+    return timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - timeBase;
+}
+
+void
+enet_time_set (enet_uint32 newTimeBase)
+{
+    struct timeval timeVal;
+
+    gettimeofday (& timeVal, NULL);
+    
+    timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase;
+}
+
+int
+enet_address_set_host (ENetAddress * address, const char * name)
+{
+    struct hostent * hostEntry = NULL;
+#ifdef HAS_GETHOSTBYNAME_R
+    struct hostent hostData;
+    char buffer [2048];
+    int errnum;
+
+#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+    gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
+#else
+    hostEntry = gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & errnum);
+#endif
+#else
+    hostEntry = gethostbyname (name);
+#endif
+
+    if (hostEntry == NULL ||
+        hostEntry -> h_addrtype != AF_INET)
+    {
+#ifdef HAS_INET_PTON
+        if (! inet_pton (AF_INET, name, & address -> host))
+#else
+        if (! inet_aton (name, (struct in_addr *) & address -> host))
+#endif
+            return -1;
+        return 0;
+    }
+
+    address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
+
+    return 0;
+}
+
+int
+enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
+{
+#ifdef HAS_INET_NTOP
+    if (inet_ntop (AF_INET, & address -> host, name, nameLength) == NULL)
+#else
+    char * addr = inet_ntoa (* (struct in_addr *) & address -> host);
+    if (addr != NULL)
+        strncpy (name, addr, nameLength);
+    else
+#endif
+        return -1;
+    return 0;
+}
+
+int
+enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
+{
+    struct in_addr in;
+    struct hostent * hostEntry = NULL;
+#ifdef HAS_GETHOSTBYADDR_R
+    struct hostent hostData;
+    char buffer [2048];
+    int errnum;
+
+    in.s_addr = address -> host;
+
+#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+    gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
+#else
+    hostEntry = gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & errnum);
+#endif
+#else
+    in.s_addr = address -> host;
+
+    hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
+#endif
+
+    if (hostEntry == NULL)
+      return enet_address_get_host_ip (address, name, nameLength);
+
+    strncpy (name, hostEntry -> h_name, nameLength);
+
+    return 0;
+}
+
+int
+enet_socket_bind (ENetSocket socket, const ENetAddress * address)
+{
+    struct sockaddr_in sin;
+
+    memset (& sin, 0, sizeof (struct sockaddr_in));
+
+    sin.sin_family = AF_INET;
+
+    if (address != NULL)
+    {
+       sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
+       sin.sin_addr.s_addr = address -> host;
+    }
+    else
+    {
+       sin.sin_port = 0;
+       sin.sin_addr.s_addr = INADDR_ANY;
+    }
+
+    return bind (socket,
+                 (struct sockaddr *) & sin,
+                 sizeof (struct sockaddr_in)); 
+}
+
+int 
+enet_socket_listen (ENetSocket socket, int backlog)
+{
+    return listen (socket, backlog < 0 ? SOMAXCONN : backlog);
+}
+
+ENetSocket
+enet_socket_create (ENetSocketType type)
+{
+    return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
+}
+
+int
+enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
+{
+    int result = -1;
+    switch (option)
+    {
+        case ENET_SOCKOPT_NONBLOCK:
+#ifdef HAS_FCNTL
+            result = fcntl (socket, F_SETFL, O_NONBLOCK | fcntl (socket, F_GETFL));
+#else
+            result = ioctl (socket, FIONBIO, & value);
+#endif
+            break;
+
+        case ENET_SOCKOPT_BROADCAST:
+            result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int));
+            break;
+
+        case ENET_SOCKOPT_REUSEADDR:
+            result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int));
+            break;
+
+        case ENET_SOCKOPT_RCVBUF:
+            result = setsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) & value, sizeof (int));
+            break;
+
+        case ENET_SOCKOPT_SNDBUF:
+            result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int));
+            break;
+
+        default:
+            break;
+    }
+    return result == -1 ? -1 : 0;
+}
+
+int
+enet_socket_connect (ENetSocket socket, const ENetAddress * address)
+{
+    struct sockaddr_in sin;
+
+    memset (& sin, 0, sizeof (struct sockaddr_in));
+
+    sin.sin_family = AF_INET;
+    sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
+    sin.sin_addr.s_addr = address -> host;
+
+    return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in));
+}
+
+ENetSocket
+enet_socket_accept (ENetSocket socket, ENetAddress * address)
+{
+    int result;
+    struct sockaddr_in sin;
+    socklen_t sinLength = sizeof (struct sockaddr_in);
+
+    result = accept (socket, 
+                     address != NULL ? (struct sockaddr *) & sin : NULL, 
+                     address != NULL ? & sinLength : NULL);
+    
+    if (result == -1)
+      return ENET_SOCKET_NULL;
+
+    if (address != NULL)
+    {
+        address -> host = (enet_uint32) sin.sin_addr.s_addr;
+        address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
+    }
+
+    return result;
+} 
+    
+void
+enet_socket_destroy (ENetSocket socket)
+{
+    close (socket);
+}
+
+int
+enet_socket_send (ENetSocket socket,
+                  const ENetAddress * address,
+                  const ENetBuffer * buffers,
+                  size_t bufferCount)
+{
+    struct msghdr msgHdr;
+    struct sockaddr_in sin;
+    int sentLength;
+
+    memset (& msgHdr, 0, sizeof (struct msghdr));
+
+    if (address != NULL)
+    {
+        memset (& sin, 0, sizeof (struct sockaddr_in));
+
+        sin.sin_family = AF_INET;
+        sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
+        sin.sin_addr.s_addr = address -> host;
+
+        msgHdr.msg_name = & sin;
+        msgHdr.msg_namelen = sizeof (struct sockaddr_in);
+    }
+
+    msgHdr.msg_iov = (struct iovec *) buffers;
+    msgHdr.msg_iovlen = bufferCount;
+
+    sentLength = sendmsg (socket, & msgHdr, MSG_NOSIGNAL);
+    
+    if (sentLength == -1)
+    {
+       if (errno == EWOULDBLOCK)
+         return 0;
+
+       return -1;
+    }
+
+    return sentLength;
+}
+
+int
+enet_socket_receive (ENetSocket socket,
+                     ENetAddress * address,
+                     ENetBuffer * buffers,
+                     size_t bufferCount)
+{
+    struct msghdr msgHdr;
+    struct sockaddr_in sin;
+    int recvLength;
+
+    memset (& msgHdr, 0, sizeof (struct msghdr));
+
+    if (address != NULL)
+    {
+        msgHdr.msg_name = & sin;
+        msgHdr.msg_namelen = sizeof (struct sockaddr_in);
+    }
+
+    msgHdr.msg_iov = (struct iovec *) buffers;
+    msgHdr.msg_iovlen = bufferCount;
+
+    recvLength = recvmsg (socket, & msgHdr, MSG_NOSIGNAL);
+
+    if (recvLength == -1)
+    {
+       if (errno == EWOULDBLOCK)
+         return 0;
+
+       return -1;
+    }
+
+#ifdef HAS_MSGHDR_FLAGS
+    if (msgHdr.msg_flags & MSG_TRUNC)
+      return -1;
+#endif
+
+    if (address != NULL)
+    {
+        address -> host = (enet_uint32) sin.sin_addr.s_addr;
+        address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
+    }
+
+    return recvLength;
+}
+
+int
+enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocketSet * writeSet, enet_uint32 timeout)
+{
+    struct timeval timeVal;
+
+    timeVal.tv_sec = timeout / 1000;
+    timeVal.tv_usec = (timeout % 1000) * 1000;
+
+    return select (maxSocket + 1, readSet, writeSet, NULL, & timeVal);
+}
+
+int
+enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout)
+{
+#ifdef HAS_POLL
+    struct pollfd pollSocket;
+    int pollCount;
+    
+    pollSocket.fd = socket;
+    pollSocket.events = 0;
+
+    if (* condition & ENET_SOCKET_WAIT_SEND)
+      pollSocket.events |= POLLOUT;
+
+    if (* condition & ENET_SOCKET_WAIT_RECEIVE)
+      pollSocket.events |= POLLIN;
+
+    pollCount = poll (& pollSocket, 1, timeout);
+
+    if (pollCount < 0)
+      return -1;
+
+    * condition = ENET_SOCKET_WAIT_NONE;
+
+    if (pollCount == 0)
+      return 0;
+
+    if (pollSocket.revents & POLLOUT)
+      * condition |= ENET_SOCKET_WAIT_SEND;
+    
+    if (pollSocket.revents & POLLIN)
+      * condition |= ENET_SOCKET_WAIT_RECEIVE;
+
+    return 0;
+#else
+    fd_set readSet, writeSet;
+    struct timeval timeVal;
+    int selectCount;
+
+    timeVal.tv_sec = timeout / 1000;
+    timeVal.tv_usec = (timeout % 1000) * 1000;
+
+    FD_ZERO (& readSet);
+    FD_ZERO (& writeSet);
+
+    if (* condition & ENET_SOCKET_WAIT_SEND)
+      FD_SET (socket, & writeSet);
+
+    if (* condition & ENET_SOCKET_WAIT_RECEIVE)
+      FD_SET (socket, & readSet);
+
+    selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
+
+    if (selectCount < 0)
+      return -1;
+
+    * condition = ENET_SOCKET_WAIT_NONE;
+
+    if (selectCount == 0)
+      return 0;
+
+    if (FD_ISSET (socket, & writeSet))
+      * condition |= ENET_SOCKET_WAIT_SEND;
+
+    if (FD_ISSET (socket, & readSet))
+      * condition |= ENET_SOCKET_WAIT_RECEIVE;
+
+    return 0;
+#endif
+}
+
+#endif
+

+ 348 - 348
ThirdParty/ENet/win32.c

@@ -1,348 +1,348 @@
-/** 
- @file  win32.c
- @brief ENet Win32 system specific functions
-*/
-#ifdef WIN32
-
-#include <time.h>
-#define ENET_BUILDING_LIB 1
-#include "enet/enet.h"
-
-static enet_uint32 timeBase = 0;
-
-int
-enet_initialize (void)
-{
-    WORD versionRequested = MAKEWORD (1, 1);
-    WSADATA wsaData;
-   
-    if (WSAStartup (versionRequested, & wsaData))
-       return -1;
-
-    if (LOBYTE (wsaData.wVersion) != 1||
-        HIBYTE (wsaData.wVersion) != 1)
-    {
-       WSACleanup ();
-       
-       return -1;
-    }
-
-    timeBeginPeriod (1);
-
-    return 0;
-}
-
-void
-enet_deinitialize (void)
-{
-    timeEndPeriod (1);
-
-    WSACleanup ();
-}
-
-enet_uint32
-enet_time_get (void)
-{
-    return (enet_uint32) timeGetTime () - timeBase;
-}
-
-void
-enet_time_set (enet_uint32 newTimeBase)
-{
-    timeBase = (enet_uint32) timeGetTime () - newTimeBase;
-}
-
-int
-enet_address_set_host (ENetAddress * address, const char * name)
-{
-    struct hostent * hostEntry;
-
-    hostEntry = gethostbyname (name);
-    if (hostEntry == NULL ||
-        hostEntry -> h_addrtype != AF_INET)
-    {
-        unsigned long host = inet_addr (name);
-        if (host == INADDR_NONE)
-            return -1;
-        address -> host = host;
-        return 0;
-    }
-
-    address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
-
-    return 0;
-}
-
-int
-enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
-{
-    char * addr = inet_ntoa (* (struct in_addr *) & address -> host);
-    if (addr == NULL)
-        return -1;
-    strncpy (name, addr, nameLength);
-    return 0;
-}
-
-int
-enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
-{
-    struct in_addr in;
-    struct hostent * hostEntry;
-    
-    in.s_addr = address -> host;
-    
-    hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
-    if (hostEntry == NULL)
-      return enet_address_get_host_ip (address, name, nameLength);
-
-    strncpy (name, hostEntry -> h_name, nameLength);
-
-    return 0;
-}
-
-int
-enet_socket_bind (ENetSocket socket, const ENetAddress * address)
-{
-    struct sockaddr_in sin;
-
-    memset (& sin, 0, sizeof (struct sockaddr_in));
-
-    sin.sin_family = AF_INET;
-
-    if (address != NULL)
-    {
-       sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
-       sin.sin_addr.s_addr = address -> host;
-    }
-    else
-    {
-       sin.sin_port = 0;
-       sin.sin_addr.s_addr = INADDR_ANY;
-    }
-
-    return bind (socket,
-                 (struct sockaddr *) & sin,
-                 sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0;
-}
-
-int
-enet_socket_listen (ENetSocket socket, int backlog)
-{
-    return listen (socket, backlog < 0 ? SOMAXCONN : backlog) == SOCKET_ERROR ? -1 : 0;
-}
-
-ENetSocket
-enet_socket_create (ENetSocketType type)
-{
-    return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
-}
-
-int
-enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
-{
-    int result = SOCKET_ERROR;
-    switch (option)
-    {
-        case ENET_SOCKOPT_NONBLOCK:
-        {
-            u_long nonBlocking = (u_long) value;
-            result = ioctlsocket (socket, FIONBIO, & nonBlocking);
-            break;
-        }
-
-        case ENET_SOCKOPT_BROADCAST:
-            result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int));
-            break;
-
-        case ENET_SOCKOPT_REUSEADDR:
-            result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int));
-            break;
-
-        case ENET_SOCKOPT_RCVBUF:
-            result = setsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) & value, sizeof (int));
-            break;
-
-        case ENET_SOCKOPT_SNDBUF:
-            result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int));
-            break;
-
-        default:
-            break;
-    }
-    return result == SOCKET_ERROR ? -1 : 0;
-}
-
-int
-enet_socket_connect (ENetSocket socket, const ENetAddress * address)
-{
-    struct sockaddr_in sin;
-
-    memset (& sin, 0, sizeof (struct sockaddr_in));
-
-    sin.sin_family = AF_INET;
-    sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
-    sin.sin_addr.s_addr = address -> host;
-
-    return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0;
-}
-
-ENetSocket
-enet_socket_accept (ENetSocket socket, ENetAddress * address)
-{
-    SOCKET result;
-    struct sockaddr_in sin;
-    int sinLength = sizeof (struct sockaddr_in);
-
-    result = accept (socket, 
-                     address != NULL ? (struct sockaddr *) & sin : NULL, 
-                     address != NULL ? & sinLength : NULL);
-
-    if (result == INVALID_SOCKET)
-      return ENET_SOCKET_NULL;
-
-    if (address != NULL)
-    {
-        address -> host = (enet_uint32) sin.sin_addr.s_addr;
-        address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
-    }
-
-    return result;
-}
-
-void
-enet_socket_destroy (ENetSocket socket)
-{
-    closesocket (socket);
-}
-
-int
-enet_socket_send (ENetSocket socket,
-                  const ENetAddress * address,
-                  const ENetBuffer * buffers,
-                  size_t bufferCount)
-{
-    struct sockaddr_in sin;
-    DWORD sentLength;
-
-    if (address != NULL)
-    {
-        memset (& sin, 0, sizeof (struct sockaddr_in));
-
-        sin.sin_family = AF_INET;
-        sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
-        sin.sin_addr.s_addr = address -> host;
-    }
-
-    if (WSASendTo (socket, 
-                   (LPWSABUF) buffers,
-                   (DWORD) bufferCount,
-                   & sentLength,
-                   0,
-                   address != NULL ? (struct sockaddr *) & sin : 0,
-                   address != NULL ? sizeof (struct sockaddr_in) : 0,
-                   NULL,
-                   NULL) == SOCKET_ERROR)
-    {
-       if (WSAGetLastError () == WSAEWOULDBLOCK)
-         return 0;
-
-       return -1;
-    }
-
-    return (int) sentLength;
-}
-
-int
-enet_socket_receive (ENetSocket socket,
-                     ENetAddress * address,
-                     ENetBuffer * buffers,
-                     size_t bufferCount)
-{
-    INT sinLength = sizeof (struct sockaddr_in);
-    DWORD flags = 0,
-          recvLength;
-    struct sockaddr_in sin;
-
-    if (WSARecvFrom (socket,
-                     (LPWSABUF) buffers,
-                     (DWORD) bufferCount,
-                     & recvLength,
-                     & flags,
-                     address != NULL ? (struct sockaddr *) & sin : NULL,
-                     address != NULL ? & sinLength : NULL,
-                     NULL,
-                     NULL) == SOCKET_ERROR)
-    {
-       switch (WSAGetLastError ())
-       {
-       case WSAEWOULDBLOCK:
-       case WSAECONNRESET:
-          return 0;
-       }
-
-       return -1;
-    }
-
-    if (flags & MSG_PARTIAL)
-      return -1;
-
-    if (address != NULL)
-    {
-        address -> host = (enet_uint32) sin.sin_addr.s_addr;
-        address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
-    }
-
-    return (int) recvLength;
-}
-
-int
-enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocketSet * writeSet, enet_uint32 timeout)
-{
-    struct timeval timeVal;
-
-    timeVal.tv_sec = timeout / 1000;
-    timeVal.tv_usec = (timeout % 1000) * 1000;
-
-    return select (maxSocket + 1, readSet, writeSet, NULL, & timeVal);
-}
-
-int
-enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout)
-{
-    fd_set readSet, writeSet;
-    struct timeval timeVal;
-    int selectCount;
-    
-    timeVal.tv_sec = timeout / 1000;
-    timeVal.tv_usec = (timeout % 1000) * 1000;
-    
-    FD_ZERO (& readSet);
-    FD_ZERO (& writeSet);
-
-    if (* condition & ENET_SOCKET_WAIT_SEND)
-      FD_SET (socket, & writeSet);
-
-    if (* condition & ENET_SOCKET_WAIT_RECEIVE)
-      FD_SET (socket, & readSet);
-
-    selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
-
-    if (selectCount < 0)
-      return -1;
-
-    * condition = ENET_SOCKET_WAIT_NONE;
-
-    if (selectCount == 0)
-      return 0;
-
-    if (FD_ISSET (socket, & writeSet))
-      * condition |= ENET_SOCKET_WAIT_SEND;
-    
-    if (FD_ISSET (socket, & readSet))
-      * condition |= ENET_SOCKET_WAIT_RECEIVE;
-
-    return 0;
-} 
-
-#endif
-
+/** 
+ @file  win32.c
+ @brief ENet Win32 system specific functions
+*/
+#ifdef WIN32
+
+#include <time.h>
+#define ENET_BUILDING_LIB 1
+#include "enet/enet.h"
+
+static enet_uint32 timeBase = 0;
+
+int
+enet_initialize (void)
+{
+    WORD versionRequested = MAKEWORD (1, 1);
+    WSADATA wsaData;
+   
+    if (WSAStartup (versionRequested, & wsaData))
+       return -1;
+
+    if (LOBYTE (wsaData.wVersion) != 1||
+        HIBYTE (wsaData.wVersion) != 1)
+    {
+       WSACleanup ();
+       
+       return -1;
+    }
+
+    timeBeginPeriod (1);
+
+    return 0;
+}
+
+void
+enet_deinitialize (void)
+{
+    timeEndPeriod (1);
+
+    WSACleanup ();
+}
+
+enet_uint32
+enet_time_get (void)
+{
+    return (enet_uint32) timeGetTime () - timeBase;
+}
+
+void
+enet_time_set (enet_uint32 newTimeBase)
+{
+    timeBase = (enet_uint32) timeGetTime () - newTimeBase;
+}
+
+int
+enet_address_set_host (ENetAddress * address, const char * name)
+{
+    struct hostent * hostEntry;
+
+    hostEntry = gethostbyname (name);
+    if (hostEntry == NULL ||
+        hostEntry -> h_addrtype != AF_INET)
+    {
+        unsigned long host = inet_addr (name);
+        if (host == INADDR_NONE)
+            return -1;
+        address -> host = host;
+        return 0;
+    }
+
+    address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
+
+    return 0;
+}
+
+int
+enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
+{
+    char * addr = inet_ntoa (* (struct in_addr *) & address -> host);
+    if (addr == NULL)
+        return -1;
+    strncpy (name, addr, nameLength);
+    return 0;
+}
+
+int
+enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
+{
+    struct in_addr in;
+    struct hostent * hostEntry;
+    
+    in.s_addr = address -> host;
+    
+    hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
+    if (hostEntry == NULL)
+      return enet_address_get_host_ip (address, name, nameLength);
+
+    strncpy (name, hostEntry -> h_name, nameLength);
+
+    return 0;
+}
+
+int
+enet_socket_bind (ENetSocket socket, const ENetAddress * address)
+{
+    struct sockaddr_in sin;
+
+    memset (& sin, 0, sizeof (struct sockaddr_in));
+
+    sin.sin_family = AF_INET;
+
+    if (address != NULL)
+    {
+       sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
+       sin.sin_addr.s_addr = address -> host;
+    }
+    else
+    {
+       sin.sin_port = 0;
+       sin.sin_addr.s_addr = INADDR_ANY;
+    }
+
+    return bind (socket,
+                 (struct sockaddr *) & sin,
+                 sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0;
+}
+
+int
+enet_socket_listen (ENetSocket socket, int backlog)
+{
+    return listen (socket, backlog < 0 ? SOMAXCONN : backlog) == SOCKET_ERROR ? -1 : 0;
+}
+
+ENetSocket
+enet_socket_create (ENetSocketType type)
+{
+    return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
+}
+
+int
+enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
+{
+    int result = SOCKET_ERROR;
+    switch (option)
+    {
+        case ENET_SOCKOPT_NONBLOCK:
+        {
+            u_long nonBlocking = (u_long) value;
+            result = ioctlsocket (socket, FIONBIO, & nonBlocking);
+            break;
+        }
+
+        case ENET_SOCKOPT_BROADCAST:
+            result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int));
+            break;
+
+        case ENET_SOCKOPT_REUSEADDR:
+            result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int));
+            break;
+
+        case ENET_SOCKOPT_RCVBUF:
+            result = setsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) & value, sizeof (int));
+            break;
+
+        case ENET_SOCKOPT_SNDBUF:
+            result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int));
+            break;
+
+        default:
+            break;
+    }
+    return result == SOCKET_ERROR ? -1 : 0;
+}
+
+int
+enet_socket_connect (ENetSocket socket, const ENetAddress * address)
+{
+    struct sockaddr_in sin;
+
+    memset (& sin, 0, sizeof (struct sockaddr_in));
+
+    sin.sin_family = AF_INET;
+    sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
+    sin.sin_addr.s_addr = address -> host;
+
+    return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0;
+}
+
+ENetSocket
+enet_socket_accept (ENetSocket socket, ENetAddress * address)
+{
+    SOCKET result;
+    struct sockaddr_in sin;
+    int sinLength = sizeof (struct sockaddr_in);
+
+    result = accept (socket, 
+                     address != NULL ? (struct sockaddr *) & sin : NULL, 
+                     address != NULL ? & sinLength : NULL);
+
+    if (result == INVALID_SOCKET)
+      return ENET_SOCKET_NULL;
+
+    if (address != NULL)
+    {
+        address -> host = (enet_uint32) sin.sin_addr.s_addr;
+        address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
+    }
+
+    return result;
+}
+
+void
+enet_socket_destroy (ENetSocket socket)
+{
+    closesocket (socket);
+}
+
+int
+enet_socket_send (ENetSocket socket,
+                  const ENetAddress * address,
+                  const ENetBuffer * buffers,
+                  size_t bufferCount)
+{
+    struct sockaddr_in sin;
+    DWORD sentLength;
+
+    if (address != NULL)
+    {
+        memset (& sin, 0, sizeof (struct sockaddr_in));
+
+        sin.sin_family = AF_INET;
+        sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
+        sin.sin_addr.s_addr = address -> host;
+    }
+
+    if (WSASendTo (socket, 
+                   (LPWSABUF) buffers,
+                   (DWORD) bufferCount,
+                   & sentLength,
+                   0,
+                   address != NULL ? (struct sockaddr *) & sin : 0,
+                   address != NULL ? sizeof (struct sockaddr_in) : 0,
+                   NULL,
+                   NULL) == SOCKET_ERROR)
+    {
+       if (WSAGetLastError () == WSAEWOULDBLOCK)
+         return 0;
+
+       return -1;
+    }
+
+    return (int) sentLength;
+}
+
+int
+enet_socket_receive (ENetSocket socket,
+                     ENetAddress * address,
+                     ENetBuffer * buffers,
+                     size_t bufferCount)
+{
+    INT sinLength = sizeof (struct sockaddr_in);
+    DWORD flags = 0,
+          recvLength;
+    struct sockaddr_in sin;
+
+    if (WSARecvFrom (socket,
+                     (LPWSABUF) buffers,
+                     (DWORD) bufferCount,
+                     & recvLength,
+                     & flags,
+                     address != NULL ? (struct sockaddr *) & sin : NULL,
+                     address != NULL ? & sinLength : NULL,
+                     NULL,
+                     NULL) == SOCKET_ERROR)
+    {
+       switch (WSAGetLastError ())
+       {
+       case WSAEWOULDBLOCK:
+       case WSAECONNRESET:
+          return 0;
+       }
+
+       return -1;
+    }
+
+    if (flags & MSG_PARTIAL)
+      return -1;
+
+    if (address != NULL)
+    {
+        address -> host = (enet_uint32) sin.sin_addr.s_addr;
+        address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
+    }
+
+    return (int) recvLength;
+}
+
+int
+enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocketSet * writeSet, enet_uint32 timeout)
+{
+    struct timeval timeVal;
+
+    timeVal.tv_sec = timeout / 1000;
+    timeVal.tv_usec = (timeout % 1000) * 1000;
+
+    return select (maxSocket + 1, readSet, writeSet, NULL, & timeVal);
+}
+
+int
+enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout)
+{
+    fd_set readSet, writeSet;
+    struct timeval timeVal;
+    int selectCount;
+    
+    timeVal.tv_sec = timeout / 1000;
+    timeVal.tv_usec = (timeout % 1000) * 1000;
+    
+    FD_ZERO (& readSet);
+    FD_ZERO (& writeSet);
+
+    if (* condition & ENET_SOCKET_WAIT_SEND)
+      FD_SET (socket, & writeSet);
+
+    if (* condition & ENET_SOCKET_WAIT_RECEIVE)
+      FD_SET (socket, & readSet);
+
+    selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
+
+    if (selectCount < 0)
+      return -1;
+
+    * condition = ENET_SOCKET_WAIT_NONE;
+
+    if (selectCount == 0)
+      return 0;
+
+    if (FD_ISSET (socket, & writeSet))
+      * condition |= ENET_SOCKET_WAIT_SEND;
+    
+    if (FD_ISSET (socket, & readSet))
+      * condition |= ENET_SOCKET_WAIT_RECEIVE;
+
+    return 0;
+} 
+
+#endif
+

+ 0 - 485
ThirdParty/ODE/ode/src/scrapbook.cpp_deprecated

@@ -1,485 +0,0 @@
-
-/*
-
-this is code that was once useful but has now been obseleted.
-
-this file should not be compiled as part of ODE!
-
-*/
-
-//***************************************************************************
-// intersect a line segment with a plane
-
-extern "C" int dClipLineToBox (const dVector3 p1, const dVector3 p2,
-			       const dVector3 p, const dMatrix3 R,
-			       const dVector3 side)
-{
-  // compute the start and end of the line (p1 and p2) relative to the box.
-  // we will do all subsequent computations in this box-relative coordinate
-  // system. we have to do a translation and rotation for each point.
-  dVector3 tmp,s,e;
-  tmp[0] = p1[0] - p[0];
-  tmp[1] = p1[1] - p[1];
-  tmp[2] = p1[2] - p[2];
-  dMULTIPLY1_331 (s,R,tmp);
-  tmp[0] = p2[0] - p[0];
-  tmp[1] = p2[1] - p[1];
-  tmp[2] = p2[2] - p[2];
-  dMULTIPLY1_331 (e,R,tmp);
-
-  // compute the vector 'v' from the start point to the end point
-  dVector3 v;
-  v[0] = e[0] - s[0];
-  v[1] = e[1] - s[1];
-  v[2] = e[2] - s[2];
-
-  // a point on the line is defined by the parameter 't'. t=0 corresponds
-  // to the start of the line, t=1 corresponds to the end of the line.
-  // we will clip the line to the box by finding the range of t where a
-  // point on the line is inside the box. the currently known bounds for
-  // t and tlo..thi.
-  dReal tlo=0,thi=1;
-
-  // clip in the X/Y/Z direction
-  for (int i=0; i<3; i++) {
-    // first adjust s,e for the current t range. this is redundant for the
-    // first iteration, but never mind.
-    e[i] = s[i] + thi*v[i];
-    s[i] = s[i] + tlo*v[i];
-    // compute where t intersects the positive and negative sides.
-    dReal tp = ( side[i] - s[i])/v[i];	// @@@ handle case where denom=0
-    dReal tm = (-side[i] - s[i])/v[i];
-    // handle 9 intersection cases
-    if (s[i] <= -side[i]) {
-      tlo = tm;
-      if (e[i] <= -side[i]) return 0;
-      else if (e[i] >= side[i]) thi = tp;
-    }
-    else if (s[i] <= side[i]) {
-      if (e[i] <= -side[i]) thi = tm;
-      else if (e[i] >= side[i]) thi = tp;
-    }
-    else {
-      tlo = tp;
-      if (e[i] <= -side[i]) thi = tm;
-      else if (e[i] >= side[i]) return 0;
-    }
-  }
-
-  //... @@@ AT HERE @@@
-
-  return 1;
-}
-
-
-//***************************************************************************
-// a nice try at C-B collision. unfortunately it doesn't work. the logic
-// for testing for line-box intersection is correct, but unfortunately the
-// closest-point distance estimates are often too large. as a result contact
-// points are placed incorrectly.
-
-
-int dCollideCB (const dxGeom *o1, const dxGeom *o2, int flags,
-		dContactGeom *contact, int skip)
-{
-  int i;
-
-  dIASSERT (skip >= (int)sizeof(dContactGeom));
-  dIASSERT (o1->_class->num == dCCylinderClass);
-  dIASSERT (o2->_class->num == dBoxClass);
-  contact->g1 = const_cast<dxGeom*> (o1);
-  contact->g2 = const_cast<dxGeom*> (o2);
-  dxCCylinder *cyl = (dxCCylinder*) CLASSDATA(o1);
-  dxBox *box = (dxBox*) CLASSDATA(o2);
-
-  // get p1,p2 = cylinder axis endpoints, get radius
-  dVector3 p1,p2;
-  dReal clen = cyl->lz * REAL(0.5);
-  p1[0] = o1->pos[0] + clen * o1->R[2];
-  p1[1] = o1->pos[1] + clen * o1->R[6];
-  p1[2] = o1->pos[2] + clen * o1->R[10];
-  p2[0] = o1->pos[0] - clen * o1->R[2];
-  p2[1] = o1->pos[1] - clen * o1->R[6];
-  p2[2] = o1->pos[2] - clen * o1->R[10];
-  dReal radius = cyl->radius;
-
-  // copy out box center, rotation matrix, and side array
-  dReal *c = o2->pos;
-  dReal *R = o2->R;
-  dReal *side = box->side;
-
-  // compute the start and end of the line (p1 and p2) relative to the box.
-  // we will do all subsequent computations in this box-relative coordinate
-  // system. we have to do a translation and rotation for each point.
-  dVector3 tmp3,s,e;
-  tmp3[0] = p1[0] - c[0];
-  tmp3[1] = p1[1] - c[1];
-  tmp3[2] = p1[2] - c[2];
-  dMULTIPLY1_331 (s,R,tmp3);
-  tmp3[0] = p2[0] - c[0];
-  tmp3[1] = p2[1] - c[1];
-  tmp3[2] = p2[2] - c[2];
-  dMULTIPLY1_331 (e,R,tmp3);
-
-  // compute the vector 'v' from the start point to the end point
-  dVector3 v;
-  v[0] = e[0] - s[0];
-  v[1] = e[1] - s[1];
-  v[2] = e[2] - s[2];
-
-  // compute the half-sides of the box
-  dReal S0 = side[0] * REAL(0.5);
-  dReal S1 = side[1] * REAL(0.5);
-  dReal S2 = side[2] * REAL(0.5);
-
-  // compute the size of the bounding box around the line segment
-  dReal B0 = dFabs (v[0]);
-  dReal B1 = dFabs (v[1]);
-  dReal B2 = dFabs (v[2]);
-
-  // for all 6 separation axes, measure the penetration depth. if any depth is
-  // less than 0 then the objects don't penetrate at all so we can just
-  // return 0. find the axis with the smallest depth, and record its normal.
-
-  // note: normalR is set to point to a column of R if that is the smallest
-  // depth normal so far. otherwise normalR is 0 and normalC is set to a
-  // vector relative to the box. invert_normal is 1 if the sign of the normal
-  // should be flipped.
-
-  dReal depth,trial_depth,tmp,length;
-  const dReal *normalR=0;
-  dVector3 normalC;
-  int invert_normal = 0;
-  int code = 0;		// 0=no contact, 1-3=face contact, 4-6=edge contact
-
-  depth = dInfinity;
-
-  // look at face-normal axes
-
-#undef TEST
-#define TEST(center,depth_expr,norm,contact_code) \
-  tmp = (center); \
-  trial_depth = radius + REAL(0.5) * ((depth_expr) - dFabs(tmp)); \
-  if (trial_depth < 0) return 0; \
-  if (trial_depth < depth) { \
-    depth = trial_depth; \
-    normalR = (norm); \
-    invert_normal = (tmp < 0); \
-    code = contact_code; \
-  }
-
-  TEST (s[0]+e[0], side[0] + B0, R+0, 1);
-  TEST (s[1]+e[1], side[1] + B1, R+1, 2);
-  TEST (s[2]+e[2], side[2] + B2, R+2, 3);
-
-  // look at v x box-edge axes
-
-#undef TEST
-#define TEST(box_radius,line_offset,nx,ny,nz,contact_code) \
-  tmp = (line_offset); \
-  trial_depth = (box_radius) - dFabs(tmp); \
-  length = dSqrt ((nx)*(nx) + (ny)*(ny) + (nz)*(nz)); \
-  if (length > 0) { \
-    length = dRecip(length); \
-    trial_depth = trial_depth * length + radius; \
-    if (trial_depth < 0) return 0; \
-    if (trial_depth < depth) { \
-      depth = trial_depth; \
-      normalR = 0; \
-      normalC[0] = (nx)*length; \
-      normalC[1] = (ny)*length; \
-      normalC[2] = (nz)*length; \
-      invert_normal = (tmp < 0); \
-      code = contact_code; \
-    } \
-  }
-
-  TEST (B2*S1+B1*S2,v[1]*s[2]-v[2]*s[1], 0,-v[2],v[1], 4);
-  TEST (B2*S0+B0*S2,v[2]*s[0]-v[0]*s[2], v[2],0,-v[0], 5);
-  TEST (B1*S0+B0*S1,v[0]*s[1]-v[1]*s[0], -v[1],v[0],0, 6);
-
-#undef TEST
-
-  // if we get to this point, the box and ccylinder interpenetrate.
-  // compute the normal in global coordinates.
-  dReal *normal = contact[0].normal;
-  if (normalR) {
-    normal[0] = normalR[0];
-    normal[1] = normalR[4];
-    normal[2] = normalR[8];
-  }
-  else {
-    dMULTIPLY0_331 (normal,R,normalC);
-  }
-  if (invert_normal) {
-    normal[0] = -normal[0];
-    normal[1] = -normal[1];
-    normal[2] = -normal[2];
-  }
-
-  // set the depth
-  contact[0].depth = depth;
-
-  if (code == 0) {
-    return 0;		// should never get here
-  }
-  else if (code >= 4) {
-    // handle edge contacts
-    // find an endpoint q1 on the intersecting edge of the box
-    dVector3 q1;
-    dReal sign[3];
-    for (i=0; i<3; i++) q1[i] = c[i];
-    sign[0] = (dCalcVectorDot3_14(normal,R+0) > 0) ? REAL(1.0) : REAL(-1.0);
-    for (i=0; i<3; i++) q1[i] += sign[0] * S0 * R[i*4];
-    sign[1] = (dCalcVectorDot3_14(normal,R+1) > 0) ? REAL(1.0) : REAL(-1.0);
-    for (i=0; i<3; i++) q1[i] += sign[1] * S1 * R[i*4+1];
-    sign[2] = (dCalcVectorDot3_14(normal,R+2) > 0) ? REAL(1.0) : REAL(-1.0);
-    for (i=0; i<3; i++) q1[i] += sign[2] * S2 * R[i*4+2];
-
-    // find the other endpoint q2 of the intersecting edge
-    dVector3 q2;
-    for (i=0; i<3; i++)
-      q2[i] = q1[i] - R[code-4 + i*4] * (sign[code-4] * side[code-4]);
-
-    // determine the closest point between the box edge and the line segment
-    dVector3 cp1,cp2;
-    dClosestLineSegmentPoints (q1,q2, p1,p2, cp1,cp2);
-    for (i=0; i<3; i++) contact[0].pos[i] = cp1[i] - REAL(0.5)*normal[i]*depth;
-    return 1;
-  }
-  else {
-    // handle face contacts.
-    // @@@ temporary: make deepest vertex on the line the contact point.
-    // @@@ this kind of works, but we sometimes need two contact points for
-    // @@@ stability.
-
-    // compute 'v' in global coordinates
-    dVector3 gv;
-    for (i=0; i<3; i++) gv[i] = p2[i] - p1[i];
-
-    if (dCalcVectorDot3 (normal,gv) > 0) {
-      for (i=0; i<3; i++)
-	contact[0].pos[i] = p1[i] + (depth*REAL(0.5)-radius)*normal[i];
-    }
-    else {
-      for (i=0; i<3; i++)
-	contact[0].pos[i] = p2[i] + (depth*REAL(0.5)-radius)*normal[i];
-    }
-    return 1;
-  }
-}
-
-//***************************************************************************
-// this function works, it's just not being used for anything at the moment:
-
-// given a box (R,side), `R' is the rotation matrix for the box, and `side'
-// is a vector of x/y/z side lengths, return the size of the interval of the
-// box projected along the given axis. if the axis has unit length then the
-// return value will be the actual diameter, otherwise the result will be
-// scaled by the axis length.
-
-static inline dReal boxDiameter (const dMatrix3 R, const dVector3 side,
-				 const dVector3 axis)
-{
-  dVector3 q;
-  dMULTIPLY1_331 (q,R,axis);	// transform axis to body-relative
-  return dFabs(q[0])*side[0] + dFabs(q[1])*side[1] + dFabs(q[2])*side[2];
-}
-
-//***************************************************************************
-// the old capped cylinder to capped cylinder collision code. this fails to
-// detect cap-to-cap contact points when the cylinder axis are aligned, but
-// other that that it is pretty robust.
-
-// this returns at most one contact point when the two cylinder's axes are not
-// aligned, and at most two (for stability) when they are aligned.
-// the algorithm minimizes the distance between two "sample spheres" that are
-// positioned along the cylinder axes according to:
-//    sphere1 = pos1 + alpha1 * axis1
-//    sphere2 = pos2 + alpha2 * axis2
-// alpha1 and alpha2 are limited to +/- half the length of the cylinders.
-// the algorithm works by finding a solution that has both alphas free, or
-// a solution that has one or both alphas fixed to the ends of the cylinder.
-
-int dCollideCCylinderCCylinder (dxGeom *o1, dxGeom *o2,
-				int flags, dContactGeom *contact, int skip)
-{
-  int i;
-  const dReal tolerance = REAL(1e-5);
-
-  dIASSERT (skip >= (int)sizeof(dContactGeom));
-  dIASSERT (o1->type == dCCylinderClass);
-  dIASSERT (o2->type == dCCylinderClass);
-  dxCCylinder *cyl1 = (dxCCylinder*) o1;
-  dxCCylinder *cyl2 = (dxCCylinder*) o2;
-
-  contact->g1 = o1;
-  contact->g2 = o2;
-
-  // copy out some variables, for convenience
-  dReal lz1 = cyl1->lz * REAL(0.5);
-  dReal lz2 = cyl2->lz * REAL(0.5);
-  dReal *pos1 = o1->pos;
-  dReal *pos2 = o2->pos;
-  dReal axis1[3],axis2[3];
-  axis1[0] = o1->R[2];
-  axis1[1] = o1->R[6];
-  axis1[2] = o1->R[10];
-  axis2[0] = o2->R[2];
-  axis2[1] = o2->R[6];
-  axis2[2] = o2->R[10];
-
-  dReal alpha1,alpha2,sphere1[3],sphere2[3];
-  int fix1 = 0;		// 0 if alpha1 is free, +/-1 to fix at +/- lz1
-  int fix2 = 0;		// 0 if alpha2 is free, +/-1 to fix at +/- lz2
-
-  for (int count=0; count<9; count++) {
-    // find a trial solution by fixing or not fixing the alphas
-    if (fix1) {
-      if (fix2) {
-	// alpha1 and alpha2 are fixed, so the solution is easy
-	if (fix1 > 0) alpha1 = lz1; else alpha1 = -lz1;
-	if (fix2 > 0) alpha2 = lz2; else alpha2 = -lz2;
-	for (i=0; i<3; i++) sphere1[i] = pos1[i] + alpha1*axis1[i];
-	for (i=0; i<3; i++) sphere2[i] = pos2[i] + alpha2*axis2[i];
-      }
-      else {
-	// fix alpha1 but let alpha2 be free
-	if (fix1 > 0) alpha1 = lz1; else alpha1 = -lz1;
-	for (i=0; i<3; i++) sphere1[i] = pos1[i] + alpha1*axis1[i];
-	alpha2 = (axis2[0]*(sphere1[0]-pos2[0]) +
-		  axis2[1]*(sphere1[1]-pos2[1]) +
-		  axis2[2]*(sphere1[2]-pos2[2]));
-	for (i=0; i<3; i++) sphere2[i] = pos2[i] + alpha2*axis2[i];
-      }
-    }
-    else {
-      if (fix2) {
-	// fix alpha2 but let alpha1 be free
-	if (fix2 > 0) alpha2 = lz2; else alpha2 = -lz2;
-	for (i=0; i<3; i++) sphere2[i] = pos2[i] + alpha2*axis2[i];
-	alpha1 = (axis1[0]*(sphere2[0]-pos1[0]) +
-		  axis1[1]*(sphere2[1]-pos1[1]) +
-		  axis1[2]*(sphere2[2]-pos1[2]));
-	for (i=0; i<3; i++) sphere1[i] = pos1[i] + alpha1*axis1[i];
-      }
-      else {
-	// let alpha1 and alpha2 be free
-	// compute determinant of d(d^2)\d(alpha) jacobian
-	dReal a1a2 = dCalcVectorDot3 (axis1,axis2);
-	dReal det = REAL(1.0)-a1a2*a1a2;
-	if (det < tolerance) {
-	  // the cylinder axes (almost) parallel, so we will generate up to two
-	  // contacts. the solution matrix is rank deficient so alpha1 and
-	  // alpha2 are related by:
-	  //       alpha2 =   alpha1 + (pos1-pos2)'*axis1   (if axis1==axis2)
-	  //    or alpha2 = -(alpha1 + (pos1-pos2)'*axis1)  (if axis1==-axis2)
-	  // first compute where the two cylinders overlap in alpha1 space:
-	  if (a1a2 < 0) {
-	    axis2[0] = -axis2[0];
-	    axis2[1] = -axis2[1];
-	    axis2[2] = -axis2[2];
-	  }
-	  dReal q[3];
-	  for (i=0; i<3; i++) q[i] = pos1[i]-pos2[i];
-	  dReal k = dCalcVectorDot3 (axis1,q);
-	  dReal a1lo = -lz1;
-	  dReal a1hi = lz1;
-	  dReal a2lo = -lz2 - k;
-	  dReal a2hi = lz2 - k;
-	  dReal lo = (a1lo > a2lo) ? a1lo : a2lo;
-	  dReal hi = (a1hi < a2hi) ? a1hi : a2hi;
-	  if (lo <= hi) {
-	    int num_contacts = flags & NUMC_MASK;
-	    if (num_contacts >= 2 && lo < hi) {
-	      // generate up to two contacts. if one of those contacts is
-	      // not made, fall back on the one-contact strategy.
-	      for (i=0; i<3; i++) sphere1[i] = pos1[i] + lo*axis1[i];
-	      for (i=0; i<3; i++) sphere2[i] = pos2[i] + (lo+k)*axis2[i];
-	      int n1 = dCollideSpheres (sphere1,cyl1->radius,
-					sphere2,cyl2->radius,contact);
-	      if (n1) {
-		for (i=0; i<3; i++) sphere1[i] = pos1[i] + hi*axis1[i];
-		for (i=0; i<3; i++) sphere2[i] = pos2[i] + (hi+k)*axis2[i];
-		dContactGeom *c2 = CONTACT(contact,skip);
-		int n2 = dCollideSpheres (sphere1,cyl1->radius,
-					  sphere2,cyl2->radius, c2);
-		if (n2) {
-		  c2->g1 = o1;
-		  c2->g2 = o2;
-		  return 2;
-		}
-	      }
-	    }
-
-	    // just one contact to generate, so put it in the middle of
-	    // the range
-	    alpha1 = (lo + hi) * REAL(0.5);
-	    alpha2 = alpha1 + k;
-	    for (i=0; i<3; i++) sphere1[i] = pos1[i] + alpha1*axis1[i];
-	    for (i=0; i<3; i++) sphere2[i] = pos2[i] + alpha2*axis2[i];
-	    return dCollideSpheres (sphere1,cyl1->radius,
-				    sphere2,cyl2->radius,contact);
-	  }
-	  else return 0;
-	}
-	det = REAL(1.0)/det;
-	dReal delta[3];
-	for (i=0; i<3; i++) delta[i] = pos1[i] - pos2[i];
-	dReal q1 = dCalcVectorDot3 (delta,axis1);
-	dReal q2 = dCalcVectorDot3 (delta,axis2);
-	alpha1 = det*(a1a2*q2-q1);
-	alpha2 = det*(q2-a1a2*q1);
-	for (i=0; i<3; i++) sphere1[i] = pos1[i] + alpha1*axis1[i];
-	for (i=0; i<3; i++) sphere2[i] = pos2[i] + alpha2*axis2[i];
-      }
-    }
-
-    // if the alphas are outside their allowed ranges then fix them and
-    // try again
-    if (fix1==0) {
-      if (alpha1 < -lz1) {
-	fix1 = -1;
-	continue;
-      }
-      if (alpha1 > lz1) {
-	fix1 = 1;
-	continue;
-      }
-    }
-    if (fix2==0) {
-      if (alpha2 < -lz2) {
-	fix2 = -1;
-	continue;
-      }
-      if (alpha2 > lz2) {
-	fix2 = 1;
-	continue;
-      }
-    }
-
-    // unfix the alpha variables if the local distance gradient indicates
-    // that we are not yet at the minimum
-    dReal tmp[3];
-    for (i=0; i<3; i++) tmp[i] = sphere1[i] - sphere2[i];
-    if (fix1) {
-      dReal gradient = dCalcVectorDot3 (tmp,axis1);
-      if ((fix1 > 0 && gradient > 0) || (fix1 < 0 && gradient < 0)) {
-	fix1 = 0;
-	continue;
-      }
-    }
-    if (fix2) {
-      dReal gradient = -dCalcVectorDot3 (tmp,axis2);
-      if ((fix2 > 0 && gradient > 0) || (fix2 < 0 && gradient < 0)) {
-	fix2 = 0;
-	continue;
-      }
-    }
-    return dCollideSpheres (sphere1,cyl1->radius,sphere2,cyl2->radius,contact);
-  }
-  // if we go through the loop too much, then give up. we should NEVER get to
-  // this point (i hope).
-  dMessage (0,"dCollideCC(): too many iterations");
-  return 0;
-}

+ 0 - 114
ThirdParty/ODE/ode/src/stack.cpp_deprecated

@@ -1,114 +0,0 @@
-/*************************************************************************
- *                                                                       *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
- * All rights reserved.  Email: [email protected]   Web: www.q12.org          *
- *                                                                       *
- * This library is free software; you can redistribute it and/or         *
- * modify it under the terms of EITHER:                                  *
- *   (1) The GNU Lesser General Public License as published by the Free  *
- *       Software Foundation; either version 2.1 of the License, or (at  *
- *       your option) any later version. The text of the GNU Lesser      *
- *       General Public License is included with this library in the     *
- *       file LICENSE.TXT.                                               *
- *   (2) The BSD-style license that is included with this library in     *
- *       the file LICENSE-BSD.TXT.                                       *
- *                                                                       *
- * This library is distributed in the hope that it will be useful,       *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
- *                                                                       *
- *************************************************************************/
-
-@@@ this file should not be compiled any more @@@
-
-#include <string.h>
-#include <errno.h>
-#include "stack.h"
-#include "ode/error.h"
-#include "ode/config.h"
-
-//****************************************************************************
-// unix version that uses mmap(). some systems have anonymous mmaps and some
-// need to mmap /dev/zero.
-
-#ifndef WIN32
-
-#include <unistd.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-
-void dStack::init (int max_size)
-{
-  if (sizeof(long int) != sizeof(char*)) dDebug (0,"internal");
-  if (max_size <= 0) dDebug (0,"Stack::init() given size <= 0");
-
-#ifndef MMAP_ANONYMOUS
-  static int dev_zero_fd = -1;	// cached file descriptor for /dev/zero
-  if (dev_zero_fd < 0) dev_zero_fd = open ("/dev/zero", O_RDWR);
-  if (dev_zero_fd < 0) dError (0,"can't open /dev/zero (%s)",strerror(errno));
-  base = (char*) mmap (0,max_size, PROT_READ | PROT_WRITE, MAP_PRIVATE,
-		       dev_zero_fd,0);
-#else
-  base = (char*) mmap (0,max_size, PROT_READ | PROT_WRITE,
-		       MAP_PRIVATE | MAP_ANON,0,0);
-#endif
-
-  if (int(base) == -1) dError (0,"Stack::init(), mmap() failed, "
-    "max_size=%d (%s)",max_size,strerror(errno));
-  size = max_size;
-  pointer = base;
-  frame = 0;
-}
-
-
-void dStack::destroy()
-{
-  munmap (base,size);
-  base = 0;
-  size = 0;
-  pointer = 0;
-  frame = 0;
-}
-
-#endif
-
-//****************************************************************************
-
-#ifdef WIN32
-
-#include "windows.h"
-
-
-void dStack::init (int max_size)
-{
-  if (sizeof(LPVOID) != sizeof(char*)) dDebug (0,"internal");
-  if (max_size <= 0) dDebug (0,"Stack::init() given size <= 0");
-  base = (char*) VirtualAlloc (NULL,max_size,MEM_RESERVE,PAGE_READWRITE);
-  if (base == 0) dError (0,"Stack::init(), VirtualAlloc() failed, "
-    "max_size=%d",max_size);
-  size = max_size;
-  pointer = base;
-  frame = 0;
-  committed = 0;
-
-  // get page size
-  SYSTEM_INFO info;
-  GetSystemInfo (&info);
-  pagesize = info.dwPageSize;
-}
-
-
-void dStack::destroy()
-{
-  VirtualFree (base,0,MEM_RELEASE);
-  base = 0;
-  size = 0;
-  pointer = 0;
-  frame = 0;
-}
-
-#endif

+ 0 - 138
ThirdParty/ODE/ode/src/stack.h_deprecated

@@ -1,138 +0,0 @@
-/*************************************************************************
- *                                                                       *
- * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
- * All rights reserved.  Email: [email protected]   Web: www.q12.org          *
- *                                                                       *
- * This library is free software; you can redistribute it and/or         *
- * modify it under the terms of EITHER:                                  *
- *   (1) The GNU Lesser General Public License as published by the Free  *
- *       Software Foundation; either version 2.1 of the License, or (at  *
- *       your option) any later version. The text of the GNU Lesser      *
- *       General Public License is included with this library in the     *
- *       file LICENSE.TXT.                                               *
- *   (2) The BSD-style license that is included with this library in     *
- *       the file LICENSE-BSD.TXT.                                       *
- *                                                                       *
- * This library is distributed in the hope that it will be useful,       *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
- * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
- *                                                                       *
- *************************************************************************/
-
-/* this comes from the `reuse' library. copy any changes back to the source.
-
-these stack allocation functions are a replacement for alloca(), except that
-they allocate memory from a separate pool.
-
-advantages over alloca():
-  - consecutive allocations are guaranteed to be contiguous with increasing
-    address.
-  - functions can allocate stack memory that is returned to the caller,
-    in other words pushing and popping stack frames is optional.
-
-disadvantages compared to alloca():
-  - less portable
-  - slightly slower, although still orders of magnitude faster than malloc().
-  - longjmp() and exceptions do not deallocate stack memory (but who cares?).
-
-just like alloca():
-  - using too much stack memory does not fail gracefully, it fails with a
-    segfault.
-
-*/
-
-
-#ifndef _ODE_STACK_H_
-#define _ODE_STACK_H_
-
-
-#ifdef WIN32
-#include "windows.h"
-#endif
-
-
-struct dStack {
-  char *base;		// bottom of the stack
-  int size;		// maximum size of the stack
-  char *pointer;	// current top of the stack
-  char *frame;		// linked list of stack frame ptrs
-# ifdef WIN32		// stuff for windows:
-  int pagesize;		//   - page size - this is ASSUMED to be a power of 2
-  int committed;	//   - bytes committed in allocated region
-#endif
-
-  // initialize the stack. `max_size' is the maximum size that the stack can
-  // reach. on unix and windows a `virtual' memory block of this size is
-  // mapped into the address space but does not actually consume physical
-  // memory until it is referenced - so it is safe to set this to a high value.
-
-  void init (int max_size);
-
-
-  // destroy the stack. this unmaps any virtual memory that was allocated.
-
-  void destroy();
-
-
-  // allocate `size' bytes from the stack and return a pointer to the allocated
-  // memory. `size' must be >= 0. the returned pointer will be aligned to the
-  // size of a long int.
-
-  char * alloc (int size)
-  {
-    char *ret = pointer;
-    pointer += ((size-1) | (sizeof(long int)-1) )+1;
-#   ifdef WIN32
-    // for windows we need to commit pages as they are required
-    if ((pointer-base) > committed) {
-      committed = ((pointer-base-1) | (pagesize-1))+1;	// round up to pgsize
-      VirtualAlloc (base,committed,MEM_COMMIT,PAGE_READWRITE);
-    }
-#   endif
-    return ret;
-  }
-
-
-  // return the address that will be returned by the next call to alloc()
-
-  char *nextAlloc()
-  {
-    return pointer;
-  }
-
-
-  // push and pop the current size of the stack. pushFrame() saves the current
-  // frame pointer on the stack, and popFrame() retrieves it. a typical
-  // stack-using function will bracket alloc() calls with pushFrame() and
-  // popFrame(). both functions return the current stack pointer - this should
-  // be the same value for the two bracketing calls. calling popFrame() too
-  // many times will result in a segfault.
-
-  char * pushFrame()
-  {
-    char *newframe = pointer;
-    char **addr = (char**) alloc (sizeof(char*));
-    *addr = frame;
-    frame = newframe;
-    return newframe;
-
-    /* OLD CODE
-	*((char**)pointer) = frame;
-	frame = pointer;
-	char *ret = pointer;
-	pointer += sizeof(char*);
-	return ret;
-    */
-  }
-
-  char * popFrame()
-  {
-    pointer = frame;
-    frame = *((char**)pointer);
-    return pointer;
-  }
-};
-
-
-#endif