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