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 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 /**
675  * An ENet peer which data packets may be sent or received from.
676  *
677  * No fields should be modified unless otherwise specified.
678  */
679 struct ENetPeer
680 {
681 	ENetListNode  dispatchList;
682 	ENetHost * host;
683 	enet_uint16   outgoingPeerID;
684 	enet_uint16   incomingPeerID;
685 	enet_uint32   connectID;
686 	enet_uint8    outgoingSessionID;
687 	enet_uint8    incomingSessionID;
688 	ENetAddress   address;            /**< Internet address of the peer */
689 	void *        data;               /**< Application private data, may be freely modified */
690 	ENetPeerState state;
691 	ENetChannel * channels;
692 	size_t        channelCount;       /**< Number of channels allocated for communication with peer */
693 	enet_uint32   incomingBandwidth;  /**< Downstream bandwidth of the client in bytes/second */
694 	enet_uint32   outgoingBandwidth;  /**< Upstream bandwidth of the client in bytes/second */
695 	enet_uint32   incomingBandwidthThrottleEpoch;
696 	enet_uint32   outgoingBandwidthThrottleEpoch;
697 	enet_uint32   incomingDataTotal;
698 	enet_uint32   outgoingDataTotal;
699 	enet_uint32   lastSendTime;
700 	enet_uint32   lastReceiveTime;
701 	enet_uint32   nextTimeout;
702 	enet_uint32   earliestTimeout;
703 	enet_uint32   packetLossEpoch;
704 	enet_uint32   packetsSent;
705 	enet_uint32   packetsLost;
706 	enet_uint32   packetLoss;          /**< mean packet loss of reliable packets as a ratio with respect to the constant ENET_PEER_PACKET_LOSS_SCALE */
707 	enet_uint32   packetLossVariance;
708 	enet_uint32   packetThrottle;
709 	enet_uint32   packetThrottleLimit;
710 	enet_uint32   packetThrottleCounter;
711 	enet_uint32   packetThrottleEpoch;
712 	enet_uint32   packetThrottleAcceleration;
713 	enet_uint32   packetThrottleDeceleration;
714 	enet_uint32   packetThrottleInterval;
715 	enet_uint32   pingInterval;
716 	enet_uint32   timeoutLimit;
717 	enet_uint32   timeoutMinimum;
718 	enet_uint32   timeoutMaximum;
719 	enet_uint32   lastRoundTripTime;
720 	enet_uint32   lowestRoundTripTime;
721 	enet_uint32   lastRoundTripTimeVariance;
722 	enet_uint32   highestRoundTripTimeVariance;
723 	enet_uint32   roundTripTime;            /**< mean round trip time (RTT), in milliseconds, between sending a reliable packet and receiving its acknowledgement */
724 	enet_uint32   roundTripTimeVariance;
725 	enet_uint32   mtu;
726 	enet_uint32   windowSize;
727 	enet_uint32   reliableDataInTransit;
728 	enet_uint16   outgoingReliableSequenceNumber;
729 	ENetList      acknowledgements;
730 	ENetList      sentReliableCommands;
731 	ENetList      sentUnreliableCommands;
732 	ENetList      outgoingReliableCommands;
733 	ENetList      outgoingUnreliableCommands;
734 	ENetList      dispatchedCommands;
735 	int           needsDispatch;
736 	enet_uint16   incomingUnsequencedGroup;
737 	enet_uint16   outgoingUnsequencedGroup;
738 	enet_uint32[ENET_PEER_UNSEQUENCED_WINDOW_SIZE / 32] unsequencedWindow;
739 	enet_uint32   eventData;
740 	size_t        totalWaitingData;
741 }
742 
743 /** An ENet packet compressor for compressing UDP packets before socket sends or receives.
744  */
745 struct ENetCompressor
746 {
747 	/** Context data for the compressor. Must be non-NULL. */
748 	void * context;
749 	/** Compresses from inBuffers[0:inBufferCount-1], containing inLimit bytes, to outData, outputting at most outLimit bytes. Should return 0 on failure. */
750 	extern(C) nothrow size_t function(void * context, const ENetBuffer * inBuffers, size_t inBufferCount, size_t inLimit, enet_uint8 * outData, size_t outLimit) compress;
751 	/** Decompresses from inData, containing inLimit bytes, to outData, outputting at most outLimit bytes. Should return 0 on failure. */
752 	extern(C) nothrow size_t function(void * context, const enet_uint8 * inData, size_t inLimit, enet_uint8 * outData, size_t outLimit) decompress;
753 	/** Destroys the context when compression is disabled or the host is destroyed. May be NULL. */
754 	extern(C) nothrow void function(void * context) destroy;
755 }
756 
757 /** Callback that computes the checksum of the data held in buffers[0:bufferCount-1] */
758 alias extern(C) nothrow enet_uint32 function(const ENetBuffer * buffers, size_t bufferCount) ENetChecksumCallback;
759 
760 /** Callback for intercepting received raw UDP packets. Should return 1 to intercept, 0 to ignore, or -1 to propagate an error. */
761 alias extern(C) nothrow int function(ENetHost * host, ENetEvent * event) ENetInterceptCallback;
762 
763 /** An ENet host for communicating with peers.
764   *
765   * No fields should be modified unless otherwise stated.
766 
767 	@sa enet_host_create()
768 	@sa enet_host_destroy()
769 	@sa enet_host_connect()
770 	@sa enet_host_service()
771 	@sa enet_host_flush()
772 	@sa enet_host_broadcast()
773 	@sa enet_host_compress()
774 	@sa enet_host_compress_with_range_coder()
775 	@sa enet_host_channel_limit()
776 	@sa enet_host_bandwidth_limit()
777 	@sa enet_host_bandwidth_throttle()
778 */
779 struct ENetHost
780 {
781 	ENetSocket           socket;
782 	ENetAddress          address;                     /**< Internet address of the host */
783 	enet_uint32          incomingBandwidth;           /**< downstream bandwidth of the host */
784 	enet_uint32          outgoingBandwidth;           /**< upstream bandwidth of the host */
785 	enet_uint32          bandwidthThrottleEpoch;
786 	enet_uint32          mtu;
787 	enet_uint32          randomSeed;
788 	int                  recalculateBandwidthLimits;
789 	ENetPeer *           peers;                       /**< array of peers allocated for this host */
790 	size_t               peerCount;                   /**< number of peers allocated for this host */
791 	size_t               channelLimit;                /**< maximum number of channels allowed for connected peers */
792 	enet_uint32          serviceTime;
793 	ENetList             dispatchQueue;
794 	int                  continueSending;
795 	size_t               packetSize;
796 	enet_uint16          headerFlags;
797 	ENetProtocol[ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS] commands;
798 	size_t               commandCount;
799 	ENetBuffer[ENET_BUFFER_MAXIMUM] buffers ;
800 	size_t               bufferCount;
801 	ENetChecksumCallback checksum;                    /**< callback the user can set to enable packet checksums for this host */
802 	ENetCompressor       compressor;
803 	enet_uint8[ENET_PROTOCOL_MAXIMUM_MTU][2] packetData;
804 	ENetAddress          receivedAddress;
805 	enet_uint8 *         receivedData;
806 	size_t               receivedDataLength;
807 	enet_uint32          totalSentData;               /**< total data sent, user should reset to 0 as needed to prevent overflow */
808 	enet_uint32          totalSentPackets;            /**< total UDP packets sent, user should reset to 0 as needed to prevent overflow */
809 	enet_uint32          totalReceivedData;           /**< total data received, user should reset to 0 as needed to prevent overflow */
810 	enet_uint32          totalReceivedPackets;        /**< total UDP packets received, user should reset to 0 as needed to prevent overflow */
811 	ENetInterceptCallback intercept;                  /**< callback the user can set to intercept received raw UDP packets */
812 	size_t               connectedPeers;
813 	size_t               bandwidthLimitedPeers;
814 	size_t               duplicatePeers;              /**< optional number of allowed peers from duplicate IPs, defaults to ENET_PROTOCOL_MAXIMUM_PEER_ID */
815 	size_t               maximumPacketSize;           /**< the maximum allowable packet size that may be sent or received on a peer */
816 	size_t               maximumWaitingData;          /**< the maximum aggregate amount of buffer space a peer may use waiting for packets to be delivered */
817 }
818 
819 /**
820  * An ENet event type, as specified in @ref ENetEvent.
821  */
822 alias int ENetEventType;
823 enum : ENetEventType
824 {
825 	/** no event occurred within the specified time limit */
826 	ENET_EVENT_TYPE_NONE       = 0,
827 
828 	/** a connection request initiated by enet_host_connect has completed.
829 	* The peer field contains the peer which successfully connected.
830 	*/
831 	ENET_EVENT_TYPE_CONNECT    = 1,
832 
833 	/** a peer has disconnected.  This event is generated on a successful
834 	* completion of a disconnect initiated by enet_pper_disconnect, if
835 	* a peer has timed out, or if a connection request intialized by
836 	* enet_host_connect has timed out.  The peer field contains the peer
837 	* which disconnected. The data field contains user supplied data
838 	* describing the disconnection, or 0, if none is available.
839 	*/
840 	ENET_EVENT_TYPE_DISCONNECT = 2,
841 
842 	/** a packet has been received from a peer.  The peer field specifies the
843 	* peer which sent the packet.  The channelID field specifies the channel
844 	* number upon which the packet was received.  The packet field contains
845 	* the packet that was received; this packet must be destroyed with
846 	* enet_packet_destroy after use.
847 	*/
848 	ENET_EVENT_TYPE_RECEIVE    = 3
849 }
850 
851 /**
852  * An ENet event as returned by enet_host_service().
853  */
854 struct ENetEvent
855 {
856 	ENetEventType        type;      /**< type of the event */
857 	ENetPeer *           peer;      /**< peer that generated a connect, disconnect or receive event */
858 	enet_uint8           channelID; /**< channel on the peer that generated the event, if appropriate */
859 	enet_uint32          data;      /**< data associated with the event, if appropriate */
860 	ENetPacket *         packet;    /**< packet associated with the event, if appropriate */
861 }
862