提交 b64540e3 编写于 作者: T tanghai

1.更新enet到1.36版

2.修复ENetClientServerTest
上级 d44020e9
...@@ -35,16 +35,28 @@ namespace LoginClient ...@@ -35,16 +35,28 @@ namespace LoginClient
await tcpClient.ConnectAsync(hostName, port); await tcpClient.ConnectAsync(hostName, port);
Tuple<string, ushort, SRP6Client> realmInfo; // ip, port, K Tuple<string, ushort, SRP6Client> realmInfo; // ip, port, K
using (var realmSession = new RealmSession(this.sessionId, new TcpChannel(tcpClient))) var realmSession = new RealmSession(this.sessionId, new TcpChannel(tcpClient));
try
{ {
realmInfo = await realmSession.Login(account, password); realmInfo = await realmSession.Login(account, password);
Logger.Trace("session: {0}, login success!", realmSession.ID); Logger.Trace("session: {0}, login success!", realmSession.ID);
} }
finally
{
realmSession.Dispose();
}
// 登录gate // 登录gate
Peer peer = await this.clientHost.ConnectAsync(realmInfo.Item1, realmInfo.Item2); Peer peer = await this.clientHost.ConnectAsync(realmInfo.Item1, realmInfo.Item2);
var gateSession = new GateSession(this.sessionId, new ENetChannel(peer)); var gateSession = new GateSession(this.sessionId, new ENetChannel(peer));
gateSession.Login(realmInfo.Item3); try
{
gateSession.Login(realmInfo.Item3);
}
finally
{
gateSession.Dispose();
}
} }
} }
} }
...@@ -147,7 +147,8 @@ namespace LoginClient ...@@ -147,7 +147,8 @@ namespace LoginClient
// 这个消息已经没有作用,只用来保持原有的代码流程 // 这个消息已经没有作用,只用来保持原有的代码流程
var cmsgAuthLogonChallenge = new CMSG_Auth_Logon_Challenge(); var cmsgAuthLogonChallenge = new CMSG_Auth_Logon_Challenge();
this.MessageChannel.SendMessage(MessageOpcode.CMSG_AUTH_LOGON_CHALLENGE, cmsgAuthLogonChallenge); this.MessageChannel.SendMessage(
MessageOpcode.CMSG_AUTH_LOGON_CHALLENGE, cmsgAuthLogonChallenge);
var smsgAuthLogonChallengeResponse = var smsgAuthLogonChallengeResponse =
await this.Handle_SMSG_Auth_Logon_Challenge_Response(); await this.Handle_SMSG_Auth_Logon_Challenge_Response();
......
using System; using System;
using System.Collections.Generic;
using System.ComponentModel.Composition; using System.ComponentModel.Composition;
using System.Windows.Threading; using System.Windows.Threading;
using ENet;
using Log; using Log;
using Microsoft.Practices.Prism.ViewModel; using Microsoft.Practices.Prism.ViewModel;
using LoginClient;
namespace Modules.Robot namespace Modules.Robot
{ {
...@@ -90,6 +87,12 @@ namespace Modules.Robot ...@@ -90,6 +87,12 @@ namespace Modules.Robot
} }
} }
public RobotViewModel()
{
this.timer.Tick += delegate { this.loginClient.RunOnce(); };
this.timer.Start();
}
~RobotViewModel() ~RobotViewModel()
{ {
this.Disposing(false); this.Disposing(false);
...@@ -105,13 +108,10 @@ namespace Modules.Robot ...@@ -105,13 +108,10 @@ namespace Modules.Robot
{ {
} }
public async void Login() public void Login()
{ {
try try
{ {
this.timer.Tick += delegate { this.loginClient.RunOnce(); };
this.timer.Start();
// 登录 // 登录
this.loginClient.Login( this.loginClient.Login(
this.LoginIP, this.LoginPort, this.Account, this.Password); this.LoginIP, this.LoginPort, this.Account, this.Password);
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertToAutoProperty/@EntryIndexedValue">DO_NOT_SHOW</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertToAutoProperty/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=DelegateSubtraction/@EntryIndexedValue">DO_NOT_SHOW</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=DelegateSubtraction/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ForCanBeConvertedToForeach/@EntryIndexedValue">DO_NOT_SHOW</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ForCanBeConvertedToForeach/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ImplicitlyCapturedClosure/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=InconsistentNaming/@EntryIndexedValue">DO_NOT_SHOW</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=InconsistentNaming/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=LoopCanBeConvertedToQuery/@EntryIndexedValue">DO_NOT_SHOW</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=LoopCanBeConvertedToQuery/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantAssignment/@EntryIndexedValue">DO_NOT_SHOW</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantAssignment/@EntryIndexedValue">DO_NOT_SHOW</s:String>
......
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Log;
namespace ENet namespace ENet
{ {
......
/** /**
@file callbacks.h @file callbacks.h
@brief ENet callbacks @brief ENet callbacks
*/ */
#ifndef __ENET_CALLBACKS_H__ #ifndef __ENET_CALLBACKS_H__
#define __ENET_CALLBACKS_H__ #define __ENET_CALLBACKS_H__
...@@ -9,15 +9,17 @@ ...@@ -9,15 +9,17 @@
typedef struct _ENetCallbacks typedef struct _ENetCallbacks
{ {
void * (ENET_CALLBACK * malloc) (size_t size);void (ENET_CALLBACK * free) (void * memory);void (ENET_CALLBACK * no_memory) (void); void * (ENET_CALLBACK * malloc) (size_t size);
void (ENET_CALLBACK * free) (void * memory);
void (ENET_CALLBACK * no_memory) (void);
} ENetCallbacks; } ENetCallbacks;
/** @defgroup callbacks ENet internal callbacks /** @defgroup callbacks ENet internal callbacks
@{ @{
@ingroup private @ingroup private
*/ */
extern void * enet_malloc(size_t); extern void * enet_malloc (size_t);
extern void enet_free(void *); extern void enet_free (void *);
/** @} */ /** @} */
......
此差异已折叠。
/** /**
@file list.h @file list.h
@brief ENet list management @brief ENet list management
*/ */
#ifndef __ENET_LIST_H__ #ifndef __ENET_LIST_H__
#define __ENET_LIST_H__ #define __ENET_LIST_H__
...@@ -9,24 +9,24 @@ ...@@ -9,24 +9,24 @@
typedef struct _ENetListNode typedef struct _ENetListNode
{ {
struct _ENetListNode * next; struct _ENetListNode * next;
struct _ENetListNode * previous; struct _ENetListNode * previous;
} ENetListNode; } ENetListNode;
typedef ENetListNode * ENetListIterator; typedef ENetListNode * ENetListIterator;
typedef struct _ENetList typedef struct _ENetList
{ {
ENetListNode sentinel; ENetListNode sentinel;
} ENetList; } ENetList;
extern void enet_list_clear(ENetList *); extern void enet_list_clear (ENetList *);
extern ENetListIterator enet_list_insert(ENetListIterator, void *); extern ENetListIterator enet_list_insert (ENetListIterator, void *);
extern void * enet_list_remove(ENetListIterator); extern void * enet_list_remove (ENetListIterator);
extern ENetListIterator enet_list_move(ENetListIterator, void *, void *); extern ENetListIterator enet_list_move (ENetListIterator, void *, void *);
extern size_t enet_list_size(ENetList *); extern size_t enet_list_size (ENetList *);
#define enet_list_begin(list) ((list) -> sentinel.next) #define enet_list_begin(list) ((list) -> sentinel.next)
#define enet_list_end(list) (& (list) -> sentinel) #define enet_list_end(list) (& (list) -> sentinel)
......
/** /**
@file protocol.h @file protocol.h
@brief ENet protocol @brief ENet protocol
*/ */
#ifndef __ENET_PROTOCOL_H__ #ifndef __ENET_PROTOCOL_H__
#define __ENET_PROTOCOL_H__ #define __ENET_PROTOCOL_H__
...@@ -9,50 +9,49 @@ ...@@ -9,50 +9,49 @@
enum enum
{ {
ENET_PROTOCOL_MINIMUM_MTU = 576, ENET_PROTOCOL_MINIMUM_MTU = 576,
ENET_PROTOCOL_MAXIMUM_MTU = 4096, ENET_PROTOCOL_MAXIMUM_MTU = 4096,
ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS = 32, ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS = 32,
ENET_PROTOCOL_MINIMUM_WINDOW_SIZE = 4096, ENET_PROTOCOL_MINIMUM_WINDOW_SIZE = 4096,
ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE = 32768, ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE = 32768,
ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT = 1, ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT = 1,
ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT = 255, ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT = 255,
ENET_PROTOCOL_MAXIMUM_PEER_ID = 0xFFF, ENET_PROTOCOL_MAXIMUM_PEER_ID = 0xFFF,
ENET_PROTOCOL_MAXIMUM_PACKET_SIZE = 1024 * 1024 * 1024, ENET_PROTOCOL_MAXIMUM_PACKET_SIZE = 1024 * 1024 * 1024,
ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT = 1024 * 1024 ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT = 1024 * 1024
}; };
typedef enum _ENetProtocolCommand typedef enum _ENetProtocolCommand
{ {
ENET_PROTOCOL_COMMAND_NONE = 0, ENET_PROTOCOL_COMMAND_NONE = 0,
ENET_PROTOCOL_COMMAND_ACKNOWLEDGE = 1, ENET_PROTOCOL_COMMAND_ACKNOWLEDGE = 1,
ENET_PROTOCOL_COMMAND_CONNECT = 2, ENET_PROTOCOL_COMMAND_CONNECT = 2,
ENET_PROTOCOL_COMMAND_VERIFY_CONNECT = 3, ENET_PROTOCOL_COMMAND_VERIFY_CONNECT = 3,
ENET_PROTOCOL_COMMAND_DISCONNECT = 4, ENET_PROTOCOL_COMMAND_DISCONNECT = 4,
ENET_PROTOCOL_COMMAND_PING = 5, ENET_PROTOCOL_COMMAND_PING = 5,
ENET_PROTOCOL_COMMAND_SEND_RELIABLE = 6, ENET_PROTOCOL_COMMAND_SEND_RELIABLE = 6,
ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE = 7, ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE = 7,
ENET_PROTOCOL_COMMAND_SEND_FRAGMENT = 8, ENET_PROTOCOL_COMMAND_SEND_FRAGMENT = 8,
ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED = 9, ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED = 9,
ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT = 10, ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT = 10,
ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE = 11, ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE = 11,
ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT = 12, ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT = 12,
ENET_PROTOCOL_COMMAND_COUNT = 13, ENET_PROTOCOL_COMMAND_COUNT = 13,
ENET_PROTOCOL_COMMAND_MASK = 0x0F ENET_PROTOCOL_COMMAND_MASK = 0x0F
} ENetProtocolCommand; } ENetProtocolCommand;
typedef enum _ENetProtocolFlag typedef enum _ENetProtocolFlag
{ {
ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE = (1 << 7), ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE = (1 << 7),
ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED = (1 << 6), ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED = (1 << 6),
ENET_PROTOCOL_HEADER_FLAG_COMPRESSED = (1 << 14), ENET_PROTOCOL_HEADER_FLAG_COMPRESSED = (1 << 14),
ENET_PROTOCOL_HEADER_FLAG_SENT_TIME = (1 << 15), ENET_PROTOCOL_HEADER_FLAG_SENT_TIME = (1 << 15),
ENET_PROTOCOL_HEADER_FLAG_MASK = ENET_PROTOCOL_HEADER_FLAG_COMPRESSED ENET_PROTOCOL_HEADER_FLAG_MASK = ENET_PROTOCOL_HEADER_FLAG_COMPRESSED | ENET_PROTOCOL_HEADER_FLAG_SENT_TIME,
| ENET_PROTOCOL_HEADER_FLAG_SENT_TIME,
ENET_PROTOCOL_HEADER_SESSION_MASK = (3 << 12),
ENET_PROTOCOL_HEADER_SESSION_MASK = (3 << 12), ENET_PROTOCOL_HEADER_SESSION_SHIFT = 12
ENET_PROTOCOL_HEADER_SESSION_SHIFT = 12
} ENetProtocolFlag; } ENetProtocolFlag;
#ifdef _MSC_VER_ #ifdef _MSC_VER_
...@@ -66,131 +65,131 @@ typedef enum _ENetProtocolFlag ...@@ -66,131 +65,131 @@ typedef enum _ENetProtocolFlag
typedef struct _ENetProtocolHeader typedef struct _ENetProtocolHeader
{ {
enet_uint16 peerID; enet_uint16 peerID;
enet_uint16 sentTime; enet_uint16 sentTime;
}ENET_PACKED ENetProtocolHeader; } ENET_PACKED ENetProtocolHeader;
typedef struct _ENetProtocolCommandHeader typedef struct _ENetProtocolCommandHeader
{ {
enet_uint8 command; enet_uint8 command;
enet_uint8 channelID; enet_uint8 channelID;
enet_uint16 reliableSequenceNumber; enet_uint16 reliableSequenceNumber;
}ENET_PACKED ENetProtocolCommandHeader; } ENET_PACKED ENetProtocolCommandHeader;
typedef struct _ENetProtocolAcknowledge typedef struct _ENetProtocolAcknowledge
{ {
ENetProtocolCommandHeader header; ENetProtocolCommandHeader header;
enet_uint16 receivedReliableSequenceNumber; enet_uint16 receivedReliableSequenceNumber;
enet_uint16 receivedSentTime; enet_uint16 receivedSentTime;
}ENET_PACKED ENetProtocolAcknowledge; } ENET_PACKED ENetProtocolAcknowledge;
typedef struct _ENetProtocolConnect typedef struct _ENetProtocolConnect
{ {
ENetProtocolCommandHeader header; ENetProtocolCommandHeader header;
enet_uint16 outgoingPeerID; enet_uint16 outgoingPeerID;
enet_uint8 incomingSessionID; enet_uint8 incomingSessionID;
enet_uint8 outgoingSessionID; enet_uint8 outgoingSessionID;
enet_uint32 mtu; enet_uint32 mtu;
enet_uint32 windowSize; enet_uint32 windowSize;
enet_uint32 channelCount; enet_uint32 channelCount;
enet_uint32 incomingBandwidth; enet_uint32 incomingBandwidth;
enet_uint32 outgoingBandwidth; enet_uint32 outgoingBandwidth;
enet_uint32 packetThrottleInterval; enet_uint32 packetThrottleInterval;
enet_uint32 packetThrottleAcceleration; enet_uint32 packetThrottleAcceleration;
enet_uint32 packetThrottleDeceleration; enet_uint32 packetThrottleDeceleration;
enet_uint32 connectID; enet_uint32 connectID;
enet_uint32 data; enet_uint32 data;
}ENET_PACKED ENetProtocolConnect; } ENET_PACKED ENetProtocolConnect;
typedef struct _ENetProtocolVerifyConnect typedef struct _ENetProtocolVerifyConnect
{ {
ENetProtocolCommandHeader header; ENetProtocolCommandHeader header;
enet_uint16 outgoingPeerID; enet_uint16 outgoingPeerID;
enet_uint8 incomingSessionID; enet_uint8 incomingSessionID;
enet_uint8 outgoingSessionID; enet_uint8 outgoingSessionID;
enet_uint32 mtu; enet_uint32 mtu;
enet_uint32 windowSize; enet_uint32 windowSize;
enet_uint32 channelCount; enet_uint32 channelCount;
enet_uint32 incomingBandwidth; enet_uint32 incomingBandwidth;
enet_uint32 outgoingBandwidth; enet_uint32 outgoingBandwidth;
enet_uint32 packetThrottleInterval; enet_uint32 packetThrottleInterval;
enet_uint32 packetThrottleAcceleration; enet_uint32 packetThrottleAcceleration;
enet_uint32 packetThrottleDeceleration; enet_uint32 packetThrottleDeceleration;
enet_uint32 connectID; enet_uint32 connectID;
}ENET_PACKED ENetProtocolVerifyConnect; } ENET_PACKED ENetProtocolVerifyConnect;
typedef struct _ENetProtocolBandwidthLimit typedef struct _ENetProtocolBandwidthLimit
{ {
ENetProtocolCommandHeader header; ENetProtocolCommandHeader header;
enet_uint32 incomingBandwidth; enet_uint32 incomingBandwidth;
enet_uint32 outgoingBandwidth; enet_uint32 outgoingBandwidth;
}ENET_PACKED ENetProtocolBandwidthLimit; } ENET_PACKED ENetProtocolBandwidthLimit;
typedef struct _ENetProtocolThrottleConfigure typedef struct _ENetProtocolThrottleConfigure
{ {
ENetProtocolCommandHeader header; ENetProtocolCommandHeader header;
enet_uint32 packetThrottleInterval; enet_uint32 packetThrottleInterval;
enet_uint32 packetThrottleAcceleration; enet_uint32 packetThrottleAcceleration;
enet_uint32 packetThrottleDeceleration; enet_uint32 packetThrottleDeceleration;
}ENET_PACKED ENetProtocolThrottleConfigure; } ENET_PACKED ENetProtocolThrottleConfigure;
typedef struct _ENetProtocolDisconnect typedef struct _ENetProtocolDisconnect
{ {
ENetProtocolCommandHeader header; ENetProtocolCommandHeader header;
enet_uint32 data; enet_uint32 data;
}ENET_PACKED ENetProtocolDisconnect; } ENET_PACKED ENetProtocolDisconnect;
typedef struct _ENetProtocolPing typedef struct _ENetProtocolPing
{ {
ENetProtocolCommandHeader header; ENetProtocolCommandHeader header;
}ENET_PACKED ENetProtocolPing; } ENET_PACKED ENetProtocolPing;
typedef struct _ENetProtocolSendReliable typedef struct _ENetProtocolSendReliable
{ {
ENetProtocolCommandHeader header; ENetProtocolCommandHeader header;
enet_uint16 dataLength; enet_uint16 dataLength;
}ENET_PACKED ENetProtocolSendReliable; } ENET_PACKED ENetProtocolSendReliable;
typedef struct _ENetProtocolSendUnreliable typedef struct _ENetProtocolSendUnreliable
{ {
ENetProtocolCommandHeader header; ENetProtocolCommandHeader header;
enet_uint16 unreliableSequenceNumber; enet_uint16 unreliableSequenceNumber;
enet_uint16 dataLength; enet_uint16 dataLength;
}ENET_PACKED ENetProtocolSendUnreliable; } ENET_PACKED ENetProtocolSendUnreliable;
typedef struct _ENetProtocolSendUnsequenced typedef struct _ENetProtocolSendUnsequenced
{ {
ENetProtocolCommandHeader header; ENetProtocolCommandHeader header;
enet_uint16 unsequencedGroup; enet_uint16 unsequencedGroup;
enet_uint16 dataLength; enet_uint16 dataLength;
}ENET_PACKED ENetProtocolSendUnsequenced; } ENET_PACKED ENetProtocolSendUnsequenced;
typedef struct _ENetProtocolSendFragment typedef struct _ENetProtocolSendFragment
{ {
ENetProtocolCommandHeader header; ENetProtocolCommandHeader header;
enet_uint16 startSequenceNumber; enet_uint16 startSequenceNumber;
enet_uint16 dataLength; enet_uint16 dataLength;
enet_uint32 fragmentCount; enet_uint32 fragmentCount;
enet_uint32 fragmentNumber; enet_uint32 fragmentNumber;
enet_uint32 totalLength; enet_uint32 totalLength;
enet_uint32 fragmentOffset; enet_uint32 fragmentOffset;
}ENET_PACKED ENetProtocolSendFragment; } ENET_PACKED ENetProtocolSendFragment;
typedef union _ENetProtocol typedef union _ENetProtocol
{ {
ENetProtocolCommandHeader header; ENetProtocolCommandHeader header;
ENetProtocolAcknowledge acknowledge; ENetProtocolAcknowledge acknowledge;
ENetProtocolConnect connect; ENetProtocolConnect connect;
ENetProtocolVerifyConnect verifyConnect; ENetProtocolVerifyConnect verifyConnect;
ENetProtocolDisconnect disconnect; ENetProtocolDisconnect disconnect;
ENetProtocolPing ping; ENetProtocolPing ping;
ENetProtocolSendReliable sendReliable; ENetProtocolSendReliable sendReliable;
ENetProtocolSendUnreliable sendUnreliable; ENetProtocolSendUnreliable sendUnreliable;
ENetProtocolSendUnsequenced sendUnsequenced; ENetProtocolSendUnsequenced sendUnsequenced;
ENetProtocolSendFragment sendFragment; ENetProtocolSendFragment sendFragment;
ENetProtocolBandwidthLimit bandwidthLimit; ENetProtocolBandwidthLimit bandwidthLimit;
ENetProtocolThrottleConfigure throttleConfigure; ENetProtocolThrottleConfigure throttleConfigure;
}ENET_PACKED ENetProtocol; } ENET_PACKED ENetProtocol;
#ifdef _MSC_VER_ #ifdef _MSC_VER_
#pragma pack(pop) #pragma pack(pop)
......
/** /**
@file time.h @file time.h
@brief ENet time constants and macros @brief ENet time constants and macros
*/ */
#ifndef __ENET_TIME_H__ #ifndef __ENET_TIME_H__
#define __ENET_TIME_H__ #define __ENET_TIME_H__
......
/** /**
@file types.h @file types.h
@brief type definitions for ENet @brief type definitions for ENet
*/ */
#ifndef __ENET_TYPES_H__ #ifndef __ENET_TYPES_H__
#define __ENET_TYPES_H__ #define __ENET_TYPES_H__
typedef unsigned char enet_uint8; /**< unsigned 8-bit type */ typedef unsigned char enet_uint8; /**< unsigned 8-bit type */
typedef unsigned short enet_uint16; /**< unsigned 16-bit type */ typedef unsigned short enet_uint16; /**< unsigned 16-bit type */
typedef unsigned int enet_uint32; /**< unsigned 32-bit type */ typedef unsigned int enet_uint32; /**< unsigned 32-bit type */
#endif /* __ENET_TYPES_H__ */ #endif /* __ENET_TYPES_H__ */
/** /**
@file unix.h @file unix.h
@brief ENet Unix header @brief ENet Unix header
*/ */
#ifndef __ENET_UNIX_H__ #ifndef __ENET_UNIX_H__
#define __ENET_UNIX_H__ #define __ENET_UNIX_H__
...@@ -15,7 +15,7 @@ typedef int ENetSocket; ...@@ -15,7 +15,7 @@ typedef int ENetSocket;
enum enum
{ {
ENET_SOCKET_NULL = -1 ENET_SOCKET_NULL = -1
}; };
#define ENET_HOST_TO_NET_16(value) (htons (value)) /**< macro that converts host to net byte-order of a 16-bit value */ #define ENET_HOST_TO_NET_16(value) (htons (value)) /**< macro that converts host to net byte-order of a 16-bit value */
...@@ -26,8 +26,8 @@ enum ...@@ -26,8 +26,8 @@ enum
typedef struct typedef struct
{ {
void * data; void * data;
size_t dataLength; size_t dataLength;
} ENetBuffer; } ENetBuffer;
#define ENET_CALLBACK #define ENET_CALLBACK
...@@ -40,6 +40,6 @@ typedef fd_set ENetSocketSet; ...@@ -40,6 +40,6 @@ typedef fd_set ENetSocketSet;
#define ENET_SOCKETSET_ADD(sockset, socket) FD_SET (socket, & (sockset)) #define ENET_SOCKETSET_ADD(sockset, socket) FD_SET (socket, & (sockset))
#define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLEAR (socket, & (sockset)) #define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLEAR (socket, & (sockset))
#define ENET_SOCKETSET_CHECK(sockset, socket) FD_ISSET (socket, & (sockset)) #define ENET_SOCKETSET_CHECK(sockset, socket) FD_ISSET (socket, & (sockset))
#endif /* __ENET_UNIX_H__ */ #endif /* __ENET_UNIX_H__ */
/** /**
@file utility.h @file utility.h
@brief ENet utility header @brief ENet utility header
*/ */
#ifndef __ENET_UTILITY_H__ #ifndef __ENET_UTILITY_H__
#define __ENET_UTILITY_H__ #define __ENET_UTILITY_H__
......
/** /**
@file win32.h @file win32.h
@brief ENet Win32 header @brief ENet Win32 header
*/ */
#ifndef __ENET_WIN32_H__ #ifndef __ENET_WIN32_H__
#define __ENET_WIN32_H__ #define __ENET_WIN32_H__
...@@ -19,7 +19,7 @@ typedef SOCKET ENetSocket; ...@@ -19,7 +19,7 @@ typedef SOCKET ENetSocket;
enum enum
{ {
ENET_SOCKET_NULL = INVALID_SOCKET ENET_SOCKET_NULL = INVALID_SOCKET
}; };
#define ENET_HOST_TO_NET_16(value) (htons (value)) #define ENET_HOST_TO_NET_16(value) (htons (value))
...@@ -30,8 +30,8 @@ enum ...@@ -30,8 +30,8 @@ enum
typedef struct typedef struct
{ {
size_t dataLength; size_t dataLength;
void * data; void * data;
} ENetBuffer; } ENetBuffer;
#define ENET_CALLBACK __cdecl #define ENET_CALLBACK __cdecl
...@@ -55,3 +55,4 @@ typedef fd_set ENetSocketSet; ...@@ -55,3 +55,4 @@ typedef fd_set ENetSocketSet;
#endif /* __ENET_WIN32_H__ */ #endif /* __ENET_WIN32_H__ */
...@@ -93,15 +93,15 @@ ...@@ -93,15 +93,15 @@
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="callbacks.c" /> <ClCompile Include="callbacks.cc" />
<ClCompile Include="compress.c" /> <ClCompile Include="compress.cc" />
<ClCompile Include="host.c" /> <ClCompile Include="host.cc" />
<ClCompile Include="list.c" /> <ClCompile Include="list.cc" />
<ClCompile Include="packet.c" /> <ClCompile Include="packet.cc" />
<ClCompile Include="peer.c" /> <ClCompile Include="peer.cc" />
<ClCompile Include="protocol.c" /> <ClCompile Include="protocol.cc" />
<ClCompile Include="unix.c" /> <ClCompile Include="unix.cc" />
<ClCompile Include="win32.c" /> <ClCompile Include="win32.cc" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="ENet\callbacks.h" /> <ClInclude Include="ENet\callbacks.h" />
......
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup> <ItemGroup>
<ClCompile Include="callbacks.c" /> <ClCompile Include="callbacks.cc" />
<ClCompile Include="compress.c" /> <ClCompile Include="compress.cc" />
<ClCompile Include="host.c" /> <ClCompile Include="host.cc" />
<ClCompile Include="list.c" /> <ClCompile Include="list.cc" />
<ClCompile Include="packet.c" /> <ClCompile Include="packet.cc" />
<ClCompile Include="peer.c" /> <ClCompile Include="peer.cc" />
<ClCompile Include="protocol.c" /> <ClCompile Include="protocol.cc" />
<ClCompile Include="unix.c" /> <ClCompile Include="unix.cc" />
<ClCompile Include="win32.c" /> <ClCompile Include="win32.cc" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Filter Include="ENet"> <Filter Include="ENet">
......
/**
@file callbacks.c
@brief ENet callback functions
*/
#define ENET_BUILDING_LIB 1
#include "enet/enet.h"
static ENetCallbacks callbacks =
{ malloc, free, abort };
int enet_initialize_with_callbacks(ENetVersion version, const ENetCallbacks * inits)
{
if (version < ENET_VERSION_CREATE (1, 3, 0))
return -1;
if (inits->malloc != NULL || inits->free != NULL)
{
if (inits->malloc == NULL || inits->free == NULL)
return -1;
callbacks.malloc = inits->malloc;
callbacks.free = inits->free;
}
if (inits->no_memory != NULL)
callbacks.no_memory = inits->no_memory;
return enet_initialize();
}
void* enet_malloc(size_t size)
{
void * memory = callbacks.malloc(size);
if (memory == NULL)
callbacks.no_memory();
return memory;
}
void enet_free(void * memory)
{
callbacks.free(memory);
}
/**
@file callbacks.c
@brief ENet callback functions
*/
#define ENET_BUILDING_LIB 1
#include "enet/enet.h"
static ENetCallbacks callbacks = { malloc, free, abort };
int
enet_initialize_with_callbacks (ENetVersion version, const ENetCallbacks * inits)
{
if (version < ENET_VERSION_CREATE (1, 3, 0))
return -1;
if (inits -> malloc != NULL || inits -> free != NULL)
{
if (inits -> malloc == NULL || inits -> free == NULL)
return -1;
callbacks.malloc = inits -> malloc;
callbacks.free = inits -> free;
}
if (inits -> no_memory != NULL)
callbacks.no_memory = inits -> no_memory;
return enet_initialize ();
}
void *
enet_malloc (size_t size)
{
void * memory = callbacks.malloc (size);
if (memory == NULL)
callbacks.no_memory ();
return memory;
}
void
enet_free (void * memory)
{
callbacks.free (memory);
}
/**
@file host.c
@brief ENet host management functions
*/
#define ENET_BUILDING_LIB 1
#define __MINGW_USE_VC2005_COMPAT 1
#include <string.h>
#include <time.h>
#include "enet/enet.h"
/** @defgroup host ENet host functions
@{
*/
/** Creates a host for communicating to peers.
@param address the address at which other peers may connect to this host. If NULL, then no peers may connect to the host.
@param peerCount the maximum number of peers that should be allocated for the host.
@param channelLimit the maximum number of channels allowed; if 0, then this is equivalent to ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT
@param incomingBandwidth downstream bandwidth of the host in bytes/second; if 0, ENet will assume unlimited bandwidth.
@param outgoingBandwidth upstream bandwidth of the host in bytes/second; if 0, ENet will assume unlimited bandwidth.
@returns the host on success and NULL on failure
@remarks ENet will strategically drop packets on specific sides of a connection between hosts
to ensure the host's bandwidth is not overwhelmed. The bandwidth parameters also determine
the window size of a connection which limits the amount of reliable packets that may be in transit
at any given time.
*/
ENetHost *enet_host_create(const ENetAddress * address, size_t peerCount, size_t channelLimit,
enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth)
{
ENetHost * host;
ENetPeer * currentPeer;
if (peerCount > ENET_PROTOCOL_MAXIMUM_PEER_ID)
return NULL;
host = (ENetHost *) enet_malloc(sizeof(ENetHost));
if (host == NULL)
return NULL;
memset(host, 0, sizeof(ENetHost));
host->peers = (ENetPeer *) enet_malloc(peerCount * sizeof(ENetPeer));
if (host->peers == NULL)
{
enet_free(host);
return NULL;
}
memset(host->peers, 0, peerCount * sizeof(ENetPeer));
host->socket = enet_socket_create(ENET_SOCKET_TYPE_DATAGRAM);
if (host->socket == ENET_SOCKET_NULL
|| (address != NULL && enet_socket_bind(host->socket, address) < 0))
{
if (host->socket != ENET_SOCKET_NULL)
enet_socket_destroy(host->socket);
enet_free(host->peers);
enet_free(host);
return NULL;
}
enet_socket_set_option(host->socket, ENET_SOCKOPT_NONBLOCK, 1);
enet_socket_set_option(host->socket, ENET_SOCKOPT_BROADCAST, 1);
enet_socket_set_option(host->socket, ENET_SOCKOPT_RCVBUF, ENET_HOST_RECEIVE_BUFFER_SIZE);
enet_socket_set_option(host->socket, ENET_SOCKOPT_SNDBUF, ENET_HOST_SEND_BUFFER_SIZE);
if (address != NULL)
host->address = *address;
if (!channelLimit || channelLimit > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
channelLimit = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT;
else if (channelLimit < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT)
channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
host->randomSeed = (enet_uint32) time(NULL) + (enet_uint32) (size_t) host;
host->randomSeed = (host->randomSeed << 16) | (host->randomSeed >> 16);
host->channelLimit = channelLimit;
host->incomingBandwidth = incomingBandwidth;
host->outgoingBandwidth = outgoingBandwidth;
host->bandwidthThrottleEpoch = 0;
host->recalculateBandwidthLimits = 0;
host->mtu = ENET_HOST_DEFAULT_MTU;
host->peerCount = peerCount;
host->commandCount = 0;
host->bufferCount = 0;
host->checksum = NULL;
host->receivedAddress.host = ENET_HOST_ANY;
host->receivedAddress.port = 0;
host->receivedData = NULL;
host->receivedDataLength = 0;
host->totalSentData = 0;
host->totalSentPackets = 0;
host->totalReceivedData = 0;
host->totalReceivedPackets = 0;
host->compressor.context = NULL;
host->compressor.compress = NULL;
host->compressor.decompress = NULL;
host->compressor.destroy = NULL;
enet_list_clear(&host->dispatchQueue);
for (currentPeer = host->peers; currentPeer < &host->peers[host->peerCount]; ++currentPeer)
{
currentPeer->host = host;
currentPeer->incomingPeerID = currentPeer - host->peers;
currentPeer->outgoingSessionID = currentPeer->incomingSessionID = 0xFF;
currentPeer->data = NULL;
enet_list_clear(&currentPeer->acknowledgements);
enet_list_clear(&currentPeer->sentReliableCommands);
enet_list_clear(&currentPeer->sentUnreliableCommands);
enet_list_clear(&currentPeer->outgoingReliableCommands);
enet_list_clear(&currentPeer->outgoingUnreliableCommands);
enet_list_clear(&currentPeer->dispatchedCommands);
enet_peer_reset(currentPeer);
}
return host;
}
void enet_enable_crc(ENetHost* host)
{
host->checksum = enet_crc32;
}
/** Destroys the host and all resources associated with it.
@param host pointer to the host to destroy
*/
void enet_host_destroy(ENetHost * host)
{
ENetPeer * currentPeer;
enet_socket_destroy(host->socket);
for (currentPeer = host->peers; currentPeer < &host->peers[host->peerCount]; ++currentPeer)
{
enet_peer_reset(currentPeer);
}
if (host->compressor.context != NULL && host->compressor.destroy)
(*host->compressor.destroy)(host->compressor.context);
enet_free(host->peers);
enet_free(host);
}
/** Initiates a connection to a foreign host.
@param host host seeking the connection
@param address destination for the connection
@param channelCount number of channels to allocate
@param data user data supplied to the receiving host
@returns a peer representing the foreign host on success, NULL on failure
@remarks The peer returned will have not completed the connection until enet_host_service()
notifies of an ENET_EVENT_TYPE_CONNECT event for the peer.
*/
ENetPeer *enet_host_connect(ENetHost * host, const ENetAddress * address, size_t channelCount,
enet_uint32 data)
{
ENetPeer * currentPeer;
ENetChannel * channel;
ENetProtocol command;
if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT)
channelCount = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
else if (channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
channelCount = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT;
for (currentPeer = host->peers; currentPeer < &host->peers[host->peerCount]; ++currentPeer)
{
if (currentPeer->state == ENET_PEER_STATE_DISCONNECTED)
break;
}
if (currentPeer >= &host->peers[host->peerCount])
return NULL;
currentPeer->channels = (ENetChannel *) enet_malloc(channelCount * sizeof(ENetChannel));
if (currentPeer->channels == NULL)
return NULL;
currentPeer->channelCount = channelCount;
currentPeer->state = ENET_PEER_STATE_CONNECTING;
currentPeer->address = *address;
currentPeer->connectID = ++host->randomSeed;
if (host->outgoingBandwidth == 0)
currentPeer->windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
else
currentPeer->windowSize = (host->outgoingBandwidth / ENET_PEER_WINDOW_SIZE_SCALE)
* ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
if (currentPeer->windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE)
currentPeer->windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
else if (currentPeer->windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
currentPeer->windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
for (channel = currentPeer->channels; channel < &currentPeer->channels[channelCount]; ++channel)
{
channel->outgoingReliableSequenceNumber = 0;
channel->outgoingUnreliableSequenceNumber = 0;
channel->incomingReliableSequenceNumber = 0;
channel->incomingUnreliableSequenceNumber = 0;
enet_list_clear(&channel->incomingReliableCommands);
enet_list_clear(&channel->incomingUnreliableCommands);
channel->usedReliableWindows = 0;
memset(channel->reliableWindows, 0, sizeof(channel->reliableWindows));
}
command.header.command = ENET_PROTOCOL_COMMAND_CONNECT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
command.header.channelID = 0xFF;
command.connect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID);
command.connect.incomingSessionID = currentPeer->incomingSessionID;
command.connect.outgoingSessionID = currentPeer->outgoingSessionID;
command.connect.mtu = ENET_HOST_TO_NET_32 (currentPeer -> mtu);
command.connect.windowSize = ENET_HOST_TO_NET_32 (currentPeer -> windowSize);
command.connect.channelCount = ENET_HOST_TO_NET_32 (channelCount);
command.connect.incomingBandwidth = ENET_HOST_TO_NET_32 (host -> incomingBandwidth);
command.connect.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
command.connect.packetThrottleInterval =
ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleInterval);
command.connect.packetThrottleAcceleration =
ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleAcceleration);
command.connect.packetThrottleDeceleration =
ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleDeceleration);
command.connect.connectID = currentPeer->connectID;
command.connect.data = ENET_HOST_TO_NET_32 (data);
enet_peer_queue_outgoing_command(currentPeer, &command, NULL, 0, 0);
return currentPeer;
}
/** Queues a packet to be sent to all peers associated with the host.
@param host host on which to broadcast the packet
@param channelID channel on which to broadcast
@param packet packet to broadcast
*/
void enet_host_broadcast(ENetHost * host, enet_uint8 channelID, ENetPacket * packet)
{
ENetPeer * currentPeer;
for (currentPeer = host->peers; currentPeer < &host->peers[host->peerCount]; ++currentPeer)
{
if (currentPeer->state != ENET_PEER_STATE_CONNECTED)
continue;
enet_peer_send(currentPeer, channelID, packet);
}
if (packet->referenceCount == 0)
enet_packet_destroy(packet);
}
/** Sets the packet compressor the host should use to compress and decompress packets.
@param host host to enable or disable compression for
@param compressor callbacks for for the packet compressor; if NULL, then compression is disabled
*/
void enet_host_compress(ENetHost * host, const ENetCompressor * compressor)
{
if (host->compressor.context != NULL && host->compressor.destroy)
(*host->compressor.destroy)(host->compressor.context);
if (compressor)
host->compressor = *compressor;
else
host->compressor.context = NULL;
}
/** Limits the maximum allowed channels of future incoming connections.
@param host host to limit
@param channelLimit the maximum number of channels allowed; if 0, then this is equivalent to ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT
*/
void enet_host_channel_limit(ENetHost * host, size_t channelLimit)
{
if (!channelLimit || channelLimit > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
channelLimit = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT;
else if (channelLimit < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT)
channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
host->channelLimit = channelLimit;
}
/** Adjusts the bandwidth limits of a host.
@param host host to adjust
@param incomingBandwidth new incoming bandwidth
@param outgoingBandwidth new outgoing bandwidth
@remarks the incoming and outgoing bandwidth parameters are identical in function to those
specified in enet_host_create().
*/
void enet_host_bandwidth_limit(ENetHost * host, enet_uint32 incomingBandwidth,
enet_uint32 outgoingBandwidth)
{
host->incomingBandwidth = incomingBandwidth;
host->outgoingBandwidth = outgoingBandwidth;
host->recalculateBandwidthLimits = 1;
}
void enet_host_bandwidth_throttle(ENetHost * host)
{
enet_uint32 timeCurrent = enet_time_get(), elapsedTime = timeCurrent
- host->bandwidthThrottleEpoch, peersTotal = 0, dataTotal = 0, peersRemaining,
bandwidth, throttle = 0, bandwidthLimit = 0;
int needsAdjustment;
ENetPeer * peer;
ENetProtocol command;
if (elapsedTime < ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL)
return;
for (peer = host->peers; peer < &host->peers[host->peerCount]; ++peer)
{
if (peer->state != ENET_PEER_STATE_CONNECTED
&& peer->state != ENET_PEER_STATE_DISCONNECT_LATER)
continue;
++peersTotal;
dataTotal += peer->outgoingDataTotal;
}
if (peersTotal == 0)
return;
peersRemaining = peersTotal;
needsAdjustment = 1;
if (host->outgoingBandwidth == 0)
bandwidth = ~0;
else
bandwidth = (host->outgoingBandwidth * elapsedTime) / 1000;
while (peersRemaining > 0 && needsAdjustment != 0)
{
needsAdjustment = 0;
if (dataTotal < bandwidth)
throttle = ENET_PEER_PACKET_THROTTLE_SCALE;
else
throttle = (bandwidth * ENET_PEER_PACKET_THROTTLE_SCALE) / dataTotal;
for (peer = host->peers; peer < &host->peers[host->peerCount]; ++peer)
{
enet_uint32 peerBandwidth;
if ((peer->state != ENET_PEER_STATE_CONNECTED
&& peer->state != ENET_PEER_STATE_DISCONNECT_LATER)
|| peer->incomingBandwidth == 0
|| peer->outgoingBandwidthThrottleEpoch == timeCurrent)
continue;
peerBandwidth = (peer->incomingBandwidth * elapsedTime) / 1000;
if ((throttle * peer->outgoingDataTotal) / ENET_PEER_PACKET_THROTTLE_SCALE
<= peerBandwidth)
continue;
peer->packetThrottleLimit = (peerBandwidth * ENET_PEER_PACKET_THROTTLE_SCALE)
/ peer->outgoingDataTotal;
if (peer->packetThrottleLimit == 0)
peer->packetThrottleLimit = 1;
if (peer->packetThrottle > peer->packetThrottleLimit)
peer->packetThrottle = peer->packetThrottleLimit;
peer->outgoingBandwidthThrottleEpoch = timeCurrent;
needsAdjustment = 1;
--peersRemaining;
bandwidth -= peerBandwidth;
dataTotal -= peerBandwidth;
}
}
if (peersRemaining > 0)
for (peer = host->peers; peer < &host->peers[host->peerCount]; ++peer)
{
if ((peer->state != ENET_PEER_STATE_CONNECTED
&& peer->state != ENET_PEER_STATE_DISCONNECT_LATER)
|| peer->outgoingBandwidthThrottleEpoch == timeCurrent)
continue;
peer->packetThrottleLimit = throttle;
if (peer->packetThrottle > peer->packetThrottleLimit)
peer->packetThrottle = peer->packetThrottleLimit;
}
if (host->recalculateBandwidthLimits)
{
host->recalculateBandwidthLimits = 0;
peersRemaining = peersTotal;
bandwidth = host->incomingBandwidth;
needsAdjustment = 1;
if (bandwidth == 0)
bandwidthLimit = 0;
else
while (peersRemaining > 0 && needsAdjustment != 0)
{
needsAdjustment = 0;
bandwidthLimit = bandwidth / peersRemaining;
for (peer = host->peers; peer < &host->peers[host->peerCount]; ++peer)
{
if ((peer->state != ENET_PEER_STATE_CONNECTED
&& peer->state != ENET_PEER_STATE_DISCONNECT_LATER)
|| peer->incomingBandwidthThrottleEpoch == timeCurrent)
continue;
if (peer->outgoingBandwidth > 0 && peer->outgoingBandwidth >= bandwidthLimit)
continue;
peer->incomingBandwidthThrottleEpoch = timeCurrent;
needsAdjustment = 1;
--peersRemaining;
bandwidth -= peer->outgoingBandwidth;
}
}
for (peer = host->peers; peer < &host->peers[host->peerCount]; ++peer)
{
if (peer->state != ENET_PEER_STATE_CONNECTED
&& peer->state != ENET_PEER_STATE_DISCONNECT_LATER)
continue;
command.header.command = ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT
| ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
command.header.channelID = 0xFF;
command.bandwidthLimit.outgoingBandwidth =
ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
if (peer->incomingBandwidthThrottleEpoch == timeCurrent)
command.bandwidthLimit.incomingBandwidth =
ENET_HOST_TO_NET_32 (peer -> outgoingBandwidth);
else
command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (bandwidthLimit);
enet_peer_queue_outgoing_command(peer, &command, NULL, 0, 0);
}
}
host->bandwidthThrottleEpoch = timeCurrent;
for (peer = host->peers; peer < &host->peers[host->peerCount]; ++peer)
{
peer->incomingDataTotal = 0;
peer->outgoingDataTotal = 0;
}
}
/** @} */
/**
@file host.c
@brief ENet host management functions
*/
#define ENET_BUILDING_LIB 1
#define __MINGW_USE_VC2005_COMPAT 1
#include <string.h>
#include <time.h>
#include "enet/enet.h"
/** @defgroup host ENet host functions
@{
*/
/** Creates a host for communicating to peers.
@param address the address at which other peers may connect to this host. If NULL, then no peers may connect to the host.
@param peerCount the maximum number of peers that should be allocated for the host.
@param channelLimit the maximum number of channels allowed; if 0, then this is equivalent to ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT
@param incomingBandwidth downstream bandwidth of the host in bytes/second; if 0, ENet will assume unlimited bandwidth.
@param outgoingBandwidth upstream bandwidth of the host in bytes/second; if 0, ENet will assume unlimited bandwidth.
@returns the host on success and NULL on failure
@remarks ENet will strategically drop packets on specific sides of a connection between hosts
to ensure the host's bandwidth is not overwhelmed. The bandwidth parameters also determine
the window size of a connection which limits the amount of reliable packets that may be in transit
at any given time.
*/
ENetHost *
enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelLimit, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth)
{
ENetHost * host;
ENetPeer * currentPeer;
if (peerCount > ENET_PROTOCOL_MAXIMUM_PEER_ID)
return NULL;
host = (ENetHost *) enet_malloc (sizeof (ENetHost));
if (host == NULL)
return NULL;
memset (host, 0, sizeof (ENetHost));
host -> peers = (ENetPeer *) enet_malloc (peerCount * sizeof (ENetPeer));
if (host -> peers == NULL)
{
enet_free (host);
return NULL;
}
memset (host -> peers, 0, peerCount * sizeof (ENetPeer));
host -> socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM);
if (host -> socket == ENET_SOCKET_NULL || (address != NULL && enet_socket_bind (host -> socket, address) < 0))
{
if (host -> socket != ENET_SOCKET_NULL)
enet_socket_destroy (host -> socket);
enet_free (host -> peers);
enet_free (host);
return NULL;
}
enet_socket_set_option (host -> socket, ENET_SOCKOPT_NONBLOCK, 1);
enet_socket_set_option (host -> socket, ENET_SOCKOPT_BROADCAST, 1);
enet_socket_set_option (host -> socket, ENET_SOCKOPT_RCVBUF, ENET_HOST_RECEIVE_BUFFER_SIZE);
enet_socket_set_option (host -> socket, ENET_SOCKOPT_SNDBUF, ENET_HOST_SEND_BUFFER_SIZE);
if (address != NULL)
host -> address = * address;
if (! channelLimit || channelLimit > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
channelLimit = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT;
else
if (channelLimit < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT)
channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
host -> randomSeed = (enet_uint32) time(NULL) + (enet_uint32) (size_t) host;
host -> randomSeed = (host -> randomSeed << 16) | (host -> randomSeed >> 16);
host -> channelLimit = channelLimit;
host -> incomingBandwidth = incomingBandwidth;
host -> outgoingBandwidth = outgoingBandwidth;
host -> bandwidthThrottleEpoch = 0;
host -> recalculateBandwidthLimits = 0;
host -> mtu = ENET_HOST_DEFAULT_MTU;
host -> peerCount = peerCount;
host -> commandCount = 0;
host -> bufferCount = 0;
host -> checksum = NULL;
host -> receivedAddress.host = ENET_HOST_ANY;
host -> receivedAddress.port = 0;
host -> receivedData = NULL;
host -> receivedDataLength = 0;
host -> totalSentData = 0;
host -> totalSentPackets = 0;
host -> totalReceivedData = 0;
host -> totalReceivedPackets = 0;
host -> compressor.context = NULL;
host -> compressor.compress = NULL;
host -> compressor.decompress = NULL;
host -> compressor.destroy = NULL;
host -> intercept = NULL;
enet_list_clear (& host -> dispatchQueue);
for (currentPeer = host -> peers;
currentPeer < & host -> peers [host -> peerCount];
++ currentPeer)
{
currentPeer -> host = host;
currentPeer -> incomingPeerID = currentPeer - host -> peers;
currentPeer -> outgoingSessionID = currentPeer -> incomingSessionID = 0xFF;
currentPeer -> data = NULL;
enet_list_clear (& currentPeer -> acknowledgements);
enet_list_clear (& currentPeer -> sentReliableCommands);
enet_list_clear (& currentPeer -> sentUnreliableCommands);
enet_list_clear (& currentPeer -> outgoingReliableCommands);
enet_list_clear (& currentPeer -> outgoingUnreliableCommands);
enet_list_clear (& currentPeer -> dispatchedCommands);
enet_peer_reset (currentPeer);
}
return host;
}
void enet_enable_crc(ENetHost* host)
{
host->checksum = enet_crc32;
}
/** Destroys the host and all resources associated with it.
@param host pointer to the host to destroy
*/
void
enet_host_destroy (ENetHost * host)
{
ENetPeer * currentPeer;
if (host == NULL)
return;
enet_socket_destroy (host -> socket);
for (currentPeer = host -> peers;
currentPeer < & host -> peers [host -> peerCount];
++ currentPeer)
{
enet_peer_reset (currentPeer);
}
if (host -> compressor.context != NULL && host -> compressor.destroy)
(* host -> compressor.destroy) (host -> compressor.context);
enet_free (host -> peers);
enet_free (host);
}
/** Initiates a connection to a foreign host.
@param host host seeking the connection
@param address destination for the connection
@param channelCount number of channels to allocate
@param data user data supplied to the receiving host
@returns a peer representing the foreign host on success, NULL on failure
@remarks The peer returned will have not completed the connection until enet_host_service()
notifies of an ENET_EVENT_TYPE_CONNECT event for the peer.
*/
ENetPeer *
enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelCount, enet_uint32 data)
{
ENetPeer * currentPeer;
ENetChannel * channel;
ENetProtocol command;
if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT)
channelCount = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
else
if (channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
channelCount = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT;
for (currentPeer = host -> peers;
currentPeer < & host -> peers [host -> peerCount];
++ currentPeer)
{
if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED)
break;
}
if (currentPeer >= & host -> peers [host -> peerCount])
return NULL;
currentPeer -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel));
if (currentPeer -> channels == NULL)
return NULL;
currentPeer -> channelCount = channelCount;
currentPeer -> state = ENET_PEER_STATE_CONNECTING;
currentPeer -> address = * address;
currentPeer -> connectID = ++ host -> randomSeed;
if (host -> outgoingBandwidth == 0)
currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
else
currentPeer -> windowSize = (host -> outgoingBandwidth /
ENET_PEER_WINDOW_SIZE_SCALE) *
ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
if (currentPeer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE)
currentPeer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE;
else
if (currentPeer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE)
currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE;
for (channel = currentPeer -> channels;
channel < & currentPeer -> channels [channelCount];
++ channel)
{
channel -> outgoingReliableSequenceNumber = 0;
channel -> outgoingUnreliableSequenceNumber = 0;
channel -> incomingReliableSequenceNumber = 0;
channel -> incomingUnreliableSequenceNumber = 0;
enet_list_clear (& channel -> incomingReliableCommands);
enet_list_clear (& channel -> incomingUnreliableCommands);
channel -> usedReliableWindows = 0;
memset (channel -> reliableWindows, 0, sizeof (channel -> reliableWindows));
}
command.header.command = ENET_PROTOCOL_COMMAND_CONNECT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
command.header.channelID = 0xFF;
command.connect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID);
command.connect.incomingSessionID = currentPeer -> incomingSessionID;
command.connect.outgoingSessionID = currentPeer -> outgoingSessionID;
command.connect.mtu = ENET_HOST_TO_NET_32 (currentPeer -> mtu);
command.connect.windowSize = ENET_HOST_TO_NET_32 (currentPeer -> windowSize);
command.connect.channelCount = ENET_HOST_TO_NET_32 (channelCount);
command.connect.incomingBandwidth = ENET_HOST_TO_NET_32 (host -> incomingBandwidth);
command.connect.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
command.connect.packetThrottleInterval = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleInterval);
command.connect.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleAcceleration);
command.connect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleDeceleration);
command.connect.connectID = currentPeer -> connectID;
command.connect.data = ENET_HOST_TO_NET_32 (data);
enet_peer_queue_outgoing_command (currentPeer, & command, NULL, 0, 0);
return currentPeer;
}
/** Queues a packet to be sent to all peers associated with the host.
@param host host on which to broadcast the packet
@param channelID channel on which to broadcast
@param packet packet to broadcast
*/
void
enet_host_broadcast (ENetHost * host, enet_uint8 channelID, ENetPacket * packet)
{
ENetPeer * currentPeer;
for (currentPeer = host -> peers;
currentPeer < & host -> peers [host -> peerCount];
++ currentPeer)
{
if (currentPeer -> state != ENET_PEER_STATE_CONNECTED)
continue;
enet_peer_send (currentPeer, channelID, packet);
}
if (packet -> referenceCount == 0)
enet_packet_destroy (packet);
}
/** Sets the packet compressor the host should use to compress and decompress packets.
@param host host to enable or disable compression for
@param compressor callbacks for for the packet compressor; if NULL, then compression is disabled
*/
void
enet_host_compress (ENetHost * host, const ENetCompressor * compressor)
{
if (host -> compressor.context != NULL && host -> compressor.destroy)
(* host -> compressor.destroy) (host -> compressor.context);
if (compressor)
host -> compressor = * compressor;
else
host -> compressor.context = NULL;
}
/** Limits the maximum allowed channels of future incoming connections.
@param host host to limit
@param channelLimit the maximum number of channels allowed; if 0, then this is equivalent to ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT
*/
void
enet_host_channel_limit (ENetHost * host, size_t channelLimit)
{
if (! channelLimit || channelLimit > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
channelLimit = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT;
else
if (channelLimit < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT)
channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT;
host -> channelLimit = channelLimit;
}
/** Adjusts the bandwidth limits of a host.
@param host host to adjust
@param incomingBandwidth new incoming bandwidth
@param outgoingBandwidth new outgoing bandwidth
@remarks the incoming and outgoing bandwidth parameters are identical in function to those
specified in enet_host_create().
*/
void
enet_host_bandwidth_limit (ENetHost * host, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth)
{
host -> incomingBandwidth = incomingBandwidth;
host -> outgoingBandwidth = outgoingBandwidth;
host -> recalculateBandwidthLimits = 1;
}
void
enet_host_bandwidth_throttle (ENetHost * host)
{
enet_uint32 timeCurrent = enet_time_get (),
elapsedTime = timeCurrent - host -> bandwidthThrottleEpoch,
peersTotal = 0,
dataTotal = 0,
peersRemaining,
bandwidth,
throttle = 0,
bandwidthLimit = 0;
int needsAdjustment;
ENetPeer * peer;
ENetProtocol command;
if (elapsedTime < ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL)
return;
for (peer = host -> peers;
peer < & host -> peers [host -> peerCount];
++ peer)
{
if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
continue;
++ peersTotal;
dataTotal += peer -> outgoingDataTotal;
}
if (peersTotal == 0)
return;
peersRemaining = peersTotal;
needsAdjustment = 1;
if (host -> outgoingBandwidth == 0)
bandwidth = ~0;
else
bandwidth = (host -> outgoingBandwidth * elapsedTime) / 1000;
while (peersRemaining > 0 && needsAdjustment != 0)
{
needsAdjustment = 0;
if (dataTotal < bandwidth)
throttle = ENET_PEER_PACKET_THROTTLE_SCALE;
else
throttle = (bandwidth * ENET_PEER_PACKET_THROTTLE_SCALE) / dataTotal;
for (peer = host -> peers;
peer < & host -> peers [host -> peerCount];
++ peer)
{
enet_uint32 peerBandwidth;
if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) ||
peer -> incomingBandwidth == 0 ||
peer -> outgoingBandwidthThrottleEpoch == timeCurrent)
continue;
peerBandwidth = (peer -> incomingBandwidth * elapsedTime) / 1000;
if ((throttle * peer -> outgoingDataTotal) / ENET_PEER_PACKET_THROTTLE_SCALE <= peerBandwidth)
continue;
peer -> packetThrottleLimit = (peerBandwidth *
ENET_PEER_PACKET_THROTTLE_SCALE) / peer -> outgoingDataTotal;
if (peer -> packetThrottleLimit == 0)
peer -> packetThrottleLimit = 1;
if (peer -> packetThrottle > peer -> packetThrottleLimit)
peer -> packetThrottle = peer -> packetThrottleLimit;
peer -> outgoingBandwidthThrottleEpoch = timeCurrent;
needsAdjustment = 1;
-- peersRemaining;
bandwidth -= peerBandwidth;
dataTotal -= peerBandwidth;
}
}
if (peersRemaining > 0)
for (peer = host -> peers;
peer < & host -> peers [host -> peerCount];
++ peer)
{
if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) ||
peer -> outgoingBandwidthThrottleEpoch == timeCurrent)
continue;
peer -> packetThrottleLimit = throttle;
if (peer -> packetThrottle > peer -> packetThrottleLimit)
peer -> packetThrottle = peer -> packetThrottleLimit;
}
if (host -> recalculateBandwidthLimits)
{
host -> recalculateBandwidthLimits = 0;
peersRemaining = peersTotal;
bandwidth = host -> incomingBandwidth;
needsAdjustment = 1;
if (bandwidth == 0)
bandwidthLimit = 0;
else
while (peersRemaining > 0 && needsAdjustment != 0)
{
needsAdjustment = 0;
bandwidthLimit = bandwidth / peersRemaining;
for (peer = host -> peers;
peer < & host -> peers [host -> peerCount];
++ peer)
{
if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) ||
peer -> incomingBandwidthThrottleEpoch == timeCurrent)
continue;
if (peer -> outgoingBandwidth > 0 &&
peer -> outgoingBandwidth >= bandwidthLimit)
continue;
peer -> incomingBandwidthThrottleEpoch = timeCurrent;
needsAdjustment = 1;
-- peersRemaining;
bandwidth -= peer -> outgoingBandwidth;
}
}
for (peer = host -> peers;
peer < & host -> peers [host -> peerCount];
++ peer)
{
if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)
continue;
command.header.command = ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE;
command.header.channelID = 0xFF;
command.bandwidthLimit.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth);
if (peer -> incomingBandwidthThrottleEpoch == timeCurrent)
command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (peer -> outgoingBandwidth);
else
command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (bandwidthLimit);
enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0);
}
}
host -> bandwidthThrottleEpoch = timeCurrent;
for (peer = host -> peers;
peer < & host -> peers [host -> peerCount];
++ peer)
{
peer -> incomingDataTotal = 0;
peer -> outgoingDataTotal = 0;
}
}
/** @} */
/**
@file list.c
@brief ENet linked list functions
*/
#define ENET_BUILDING_LIB 1
#include "enet/enet.h"
/**
@defgroup list ENet linked list utility functions
@ingroup private
@{
*/
void enet_list_clear(ENetList * list)
{
list->sentinel.next = &list->sentinel;
list->sentinel.previous = &list->sentinel;
}
ENetListIterator enet_list_insert(ENetListIterator position, void * data)
{
ENetListIterator result = (ENetListIterator) data;
result->previous = position->previous;
result->next = position;
result->previous->next = result;
position->previous = result;
return result;
}
void *enet_list_remove(ENetListIterator position)
{
position->previous->next = position->next;
position->next->previous = position->previous;
return position;
}
ENetListIterator enet_list_move(ENetListIterator position, void * dataFirst, void * dataLast)
{
ENetListIterator first = (ENetListIterator) dataFirst, last = (ENetListIterator) dataLast;
first->previous->next = last->next;
last->next->previous = first->previous;
first->previous = position->previous;
last->next = position;
first->previous->next = first;
position->previous = last;
return first;
}
size_t enet_list_size(ENetList * list)
{
size_t size = 0;
ENetListIterator position;
for (position = enet_list_begin (list); position != enet_list_end (list); position =
enet_list_next (position))
++size;
return size;
}
/** @} */
/**
@file list.c
@brief ENet linked list functions
*/
#define ENET_BUILDING_LIB 1
#include "enet/enet.h"
/**
@defgroup list ENet linked list utility functions
@ingroup private
@{
*/
void
enet_list_clear (ENetList * list)
{
list -> sentinel.next = & list -> sentinel;
list -> sentinel.previous = & list -> sentinel;
}
ENetListIterator
enet_list_insert (ENetListIterator position, void * data)
{
ENetListIterator result = (ENetListIterator) data;
result -> previous = position -> previous;
result -> next = position;
result -> previous -> next = result;
position -> previous = result;
return result;
}
void *
enet_list_remove (ENetListIterator position)
{
position -> previous -> next = position -> next;
position -> next -> previous = position -> previous;
return position;
}
ENetListIterator
enet_list_move (ENetListIterator position, void * dataFirst, void * dataLast)
{
ENetListIterator first = (ENetListIterator) dataFirst,
last = (ENetListIterator) dataLast;
first -> previous -> next = last -> next;
last -> next -> previous = first -> previous;
first -> previous = position -> previous;
last -> next = position;
first -> previous -> next = first;
position -> previous = last;
return first;
}
size_t
enet_list_size (ENetList * list)
{
size_t size = 0;
ENetListIterator position;
for (position = enet_list_begin (list);
position != enet_list_end (list);
position = enet_list_next (position))
++ size;
return size;
}
/** @} */
/**
@file packet.c
@brief ENet packet management functions
*/
#include <string.h>
#define ENET_BUILDING_LIB 1
#include "enet/enet.h"
/** @defgroup Packet ENet packet functions
@{
*/
/** Creates a packet that may be sent to a peer.
@param dataContents initial contents of the packet's data; the packet's data will remain uninitialized if dataContents is NULL.
@param dataLength size of the data allocated for this packet
@param flags flags for this packet as described for the ENetPacket structure.
@returns the packet on success, NULL on failure
*/
ENetPacket *enet_packet_create(const void * data, size_t dataLength, enet_uint32 flags)
{
ENetPacket * packet = (ENetPacket *) enet_malloc(sizeof(ENetPacket));
if (packet == NULL)
return NULL;
if (flags & ENET_PACKET_FLAG_NO_ALLOCATE)
packet->data = (enet_uint8 *) data;
else if (dataLength <= 0)
packet->data = NULL;
else
{
packet->data = (enet_uint8 *) enet_malloc(dataLength);
if (packet->data == NULL)
{
enet_free(packet);
return NULL;
}
if (data != NULL)
memcpy(packet->data, data, dataLength);
}
packet->referenceCount = 0;
packet->flags = flags;
packet->dataLength = dataLength;
packet->freeCallback = NULL;
return packet;
}
/** Destroys the packet and deallocates its data.
@param packet packet to be destroyed
*/
void enet_packet_destroy(ENetPacket * packet)
{
if (packet->freeCallback != NULL)
(*packet->freeCallback)(packet);
if (!(packet->flags & ENET_PACKET_FLAG_NO_ALLOCATE) && packet->data != NULL)
enet_free(packet->data);
enet_free(packet);
}
/** Attempts to resize the data in the packet to length specified in the
dataLength parameter
@param packet packet to resize
@param dataLength new size for the packet data
@returns 0 on success, < 0 on failure
*/
int enet_packet_resize(ENetPacket * packet, size_t dataLength)
{
enet_uint8 * newData;
if (dataLength <= packet->dataLength || (packet->flags & ENET_PACKET_FLAG_NO_ALLOCATE))
{
packet->dataLength = dataLength;
return 0;
}
newData = (enet_uint8 *) enet_malloc(dataLength);
if (newData == NULL)
return -1;
memcpy(newData, packet->data, packet->dataLength);
enet_free(packet->data);
packet->data = newData;
packet->dataLength = dataLength;
return 0;
}
static int initializedCRC32 = 0;
static enet_uint32 crcTable[256];
static enet_uint32 reflect_crc(int val, int bits)
{
int result = 0, bit;
for (bit = 0; bit < bits; bit++)
{
if (val & 1)
result |= 1 << (bits - 1 - bit);
val >>= 1;
}
return result;
}
static void initialize_crc32()
{
int byte;
for (byte = 0; byte < 256; ++byte)
{
enet_uint32 crc = reflect_crc(byte, 8) << 24;
int offset;
for (offset = 0; offset < 8; ++offset)
{
if (crc & 0x80000000)
crc = (crc << 1) ^ 0x04c11db7;
else
crc <<= 1;
}
crcTable[byte] = reflect_crc(crc, 32);
}
initializedCRC32 = 1;
}
enet_uint32 enet_crc32(const ENetBuffer * buffers, size_t bufferCount)
{
enet_uint32 crc = 0xFFFFFFFF;
if (!initializedCRC32)
initialize_crc32();
while (bufferCount-- > 0)
{
const enet_uint8 * data = (const enet_uint8 *) buffers->data, *dataEnd =
&data[buffers->dataLength];
while (data < dataEnd)
{
crc = (crc >> 8) ^ crcTable[(crc & 0xFF) ^ *data++];
}
++buffers;
}
return ENET_HOST_TO_NET_32 (~ crc);
}
/** @} */
/**
@file packet.c
@brief ENet packet management functions
*/
#include <string.h>
#define ENET_BUILDING_LIB 1
#include "enet/enet.h"
/** @defgroup Packet ENet packet functions
@{
*/
/** Creates a packet that may be sent to a peer.
@param dataContents initial contents of the packet's data; the packet's data will remain uninitialized if dataContents is NULL.
@param dataLength size of the data allocated for this packet
@param flags flags for this packet as described for the ENetPacket structure.
@returns the packet on success, NULL on failure
*/
ENetPacket *
enet_packet_create (const void * data, size_t dataLength, enet_uint32 flags)
{
ENetPacket * packet = (ENetPacket *) enet_malloc (sizeof (ENetPacket));
if (packet == NULL)
return NULL;
if (flags & ENET_PACKET_FLAG_NO_ALLOCATE)
packet -> data = (enet_uint8 *) data;
else
if (dataLength <= 0)
packet -> data = NULL;
else
{
packet -> data = (enet_uint8 *) enet_malloc (dataLength);
if (packet -> data == NULL)
{
enet_free (packet);
return NULL;
}
if (data != NULL)
memcpy (packet -> data, data, dataLength);
}
packet -> referenceCount = 0;
packet -> flags = flags;
packet -> dataLength = dataLength;
packet -> freeCallback = NULL;
return packet;
}
/** Destroys the packet and deallocates its data.
@param packet packet to be destroyed
*/
void
enet_packet_destroy (ENetPacket * packet)
{
if (packet == NULL)
return;
if (packet -> freeCallback != NULL)
(* packet -> freeCallback) (packet);
if (! (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE) &&
packet -> data != NULL)
enet_free (packet -> data);
enet_free (packet);
}
/** Attempts to resize the data in the packet to length specified in the
dataLength parameter
@param packet packet to resize
@param dataLength new size for the packet data
@returns 0 on success, < 0 on failure
*/
int
enet_packet_resize (ENetPacket * packet, size_t dataLength)
{
enet_uint8 * newData;
if (dataLength <= packet -> dataLength || (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE))
{
packet -> dataLength = dataLength;
return 0;
}
newData = (enet_uint8 *) enet_malloc (dataLength);
if (newData == NULL)
return -1;
memcpy (newData, packet -> data, packet -> dataLength);
enet_free (packet -> data);
packet -> data = newData;
packet -> dataLength = dataLength;
return 0;
}
static int initializedCRC32 = 0;
static enet_uint32 crcTable [256];
static enet_uint32
reflect_crc (int val, int bits)
{
int result = 0, bit;
for (bit = 0; bit < bits; bit ++)
{
if(val & 1) result |= 1 << (bits - 1 - bit);
val >>= 1;
}
return result;
}
static void
initialize_crc32 ()
{
int byte;
for (byte = 0; byte < 256; ++ byte)
{
enet_uint32 crc = reflect_crc (byte, 8) << 24;
int offset;
for(offset = 0; offset < 8; ++ offset)
{
if (crc & 0x80000000)
crc = (crc << 1) ^ 0x04c11db7;
else
crc <<= 1;
}
crcTable [byte] = reflect_crc (crc, 32);
}
initializedCRC32 = 1;
}
enet_uint32
enet_crc32 (const ENetBuffer * buffers, size_t bufferCount)
{
enet_uint32 crc = 0xFFFFFFFF;
if (! initializedCRC32) initialize_crc32 ();
while (bufferCount -- > 0)
{
const enet_uint8 * data = (const enet_uint8 *) buffers -> data,
* dataEnd = & data [buffers -> dataLength];
while (data < dataEnd)
{
crc = (crc >> 8) ^ crcTable [(crc & 0xFF) ^ *data++];
}
++ buffers;
}
return ENET_HOST_TO_NET_32 (~ crc);
}
/** @} */
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
/**
@file win32.c
@brief ENet Win32 system specific functions
*/
#ifdef WIN32
#include <time.h>
#define ENET_BUILDING_LIB 1
#include "enet/enet.h"
static enet_uint32 timeBase = 0;
int enet_initialize (void)
{
WORD versionRequested = MAKEWORD (1, 1);
WSADATA wsaData;
if (WSAStartup (versionRequested, & wsaData))
return -1;
if (LOBYTE (wsaData.wVersion) != 1||
HIBYTE (wsaData.wVersion) != 1)
{
WSACleanup ();
return -1;
}
timeBeginPeriod (1);
return 0;
}
void enet_deinitialize (void)
{
timeEndPeriod (1);
WSACleanup ();
}
enet_uint32 enet_time_get (void)
{
return (enet_uint32) timeGetTime () - timeBase;
}
void enet_time_set (enet_uint32 newTimeBase)
{
timeBase = (enet_uint32) timeGetTime () - newTimeBase;
}
int enet_address_set_host (ENetAddress * address, const char * name)
{
struct hostent * hostEntry;
hostEntry = gethostbyname (name);
if (hostEntry == NULL ||
hostEntry -> h_addrtype != AF_INET)
{
unsigned long host = inet_addr (name);
if (host == INADDR_NONE)
return -1;
address -> host = host;
return 0;
}
address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
return 0;
}
int enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
{
char * addr = inet_ntoa (* (struct in_addr *) & address -> host);
if (addr == NULL)
return -1;
strncpy (name, addr, nameLength);
return 0;
}
int enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
{
struct in_addr in;
struct hostent * hostEntry;
in.s_addr = address -> host;
hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
if (hostEntry == NULL)
return enet_address_get_host_ip (address, name, nameLength);
strncpy (name, hostEntry -> h_name, nameLength);
return 0;
}
int enet_socket_bind (ENetSocket socket, const ENetAddress * address)
{
struct sockaddr_in sin;
memset (& sin, 0, sizeof (struct sockaddr_in));
sin.sin_family = AF_INET;
if (address != NULL)
{
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
sin.sin_addr.s_addr = address -> host;
}
else
{
sin.sin_port = 0;
sin.sin_addr.s_addr = INADDR_ANY;
}
return bind (socket,
(struct sockaddr *) & sin,
sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0;
}
int enet_socket_listen (ENetSocket socket, int backlog)
{
return listen (socket, backlog < 0 ? SOMAXCONN : backlog) == SOCKET_ERROR ? -1 : 0;
}
ENetSocket enet_socket_create (ENetSocketType type)
{
return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0);
}
int enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value)
{
int result = SOCKET_ERROR;
switch (option)
{
case ENET_SOCKOPT_NONBLOCK:
{
u_long nonBlocking = (u_long) value;
result = ioctlsocket (socket, FIONBIO, & nonBlocking);
break;
}
case ENET_SOCKOPT_BROADCAST:
result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int));
break;
case ENET_SOCKOPT_REUSEADDR:
result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int));
break;
case ENET_SOCKOPT_RCVBUF:
result = setsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) & value, sizeof (int));
break;
case ENET_SOCKOPT_SNDBUF:
result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int));
break;
case ENET_SOCKOPT_RCVTIMEO:
result = setsockopt (socket, SOL_SOCKET, SO_RCVTIMEO, (char *) & value, sizeof (int));
break;
case ENET_SOCKOPT_SNDTIMEO:
result = setsockopt (socket, SOL_SOCKET, SO_SNDTIMEO, (char *) & value, sizeof (int));
break;
default:
break;
}
return result == SOCKET_ERROR ? -1 : 0;
}
int enet_socket_connect (ENetSocket socket, const ENetAddress * address)
{
struct sockaddr_in sin;
memset (& sin, 0, sizeof (struct sockaddr_in));
sin.sin_family = AF_INET;
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
sin.sin_addr.s_addr = address -> host;
return connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0;
}
ENetSocket enet_socket_accept (ENetSocket socket, ENetAddress * address)
{
SOCKET result;
struct sockaddr_in sin;
int sinLength = sizeof (struct sockaddr_in);
result = accept (socket,
address != NULL ? (struct sockaddr *) & sin : NULL,
address != NULL ? & sinLength : NULL);
if (result == INVALID_SOCKET)
return ENET_SOCKET_NULL;
if (address != NULL)
{
address -> host = (enet_uint32) sin.sin_addr.s_addr;
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
}
return result;
}
void enet_socket_destroy (ENetSocket socket)
{
closesocket (socket);
}
int enet_socket_send (ENetSocket socket,
const ENetAddress * address,
const ENetBuffer * buffers,
size_t bufferCount)
{
struct sockaddr_in sin;
DWORD sentLength;
if (address != NULL)
{
memset (& sin, 0, sizeof (struct sockaddr_in));
sin.sin_family = AF_INET;
sin.sin_port = ENET_HOST_TO_NET_16 (address -> port);
sin.sin_addr.s_addr = address -> host;
}
if (WSASendTo (socket,
(LPWSABUF) buffers,
(DWORD) bufferCount,
& sentLength,
0,
address != NULL ? (struct sockaddr *) & sin : NULL,
address != NULL ? sizeof (struct sockaddr_in) : 0,
NULL,
NULL) == SOCKET_ERROR)
{
if (WSAGetLastError () == WSAEWOULDBLOCK)
return 0;
return -1;
}
return (int) sentLength;
}
int enet_socket_receive (ENetSocket socket,
ENetAddress * address,
ENetBuffer * buffers,
size_t bufferCount)
{
INT sinLength = sizeof (struct sockaddr_in);
DWORD flags = 0,
recvLength;
struct sockaddr_in sin;
if (WSARecvFrom (socket,
(LPWSABUF) buffers,
(DWORD) bufferCount,
& recvLength,
& flags,
address != NULL ? (struct sockaddr *) & sin : NULL,
address != NULL ? & sinLength : NULL,
NULL,
NULL) == SOCKET_ERROR)
{
switch (WSAGetLastError ())
{
case WSAEWOULDBLOCK:
case WSAECONNRESET:
return 0;
}
return -1;
}
if (flags & MSG_PARTIAL)
return -1;
if (address != NULL)
{
address -> host = (enet_uint32) sin.sin_addr.s_addr;
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
}
return (int) recvLength;
}
int enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocketSet * writeSet, enet_uint32 timeout)
{
struct timeval timeVal;
timeVal.tv_sec = timeout / 1000;
timeVal.tv_usec = (timeout % 1000) * 1000;
return select (maxSocket + 1, readSet, writeSet, NULL, & timeVal);
}
int enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout)
{
fd_set readSet, writeSet;
struct timeval timeVal;
int selectCount;
timeVal.tv_sec = timeout / 1000;
timeVal.tv_usec = (timeout % 1000) * 1000;
FD_ZERO (& readSet);
FD_ZERO (& writeSet);
if (* condition & ENET_SOCKET_WAIT_SEND)
FD_SET (socket, & writeSet);
if (* condition & ENET_SOCKET_WAIT_RECEIVE)
FD_SET (socket, & readSet);
selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal);
if (selectCount < 0)
return -1;
* condition = ENET_SOCKET_WAIT_NONE;
if (selectCount == 0)
return 0;
if (FD_ISSET (socket, & writeSet))
* condition |= ENET_SOCKET_WAIT_SEND;
if (FD_ISSET (socket, & readSet))
* condition |= ENET_SOCKET_WAIT_RECEIVE;
return 0;
}
#endif
此差异已折叠。
...@@ -29,13 +29,12 @@ namespace ENetCSTest ...@@ -29,13 +29,12 @@ namespace ENetCSTest
} }
private static async void ServerEvent(ServerHost host, Barrier barrier) private static async void ServerEvent(ServerHost host, Barrier barrier)
{ {
barrier.SignalAndWait();
var peer = await host.AcceptAsync(); var peer = await host.AcceptAsync();
// Client断开,Server端收到Disconnect事件,结束Server线程 // Client断开,Server端收到Disconnect事件,结束Server线程
peer.PeerEvent.Disconnect += ev => host.Stop(); peer.PeerEvent.Disconnect += ev => host.Stop();
barrier.SignalAndWait();
using (var rPacket = await peer.ReadAsync()) using (var rPacket = await peer.ReadAsync())
{ {
Logger.Debug(rPacket.Bytes.ToHex()); Logger.Debug(rPacket.Bytes.ToHex());
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册