renet 0.1.14 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,43 @@
1
+ /**
2
+ @file list.h
3
+ @brief ENet list management
4
+ */
5
+ #ifndef __ENET_LIST_H__
6
+ #define __ENET_LIST_H__
7
+
8
+ #include <stdlib.h>
9
+
10
+ typedef struct _ENetListNode
11
+ {
12
+ struct _ENetListNode * next;
13
+ struct _ENetListNode * previous;
14
+ } ENetListNode;
15
+
16
+ typedef ENetListNode * ENetListIterator;
17
+
18
+ typedef struct _ENetList
19
+ {
20
+ ENetListNode sentinel;
21
+ } ENetList;
22
+
23
+ extern void enet_list_clear (ENetList *);
24
+
25
+ extern ENetListIterator enet_list_insert (ENetListIterator, void *);
26
+ extern void * enet_list_remove (ENetListIterator);
27
+ extern ENetListIterator enet_list_move (ENetListIterator, void *, void *);
28
+
29
+ extern size_t enet_list_size (ENetList *);
30
+
31
+ #define enet_list_begin(list) ((list) -> sentinel.next)
32
+ #define enet_list_end(list) (& (list) -> sentinel)
33
+
34
+ #define enet_list_empty(list) (enet_list_begin (list) == enet_list_end (list))
35
+
36
+ #define enet_list_next(iterator) ((iterator) -> next)
37
+ #define enet_list_previous(iterator) ((iterator) -> previous)
38
+
39
+ #define enet_list_front(list) ((void *) (list) -> sentinel.next)
40
+ #define enet_list_back(list) ((void *) (list) -> sentinel.previous)
41
+
42
+ #endif /* __ENET_LIST_H__ */
43
+
@@ -0,0 +1,198 @@
1
+ /**
2
+ @file protocol.h
3
+ @brief ENet protocol
4
+ */
5
+ #ifndef __ENET_PROTOCOL_H__
6
+ #define __ENET_PROTOCOL_H__
7
+
8
+ #include "enet/types.h"
9
+
10
+ enum
11
+ {
12
+ ENET_PROTOCOL_MINIMUM_MTU = 576,
13
+ ENET_PROTOCOL_MAXIMUM_MTU = 4096,
14
+ ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS = 32,
15
+ ENET_PROTOCOL_MINIMUM_WINDOW_SIZE = 4096,
16
+ ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE = 65536,
17
+ ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT = 1,
18
+ ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT = 255,
19
+ ENET_PROTOCOL_MAXIMUM_PEER_ID = 0xFFF,
20
+ ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT = 1024 * 1024
21
+ };
22
+
23
+ typedef enum _ENetProtocolCommand
24
+ {
25
+ ENET_PROTOCOL_COMMAND_NONE = 0,
26
+ ENET_PROTOCOL_COMMAND_ACKNOWLEDGE = 1,
27
+ ENET_PROTOCOL_COMMAND_CONNECT = 2,
28
+ ENET_PROTOCOL_COMMAND_VERIFY_CONNECT = 3,
29
+ ENET_PROTOCOL_COMMAND_DISCONNECT = 4,
30
+ ENET_PROTOCOL_COMMAND_PING = 5,
31
+ ENET_PROTOCOL_COMMAND_SEND_RELIABLE = 6,
32
+ ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE = 7,
33
+ ENET_PROTOCOL_COMMAND_SEND_FRAGMENT = 8,
34
+ ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED = 9,
35
+ ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT = 10,
36
+ ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE = 11,
37
+ ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT = 12,
38
+ ENET_PROTOCOL_COMMAND_COUNT = 13,
39
+
40
+ ENET_PROTOCOL_COMMAND_MASK = 0x0F
41
+ } ENetProtocolCommand;
42
+
43
+ typedef enum _ENetProtocolFlag
44
+ {
45
+ ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE = (1 << 7),
46
+ ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED = (1 << 6),
47
+
48
+ ENET_PROTOCOL_HEADER_FLAG_COMPRESSED = (1 << 14),
49
+ ENET_PROTOCOL_HEADER_FLAG_SENT_TIME = (1 << 15),
50
+ ENET_PROTOCOL_HEADER_FLAG_MASK = ENET_PROTOCOL_HEADER_FLAG_COMPRESSED | ENET_PROTOCOL_HEADER_FLAG_SENT_TIME,
51
+
52
+ ENET_PROTOCOL_HEADER_SESSION_MASK = (3 << 12),
53
+ ENET_PROTOCOL_HEADER_SESSION_SHIFT = 12
54
+ } ENetProtocolFlag;
55
+
56
+ #ifdef _MSC_VER
57
+ #pragma pack(push, 1)
58
+ #define ENET_PACKED
59
+ #elif defined(__GNUC__) || defined(__clang__)
60
+ #define ENET_PACKED __attribute__ ((packed))
61
+ #else
62
+ #define ENET_PACKED
63
+ #endif
64
+
65
+ typedef struct _ENetProtocolHeader
66
+ {
67
+ enet_uint16 peerID;
68
+ enet_uint16 sentTime;
69
+ } ENET_PACKED ENetProtocolHeader;
70
+
71
+ typedef struct _ENetProtocolCommandHeader
72
+ {
73
+ enet_uint8 command;
74
+ enet_uint8 channelID;
75
+ enet_uint16 reliableSequenceNumber;
76
+ } ENET_PACKED ENetProtocolCommandHeader;
77
+
78
+ typedef struct _ENetProtocolAcknowledge
79
+ {
80
+ ENetProtocolCommandHeader header;
81
+ enet_uint16 receivedReliableSequenceNumber;
82
+ enet_uint16 receivedSentTime;
83
+ } ENET_PACKED ENetProtocolAcknowledge;
84
+
85
+ typedef struct _ENetProtocolConnect
86
+ {
87
+ ENetProtocolCommandHeader header;
88
+ enet_uint16 outgoingPeerID;
89
+ enet_uint8 incomingSessionID;
90
+ enet_uint8 outgoingSessionID;
91
+ enet_uint32 mtu;
92
+ enet_uint32 windowSize;
93
+ enet_uint32 channelCount;
94
+ enet_uint32 incomingBandwidth;
95
+ enet_uint32 outgoingBandwidth;
96
+ enet_uint32 packetThrottleInterval;
97
+ enet_uint32 packetThrottleAcceleration;
98
+ enet_uint32 packetThrottleDeceleration;
99
+ enet_uint32 connectID;
100
+ enet_uint32 data;
101
+ } ENET_PACKED ENetProtocolConnect;
102
+
103
+ typedef struct _ENetProtocolVerifyConnect
104
+ {
105
+ ENetProtocolCommandHeader header;
106
+ enet_uint16 outgoingPeerID;
107
+ enet_uint8 incomingSessionID;
108
+ enet_uint8 outgoingSessionID;
109
+ enet_uint32 mtu;
110
+ enet_uint32 windowSize;
111
+ enet_uint32 channelCount;
112
+ enet_uint32 incomingBandwidth;
113
+ enet_uint32 outgoingBandwidth;
114
+ enet_uint32 packetThrottleInterval;
115
+ enet_uint32 packetThrottleAcceleration;
116
+ enet_uint32 packetThrottleDeceleration;
117
+ enet_uint32 connectID;
118
+ } ENET_PACKED ENetProtocolVerifyConnect;
119
+
120
+ typedef struct _ENetProtocolBandwidthLimit
121
+ {
122
+ ENetProtocolCommandHeader header;
123
+ enet_uint32 incomingBandwidth;
124
+ enet_uint32 outgoingBandwidth;
125
+ } ENET_PACKED ENetProtocolBandwidthLimit;
126
+
127
+ typedef struct _ENetProtocolThrottleConfigure
128
+ {
129
+ ENetProtocolCommandHeader header;
130
+ enet_uint32 packetThrottleInterval;
131
+ enet_uint32 packetThrottleAcceleration;
132
+ enet_uint32 packetThrottleDeceleration;
133
+ } ENET_PACKED ENetProtocolThrottleConfigure;
134
+
135
+ typedef struct _ENetProtocolDisconnect
136
+ {
137
+ ENetProtocolCommandHeader header;
138
+ enet_uint32 data;
139
+ } ENET_PACKED ENetProtocolDisconnect;
140
+
141
+ typedef struct _ENetProtocolPing
142
+ {
143
+ ENetProtocolCommandHeader header;
144
+ } ENET_PACKED ENetProtocolPing;
145
+
146
+ typedef struct _ENetProtocolSendReliable
147
+ {
148
+ ENetProtocolCommandHeader header;
149
+ enet_uint16 dataLength;
150
+ } ENET_PACKED ENetProtocolSendReliable;
151
+
152
+ typedef struct _ENetProtocolSendUnreliable
153
+ {
154
+ ENetProtocolCommandHeader header;
155
+ enet_uint16 unreliableSequenceNumber;
156
+ enet_uint16 dataLength;
157
+ } ENET_PACKED ENetProtocolSendUnreliable;
158
+
159
+ typedef struct _ENetProtocolSendUnsequenced
160
+ {
161
+ ENetProtocolCommandHeader header;
162
+ enet_uint16 unsequencedGroup;
163
+ enet_uint16 dataLength;
164
+ } ENET_PACKED ENetProtocolSendUnsequenced;
165
+
166
+ typedef struct _ENetProtocolSendFragment
167
+ {
168
+ ENetProtocolCommandHeader header;
169
+ enet_uint16 startSequenceNumber;
170
+ enet_uint16 dataLength;
171
+ enet_uint32 fragmentCount;
172
+ enet_uint32 fragmentNumber;
173
+ enet_uint32 totalLength;
174
+ enet_uint32 fragmentOffset;
175
+ } ENET_PACKED ENetProtocolSendFragment;
176
+
177
+ typedef union _ENetProtocol
178
+ {
179
+ ENetProtocolCommandHeader header;
180
+ ENetProtocolAcknowledge acknowledge;
181
+ ENetProtocolConnect connect;
182
+ ENetProtocolVerifyConnect verifyConnect;
183
+ ENetProtocolDisconnect disconnect;
184
+ ENetProtocolPing ping;
185
+ ENetProtocolSendReliable sendReliable;
186
+ ENetProtocolSendUnreliable sendUnreliable;
187
+ ENetProtocolSendUnsequenced sendUnsequenced;
188
+ ENetProtocolSendFragment sendFragment;
189
+ ENetProtocolBandwidthLimit bandwidthLimit;
190
+ ENetProtocolThrottleConfigure throttleConfigure;
191
+ } ENET_PACKED ENetProtocol;
192
+
193
+ #ifdef _MSC_VER
194
+ #pragma pack(pop)
195
+ #endif
196
+
197
+ #endif /* __ENET_PROTOCOL_H__ */
198
+
@@ -0,0 +1,18 @@
1
+ /**
2
+ @file time.h
3
+ @brief ENet time constants and macros
4
+ */
5
+ #ifndef __ENET_TIME_H__
6
+ #define __ENET_TIME_H__
7
+
8
+ #define ENET_TIME_OVERFLOW 86400000
9
+
10
+ #define ENET_TIME_LESS(a, b) ((a) - (b) >= ENET_TIME_OVERFLOW)
11
+ #define ENET_TIME_GREATER(a, b) ((b) - (a) >= ENET_TIME_OVERFLOW)
12
+ #define ENET_TIME_LESS_EQUAL(a, b) (! ENET_TIME_GREATER (a, b))
13
+ #define ENET_TIME_GREATER_EQUAL(a, b) (! ENET_TIME_LESS (a, b))
14
+
15
+ #define ENET_TIME_DIFFERENCE(a, b) ((a) - (b) >= ENET_TIME_OVERFLOW ? (b) - (a) : (a) - (b))
16
+
17
+ #endif /* __ENET_TIME_H__ */
18
+
@@ -0,0 +1,13 @@
1
+ /**
2
+ @file types.h
3
+ @brief type definitions for ENet
4
+ */
5
+ #ifndef __ENET_TYPES_H__
6
+ #define __ENET_TYPES_H__
7
+
8
+ typedef unsigned char enet_uint8; /**< unsigned 8-bit type */
9
+ typedef unsigned short enet_uint16; /**< unsigned 16-bit type */
10
+ typedef unsigned int enet_uint32; /**< unsigned 32-bit type */
11
+
12
+ #endif /* __ENET_TYPES_H__ */
13
+
@@ -0,0 +1,47 @@
1
+ /**
2
+ @file unix.h
3
+ @brief ENet Unix header
4
+ */
5
+ #ifndef __ENET_UNIX_H__
6
+ #define __ENET_UNIX_H__
7
+
8
+ #include <stdlib.h>
9
+ #include <sys/time.h>
10
+ #include <sys/types.h>
11
+ #include <sys/socket.h>
12
+ #include <netinet/in.h>
13
+ #include <unistd.h>
14
+
15
+ #ifdef MSG_MAXIOVLEN
16
+ #define ENET_BUFFER_MAXIMUM MSG_MAXIOVLEN
17
+ #endif
18
+
19
+ typedef int ENetSocket;
20
+
21
+ #define ENET_SOCKET_NULL -1
22
+
23
+ #define ENET_HOST_TO_NET_16(value) (htons (value)) /**< macro that converts host to net byte-order of a 16-bit value */
24
+ #define ENET_HOST_TO_NET_32(value) (htonl (value)) /**< macro that converts host to net byte-order of a 32-bit value */
25
+
26
+ #define ENET_NET_TO_HOST_16(value) (ntohs (value)) /**< macro that converts net to host byte-order of a 16-bit value */
27
+ #define ENET_NET_TO_HOST_32(value) (ntohl (value)) /**< macro that converts net to host byte-order of a 32-bit value */
28
+
29
+ typedef struct
30
+ {
31
+ void * data;
32
+ size_t dataLength;
33
+ } ENetBuffer;
34
+
35
+ #define ENET_CALLBACK
36
+
37
+ #define ENET_API extern
38
+
39
+ typedef fd_set ENetSocketSet;
40
+
41
+ #define ENET_SOCKETSET_EMPTY(sockset) FD_ZERO (& (sockset))
42
+ #define ENET_SOCKETSET_ADD(sockset, socket) FD_SET (socket, & (sockset))
43
+ #define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLR (socket, & (sockset))
44
+ #define ENET_SOCKETSET_CHECK(sockset, socket) FD_ISSET (socket, & (sockset))
45
+
46
+ #endif /* __ENET_UNIX_H__ */
47
+
@@ -0,0 +1,12 @@
1
+ /**
2
+ @file utility.h
3
+ @brief ENet utility header
4
+ */
5
+ #ifndef __ENET_UTILITY_H__
6
+ #define __ENET_UTILITY_H__
7
+
8
+ #define ENET_MAX(x, y) ((x) > (y) ? (x) : (y))
9
+ #define ENET_MIN(x, y) ((x) < (y) ? (x) : (y))
10
+
11
+ #endif /* __ENET_UTILITY_H__ */
12
+
@@ -0,0 +1,57 @@
1
+ /**
2
+ @file win32.h
3
+ @brief ENet Win32 header
4
+ */
5
+ #ifndef __ENET_WIN32_H__
6
+ #define __ENET_WIN32_H__
7
+
8
+ #ifdef _MSC_VER
9
+ #ifdef ENET_BUILDING_LIB
10
+ #pragma warning (disable: 4267) // size_t to int conversion
11
+ #pragma warning (disable: 4244) // 64bit to 32bit int
12
+ #pragma warning (disable: 4018) // signed/unsigned mismatch
13
+ #pragma warning (disable: 4146) // unary minus operator applied to unsigned type
14
+ #endif
15
+ #endif
16
+
17
+ #include <stdlib.h>
18
+ #include <winsock2.h>
19
+
20
+ typedef SOCKET ENetSocket;
21
+
22
+ #define ENET_SOCKET_NULL INVALID_SOCKET
23
+
24
+ #define ENET_HOST_TO_NET_16(value) (htons (value))
25
+ #define ENET_HOST_TO_NET_32(value) (htonl (value))
26
+
27
+ #define ENET_NET_TO_HOST_16(value) (ntohs (value))
28
+ #define ENET_NET_TO_HOST_32(value) (ntohl (value))
29
+
30
+ typedef struct
31
+ {
32
+ size_t dataLength;
33
+ void * data;
34
+ } ENetBuffer;
35
+
36
+ #define ENET_CALLBACK __cdecl
37
+
38
+ #ifdef ENET_DLL
39
+ #ifdef ENET_BUILDING_LIB
40
+ #define ENET_API __declspec( dllexport )
41
+ #else
42
+ #define ENET_API __declspec( dllimport )
43
+ #endif /* ENET_BUILDING_LIB */
44
+ #else /* !ENET_DLL */
45
+ #define ENET_API extern
46
+ #endif /* ENET_DLL */
47
+
48
+ typedef fd_set ENetSocketSet;
49
+
50
+ #define ENET_SOCKETSET_EMPTY(sockset) FD_ZERO (& (sockset))
51
+ #define ENET_SOCKETSET_ADD(sockset, socket) FD_SET (socket, & (sockset))
52
+ #define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLR (socket, & (sockset))
53
+ #define ENET_SOCKETSET_CHECK(sockset, socket) FD_ISSET (socket, & (sockset))
54
+
55
+ #endif /* __ENET_WIN32_H__ */
56
+
57
+
@@ -1,18 +1,7 @@
1
1
  require 'mkmf'
2
-
3
- extension_name = 'renet'
4
-
5
- if !have_library('enet', 'enet_initialize')
6
- puts "ENet library required to build the gem, please install it"
2
+ # $CFLAGS += ' -Wall -Werror -Wno-declaration-after-statement'
3
+ case RUBY_PLATFORM
4
+ when /(mingw|mswin|windows)/i
5
+ $LDFLAGS += ' -lwinmm '
7
6
  end
8
-
9
- dir_config('enet', '/usr/include/enet', 'usr/lib')
10
- create_makefile(extension_name)
11
-
12
- system("make")
13
-
14
- #if `uname`.chomp == 'Darwin'
15
- # `ln -s renet.bundle ../../lib/renet.bundle`
16
- #else
17
- # `ln -s renet.so ../../lib/renet.so`
18
- #end
7
+ create_makefile('renet/renet')
@@ -0,0 +1,492 @@
1
+ /**
2
+ @file host.c
3
+ @brief ENet host management functions
4
+ */
5
+ #define ENET_BUILDING_LIB 1
6
+ #include <string.h>
7
+ #include "enet/enet.h"
8
+
9
+ /** @defgroup host ENet host functions
10
+ @{
11
+ */
12
+
13
+ /** Creates a host for communicating to peers.
14
+
15
+ @param address the address at which other peers may connect to this host. If NULL, then no peers may connect to the host.
16
+ @param peerCount the maximum number of peers that should be allocated for the host.
17
+ @param channelLimit the maximum number of channels allowed; if 0, then this is equivalent to ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT
18
+ @param incomingBandwidth downstream bandwidth of the host in bytes/second; if 0, ENet will assume unlimited bandwidth.
19
+ @param outgoingBandwidth upstream bandwidth of the host in bytes/second; if 0, ENet will assume unlimited bandwidth.
20
+
21
+ @returns the host on success and NULL on failure
22
+
23
+ @remarks ENet will strategically drop packets on specific sides of a connection between hosts
24
+ to ensure the host's bandwidth is not overwhelmed. The bandwidth parameters also determine
25
+ the window size of a connection which limits the amount of reliable packets that may be in transit
26
+ at any given time.
27
+ */
28
+ ENetHost *
29
+ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelLimit, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth)
30
+ {
31
+ ENetHost * host;
32
+ ENetPeer * currentPeer;
33
+
34
+ if (peerCount > ENET_PROTOCOL_MAXIMUM_PEER_ID)
35
+ return NULL;
36
+
37
+ host = (ENetHost *) enet_malloc (sizeof (ENetHost));
38
+ if (host == NULL)
39
+ return NULL;
40
+ memset (host, 0, sizeof (ENetHost));
41
+
42
+ host -> peers = (ENetPeer *) enet_malloc (peerCount * sizeof (ENetPeer));
43
+ if (host -> peers == NULL)
44
+ {
45
+ enet_free (host);
46
+
47
+ return NULL;
48
+ }
49
+ memset (host -> peers, 0, peerCount * sizeof (ENetPeer));
50
+
51
+ host -> socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM);
52
+ if (host -> socket == ENET_SOCKET_NULL || (address != NULL && enet_socket_bind (host -> socket, address) < 0))
53
+ {
54
+ if (host -> socket != ENET_SOCKET_NULL)
55
+ enet_socket_destroy (host -> socket);
56
+
57
+ enet_free (host -> peers);
58
+ enet_free (host);
59
+
60
+ return NULL;
61
+ }
62
+
63
+ enet_socket_set_option (host -> socket, ENET_SOCKOPT_NONBLOCK, 1);
64
+ enet_socket_set_option (host -> socket, ENET_SOCKOPT_BROADCAST, 1);
65
+ enet_socket_set_option (host -> socket, ENET_SOCKOPT_RCVBUF, ENET_HOST_RECEIVE_BUFFER_SIZE);
66
+ enet_socket_set_option (host -> socket, ENET_SOCKOPT_SNDBUF, ENET_HOST_SEND_BUFFER_SIZE);
67
+
68
+ if (address != NULL && enet_socket_get_address (host -> socket, & host -> address) < 0)
69
+ host -> address = * address;
70
+
71
+ if (! channelLimit || channelLimit > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
72
+ channelLimit = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT;
73
+ else
74
+ if (channelLimit < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT)
75
+ channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
76
+
77
+ host -> randomSeed = (enet_uint32) (size_t) host;
78
+ host -> randomSeed += enet_host_random_seed ();
79
+ host -> randomSeed = (host -> randomSeed << 16) | (host -> randomSeed >> 16);
80
+ host -> channelLimit = channelLimit;
81
+ host -> incomingBandwidth = incomingBandwidth;
82
+ host -> outgoingBandwidth = outgoingBandwidth;
83
+ host -> bandwidthThrottleEpoch = 0;
84
+ host -> recalculateBandwidthLimits = 0;
85
+ host -> mtu = ENET_HOST_DEFAULT_MTU;
86
+ host -> peerCount = peerCount;
87
+ host -> commandCount = 0;
88
+ host -> bufferCount = 0;
89
+ host -> checksum = NULL;
90
+ host -> receivedAddress.host = ENET_HOST_ANY;
91
+ host -> receivedAddress.port = 0;
92
+ host -> receivedData = NULL;
93
+ host -> receivedDataLength = 0;
94
+
95
+ host -> totalSentData = 0;
96
+ host -> totalSentPackets = 0;
97
+ host -> totalReceivedData = 0;
98
+ host -> totalReceivedPackets = 0;
99
+
100
+ host -> connectedPeers = 0;
101
+ host -> bandwidthLimitedPeers = 0;
102
+ host -> duplicatePeers = ENET_PROTOCOL_MAXIMUM_PEER_ID;
103
+ host -> maximumPacketSize = ENET_HOST_DEFAULT_MAXIMUM_PACKET_SIZE;
104
+ host -> maximumWaitingData = ENET_HOST_DEFAULT_MAXIMUM_WAITING_DATA;
105
+
106
+ host -> compressor.context = NULL;
107
+ host -> compressor.compress = NULL;
108
+ host -> compressor.decompress = NULL;
109
+ host -> compressor.destroy = NULL;
110
+
111
+ host -> intercept = NULL;
112
+
113
+ enet_list_clear (& host -> dispatchQueue);
114
+
115
+ for (currentPeer = host -> peers;
116
+ currentPeer < & host -> peers [host -> peerCount];
117
+ ++ currentPeer)
118
+ {
119
+ currentPeer -> host = host;
120
+ currentPeer -> incomingPeerID = currentPeer - host -> peers;
121
+ currentPeer -> outgoingSessionID = currentPeer -> incomingSessionID = 0xFF;
122
+ currentPeer -> data = NULL;
123
+
124
+ enet_list_clear (& currentPeer -> acknowledgements);
125
+ enet_list_clear (& currentPeer -> sentReliableCommands);
126
+ enet_list_clear (& currentPeer -> sentUnreliableCommands);
127
+ enet_list_clear (& currentPeer -> outgoingReliableCommands);
128
+ enet_list_clear (& currentPeer -> outgoingUnreliableCommands);
129
+ enet_list_clear (& currentPeer -> dispatchedCommands);
130
+
131
+ enet_peer_reset (currentPeer);
132
+ }
133
+
134
+ return host;
135
+ }
136
+
137
+ /** Destroys the host and all resources associated with it.
138
+ @param host pointer to the host to destroy
139
+ */
140
+ void
141
+ enet_host_destroy (ENetHost * host)
142
+ {
143
+ ENetPeer * currentPeer;
144
+
145
+ if (host == NULL)
146
+ return;
147
+
148
+ enet_socket_destroy (host -> socket);
149
+
150
+ for (currentPeer = host -> peers;
151
+ currentPeer < & host -> peers [host -> peerCount];
152
+ ++ currentPeer)
153
+ {
154
+ enet_peer_reset (currentPeer);
155
+ }
156
+
157
+ if (host -> compressor.context != NULL && host -> compressor.destroy)
158
+ (* host -> compressor.destroy) (host -> compressor.context);
159
+
160
+ enet_free (host -> peers);
161
+ enet_free (host);
162
+ }
163
+
164
+ /** Initiates a connection to a foreign host.
165
+ @param host host seeking the connection
166
+ @param address destination for the connection
167
+ @param channelCount number of channels to allocate
168
+ @param data user data supplied to the receiving host
169
+ @returns a peer representing the foreign host on success, NULL on failure
170
+ @remarks The peer returned will have not completed the connection until enet_host_service()
171
+ notifies of an ENET_EVENT_TYPE_CONNECT event for the peer.
172
+ */
173
+ ENetPeer *
174
+ enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelCount, enet_uint32 data)
175
+ {
176
+ ENetPeer * currentPeer;
177
+ ENetChannel * channel;
178
+ ENetProtocol command;
179
+
180
+ if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT)
181
+ channelCount = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
182
+ else
183
+ if (channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
184
+ channelCount = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT;
185
+
186
+ for (currentPeer = host -> peers;
187
+ currentPeer < & host -> peers [host -> peerCount];
188
+ ++ currentPeer)
189
+ {
190
+ if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED)
191
+ break;
192
+ }
193
+
194
+ if (currentPeer >= & host -> peers [host -> peerCount])
195
+ return NULL;
196
+
197
+ currentPeer -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel));
198
+ if (currentPeer -> channels == NULL)
199
+ return NULL;
200
+ currentPeer -> channelCount = channelCount;
201
+ currentPeer -> state = ENET_PEER_STATE_CONNECTING;
202
+ currentPeer -> address = * address;
203
+ currentPeer -> connectID = ++ host -> randomSeed;
204
+
205
+ if (host -> outgoingBandwidth == 0)
206
+ currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
207
+ else
208
+ currentPeer -> windowSize = (host -> outgoingBandwidth /
209
+ ENET_PEER_WINDOW_SIZE_SCALE) *
210
+ ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
211
+
212
+ if (currentPeer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE)
213
+ currentPeer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
214
+ else
215
+ if (currentPeer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
216
+ currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
217
+
218
+ for (channel = currentPeer -> channels;
219
+ channel < & currentPeer -> channels [channelCount];
220
+ ++ channel)
221
+ {
222
+ channel -> outgoingReliableSequenceNumber = 0;
223
+ channel -> outgoingUnreliableSequenceNumber = 0;
224
+ channel -> incomingReliableSequenceNumber = 0;
225
+ channel -> incomingUnreliableSequenceNumber = 0;
226
+
227
+ enet_list_clear (& channel -> incomingReliableCommands);
228
+ enet_list_clear (& channel -> incomingUnreliableCommands);
229
+
230
+ channel -> usedReliableWindows = 0;
231
+ memset (channel -> reliableWindows, 0, sizeof (channel -> reliableWindows));
232
+ }
233
+
234
+ command.header.command = ENET_PROTOCOL_COMMAND_CONNECT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
235
+ command.header.channelID = 0xFF;
236
+ command.connect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID);
237
+ command.connect.incomingSessionID = currentPeer -> incomingSessionID;
238
+ command.connect.outgoingSessionID = currentPeer -> outgoingSessionID;
239
+ command.connect.mtu = ENET_HOST_TO_NET_32 (currentPeer -> mtu);
240
+ command.connect.windowSize = ENET_HOST_TO_NET_32 (currentPeer -> windowSize);
241
+ command.connect.channelCount = ENET_HOST_TO_NET_32 (channelCount);
242
+ command.connect.incomingBandwidth = ENET_HOST_TO_NET_32 (host -> incomingBandwidth);
243
+ command.connect.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
244
+ command.connect.packetThrottleInterval = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleInterval);
245
+ command.connect.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleAcceleration);
246
+ command.connect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleDeceleration);
247
+ command.connect.connectID = currentPeer -> connectID;
248
+ command.connect.data = ENET_HOST_TO_NET_32 (data);
249
+
250
+ enet_peer_queue_outgoing_command (currentPeer, & command, NULL, 0, 0);
251
+
252
+ return currentPeer;
253
+ }
254
+
255
+ /** Queues a packet to be sent to all peers associated with the host.
256
+ @param host host on which to broadcast the packet
257
+ @param channelID channel on which to broadcast
258
+ @param packet packet to broadcast
259
+ */
260
+ void
261
+ enet_host_broadcast (ENetHost * host, enet_uint8 channelID, ENetPacket * packet)
262
+ {
263
+ ENetPeer * currentPeer;
264
+
265
+ for (currentPeer = host -> peers;
266
+ currentPeer < & host -> peers [host -> peerCount];
267
+ ++ currentPeer)
268
+ {
269
+ if (currentPeer -> state != ENET_PEER_STATE_CONNECTED)
270
+ continue;
271
+
272
+ enet_peer_send (currentPeer, channelID, packet);
273
+ }
274
+
275
+ if (packet -> referenceCount == 0)
276
+ enet_packet_destroy (packet);
277
+ }
278
+
279
+ /** Sets the packet compressor the host should use to compress and decompress packets.
280
+ @param host host to enable or disable compression for
281
+ @param compressor callbacks for for the packet compressor; if NULL, then compression is disabled
282
+ */
283
+ void
284
+ enet_host_compress (ENetHost * host, const ENetCompressor * compressor)
285
+ {
286
+ if (host -> compressor.context != NULL && host -> compressor.destroy)
287
+ (* host -> compressor.destroy) (host -> compressor.context);
288
+
289
+ if (compressor)
290
+ host -> compressor = * compressor;
291
+ else
292
+ host -> compressor.context = NULL;
293
+ }
294
+
295
+ /** Limits the maximum allowed channels of future incoming connections.
296
+ @param host host to limit
297
+ @param channelLimit the maximum number of channels allowed; if 0, then this is equivalent to ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT
298
+ */
299
+ void
300
+ enet_host_channel_limit (ENetHost * host, size_t channelLimit)
301
+ {
302
+ if (! channelLimit || channelLimit > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
303
+ channelLimit = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT;
304
+ else
305
+ if (channelLimit < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT)
306
+ channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
307
+
308
+ host -> channelLimit = channelLimit;
309
+ }
310
+
311
+
312
+ /** Adjusts the bandwidth limits of a host.
313
+ @param host host to adjust
314
+ @param incomingBandwidth new incoming bandwidth
315
+ @param outgoingBandwidth new outgoing bandwidth
316
+ @remarks the incoming and outgoing bandwidth parameters are identical in function to those
317
+ specified in enet_host_create().
318
+ */
319
+ void
320
+ enet_host_bandwidth_limit (ENetHost * host, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth)
321
+ {
322
+ host -> incomingBandwidth = incomingBandwidth;
323
+ host -> outgoingBandwidth = outgoingBandwidth;
324
+ host -> recalculateBandwidthLimits = 1;
325
+ }
326
+
327
+ void
328
+ enet_host_bandwidth_throttle (ENetHost * host)
329
+ {
330
+ enet_uint32 timeCurrent = enet_time_get (),
331
+ elapsedTime = timeCurrent - host -> bandwidthThrottleEpoch,
332
+ peersRemaining = (enet_uint32) host -> connectedPeers,
333
+ dataTotal = ~0,
334
+ bandwidth = ~0,
335
+ throttle = 0,
336
+ bandwidthLimit = 0;
337
+ int needsAdjustment = host -> bandwidthLimitedPeers > 0 ? 1 : 0;
338
+ ENetPeer * peer;
339
+ ENetProtocol command;
340
+
341
+ if (elapsedTime < ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL)
342
+ return;
343
+
344
+ host -> bandwidthThrottleEpoch = timeCurrent;
345
+
346
+ if (peersRemaining == 0)
347
+ return;
348
+
349
+ if (host -> outgoingBandwidth != 0)
350
+ {
351
+ dataTotal = 0;
352
+ bandwidth = (host -> outgoingBandwidth * elapsedTime) / 1000;
353
+
354
+ for (peer = host -> peers;
355
+ peer < & host -> peers [host -> peerCount];
356
+ ++ peer)
357
+ {
358
+ if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
359
+ continue;
360
+
361
+ dataTotal += peer -> outgoingDataTotal;
362
+ }
363
+ }
364
+
365
+ while (peersRemaining > 0 && needsAdjustment != 0)
366
+ {
367
+ needsAdjustment = 0;
368
+
369
+ if (dataTotal <= bandwidth)
370
+ throttle = ENET_PEER_PACKET_THROTTLE_SCALE;
371
+ else
372
+ throttle = (bandwidth * ENET_PEER_PACKET_THROTTLE_SCALE) / dataTotal;
373
+
374
+ for (peer = host -> peers;
375
+ peer < & host -> peers [host -> peerCount];
376
+ ++ peer)
377
+ {
378
+ enet_uint32 peerBandwidth;
379
+
380
+ if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) ||
381
+ peer -> incomingBandwidth == 0 ||
382
+ peer -> outgoingBandwidthThrottleEpoch == timeCurrent)
383
+ continue;
384
+
385
+ peerBandwidth = (peer -> incomingBandwidth * elapsedTime) / 1000;
386
+ if ((throttle * peer -> outgoingDataTotal) / ENET_PEER_PACKET_THROTTLE_SCALE <= peerBandwidth)
387
+ continue;
388
+
389
+ peer -> packetThrottleLimit = (peerBandwidth *
390
+ ENET_PEER_PACKET_THROTTLE_SCALE) / peer -> outgoingDataTotal;
391
+
392
+ if (peer -> packetThrottleLimit == 0)
393
+ peer -> packetThrottleLimit = 1;
394
+
395
+ if (peer -> packetThrottle > peer -> packetThrottleLimit)
396
+ peer -> packetThrottle = peer -> packetThrottleLimit;
397
+
398
+ peer -> outgoingBandwidthThrottleEpoch = timeCurrent;
399
+
400
+ peer -> incomingDataTotal = 0;
401
+ peer -> outgoingDataTotal = 0;
402
+
403
+ needsAdjustment = 1;
404
+ -- peersRemaining;
405
+ bandwidth -= peerBandwidth;
406
+ dataTotal -= peerBandwidth;
407
+ }
408
+ }
409
+
410
+ if (peersRemaining > 0)
411
+ {
412
+ if (dataTotal <= bandwidth)
413
+ throttle = ENET_PEER_PACKET_THROTTLE_SCALE;
414
+ else
415
+ throttle = (bandwidth * ENET_PEER_PACKET_THROTTLE_SCALE) / dataTotal;
416
+
417
+ for (peer = host -> peers;
418
+ peer < & host -> peers [host -> peerCount];
419
+ ++ peer)
420
+ {
421
+ if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) ||
422
+ peer -> outgoingBandwidthThrottleEpoch == timeCurrent)
423
+ continue;
424
+
425
+ peer -> packetThrottleLimit = throttle;
426
+
427
+ if (peer -> packetThrottle > peer -> packetThrottleLimit)
428
+ peer -> packetThrottle = peer -> packetThrottleLimit;
429
+
430
+ peer -> incomingDataTotal = 0;
431
+ peer -> outgoingDataTotal = 0;
432
+ }
433
+ }
434
+
435
+ if (host -> recalculateBandwidthLimits)
436
+ {
437
+ host -> recalculateBandwidthLimits = 0;
438
+
439
+ peersRemaining = (enet_uint32) host -> connectedPeers;
440
+ bandwidth = host -> incomingBandwidth;
441
+ needsAdjustment = 1;
442
+
443
+ if (bandwidth == 0)
444
+ bandwidthLimit = 0;
445
+ else
446
+ while (peersRemaining > 0 && needsAdjustment != 0)
447
+ {
448
+ needsAdjustment = 0;
449
+ bandwidthLimit = bandwidth / peersRemaining;
450
+
451
+ for (peer = host -> peers;
452
+ peer < & host -> peers [host -> peerCount];
453
+ ++ peer)
454
+ {
455
+ if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) ||
456
+ peer -> incomingBandwidthThrottleEpoch == timeCurrent)
457
+ continue;
458
+
459
+ if (peer -> outgoingBandwidth > 0 &&
460
+ peer -> outgoingBandwidth >= bandwidthLimit)
461
+ continue;
462
+
463
+ peer -> incomingBandwidthThrottleEpoch = timeCurrent;
464
+
465
+ needsAdjustment = 1;
466
+ -- peersRemaining;
467
+ bandwidth -= peer -> outgoingBandwidth;
468
+ }
469
+ }
470
+
471
+ for (peer = host -> peers;
472
+ peer < & host -> peers [host -> peerCount];
473
+ ++ peer)
474
+ {
475
+ if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
476
+ continue;
477
+
478
+ command.header.command = ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
479
+ command.header.channelID = 0xFF;
480
+ command.bandwidthLimit.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
481
+
482
+ if (peer -> incomingBandwidthThrottleEpoch == timeCurrent)
483
+ command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (peer -> outgoingBandwidth);
484
+ else
485
+ command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (bandwidthLimit);
486
+
487
+ enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
488
+ }
489
+ }
490
+ }
491
+
492
+ /** @} */