Merge pull request #7985 from Faless/enet_godot_sock_squash
Update ENet to use Godot sockets.
This commit is contained in:
commit
296ece2c6a
19 changed files with 423 additions and 1199 deletions
|
@ -31,6 +31,11 @@
|
|||
|
||||
PacketPeerUDP *(*PacketPeerUDP::_create)() = NULL;
|
||||
|
||||
void PacketPeerUDP::set_blocking_mode(bool p_enable) {
|
||||
|
||||
blocking = p_enable;
|
||||
}
|
||||
|
||||
String PacketPeerUDP::_get_packet_ip() const {
|
||||
|
||||
return get_packet_address();
|
||||
|
@ -78,4 +83,6 @@ PacketPeerUDP *PacketPeerUDP::create() {
|
|||
}
|
||||
|
||||
PacketPeerUDP::PacketPeerUDP() {
|
||||
|
||||
blocking = true;
|
||||
}
|
||||
|
|
|
@ -36,6 +36,8 @@ class PacketPeerUDP : public PacketPeer {
|
|||
GDCLASS(PacketPeerUDP, PacketPeer);
|
||||
|
||||
protected:
|
||||
bool blocking;
|
||||
|
||||
static PacketPeerUDP *(*_create)();
|
||||
static void _bind_methods();
|
||||
|
||||
|
@ -44,6 +46,8 @@ protected:
|
|||
Error _set_dest_address(const String &p_address, int p_port);
|
||||
|
||||
public:
|
||||
void set_blocking_mode(bool p_enable);
|
||||
|
||||
virtual Error listen(int p_port, IP_Address p_bind_address = IP_Address("*"), int p_recv_buffer_size = 65536) = 0;
|
||||
virtual void close() = 0;
|
||||
virtual Error wait() = 0;
|
||||
|
|
|
@ -107,10 +107,14 @@ Error PacketPeerUDPPosix::put_packet(const uint8_t *p_buffer, int p_buffer_size)
|
|||
errno = 0;
|
||||
int err;
|
||||
|
||||
_set_sock_blocking(blocking);
|
||||
|
||||
while ((err = sendto(sock, p_buffer, p_buffer_size, 0, (struct sockaddr *)&addr, addr_size)) != p_buffer_size) {
|
||||
|
||||
if (errno != EAGAIN) {
|
||||
return FAILED;
|
||||
} else if (!blocking) {
|
||||
return ERR_UNAVAILABLE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,10 +177,12 @@ Error PacketPeerUDPPosix::_poll(bool p_wait) {
|
|||
return FAILED;
|
||||
}
|
||||
|
||||
_set_sock_blocking(p_wait);
|
||||
|
||||
struct sockaddr_storage from = { 0 };
|
||||
socklen_t len = sizeof(struct sockaddr_storage);
|
||||
int ret;
|
||||
while ((ret = recvfrom(sockfd, recv_buffer, MIN((int)sizeof(recv_buffer), MAX(rb.space_left() - 24, 0)), p_wait ? 0 : MSG_DONTWAIT, (struct sockaddr *)&from, &len)) > 0) {
|
||||
while ((ret = recvfrom(sockfd, recv_buffer, MIN((int)sizeof(recv_buffer), MAX(rb.space_left() - 24, 0)), 0, (struct sockaddr *)&from, &len)) > 0) {
|
||||
|
||||
uint32_t port = 0;
|
||||
|
||||
|
@ -243,9 +249,35 @@ int PacketPeerUDPPosix::_get_socket() {
|
|||
|
||||
sockfd = _socket_create(sock_type, SOCK_DGRAM, IPPROTO_UDP);
|
||||
|
||||
if (sockfd != -1)
|
||||
_set_sock_blocking(false);
|
||||
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
void PacketPeerUDPPosix::_set_sock_blocking(bool p_blocking) {
|
||||
|
||||
if (sock_blocking == p_blocking)
|
||||
return;
|
||||
|
||||
sock_blocking = p_blocking;
|
||||
|
||||
#ifndef NO_FCNTL
|
||||
int opts = fcntl(sockfd, F_GETFL);
|
||||
int ret = 0;
|
||||
if (sock_blocking)
|
||||
ret = fcntl(sockfd, F_SETFL, opts & ~O_NONBLOCK);
|
||||
else
|
||||
ret = fcntl(sockfd, F_SETFL, opts | O_NONBLOCK);
|
||||
if (ret == -1)
|
||||
perror("setting non-block mode");
|
||||
#else
|
||||
int bval = sock_blocking ? 0 : 1;
|
||||
if (ioctl(sockfd, FIONBIO, &bval) == -1)
|
||||
perror("setting non-block mode");
|
||||
#endif
|
||||
}
|
||||
|
||||
void PacketPeerUDPPosix::set_dest_address(const IP_Address &p_address, int p_port) {
|
||||
|
||||
peer_addr = p_address;
|
||||
|
@ -264,6 +296,8 @@ void PacketPeerUDPPosix::make_default() {
|
|||
|
||||
PacketPeerUDPPosix::PacketPeerUDPPosix() {
|
||||
|
||||
blocking = true;
|
||||
sock_blocking = true;
|
||||
sockfd = -1;
|
||||
packet_port = 0;
|
||||
queue_count = 0;
|
||||
|
|
|
@ -47,6 +47,7 @@ class PacketPeerUDPPosix : public PacketPeerUDP {
|
|||
mutable int packet_port;
|
||||
mutable int queue_count;
|
||||
int sockfd;
|
||||
bool sock_blocking;
|
||||
IP::Type sock_type;
|
||||
|
||||
IP_Address peer_addr;
|
||||
|
@ -55,6 +56,7 @@ class PacketPeerUDPPosix : public PacketPeerUDP {
|
|||
_FORCE_INLINE_ int _get_socket();
|
||||
|
||||
static PacketPeerUDP *_create();
|
||||
void _set_sock_blocking(bool p_blocking);
|
||||
virtual Error _poll(bool p_block);
|
||||
|
||||
public:
|
||||
|
|
|
@ -10,6 +10,7 @@ env_enet = env_modules.Clone()
|
|||
if (env['builtin_enet'] != 'no'):
|
||||
thirdparty_dir = "#thirdparty/enet/"
|
||||
thirdparty_sources = [
|
||||
"godot.cpp",
|
||||
"callbacks.c",
|
||||
"compress.c",
|
||||
"host.c",
|
||||
|
@ -17,12 +18,11 @@ if (env['builtin_enet'] != 'no'):
|
|||
"packet.c",
|
||||
"peer.c",
|
||||
"protocol.c",
|
||||
"unix.c",
|
||||
"win32.c",
|
||||
]
|
||||
thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
|
||||
|
||||
env_enet.add_source_files(env.modules_sources, thirdparty_sources)
|
||||
env_enet.Append(CPPPATH=[thirdparty_dir])
|
||||
env_enet.Append(CPPFLAGS=["-DGODOT_ENET"])
|
||||
|
||||
env_enet.add_source_files(env.modules_sources, "*.cpp")
|
||||
|
|
|
@ -53,8 +53,21 @@ Error NetworkedMultiplayerENet::create_server(int p_port, int p_max_clients, int
|
|||
ERR_FAIL_COND_V(active, ERR_ALREADY_IN_USE);
|
||||
|
||||
ENetAddress address;
|
||||
address.host = bind_ip;
|
||||
|
||||
#ifdef GODOT_ENET
|
||||
if (bind_ip.is_wildcard()) {
|
||||
address.wildcard = 1;
|
||||
} else {
|
||||
enet_address_set_ip(&address, bind_ip.get_ipv6(), 16);
|
||||
}
|
||||
#else
|
||||
if (bind_ip.is_wildcard()) {
|
||||
address.host = 0;
|
||||
} else {
|
||||
ERR_FAIL_COND_V(!bind_ip.is_ipv4(), ERR_INVALID_PARAMETER);
|
||||
address.host = *(uint32_t *)bind_ip.get_ipv4();
|
||||
}
|
||||
#endif
|
||||
address.port = p_port;
|
||||
|
||||
host = enet_host_create(&address /* the address to bind the server host to */,
|
||||
|
@ -76,7 +89,6 @@ Error NetworkedMultiplayerENet::create_server(int p_port, int p_max_clients, int
|
|||
Error NetworkedMultiplayerENet::create_client(const IP_Address &p_ip, int p_port, int p_in_bandwidth, int p_out_bandwidth) {
|
||||
|
||||
ERR_FAIL_COND_V(active, ERR_ALREADY_IN_USE);
|
||||
ERR_FAIL_COND_V(!p_ip.is_ipv4(), ERR_INVALID_PARAMETER);
|
||||
|
||||
host = enet_host_create(NULL /* create a client host */,
|
||||
1 /* only allow 1 outgoing connection */,
|
||||
|
@ -89,7 +101,12 @@ Error NetworkedMultiplayerENet::create_client(const IP_Address &p_ip, int p_port
|
|||
_setup_compressor();
|
||||
|
||||
ENetAddress address;
|
||||
address.host = *((uint32_t *)p_ip.get_ipv4());
|
||||
#ifdef GODOT_ENET
|
||||
enet_address_set_ip(&address, p_ip.get_ipv6(), 16);
|
||||
#else
|
||||
ERR_FAIL_COND_V(!p_ip.is_ipv4(), ERR_INVALID_PARAMETER);
|
||||
address.host = *(uint32_t *)p_ip.get_ipv4();
|
||||
#endif
|
||||
address.port = p_port;
|
||||
|
||||
//enet_address_set_host (& address, "localhost");
|
||||
|
@ -146,9 +163,6 @@ void NetworkedMultiplayerENet::poll() {
|
|||
break;
|
||||
}
|
||||
|
||||
IP_Address ip;
|
||||
ip.set_ipv4((uint8_t *)&(event.peer->address.host));
|
||||
|
||||
int *new_id = memnew(int);
|
||||
*new_id = event.data;
|
||||
|
||||
|
@ -657,7 +671,7 @@ NetworkedMultiplayerENet::NetworkedMultiplayerENet() {
|
|||
enet_compressor.decompress = enet_decompress;
|
||||
enet_compressor.destroy = enet_compressor_destroy;
|
||||
|
||||
bind_ip = ENET_HOST_ANY;
|
||||
bind_ip = IP_Address("*");
|
||||
}
|
||||
|
||||
NetworkedMultiplayerENet::~NetworkedMultiplayerENet() {
|
||||
|
@ -668,6 +682,7 @@ NetworkedMultiplayerENet::~NetworkedMultiplayerENet() {
|
|||
// sets IP for ENet to bind when using create_server
|
||||
// if no IP is set, then ENet bind to ENET_HOST_ANY
|
||||
void NetworkedMultiplayerENet::set_bind_ip(const IP_Address &p_ip) {
|
||||
ERR_FAIL_COND(!p_ip.is_ipv4());
|
||||
bind_ip = *(uint32_t *)p_ip.get_ipv4();
|
||||
ERR_FAIL_COND(!p_ip.is_valid() && !p_ip.is_wildcard());
|
||||
|
||||
bind_ip = p_ip;
|
||||
}
|
||||
|
|
|
@ -100,7 +100,7 @@ private:
|
|||
static void enet_compressor_destroy(void *context);
|
||||
void _setup_compressor();
|
||||
|
||||
enet_uint32 bind_ip;
|
||||
IP_Address bind_ip;
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
|
|
@ -82,7 +82,7 @@ Error PacketPeerUDPWinsock::put_packet(const uint8_t *p_buffer, int p_buffer_siz
|
|||
struct sockaddr_storage addr;
|
||||
size_t addr_size = _set_sockaddr(&addr, peer_addr, peer_port, sock_type);
|
||||
|
||||
_set_blocking(true);
|
||||
_set_sock_blocking(blocking);
|
||||
|
||||
errno = 0;
|
||||
int err;
|
||||
|
@ -90,7 +90,9 @@ Error PacketPeerUDPWinsock::put_packet(const uint8_t *p_buffer, int p_buffer_siz
|
|||
|
||||
if (WSAGetLastError() != WSAEWOULDBLOCK) {
|
||||
return FAILED;
|
||||
};
|
||||
} else if (!blocking) {
|
||||
return ERR_UNAVAILABLE;
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
@ -101,15 +103,13 @@ int PacketPeerUDPWinsock::get_max_packet_size() const {
|
|||
return 512; // uhm maybe not
|
||||
}
|
||||
|
||||
void PacketPeerUDPWinsock::_set_blocking(bool p_blocking) {
|
||||
//am no windows expert
|
||||
//hope this is the right thing
|
||||
void PacketPeerUDPWinsock::_set_sock_blocking(bool p_blocking) {
|
||||
|
||||
if (blocking == p_blocking)
|
||||
if (sock_blocking == p_blocking)
|
||||
return;
|
||||
|
||||
blocking = p_blocking;
|
||||
unsigned long par = blocking ? 0 : 1;
|
||||
sock_blocking = p_blocking;
|
||||
unsigned long par = sock_blocking ? 0 : 1;
|
||||
if (ioctlsocket(sockfd, FIONBIO, &par)) {
|
||||
perror("setting non-block mode");
|
||||
//close();
|
||||
|
@ -139,8 +139,6 @@ Error PacketPeerUDPWinsock::listen(int p_port, IP_Address p_bind_address, int p_
|
|||
return ERR_UNAVAILABLE;
|
||||
}
|
||||
|
||||
blocking = true;
|
||||
|
||||
printf("UDP Connection listening on port %i\n", p_port);
|
||||
rb.resize(nearest_shift(p_recv_buffer_size));
|
||||
return OK;
|
||||
|
@ -166,7 +164,7 @@ Error PacketPeerUDPWinsock::_poll(bool p_wait) {
|
|||
return FAILED;
|
||||
}
|
||||
|
||||
_set_blocking(p_wait);
|
||||
_set_sock_blocking(p_wait);
|
||||
|
||||
struct sockaddr_storage from = { 0 };
|
||||
int len = sizeof(struct sockaddr_storage);
|
||||
|
@ -252,6 +250,9 @@ int PacketPeerUDPWinsock::_get_socket() {
|
|||
|
||||
sockfd = _socket_create(sock_type, SOCK_DGRAM, IPPROTO_UDP);
|
||||
|
||||
if (sockfd != -1)
|
||||
_set_sock_blocking(false);
|
||||
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
|
@ -273,6 +274,8 @@ PacketPeerUDP *PacketPeerUDPWinsock::_create() {
|
|||
|
||||
PacketPeerUDPWinsock::PacketPeerUDPWinsock() {
|
||||
|
||||
blocking = true;
|
||||
sock_blocking = true;
|
||||
sockfd = -1;
|
||||
packet_port = 0;
|
||||
queue_count = 0;
|
||||
|
|
|
@ -45,6 +45,7 @@ class PacketPeerUDPWinsock : public PacketPeerUDP {
|
|||
mutable int packet_port;
|
||||
mutable int queue_count;
|
||||
int sockfd;
|
||||
bool sock_blocking;
|
||||
IP::Type sock_type;
|
||||
|
||||
IP_Address peer_addr;
|
||||
|
@ -54,8 +55,7 @@ class PacketPeerUDPWinsock : public PacketPeerUDP {
|
|||
|
||||
static PacketPeerUDP *_create();
|
||||
|
||||
bool blocking;
|
||||
void _set_blocking(bool p_blocking);
|
||||
void _set_sock_blocking(bool p_blocking);
|
||||
|
||||
Error _poll(bool p_wait);
|
||||
|
||||
|
|
15
thirdparty/README.md
vendored
15
thirdparty/README.md
vendored
|
@ -16,13 +16,18 @@ TODO.
|
|||
|
||||
Files extracted from upstream source:
|
||||
|
||||
- all .c files in the main directory
|
||||
- the include/enet/ folder as enet/
|
||||
- all .c files in the main directory (except unix.c win32.c)
|
||||
- the include/enet/ folder as enet/ (except unix.h win32.h)
|
||||
- LICENSE file
|
||||
|
||||
Important: Some files have been modified by Godot developers so that they work
|
||||
for all platforms (especially UWP). Check the diff with the 1.3.13 tarball
|
||||
before the next update.
|
||||
Important: enet.h, host.c, protocol.c have been slightly modified
|
||||
to be usable by godot socket implementation and allow IPv6.
|
||||
Two files (godot.cpp and enet/godot.h) have been added to provide
|
||||
enet socket implementation using Godot classes.
|
||||
It is still possible to build against a system wide ENet but doing so
|
||||
will limit it's functionality to IPv4 only.
|
||||
Check the diff of enet.h, protocol.c, and host.c with the 1.3.13
|
||||
tarball before the next update.
|
||||
|
||||
|
||||
## fonts
|
||||
|
|
21
thirdparty/enet/enet/enet.h
vendored
21
thirdparty/enet/enet/enet.h
vendored
|
@ -12,11 +12,7 @@ extern "C"
|
|||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "enet/win32.h"
|
||||
#else
|
||||
#include "enet/unix.h"
|
||||
#endif
|
||||
#include "enet/godot.h"
|
||||
|
||||
#include "enet/types.h"
|
||||
#include "enet/protocol.h"
|
||||
|
@ -72,7 +68,6 @@ typedef enum _ENetSocketShutdown
|
|||
ENET_SOCKET_SHUTDOWN_READ_WRITE = 2
|
||||
} ENetSocketShutdown;
|
||||
|
||||
#define ENET_HOST_ANY 0
|
||||
#define ENET_HOST_BROADCAST 0xFFFFFFFFU
|
||||
#define ENET_PORT_ANY 0
|
||||
|
||||
|
@ -88,9 +83,11 @@ typedef enum _ENetSocketShutdown
|
|||
*/
|
||||
typedef struct _ENetAddress
|
||||
{
|
||||
enet_uint32 host;
|
||||
uint8_t host[16];
|
||||
enet_uint16 port;
|
||||
uint8_t wildcard;
|
||||
} ENetAddress;
|
||||
#define enet_host_equal(host_a, host_b) (memcmp(&host_a, &host_b,16) == 0)
|
||||
|
||||
/**
|
||||
* Packet flag bit constants.
|
||||
|
@ -519,6 +516,16 @@ ENET_API int enet_socketset_select (ENetSocket, ENetSocketSet *, ENetSock
|
|||
*/
|
||||
ENET_API int enet_address_set_host (ENetAddress * address, const char * hostName);
|
||||
|
||||
/** Sets the host field in the address parameter from ip struct.
|
||||
@param address destination to store resolved address
|
||||
@param ip the ip struct to read from
|
||||
@param size the size of the ip struct.
|
||||
@retval 0 on success
|
||||
@retval != 0 on failure
|
||||
@returns the address of the given ip in address on success.
|
||||
*/
|
||||
ENET_API void enet_address_set_ip(ENetAddress * address, const uint8_t * ip, size_t size);
|
||||
|
||||
/** Gives the printable form of the IP address specified in the address parameter.
|
||||
@param address address printed
|
||||
@param hostName destination for name, must not be NULL
|
||||
|
|
71
thirdparty/enet/enet/godot.h
vendored
Normal file
71
thirdparty/enet/enet/godot.h
vendored
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*************************************************************************/
|
||||
/* godot.h */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
/**
|
||||
@file godot.h
|
||||
@brief ENet Godot header
|
||||
*/
|
||||
|
||||
#ifndef __ENET_GODOT_H__
|
||||
#define __ENET_GODOT_H__
|
||||
|
||||
#ifdef WINDOWS_ENABLED
|
||||
#include <stdint.h>
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
#ifdef UNIX_ENABLED
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#ifdef MSG_MAXIOVLEN
|
||||
#define ENET_BUFFER_MAXIMUM MSG_MAXIOVLEN
|
||||
#endif
|
||||
|
||||
typedef void *ENetSocket;
|
||||
|
||||
#define ENET_SOCKET_NULL NULL
|
||||
|
||||
#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_32(value) (htonl(value)) /**< macro that converts host to net byte-order of a 32-bit value */
|
||||
|
||||
#define ENET_NET_TO_HOST_16(value) (ntohs(value)) /**< macro that converts net to host byte-order of a 16-bit value */
|
||||
#define ENET_NET_TO_HOST_32(value) (ntohl(value)) /**< macro that converts net to host byte-order of a 32-bit value */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *data;
|
||||
size_t dataLength;
|
||||
} ENetBuffer;
|
||||
|
||||
#define ENET_CALLBACK
|
||||
|
||||
#define ENET_API extern
|
||||
|
||||
typedef void ENetSocketSet;
|
||||
|
||||
#endif /* __ENET_GODOT_H__ */
|
47
thirdparty/enet/enet/unix.h
vendored
47
thirdparty/enet/enet/unix.h
vendored
|
@ -1,47 +0,0 @@
|
|||
/**
|
||||
@file unix.h
|
||||
@brief ENet Unix header
|
||||
*/
|
||||
#ifndef __ENET_UNIX_H__
|
||||
#define __ENET_UNIX_H__
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef MSG_MAXIOVLEN
|
||||
#define ENET_BUFFER_MAXIMUM MSG_MAXIOVLEN
|
||||
#endif
|
||||
|
||||
typedef int ENetSocket;
|
||||
|
||||
#define 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_32(value) (htonl (value)) /**< macro that converts host to net byte-order of a 32-bit value */
|
||||
|
||||
#define ENET_NET_TO_HOST_16(value) (ntohs (value)) /**< macro that converts net to host byte-order of a 16-bit value */
|
||||
#define ENET_NET_TO_HOST_32(value) (ntohl (value)) /**< macro that converts net to host byte-order of a 32-bit value */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void * data;
|
||||
size_t dataLength;
|
||||
} ENetBuffer;
|
||||
|
||||
#define ENET_CALLBACK
|
||||
|
||||
#define ENET_API extern
|
||||
|
||||
typedef fd_set ENetSocketSet;
|
||||
|
||||
#define ENET_SOCKETSET_EMPTY(sockset) FD_ZERO (& (sockset))
|
||||
#define ENET_SOCKETSET_ADD(sockset, socket) FD_SET (socket, & (sockset))
|
||||
#define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLR (socket, & (sockset))
|
||||
#define ENET_SOCKETSET_CHECK(sockset, socket) FD_ISSET (socket, & (sockset))
|
||||
|
||||
#endif /* __ENET_UNIX_H__ */
|
||||
|
57
thirdparty/enet/enet/win32.h
vendored
57
thirdparty/enet/enet/win32.h
vendored
|
@ -1,57 +0,0 @@
|
|||
/**
|
||||
@file win32.h
|
||||
@brief ENet Win32 header
|
||||
*/
|
||||
#ifndef __ENET_WIN32_H__
|
||||
#define __ENET_WIN32_H__
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#ifdef ENET_BUILDING_LIB
|
||||
#pragma warning (disable: 4267) // size_t to int conversion
|
||||
#pragma warning (disable: 4244) // 64bit to 32bit int
|
||||
#pragma warning (disable: 4018) // signed/unsigned mismatch
|
||||
#pragma warning (disable: 4146) // unary minus operator applied to unsigned type
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <winsock2.h>
|
||||
|
||||
typedef SOCKET ENetSocket;
|
||||
|
||||
#define ENET_SOCKET_NULL INVALID_SOCKET
|
||||
|
||||
#define ENET_HOST_TO_NET_16(value) (htons (value))
|
||||
#define ENET_HOST_TO_NET_32(value) (htonl (value))
|
||||
|
||||
#define ENET_NET_TO_HOST_16(value) (ntohs (value))
|
||||
#define ENET_NET_TO_HOST_32(value) (ntohl (value))
|
||||
|
||||
typedef struct
|
||||
{
|
||||
size_t dataLength;
|
||||
void * data;
|
||||
} ENetBuffer;
|
||||
|
||||
#define ENET_CALLBACK __cdecl
|
||||
|
||||
#ifdef ENET_DLL
|
||||
#ifdef ENET_BUILDING_LIB
|
||||
#define ENET_API __declspec( dllexport )
|
||||
#else
|
||||
#define ENET_API __declspec( dllimport )
|
||||
#endif /* ENET_BUILDING_LIB */
|
||||
#else /* !ENET_DLL */
|
||||
#define ENET_API extern
|
||||
#endif /* ENET_DLL */
|
||||
|
||||
typedef fd_set ENetSocketSet;
|
||||
|
||||
#define ENET_SOCKETSET_EMPTY(sockset) FD_ZERO (& (sockset))
|
||||
#define ENET_SOCKETSET_ADD(sockset, socket) FD_SET (socket, & (sockset))
|
||||
#define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLR (socket, & (sockset))
|
||||
#define ENET_SOCKETSET_CHECK(sockset, socket) FD_ISSET (socket, & (sockset))
|
||||
|
||||
#endif /* __ENET_WIN32_H__ */
|
||||
|
||||
|
232
thirdparty/enet/godot.cpp
vendored
Normal file
232
thirdparty/enet/godot.cpp
vendored
Normal file
|
@ -0,0 +1,232 @@
|
|||
/*************************************************************************/
|
||||
/* godot.cpp */
|
||||
/*************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* http://www.godotengine.org */
|
||||
/*************************************************************************/
|
||||
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
/**
|
||||
@file godot.cpp
|
||||
@brief ENet Godot specific functions
|
||||
*/
|
||||
|
||||
#include "core/io/ip.h"
|
||||
#include "core/io/packet_peer_udp.h"
|
||||
#include "core/os/os.h"
|
||||
|
||||
// This must be last for windows to compile (tested with MinGW)
|
||||
#include "enet/enet.h"
|
||||
|
||||
static enet_uint32 timeBase = 0;
|
||||
|
||||
int enet_initialize(void) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void enet_deinitialize(void) {
|
||||
}
|
||||
|
||||
enet_uint32 enet_host_random_seed(void) {
|
||||
|
||||
return (enet_uint32)OS::get_singleton()->get_unix_time();
|
||||
}
|
||||
|
||||
enet_uint32 enet_time_get(void) {
|
||||
|
||||
return OS::get_singleton()->get_ticks_msec() - timeBase;
|
||||
}
|
||||
|
||||
void enet_time_set(enet_uint32 newTimeBase) {
|
||||
|
||||
timeBase = OS::get_singleton()->get_ticks_msec() - newTimeBase;
|
||||
}
|
||||
|
||||
int enet_address_set_host(ENetAddress *address, const char *name) {
|
||||
|
||||
IP_Address ip = IP::get_singleton()->resolve_hostname(name);
|
||||
ERR_FAIL_COND_V(!ip.is_valid(), -1);
|
||||
|
||||
enet_address_set_ip(address, ip.get_ipv6(), 16);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void enet_address_set_ip(ENetAddress *address, const uint8_t *ip, size_t size) {
|
||||
|
||||
int len = size > 16 ? 16 : size;
|
||||
memset(address->host, 0, 16);
|
||||
memcpy(address->host, ip, len);
|
||||
}
|
||||
|
||||
int enet_address_get_host_ip(const ENetAddress *address, char *name, size_t nameLength) {
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int enet_address_get_host(const ENetAddress *address, char *name, size_t nameLength) {
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int enet_socket_bind(ENetSocket socket, const ENetAddress *address) {
|
||||
|
||||
IP_Address ip;
|
||||
if (address->wildcard) {
|
||||
ip = IP_Address("*");
|
||||
} else {
|
||||
ip.set_ipv6(address->host);
|
||||
}
|
||||
|
||||
PacketPeerUDP *sock = (PacketPeerUDP *)socket;
|
||||
if (sock->listen(address->port, ip) != OK) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ENetSocket enet_socket_create(ENetSocketType type) {
|
||||
|
||||
PacketPeerUDP *socket = PacketPeerUDP::create();
|
||||
socket->set_blocking_mode(false);
|
||||
|
||||
return socket;
|
||||
}
|
||||
|
||||
void enet_socket_destroy(ENetSocket socket) {
|
||||
PacketPeerUDP *sock = (PacketPeerUDP *)socket;
|
||||
sock->close();
|
||||
memdelete(sock);
|
||||
}
|
||||
|
||||
int enet_socket_send(ENetSocket socket, const ENetAddress *address, const ENetBuffer *buffers, size_t bufferCount) {
|
||||
|
||||
ERR_FAIL_COND_V(address == NULL, -1);
|
||||
|
||||
PacketPeerUDP *sock = (PacketPeerUDP *)socket;
|
||||
IP_Address dest;
|
||||
Error err;
|
||||
size_t i = 0;
|
||||
|
||||
dest.set_ipv6(address->host);
|
||||
sock->set_dest_address(dest, address->port);
|
||||
|
||||
// Create a single packet.
|
||||
PoolVector<uint8_t> out;
|
||||
PoolVector<uint8_t>::Write w;
|
||||
int size = 0;
|
||||
int pos = 0;
|
||||
for (i = 0; i < bufferCount; i++) {
|
||||
size += buffers[i].dataLength;
|
||||
}
|
||||
|
||||
out.resize(size);
|
||||
w = out.write();
|
||||
for (i = 0; i < bufferCount; i++) {
|
||||
memcpy(&w[pos], buffers[i].data, buffers[i].dataLength);
|
||||
pos += buffers[i].dataLength;
|
||||
}
|
||||
|
||||
err = sock->put_packet((const uint8_t *)&w[0], size);
|
||||
if (err != OK) {
|
||||
|
||||
if (err == ERR_UNAVAILABLE) { // blocking call
|
||||
return 0;
|
||||
}
|
||||
|
||||
WARN_PRINT("Sending failed!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int enet_socket_receive(ENetSocket socket, ENetAddress *address, ENetBuffer *buffers, size_t bufferCount) {
|
||||
|
||||
ERR_FAIL_COND_V(bufferCount != 1, -1);
|
||||
|
||||
PacketPeerUDP *sock = (PacketPeerUDP *)socket;
|
||||
|
||||
if (sock->get_available_packet_count() == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const uint8_t *buffer;
|
||||
int buffer_size;
|
||||
Error err = sock->get_packet(&buffer, buffer_size);
|
||||
if (err)
|
||||
return -1;
|
||||
|
||||
copymem(buffers[0].data, buffer, buffer_size);
|
||||
|
||||
enet_address_set_ip(address, sock->get_packet_address().get_ipv6(), 16);
|
||||
address->port = sock->get_packet_port();
|
||||
|
||||
return buffer_size;
|
||||
}
|
||||
|
||||
// Not implemented
|
||||
int enet_socket_wait(ENetSocket socket, enet_uint32 *condition, enet_uint32 timeout) {
|
||||
|
||||
return 0; // do we need this function?
|
||||
}
|
||||
|
||||
int enet_socket_get_address(ENetSocket socket, ENetAddress *address) {
|
||||
|
||||
return -1; // do we need this function?
|
||||
}
|
||||
|
||||
int enet_socketset_select(ENetSocket maxSocket, ENetSocketSet *readSet, ENetSocketSet *writeSet, enet_uint32 timeout) {
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int enet_socket_listen(ENetSocket socket, int backlog) {
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int enet_socket_set_option(ENetSocket socket, ENetSocketOption option, int value) {
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int enet_socket_get_option(ENetSocket socket, ENetSocketOption option, int *value) {
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int enet_socket_connect(ENetSocket socket, const ENetAddress *address) {
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
ENetSocket enet_socket_accept(ENetSocket socket, ENetAddress *address) {
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int enet_socket_shutdown(ENetSocket socket, ENetSocketShutdown how) {
|
||||
|
||||
return -1;
|
||||
}
|
2
thirdparty/enet/host.c
vendored
2
thirdparty/enet/host.c
vendored
|
@ -87,7 +87,7 @@ enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelL
|
|||
host -> commandCount = 0;
|
||||
host -> bufferCount = 0;
|
||||
host -> checksum = NULL;
|
||||
host -> receivedAddress.host = ENET_HOST_ANY;
|
||||
memset(host -> receivedAddress.host, 0, 16);
|
||||
host -> receivedAddress.port = 0;
|
||||
host -> receivedData = NULL;
|
||||
host -> receivedDataLength = 0;
|
||||
|
|
9
thirdparty/enet/protocol.c
vendored
9
thirdparty/enet/protocol.c
vendored
|
@ -299,7 +299,7 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet
|
|||
}
|
||||
else
|
||||
if (currentPeer -> state != ENET_PEER_STATE_CONNECTING &&
|
||||
currentPeer -> address.host == host -> receivedAddress.host)
|
||||
enet_host_equal(currentPeer -> address.host, host -> receivedAddress.host))
|
||||
{
|
||||
if (currentPeer -> address.port == host -> receivedAddress.port &&
|
||||
currentPeer -> connectID == command -> connect.connectID)
|
||||
|
@ -1011,9 +1011,8 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
|
|||
|
||||
if (peer -> state == ENET_PEER_STATE_DISCONNECTED ||
|
||||
peer -> state == ENET_PEER_STATE_ZOMBIE ||
|
||||
((host -> receivedAddress.host != peer -> address.host ||
|
||||
host -> receivedAddress.port != peer -> address.port) &&
|
||||
peer -> address.host != ENET_HOST_BROADCAST) ||
|
||||
(!enet_host_equal(host -> receivedAddress.host, peer -> address.host) ||
|
||||
host -> receivedAddress.port != peer -> address.port) ||
|
||||
(peer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID &&
|
||||
sessionID != peer -> incomingSessionID))
|
||||
return 0;
|
||||
|
@ -1055,7 +1054,7 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
|
|||
|
||||
if (peer != NULL)
|
||||
{
|
||||
peer -> address.host = host -> receivedAddress.host;
|
||||
enet_address_set_ip(&(peer -> address), host -> receivedAddress.host, 16);
|
||||
peer -> address.port = host -> receivedAddress.port;
|
||||
peer -> incomingDataTotal += host -> receivedDataLength;
|
||||
}
|
||||
|
|
616
thirdparty/enet/unix.c
vendored
616
thirdparty/enet/unix.c
vendored
|
@ -1,616 +0,0 @@
|
|||
/**
|
||||
@file unix.c
|
||||
@brief ENet Unix system specific functions
|
||||
*/
|
||||
#ifndef _WIN32
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/time.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
|
||||
#define ENET_BUILDING_LIB 1
|
||||
#include "enet/enet.h"
|
||||
|
||||
//@godot: added this since enet takes them fromt he build system
|
||||
#define HAS_POLL
|
||||
#define HAS_FCNTL
|
||||
#define HAS_SOCKLEN_T
|
||||
|
||||
|
||||
#ifdef __APPLE__
|
||||
#ifdef HAS_POLL
|
||||
#undef HAS_POLL
|
||||
#endif
|
||||
#ifndef HAS_FCNTL
|
||||
#define HAS_FCNTL 1
|
||||
#endif
|
||||
#ifndef HAS_INET_PTON
|
||||
#define HAS_INET_PTON 1
|
||||
#endif
|
||||
#ifndef HAS_INET_NTOP
|
||||
#define HAS_INET_NTOP 1
|
||||
#endif
|
||||
#ifndef HAS_MSGHDR_FLAGS
|
||||
#define HAS_MSGHDR_FLAGS 1
|
||||
#endif
|
||||
#ifndef HAS_SOCKLEN_T
|
||||
#define HAS_SOCKLEN_T 1
|
||||
#endif
|
||||
#ifndef HAS_GETADDRINFO
|
||||
#define HAS_GETADDRINFO 1
|
||||
#endif
|
||||
#ifndef HAS_GETNAMEINFO
|
||||
#define HAS_GETNAMEINFO 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAS_FCNTL
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAS_POLL
|
||||
#include <sys/poll.h>
|
||||
#endif
|
||||
|
||||
#ifndef HAS_SOCKLEN_T
|
||||
typedef int socklen_t;
|
||||
#endif
|
||||
|
||||
#ifndef MSG_NOSIGNAL
|
||||
#define MSG_NOSIGNAL 0
|
||||
#endif
|
||||
|
||||
static enet_uint32 timeBase = 0;
|
||||
|
||||
int
|
||||
enet_initialize (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
enet_deinitialize (void)
|
||||
{
|
||||
}
|
||||
|
||||
enet_uint32
|
||||
enet_host_random_seed (void)
|
||||
{
|
||||
return (enet_uint32) time (NULL);
|
||||
}
|
||||
|
||||
enet_uint32
|
||||
enet_time_get (void)
|
||||
{
|
||||
struct timeval timeVal;
|
||||
|
||||
gettimeofday (& timeVal, NULL);
|
||||
|
||||
return timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - timeBase;
|
||||
}
|
||||
|
||||
void
|
||||
enet_time_set (enet_uint32 newTimeBase)
|
||||
{
|
||||
struct timeval timeVal;
|
||||
|
||||
gettimeofday (& timeVal, NULL);
|
||||
|
||||
timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase;
|
||||
}
|
||||
|
||||
int
|
||||
enet_address_set_host (ENetAddress * address, const char * name)
|
||||
{
|
||||
#ifdef HAS_GETADDRINFO
|
||||
struct addrinfo hints, * resultList = NULL, * result = NULL;
|
||||
|
||||
memset (& hints, 0, sizeof (hints));
|
||||
hints.ai_family = AF_INET;
|
||||
|
||||
if (getaddrinfo (name, NULL, NULL, & resultList) != 0)
|
||||
return -1;
|
||||
|
||||
for (result = resultList; result != NULL; result = result -> ai_next)
|
||||
{
|
||||
if (result -> ai_family == AF_INET && result -> ai_addr != NULL && result -> ai_addrlen >= sizeof (struct sockaddr_in))
|
||||
{
|
||||
struct sockaddr_in * sin = (struct sockaddr_in *) result -> ai_addr;
|
||||
|
||||
address -> host = sin -> sin_addr.s_addr;
|
||||
|
||||
freeaddrinfo (resultList);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (resultList != NULL)
|
||||
freeaddrinfo (resultList);
|
||||
#else
|
||||
struct hostent * hostEntry = NULL;
|
||||
#ifdef HAS_GETHOSTBYNAME_R
|
||||
struct hostent hostData;
|
||||
char buffer [2048];
|
||||
int errnum;
|
||||
|
||||
#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
|
||||
gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
|
||||
#else
|
||||
hostEntry = gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & errnum);
|
||||
#endif
|
||||
#else
|
||||
hostEntry = gethostbyname (name);
|
||||
#endif
|
||||
|
||||
if (hostEntry != NULL && hostEntry -> h_addrtype == AF_INET)
|
||||
{
|
||||
address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0];
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAS_INET_PTON
|
||||
if (! inet_pton (AF_INET, name, & address -> host))
|
||||
#else
|
||||
if (! inet_aton (name, (struct in_addr *) & address -> host))
|
||||
#endif
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength)
|
||||
{
|
||||
#ifdef HAS_INET_NTOP
|
||||
if (inet_ntop (AF_INET, & address -> host, name, nameLength) == NULL)
|
||||
#else
|
||||
char * addr = inet_ntoa (* (struct in_addr *) & address -> host);
|
||||
if (addr != NULL)
|
||||
{
|
||||
size_t addrLen = strlen(addr);
|
||||
if (addrLen >= nameLength)
|
||||
return -1;
|
||||
memcpy (name, addr, addrLen + 1);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength)
|
||||
{
|
||||
#ifdef HAS_GETNAMEINFO
|
||||
struct sockaddr_in sin;
|
||||
int err;
|
||||
|
||||
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;
|
||||
|
||||
err = getnameinfo ((struct sockaddr *) & sin, sizeof (sin), name, nameLength, NULL, 0, NI_NAMEREQD);
|
||||
if (! err)
|
||||
{
|
||||
if (name != NULL && nameLength > 0 && ! memchr (name, '\0', nameLength))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
if (err != EAI_NONAME)
|
||||
return -1;
|
||||
#else
|
||||
struct in_addr in;
|
||||
struct hostent * hostEntry = NULL;
|
||||
#ifdef HAS_GETHOSTBYADDR_R
|
||||
struct hostent hostData;
|
||||
char buffer [2048];
|
||||
int errnum;
|
||||
|
||||
in.s_addr = address -> host;
|
||||
|
||||
#if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
|
||||
gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum);
|
||||
#else
|
||||
hostEntry = gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & errnum);
|
||||
#endif
|
||||
#else
|
||||
in.s_addr = address -> host;
|
||||
|
||||
hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET);
|
||||
#endif
|
||||
|
||||
if (hostEntry != NULL)
|
||||
{
|
||||
size_t hostLen = strlen (hostEntry -> h_name);
|
||||
if (hostLen >= nameLength)
|
||||
return -1;
|
||||
memcpy (name, hostEntry -> h_name, hostLen + 1);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return enet_address_get_host_ip (address, name, nameLength);
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_get_address (ENetSocket socket, ENetAddress * address)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
socklen_t sinLength = sizeof (struct sockaddr_in);
|
||||
|
||||
if (getsockname (socket, (struct sockaddr *) & sin, & sinLength) == -1)
|
||||
return -1;
|
||||
|
||||
address -> host = (enet_uint32) sin.sin_addr.s_addr;
|
||||
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_listen (ENetSocket socket, int backlog)
|
||||
{
|
||||
return listen (socket, backlog < 0 ? SOMAXCONN : backlog);
|
||||
}
|
||||
|
||||
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 = -1;
|
||||
switch (option)
|
||||
{
|
||||
case ENET_SOCKOPT_NONBLOCK:
|
||||
#ifdef HAS_FCNTL
|
||||
result = fcntl (socket, F_SETFL, (value ? O_NONBLOCK : 0) | (fcntl (socket, F_GETFL) & ~O_NONBLOCK));
|
||||
#else
|
||||
result = ioctl (socket, FIONBIO, & value);
|
||||
#endif
|
||||
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:
|
||||
{
|
||||
struct timeval timeVal;
|
||||
timeVal.tv_sec = value / 1000;
|
||||
timeVal.tv_usec = (value % 1000) * 1000;
|
||||
result = setsockopt (socket, SOL_SOCKET, SO_RCVTIMEO, (char *) & timeVal, sizeof (struct timeval));
|
||||
break;
|
||||
}
|
||||
|
||||
case ENET_SOCKOPT_SNDTIMEO:
|
||||
{
|
||||
struct timeval timeVal;
|
||||
timeVal.tv_sec = value / 1000;
|
||||
timeVal.tv_usec = (value % 1000) * 1000;
|
||||
result = setsockopt (socket, SOL_SOCKET, SO_SNDTIMEO, (char *) & timeVal, sizeof (struct timeval));
|
||||
break;
|
||||
}
|
||||
|
||||
case ENET_SOCKOPT_NODELAY:
|
||||
result = setsockopt (socket, IPPROTO_TCP, TCP_NODELAY, (char *) & value, sizeof (int));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result == -1 ? -1 : 0;
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_get_option (ENetSocket socket, ENetSocketOption option, int * value)
|
||||
{
|
||||
int result = -1;
|
||||
socklen_t len;
|
||||
switch (option)
|
||||
{
|
||||
case ENET_SOCKOPT_ERROR:
|
||||
len = sizeof (int);
|
||||
result = getsockopt (socket, SOL_SOCKET, SO_ERROR, value, & len);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result == -1 ? -1 : 0;
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_connect (ENetSocket socket, const ENetAddress * address)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
int result;
|
||||
|
||||
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;
|
||||
|
||||
result = connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in));
|
||||
if (result == -1 && errno == EINPROGRESS)
|
||||
return 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ENetSocket
|
||||
enet_socket_accept (ENetSocket socket, ENetAddress * address)
|
||||
{
|
||||
int result;
|
||||
struct sockaddr_in sin;
|
||||
socklen_t sinLength = sizeof (struct sockaddr_in);
|
||||
|
||||
result = accept (socket,
|
||||
address != NULL ? (struct sockaddr *) & sin : NULL,
|
||||
address != NULL ? & sinLength : NULL);
|
||||
|
||||
if (result == -1)
|
||||
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;
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_shutdown (ENetSocket socket, ENetSocketShutdown how)
|
||||
{
|
||||
return shutdown (socket, (int) how);
|
||||
}
|
||||
|
||||
void
|
||||
enet_socket_destroy (ENetSocket socket)
|
||||
{
|
||||
if (socket != -1)
|
||||
close (socket);
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_send (ENetSocket socket,
|
||||
const ENetAddress * address,
|
||||
const ENetBuffer * buffers,
|
||||
size_t bufferCount)
|
||||
{
|
||||
struct msghdr msgHdr;
|
||||
struct sockaddr_in sin;
|
||||
int sentLength;
|
||||
|
||||
memset (& msgHdr, 0, sizeof (struct msghdr));
|
||||
|
||||
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;
|
||||
|
||||
msgHdr.msg_name = & sin;
|
||||
msgHdr.msg_namelen = sizeof (struct sockaddr_in);
|
||||
}
|
||||
|
||||
msgHdr.msg_iov = (struct iovec *) buffers;
|
||||
msgHdr.msg_iovlen = bufferCount;
|
||||
|
||||
sentLength = sendmsg (socket, & msgHdr, MSG_NOSIGNAL);
|
||||
|
||||
if (sentLength == -1)
|
||||
{
|
||||
if (errno == EWOULDBLOCK)
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
return sentLength;
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_receive (ENetSocket socket,
|
||||
ENetAddress * address,
|
||||
ENetBuffer * buffers,
|
||||
size_t bufferCount)
|
||||
{
|
||||
struct msghdr msgHdr;
|
||||
struct sockaddr_in sin;
|
||||
int recvLength;
|
||||
|
||||
memset (& msgHdr, 0, sizeof (struct msghdr));
|
||||
|
||||
if (address != NULL)
|
||||
{
|
||||
msgHdr.msg_name = & sin;
|
||||
msgHdr.msg_namelen = sizeof (struct sockaddr_in);
|
||||
}
|
||||
|
||||
msgHdr.msg_iov = (struct iovec *) buffers;
|
||||
msgHdr.msg_iovlen = bufferCount;
|
||||
|
||||
recvLength = recvmsg (socket, & msgHdr, MSG_NOSIGNAL);
|
||||
|
||||
if (recvLength == -1)
|
||||
{
|
||||
if (errno == EWOULDBLOCK)
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef HAS_MSGHDR_FLAGS
|
||||
if (msgHdr.msg_flags & MSG_TRUNC)
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
if (address != NULL)
|
||||
{
|
||||
address -> host = (enet_uint32) sin.sin_addr.s_addr;
|
||||
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
|
||||
}
|
||||
|
||||
return 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)
|
||||
{
|
||||
#ifdef HAS_POLL
|
||||
struct pollfd pollSocket;
|
||||
int pollCount;
|
||||
|
||||
pollSocket.fd = socket;
|
||||
pollSocket.events = 0;
|
||||
|
||||
if (* condition & ENET_SOCKET_WAIT_SEND)
|
||||
pollSocket.events |= POLLOUT;
|
||||
|
||||
if (* condition & ENET_SOCKET_WAIT_RECEIVE)
|
||||
pollSocket.events |= POLLIN;
|
||||
|
||||
pollCount = poll (& pollSocket, 1, timeout);
|
||||
|
||||
if (pollCount < 0)
|
||||
{
|
||||
if (errno == EINTR && * condition & ENET_SOCKET_WAIT_INTERRUPT)
|
||||
{
|
||||
* condition = ENET_SOCKET_WAIT_INTERRUPT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
* condition = ENET_SOCKET_WAIT_NONE;
|
||||
|
||||
if (pollCount == 0)
|
||||
return 0;
|
||||
|
||||
if (pollSocket.revents & POLLOUT)
|
||||
* condition |= ENET_SOCKET_WAIT_SEND;
|
||||
|
||||
if (pollSocket.revents & POLLIN)
|
||||
* condition |= ENET_SOCKET_WAIT_RECEIVE;
|
||||
|
||||
return 0;
|
||||
#else
|
||||
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)
|
||||
{
|
||||
if (errno == EINTR && * condition & ENET_SOCKET_WAIT_INTERRUPT)
|
||||
{
|
||||
* condition = ENET_SOCKET_WAIT_INTERRUPT;
|
||||
|
||||
return 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
|
||||
}
|
||||
|
||||
#endif
|
||||
|
435
thirdparty/enet/win32.c
vendored
435
thirdparty/enet/win32.c
vendored
|
@ -1,435 +0,0 @@
|
|||
/**
|
||||
@file win32.c
|
||||
@brief ENet Win32 system specific functions
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
|
||||
#define ENET_BUILDING_LIB 0
|
||||
#include "enet/enet.h"
|
||||
#include <windows.h>
|
||||
#include <mmsystem.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;
|
||||
}
|
||||
|
||||
#ifndef UWP_ENABLED
|
||||
timeBeginPeriod (1);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
enet_deinitialize (void)
|
||||
{
|
||||
#ifndef UWP_ENABLED
|
||||
timeEndPeriod (1);
|
||||
#endif
|
||||
|
||||
WSACleanup ();
|
||||
}
|
||||
|
||||
#ifdef UWP_ENABLED
|
||||
enet_uint32
|
||||
timeGetTime() {
|
||||
ULONGLONG ticks = GetTickCount64();
|
||||
return (enet_uint32)ticks;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
enet_uint32
|
||||
enet_host_random_seed (void)
|
||||
{
|
||||
return (enet_uint32) timeGetTime ();
|
||||
}
|
||||
|
||||
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;
|
||||
else
|
||||
{
|
||||
size_t addrLen = strlen(addr);
|
||||
if (addrLen >= nameLength)
|
||||
return -1;
|
||||
memcpy (name, addr, addrLen + 1);
|
||||
}
|
||||
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);
|
||||
else
|
||||
{
|
||||
size_t hostLen = strlen (hostEntry -> h_name);
|
||||
if (hostLen >= nameLength)
|
||||
return -1;
|
||||
memcpy (name, hostEntry -> h_name, hostLen + 1);
|
||||
}
|
||||
|
||||
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_get_address (ENetSocket socket, ENetAddress * address)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
int sinLength = sizeof (struct sockaddr_in);
|
||||
|
||||
if (getsockname (socket, (struct sockaddr *) & sin, & sinLength) == -1)
|
||||
return -1;
|
||||
|
||||
address -> host = (enet_uint32) sin.sin_addr.s_addr;
|
||||
address -> port = ENET_NET_TO_HOST_16 (sin.sin_port);
|
||||
|
||||
return 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;
|
||||
|
||||
case ENET_SOCKOPT_NODELAY:
|
||||
result = setsockopt (socket, IPPROTO_TCP, TCP_NODELAY, (char *) & value, sizeof (int));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result == SOCKET_ERROR ? -1 : 0;
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_get_option (ENetSocket socket, ENetSocketOption option, int * value)
|
||||
{
|
||||
int result = SOCKET_ERROR, len;
|
||||
switch (option)
|
||||
{
|
||||
case ENET_SOCKOPT_ERROR:
|
||||
len = sizeof(int);
|
||||
result = getsockopt (socket, SOL_SOCKET, SO_ERROR, (char *) value, & len);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return result == SOCKET_ERROR ? -1 : 0;
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_connect (ENetSocket socket, const ENetAddress * address)
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
int result;
|
||||
|
||||
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;
|
||||
|
||||
result = connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in));
|
||||
if (result == SOCKET_ERROR && WSAGetLastError () != WSAEWOULDBLOCK)
|
||||
return -1;
|
||||
|
||||
return 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;
|
||||
}
|
||||
|
||||
int
|
||||
enet_socket_shutdown (ENetSocket socket, ENetSocketShutdown how)
|
||||
{
|
||||
return shutdown (socket, (int) how) == SOCKET_ERROR ? -1 : 0;
|
||||
}
|
||||
|
||||
void
|
||||
enet_socket_destroy (ENetSocket socket)
|
||||
{
|
||||
if (socket != INVALID_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
|
||||
|
Loading…
Reference in a new issue