renet 0.1.14 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+ /** @} */