1 /*
2  * Copyright (c) 2013 Derelict Developers
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  *   notice, this list of conditions and the following disclaimer.
11  *
12  * * Redistributions in binary form must reproduce the above copyright
13  *   notice, this list of conditions and the following disclaimer in the
14  *   documentation and/or other materials provided with the distribution.
15  *
16  * * Neither the names 'Derelict', 'DerelictILUT', nor the names of its contributors
17  *   may be used to endorse or promote products derived from this software
18  *   without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 module enet.types;
33 
34 version(BigEndian) 
35 {
36      ushort ENET_HOST_TO_NET_16(ushort x)
37      {
38           return x;
39      }
40 
41      uint ENET_HOST_TO_NET_32(uint x)
42      {
43           return x;
44      }
45 }
46 else version(LittleEndian) 
47 {
48     import core.bitop;
49     ushort ENET_HOST_TO_NET_16(ushort x)
50     {
51         return ((x & 255) << 8) | (x >> 8);
52     }
53 
54     uint ENET_HOST_TO_NET_32(uint x)
55     {
56         return bswap(x);
57     }
58 }
59 else 
60      static assert(false, "Compiling on another planet!");
61 
62 alias ENET_HOST_TO_NET_16 ENET_NET_TO_HOST_16;
63 alias ENET_HOST_TO_NET_32 ENET_NET_TO_HOST_32;
64 
65 
66 // win32.h
67 
68 version(Windows)
69 {
70      // some things from winsock2.h too
71 
72      version (X86_64)
73           alias ulong SOCKET;
74      else
75           alias uint SOCKET;
76 
77      alias SOCKET ENetSocket; 
78 
79      enum ENET_SOCKET_NULL = ~0;
80 
81      struct ENetBuffer
82      {
83          size_t dataLength;
84          void * data;
85      }
86 
87      enum FD_SETSIZE = 64;
88 
89      
90      struct fd_set 
91      {
92         uint fd_count;               /* how many are SET? */
93         SOCKET[FD_SETSIZE] fd_array; /* an array of SOCKETs */
94      }
95 
96      alias fd_set ENetSocketSet;
97 
98      void ENET_SOCKETSET_EMPTY(ref ENetSocketSet sockset)
99      {
100           sockset.fd_count = 0;
101      }
102 
103      void ENET_SOCKETSET_ADD(ref ENetSocketSet sockset, ENetSocket socket)
104      {
105           uint i;
106           for (i = 0; i < sockset.fd_count; ++i)
107           {
108                if (sockset.fd_array[i] == socket)
109                     break;
110           }
111           if (i == sockset.fd_count)
112           {
113                if (sockset.fd_count < FD_SETSIZE)
114                {
115                     sockset.fd_array[i] = socket;
116                     sockset.fd_count++;
117                }
118           }
119      }
120 
121 
122      int ENET_SOCKETSET_CHECK(ref ENetSocketSet sockset, ENetSocket socket)
123      {
124           for (uint i = 0; i < sockset.fd_count; ++i)
125           {
126                if (sockset.fd_array[i] == socket)
127                     return 1;
128           }
129           return 0;
130      }
131 
132      void ENET_SOCKETSET_REMOVE(ref ENetSocketSet sockset, ENetSocket socket)
133      {
134           for (uint i = 0; i < sockset.fd_count; ++i)
135           {
136                if (sockset.fd_array[i] == socket)
137                {
138                     while (i < sockset.fd_count - 1)
139                     {
140                          sockset.fd_array[i] = sockset.fd_array[i + 1];
141                          i++;
142                     }
143                     sockset.fd_count--;
144                     break;
145                }
146           }
147      }
148 }
149 else
150 {
151      // unix.h
152 
153      import core.sys.posix.arpa.inet;
154      import core.sys.posix.sys.select;
155 
156      alias int ENetSocket;
157 
158      enum ENET_SOCKET_NULL = -1;
159 
160      struct ENetBuffer
161      {
162          void* data;
163          size_t dataLength;
164      }
165 
166      alias fd_set ENetSocketSet;
167 
168      void ENET_SOCKETSET_EMPTY(ref ENetSocketSet sockset)
169      {
170           FD_ZERO(&sockset);
171      }
172 
173      void ENET_SOCKETSET_ADD(ref ENetSocketSet sockset, ENetSocket socket)
174      {
175           FD_SET(socket, &sockset);
176      }    
177 
178      void ENET_SOCKETSET_REMOVE(ref ENetSocketSet sockset, ENetSocket socket)
179      {          
180           FD_CLR(socket, &sockset);
181      }
182 
183      bool ENET_SOCKETSET_CHECK(ref ENetSocketSet sockset, ENetSocket socket)
184      {
185           return FD_ISSET(socket, &sockset);
186      }
187 }
188 
189 // types.h
190 alias ubyte enet_uint8;       /**< unsigned 8-bit type  */
191 alias ushort enet_uint16;     /**< unsigned 16-bit type */
192 alias uint enet_uint32;       /**< unsigned 32-bit type */
193 
194 
195 // file  protocol.h
196 
197 enum
198 {
199    ENET_PROTOCOL_MINIMUM_MTU             = 576,
200    ENET_PROTOCOL_MAXIMUM_MTU             = 4096,
201    ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS = 32,
202    ENET_PROTOCOL_MINIMUM_WINDOW_SIZE     = 4096,
203 
204    // Warning when using this constant, it depends on the linked library version:
205    // - enet <= 1.3.9 defines ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE as 32768
206    // - enet >= 1.3.9 defines ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE as 65536
207    ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE     = 65536,
208 
209    ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT   = 1,
210    ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT   = 255,
211    ENET_PROTOCOL_MAXIMUM_PEER_ID         = 0xFFF,
212    ENET_PROTOCOL_MAXIMUM_PACKET_SIZE     = 1024 * 1024 * 1024,
213    ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT  = 1024 * 1024
214 }
215 
216 alias int ENetProtocolCommand;
217 enum : ENetProtocolCommand
218 {
219    ENET_PROTOCOL_COMMAND_NONE               = 0,
220    ENET_PROTOCOL_COMMAND_ACKNOWLEDGE        = 1,
221    ENET_PROTOCOL_COMMAND_CONNECT            = 2,
222    ENET_PROTOCOL_COMMAND_VERIFY_CONNECT     = 3,
223    ENET_PROTOCOL_COMMAND_DISCONNECT         = 4,
224    ENET_PROTOCOL_COMMAND_PING               = 5,
225    ENET_PROTOCOL_COMMAND_SEND_RELIABLE      = 6,
226    ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE    = 7,
227    ENET_PROTOCOL_COMMAND_SEND_FRAGMENT      = 8,
228    ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED   = 9,
229    ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT    = 10,
230    ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE = 11,
231    ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT = 12,
232    ENET_PROTOCOL_COMMAND_COUNT              = 13,
233 
234    ENET_PROTOCOL_COMMAND_MASK               = 0x0F
235 }
236 
237 alias int ENetProtocolFlag;
238 enum : ENetProtocolFlag
239 {
240    ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE = (1 << 7),
241    ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED = (1 << 6),
242 
243    ENET_PROTOCOL_HEADER_FLAG_COMPRESSED = (1 << 14),
244    ENET_PROTOCOL_HEADER_FLAG_SENT_TIME  = (1 << 15),
245    ENET_PROTOCOL_HEADER_FLAG_MASK       = ENET_PROTOCOL_HEADER_FLAG_COMPRESSED | ENET_PROTOCOL_HEADER_FLAG_SENT_TIME,
246 
247    ENET_PROTOCOL_HEADER_SESSION_MASK    = (3 << 12),
248    ENET_PROTOCOL_HEADER_SESSION_SHIFT   = 12
249 }
250 
251 align(1) struct ENetProtocolHeader
252 {
253    enet_uint16 peerID;
254    enet_uint16 sentTime;
255 }
256 
257 align(1) struct ENetProtocolCommandHeader
258 {
259    enet_uint8 command;
260    enet_uint8 channelID;
261    enet_uint16 reliableSequenceNumber;
262 }
263 
264 align(1) struct ENetProtocolAcknowledge
265 {
266    ENetProtocolCommandHeader header;
267    enet_uint16 receivedReliableSequenceNumber;
268    enet_uint16 receivedSentTime;
269 }
270 
271 align(1) struct ENetProtocolConnect
272 {
273    ENetProtocolCommandHeader header;
274    enet_uint16 outgoingPeerID;
275    enet_uint8  incomingSessionID;
276    enet_uint8  outgoingSessionID;
277    enet_uint32 mtu;
278    enet_uint32 windowSize;
279    enet_uint32 channelCount;
280    enet_uint32 incomingBandwidth;
281    enet_uint32 outgoingBandwidth;
282    enet_uint32 packetThrottleInterval;
283    enet_uint32 packetThrottleAcceleration;
284    enet_uint32 packetThrottleDeceleration;
285    enet_uint32 connectID;
286    enet_uint32 data;
287 }
288 
289 align(1) struct ENetProtocolVerifyConnect
290 {
291    ENetProtocolCommandHeader header;
292    enet_uint16 outgoingPeerID;
293    enet_uint8  incomingSessionID;
294    enet_uint8  outgoingSessionID;
295    enet_uint32 mtu;
296    enet_uint32 windowSize;
297    enet_uint32 channelCount;
298    enet_uint32 incomingBandwidth;
299    enet_uint32 outgoingBandwidth;
300    enet_uint32 packetThrottleInterval;
301    enet_uint32 packetThrottleAcceleration;
302    enet_uint32 packetThrottleDeceleration;
303    enet_uint32 connectID;
304 }
305 
306 align(1) struct ENetProtocolBandwidthLimit
307 {
308    ENetProtocolCommandHeader header;
309    enet_uint32 incomingBandwidth;
310    enet_uint32 outgoingBandwidth;
311 }
312 
313 align(1) struct ENetProtocolThrottleConfigure
314 {
315    ENetProtocolCommandHeader header;
316    enet_uint32 packetThrottleInterval;
317    enet_uint32 packetThrottleAcceleration;
318    enet_uint32 packetThrottleDeceleration;
319 }
320 
321 align(1) struct ENetProtocolDisconnect
322 {
323    ENetProtocolCommandHeader header;
324    enet_uint32 data;
325 }
326 
327 align(1) struct ENetProtocolPing
328 {
329    ENetProtocolCommandHeader header;
330 }
331 
332 align(1) struct ENetProtocolSendReliable
333 {
334    ENetProtocolCommandHeader header;
335    enet_uint16 dataLength;
336 }
337 
338 align(1) struct ENetProtocolSendUnreliable
339 {
340    ENetProtocolCommandHeader header;
341    enet_uint16 unreliableSequenceNumber;
342    enet_uint16 dataLength;
343 }
344 
345 align(1) struct ENetProtocolSendUnsequenced
346 {
347    ENetProtocolCommandHeader header;
348    enet_uint16 unsequencedGroup;
349    enet_uint16 dataLength;
350 }
351 
352 align(1) struct ENetProtocolSendFragment
353 {
354    ENetProtocolCommandHeader header;
355    enet_uint16 startSequenceNumber;
356    enet_uint16 dataLength;
357    enet_uint32 fragmentCount;
358    enet_uint32 fragmentNumber;
359    enet_uint32 totalLength;
360    enet_uint32 fragmentOffset;
361 }
362 
363 align(1) union ENetProtocol
364 {
365    ENetProtocolCommandHeader header;
366    ENetProtocolAcknowledge acknowledge;
367    ENetProtocolConnect connect;
368    ENetProtocolVerifyConnect verifyConnect;
369    ENetProtocolDisconnect disconnect;
370    ENetProtocolPing ping;
371    ENetProtocolSendReliable sendReliable;
372    ENetProtocolSendUnreliable sendUnreliable;
373    ENetProtocolSendUnsequenced sendUnsequenced;
374    ENetProtocolSendFragment sendFragment;
375    ENetProtocolBandwidthLimit bandwidthLimit;
376    ENetProtocolThrottleConfigure throttleConfigure;
377 }
378 
379 
380 // list.h
381 struct ENetListNode
382 {
383    ENetListNode* next;
384    ENetListNode* previous;
385 }
386 
387 alias ENetListNode* ENetListIterator;
388 
389 struct ENetList
390 {
391    ENetListNode sentinel;
392 }
393 
394 ENetListIterator enet_list_begin(ENetList* list)
395 {
396      return list.sentinel.next;
397 }
398 
399 ENetListIterator enet_list_end(ENetList* list)
400 {
401      return &list.sentinel;
402 }
403 
404 bool enet_list_empty(ENetList* list)
405 {
406      return enet_list_begin(list) == enet_list_end(list);
407 }
408 
409 ENetListIterator enet_list_next(ENetListIterator iterator)
410 {
411      return iterator.next;
412 }
413 
414 ENetListIterator enet_list_previous(ENetListIterator iterator)
415 {
416      return iterator.previous;
417 }
418 
419 void* enet_list_front(ENetList* list)
420 {
421      return cast(void*)(list.sentinel.next);
422 }
423 
424 void* enet_list_back(ENetList* list)
425 {
426      return cast(void*)(list.sentinel.previous);
427 }
428 
429 
430 // callbacks.h
431 
432 struct ENetCallbacks
433 {
434     extern(C) nothrow void* function(size_t size) malloc;
435     extern(C) nothrow void function(void* memory) free;
436     extern(C) nothrow void function() no_memory;
437 }
438 
439 // enet.h
440 
441 enum ENET_VERSION_MAJOR = 1;
442 enum ENET_VERSION_MINOR = 3;
443 enum ENET_VERSION_PATCH = 13;
444 
445 int ENET_VERSION_CREATE(int major, int minor, int patch)
446 {
447     return (major << 16) | (minor << 8) | patch;
448 } 
449 
450 int ENET_VERSION_GET_MAJOR(int version_) 
451 {
452      return (version_ >> 16) & 0xFF;
453 }
454 
455 int ENET_VERSION_GET_MINOR(int version_)
456 {
457      return (version_ >> 8) & 0xFF;
458 }
459 
460 int ENET_VERSION_GET_PATCH(int version_)
461 {
462      return version_ & 0xFF;
463 }
464 
465 enum ENET_VERSION = ENET_VERSION_CREATE(ENET_VERSION_MAJOR, ENET_VERSION_MINOR, ENET_VERSION_PATCH);
466 
467 alias enet_uint32 ENetVersion;
468 
469 alias int ENetSocketType;
470 enum : ENetSocketType
471 {
472    ENET_SOCKET_TYPE_STREAM   = 1,
473    ENET_SOCKET_TYPE_DATAGRAM = 2
474 }
475 
476 alias int ENetSocketWait;
477 enum : ENetSocketWait
478 {
479    ENET_SOCKET_WAIT_NONE      = 0,
480    ENET_SOCKET_WAIT_SEND      = (1 << 0),
481    ENET_SOCKET_WAIT_RECEIVE   = (1 << 1),
482    ENET_SOCKET_WAIT_INTERRUPT = (1 << 2)
483 }
484 
485 alias int ENetSocketOption;
486 enum : ENetSocketOption
487 {
488    ENET_SOCKOPT_NONBLOCK  = 1,
489    ENET_SOCKOPT_BROADCAST = 2,
490    ENET_SOCKOPT_RCVBUF    = 3,
491    ENET_SOCKOPT_SNDBUF    = 4,
492    ENET_SOCKOPT_REUSEADDR = 5,
493    ENET_SOCKOPT_RCVTIMEO  = 6,
494    ENET_SOCKOPT_SNDTIMEO  = 7,
495    ENET_SOCKOPT_ERROR     = 8
496 }
497 
498 alias int ENetSocketShutdown;
499 enum : ENetSocketShutdown
500 {
501     ENET_SOCKET_SHUTDOWN_READ       = 0,
502     ENET_SOCKET_SHUTDOWN_WRITE      = 1,
503     ENET_SOCKET_SHUTDOWN_READ_WRITE = 2
504 }
505 
506 enum ENET_HOST_ANY =       0;
507 enum ENET_HOST_BROADCAST = 0xFFFFFFFFU;
508 enum ENET_PORT_ANY =       0;
509 
510 /**
511  * Portable internet address structure. 
512  *
513  * The host must be specified in network byte-order, and the port must be in host 
514  * byte-order. The constant ENET_HOST_ANY may be used to specify the default 
515  * server host. The constant ENET_HOST_BROADCAST may be used to specify the
516  * broadcast address (255.255.255.255).  This makes sense for enet_host_connect,
517  * but not for enet_host_create.  Once a server responds to a broadcast, the
518  * address is updated from ENET_HOST_BROADCAST to the server's actual IP address.
519  */
520 struct ENetAddress
521 {
522    enet_uint32 host;
523    enet_uint16 port;
524 }
525 
526 /**
527  * Packet flag bit constants.
528  *
529  * The host must be specified in network byte-order, and the port must be in
530  * host byte-order. The constant ENET_HOST_ANY may be used to specify the
531  * default server host.
532  */
533 alias int ENetPacketFlag;
534 enum : ENetPacketFlag
535 {
536    /** packet must be received by the target peer and resend attempts should be
537      * made until the packet is delivered */
538    ENET_PACKET_FLAG_RELIABLE    = (1 << 0),
539    /** packet will not be sequenced with other packets
540      * not supported for reliable packets
541      */
542    ENET_PACKET_FLAG_UNSEQUENCED = (1 << 1),
543    /** packet will not allocate data, and user must supply it instead */
544    ENET_PACKET_FLAG_NO_ALLOCATE = (1 << 2),
545    /** packet will be fragmented using unreliable (instead of reliable) sends
546      * if it exceeds the MTU */
547    ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT = (1 << 3),
548 
549    /** whether the packet has been sent from all queues it has been entered into */
550    ENET_PACKET_FLAG_SENT = (1<<8)
551 }
552 
553 alias extern(C) nothrow void function(ENetPacket *) ENetPacketFreeCallback;
554 
555 /**
556  * ENet packet structure.
557  *
558  * An ENet data packet that may be sent to or received from a peer. The shown 
559  * fields should only be read and never modified. The data field contains the 
560  * allocated data for the packet. The dataLength fields specifies the length 
561  * of the allocated data.  The flags field is either 0 (specifying no flags), 
562  * or a bitwise-or of any combination of the following flags:
563  *
564  *    ENET_PACKET_FLAG_RELIABLE - packet must be received by the target peer
565  *    and resend attempts should be made until the packet is delivered
566  *
567  *    ENET_PACKET_FLAG_UNSEQUENCED - packet will not be sequenced with other packets 
568  *    (not supported for reliable packets)
569  *
570  *    ENET_PACKET_FLAG_NO_ALLOCATE - packet will not allocate data, and user must supply it instead
571  */
572 struct ENetPacket
573 {
574    size_t                   referenceCount;  /**< internal use only */
575    enet_uint32              flags;           /**< bitwise-or of ENetPacketFlag constants */
576    enet_uint8 *             data;            /**< allocated data for packet */
577    size_t                   dataLength;      /**< length of data */
578    ENetPacketFreeCallback   freeCallback;    /**< function to be called when the packet is no longer in use */
579    void *                   userData;        /**< application private data, may be freely modified */
580 }
581 
582 struct ENetAcknowledgement
583 {
584    ENetListNode acknowledgementList;
585    enet_uint32  sentTime;
586    ENetProtocol command;
587 }
588 
589 struct ENetOutgoingCommand
590 {
591    ENetListNode outgoingCommandList;
592    enet_uint16  reliableSequenceNumber;
593    enet_uint16  unreliableSequenceNumber;
594    enet_uint32  sentTime;
595    enet_uint32  roundTripTimeout;
596    enet_uint32  roundTripTimeoutLimit;
597    enet_uint32  fragmentOffset;
598    enet_uint16  fragmentLength;
599    enet_uint16  sendAttempts;
600    ENetProtocol command;
601    ENetPacket * packet;
602 }
603 
604 struct ENetIncomingCommand
605 {  
606    ENetListNode     incomingCommandList;
607    enet_uint16      reliableSequenceNumber;
608    enet_uint16      unreliableSequenceNumber;
609    ENetProtocol     command;
610    enet_uint32      fragmentCount;
611    enet_uint32      fragmentsRemaining;
612    enet_uint32 *    fragments;
613    ENetPacket *     packet;
614 }
615 
616 alias int ENetPeerState;
617 enum : ENetPeerState
618 {
619    ENET_PEER_STATE_DISCONNECTED                = 0,
620    ENET_PEER_STATE_CONNECTING                  = 1,
621    ENET_PEER_STATE_ACKNOWLEDGING_CONNECT       = 2,
622    ENET_PEER_STATE_CONNECTION_PENDING          = 3,
623    ENET_PEER_STATE_CONNECTION_SUCCEEDED        = 4,
624    ENET_PEER_STATE_CONNECTED                   = 5,
625    ENET_PEER_STATE_DISCONNECT_LATER            = 6,
626    ENET_PEER_STATE_DISCONNECTING               = 7,
627    ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT    = 8,
628    ENET_PEER_STATE_ZOMBIE                      = 9 
629 }
630 
631 enum ENET_BUFFER_MAXIMUM  = 1 + 2 * ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS;
632 
633 enum : int
634 {
635    ENET_HOST_RECEIVE_BUFFER_SIZE          = 256 * 1024,
636    ENET_HOST_SEND_BUFFER_SIZE             = 256 * 1024,
637    ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL  = 1000,
638    ENET_HOST_DEFAULT_MTU                  = 1400,
639 
640    ENET_PEER_DEFAULT_ROUND_TRIP_TIME      = 500,
641    ENET_PEER_DEFAULT_PACKET_THROTTLE      = 32,
642    ENET_PEER_PACKET_THROTTLE_SCALE        = 32,
643    ENET_PEER_PACKET_THROTTLE_COUNTER      = 7, 
644    ENET_PEER_PACKET_THROTTLE_ACCELERATION = 2,
645    ENET_PEER_PACKET_THROTTLE_DECELERATION = 2,
646    ENET_PEER_PACKET_THROTTLE_INTERVAL     = 5000,
647    ENET_PEER_PACKET_LOSS_SCALE            = (1 << 16),
648    ENET_PEER_PACKET_LOSS_INTERVAL         = 10000,
649    ENET_PEER_WINDOW_SIZE_SCALE            = 64 * 1024,
650    ENET_PEER_TIMEOUT_LIMIT                = 32,
651    ENET_PEER_TIMEOUT_MINIMUM              = 5000,
652    ENET_PEER_TIMEOUT_MAXIMUM              = 30000,
653    ENET_PEER_PING_INTERVAL                = 500,
654    ENET_PEER_UNSEQUENCED_WINDOWS          = 64,
655    ENET_PEER_UNSEQUENCED_WINDOW_SIZE      = 1024,
656    ENET_PEER_FREE_UNSEQUENCED_WINDOWS     = 32,
657    ENET_PEER_RELIABLE_WINDOWS             = 16,
658    ENET_PEER_RELIABLE_WINDOW_SIZE         = 0x1000,
659    ENET_PEER_FREE_RELIABLE_WINDOWS        = 8
660 }
661 
662 struct ENetChannel
663 {
664    enet_uint16  outgoingReliableSequenceNumber;
665    enet_uint16  outgoingUnreliableSequenceNumber;
666    enet_uint16  usedReliableWindows;
667    enet_uint16[ENET_PEER_RELIABLE_WINDOWS] reliableWindows;
668    enet_uint16  incomingReliableSequenceNumber;
669    enet_uint16  incomingUnreliableSequenceNumber;
670    ENetList     incomingReliableCommands;
671    ENetList     incomingUnreliableCommands;
672 }
673 
674 enum ENetPeerFlag : int
675 {
676    ENET_PEER_FLAG_NEEDS_DISPATCH = (1 << 0),
677 }
678 
679 /**
680  * An ENet peer which data packets may be sent or received from. 
681  *
682  * No fields should be modified unless otherwise specified. 
683  */
684 struct ENetPeer
685 { 
686    ENetListNode  dispatchList;
687    ENetHost * host;
688    enet_uint16   outgoingPeerID;
689    enet_uint16   incomingPeerID;
690    enet_uint32   connectID;
691    enet_uint8    outgoingSessionID;
692    enet_uint8    incomingSessionID;
693    ENetAddress   address;            /**< Internet address of the peer */
694    void *        data;               /**< Application private data, may be freely modified */
695    ENetPeerState state;
696    ENetChannel * channels;
697    size_t        channelCount;       /**< Number of channels allocated for communication with peer */
698    enet_uint32   incomingBandwidth;  /**< Downstream bandwidth of the client in bytes/second */
699    enet_uint32   outgoingBandwidth;  /**< Upstream bandwidth of the client in bytes/second */
700    enet_uint32   incomingBandwidthThrottleEpoch;
701    enet_uint32   outgoingBandwidthThrottleEpoch;
702    enet_uint32   incomingDataTotal;
703    enet_uint32   outgoingDataTotal;
704    enet_uint32   lastSendTime;
705    enet_uint32   lastReceiveTime;
706    enet_uint32   nextTimeout;
707    enet_uint32   earliestTimeout;
708    enet_uint32   packetLossEpoch;
709    enet_uint32   packetsSent;
710    enet_uint32   packetsLost;
711    enet_uint32   packetLoss;          /**< mean packet loss of reliable packets as a ratio with respect to the constant ENET_PEER_PACKET_LOSS_SCALE */
712    enet_uint32   packetLossVariance;
713    enet_uint32   packetThrottle;
714    enet_uint32   packetThrottleLimit;
715    enet_uint32   packetThrottleCounter;
716    enet_uint32   packetThrottleEpoch;
717    enet_uint32   packetThrottleAcceleration;
718    enet_uint32   packetThrottleDeceleration;
719    enet_uint32   packetThrottleInterval;
720    enet_uint32   pingInterval;
721    enet_uint32   timeoutLimit;
722    enet_uint32   timeoutMinimum;
723    enet_uint32   timeoutMaximum;
724    enet_uint32   lastRoundTripTime;
725    enet_uint32   lowestRoundTripTime;
726    enet_uint32   lastRoundTripTimeVariance;
727    enet_uint32   highestRoundTripTimeVariance;
728    enet_uint32   roundTripTime;            /**< mean round trip time (RTT), in milliseconds, between sending a reliable packet and receiving its acknowledgement */
729    enet_uint32   roundTripTimeVariance;
730    enet_uint32   mtu;
731    enet_uint32   windowSize;
732    enet_uint32   reliableDataInTransit;
733    enet_uint16   outgoingReliableSequenceNumber;
734    ENetList      acknowledgements;
735    ENetList      sentReliableCommands;
736    ENetList      sentUnreliableCommands;
737    ENetList      outgoingReliableCommands;
738    ENetList      outgoingUnreliableCommands;
739    ENetList      dispatchedCommands;
740    enet_uint16   flags;
741    enet_uint8    roundTripTimeRemainder;
742    enet_uint8    roundTripTimeVarianceRemainder;
743    enet_uint16   incomingUnsequencedGroup;
744    enet_uint16   outgoingUnsequencedGroup;
745    enet_uint32[ENET_PEER_UNSEQUENCED_WINDOW_SIZE / 32] unsequencedWindow; 
746    enet_uint32   eventData;
747    size_t        totalWaitingData;
748 }
749 
750 /** An ENet packet compressor for compressing UDP packets before socket sends or receives.
751  */
752 struct ENetCompressor
753 {
754    /** Context data for the compressor. Must be non-NULL. */
755    void * context;
756    /** Compresses from inBuffers[0:inBufferCount-1], containing inLimit bytes, to outData, outputting at most outLimit bytes. Should return 0 on failure. */
757    extern(C) nothrow size_t function(void * context, const ENetBuffer * inBuffers, size_t inBufferCount, size_t inLimit, enet_uint8 * outData, size_t outLimit) compress;
758    /** Decompresses from inData, containing inLimit bytes, to outData, outputting at most outLimit bytes. Should return 0 on failure. */
759    extern(C) nothrow size_t function(void * context, const enet_uint8 * inData, size_t inLimit, enet_uint8 * outData, size_t outLimit) decompress;
760    /** Destroys the context when compression is disabled or the host is destroyed. May be NULL. */
761    extern(C) nothrow void function(void * context) destroy;
762 }
763 
764 /** Callback that computes the checksum of the data held in buffers[0:bufferCount-1] */
765 alias extern(C) nothrow enet_uint32 function(const ENetBuffer * buffers, size_t bufferCount) ENetChecksumCallback;
766 
767 /** Callback for intercepting received raw UDP packets. Should return 1 to intercept, 0 to ignore, or -1 to propagate an error. */
768 alias extern(C) nothrow int function(ENetHost * host, ENetEvent * event) ENetInterceptCallback;
769  
770 /** An ENet host for communicating with peers.
771   *
772   * No fields should be modified unless otherwise stated.
773 
774     @sa enet_host_create()
775     @sa enet_host_destroy()
776     @sa enet_host_connect()
777     @sa enet_host_service()
778     @sa enet_host_flush()
779     @sa enet_host_broadcast()
780     @sa enet_host_compress()
781     @sa enet_host_compress_with_range_coder()
782     @sa enet_host_channel_limit()
783     @sa enet_host_bandwidth_limit()
784     @sa enet_host_bandwidth_throttle()
785   */
786 struct ENetHost
787 {
788    ENetSocket           socket;
789    ENetAddress          address;                     /**< Internet address of the host */
790    enet_uint32          incomingBandwidth;           /**< downstream bandwidth of the host */
791    enet_uint32          outgoingBandwidth;           /**< upstream bandwidth of the host */
792    enet_uint32          bandwidthThrottleEpoch;
793    enet_uint32          mtu;
794    enet_uint32          randomSeed;
795    int                  recalculateBandwidthLimits;
796    ENetPeer *           peers;                       /**< array of peers allocated for this host */
797    size_t               peerCount;                   /**< number of peers allocated for this host */
798    size_t               channelLimit;                /**< maximum number of channels allowed for connected peers */
799    enet_uint32          serviceTime;
800    ENetList             dispatchQueue;
801    int                  continueSending;
802    size_t               packetSize;
803    enet_uint16          headerFlags;
804    ENetProtocol[ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS] commands;
805    size_t               commandCount;
806    ENetBuffer[ENET_BUFFER_MAXIMUM] buffers ;
807    size_t               bufferCount;
808    ENetChecksumCallback checksum;                    /**< callback the user can set to enable packet checksums for this host */
809    ENetCompressor       compressor;
810    enet_uint8[ENET_PROTOCOL_MAXIMUM_MTU][2] packetData;
811    ENetAddress          receivedAddress;
812    enet_uint8 *         receivedData;
813    size_t               receivedDataLength;
814    enet_uint32          totalSentData;               /**< total data sent, user should reset to 0 as needed to prevent overflow */
815    enet_uint32          totalSentPackets;            /**< total UDP packets sent, user should reset to 0 as needed to prevent overflow */
816    enet_uint32          totalReceivedData;           /**< total data received, user should reset to 0 as needed to prevent overflow */
817    enet_uint32          totalReceivedPackets;        /**< total UDP packets received, user should reset to 0 as needed to prevent overflow */
818    ENetInterceptCallback intercept;                  /**< callback the user can set to intercept received raw UDP packets */
819    size_t               connectedPeers;
820    size_t               bandwidthLimitedPeers;
821    size_t               duplicatePeers;              /**< optional number of allowed peers from duplicate IPs, defaults to ENET_PROTOCOL_MAXIMUM_PEER_ID */
822    size_t               maximumPacketSize;           /**< the maximum allowable packet size that may be sent or received on a peer */
823    size_t               maximumWaitingData;          /**< the maximum aggregate amount of buffer space a peer may use waiting for packets to be delivered */
824 }
825 
826 /**
827  * An ENet event type, as specified in @ref ENetEvent.
828  */
829 alias int ENetEventType;
830 enum : ENetEventType
831 {
832    /** no event occurred within the specified time limit */
833    ENET_EVENT_TYPE_NONE       = 0,  
834 
835    /** a connection request initiated by enet_host_connect has completed.  
836      * The peer field contains the peer which successfully connected. 
837      */
838    ENET_EVENT_TYPE_CONNECT    = 1,  
839 
840    /** a peer has disconnected.  This event is generated on a successful 
841      * completion of a disconnect initiated by enet_pper_disconnect, if 
842      * a peer has timed out, or if a connection request intialized by 
843      * enet_host_connect has timed out.  The peer field contains the peer 
844      * which disconnected. The data field contains user supplied data 
845      * describing the disconnection, or 0, if none is available.
846      */
847    ENET_EVENT_TYPE_DISCONNECT = 2,  
848 
849    /** a packet has been received from a peer.  The peer field specifies the
850      * peer which sent the packet.  The channelID field specifies the channel
851      * number upon which the packet was received.  The packet field contains
852      * the packet that was received; this packet must be destroyed with
853      * enet_packet_destroy after use.
854      */
855    ENET_EVENT_TYPE_RECEIVE    = 3
856 }
857 
858 /**
859  * An ENet event as returned by enet_host_service().
860  */
861 struct ENetEvent 
862 {
863    ENetEventType        type;      /**< type of the event */
864    ENetPeer *           peer;      /**< peer that generated a connect, disconnect or receive event */
865    enet_uint8           channelID; /**< channel on the peer that generated the event, if appropriate */
866    enet_uint32          data;      /**< data associated with the event, if appropriate */
867    ENetPacket *         packet;    /**< packet associated with the event, if appropriate */
868 }
869