Merge pull request #40374 from Faless/udp/server_abstraction
UDPServer uses single socket, abstract clients.
This commit is contained in:
commit
9bdcfc4e87
|
@ -31,12 +31,14 @@
|
|||
#include "packet_peer_udp.h"
|
||||
|
||||
#include "core/io/ip.h"
|
||||
#include "core/io/udp_server.h"
|
||||
|
||||
void PacketPeerUDP::set_blocking_mode(bool p_enable) {
|
||||
blocking = p_enable;
|
||||
}
|
||||
|
||||
void PacketPeerUDP::set_broadcast_enabled(bool p_enabled) {
|
||||
ERR_FAIL_COND(udp_server);
|
||||
broadcast = p_enabled;
|
||||
if (_sock.is_valid() && _sock->is_open()) {
|
||||
_sock->set_broadcasting_enabled(p_enabled);
|
||||
|
@ -44,6 +46,7 @@ void PacketPeerUDP::set_broadcast_enabled(bool p_enabled) {
|
|||
}
|
||||
|
||||
Error PacketPeerUDP::join_multicast_group(IP_Address p_multi_address, String p_if_name) {
|
||||
ERR_FAIL_COND_V(udp_server, ERR_LOCKED);
|
||||
ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
|
||||
ERR_FAIL_COND_V(!p_multi_address.is_valid(), ERR_INVALID_PARAMETER);
|
||||
|
||||
|
@ -58,6 +61,7 @@ Error PacketPeerUDP::join_multicast_group(IP_Address p_multi_address, String p_i
|
|||
}
|
||||
|
||||
Error PacketPeerUDP::leave_multicast_group(IP_Address p_multi_address, String p_if_name) {
|
||||
ERR_FAIL_COND_V(udp_server, ERR_LOCKED);
|
||||
ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
|
||||
ERR_FAIL_COND_V(!_sock->is_open(), ERR_UNCONFIGURED);
|
||||
return _sock->leave_multicast_group(p_multi_address, p_if_name);
|
||||
|
@ -130,7 +134,7 @@ Error PacketPeerUDP::put_packet(const uint8_t *p_buffer, int p_buffer_size) {
|
|||
}
|
||||
|
||||
do {
|
||||
if (connected) {
|
||||
if (connected && !udp_server) {
|
||||
err = _sock->send(p_buffer, p_buffer_size, sent);
|
||||
} else {
|
||||
err = _sock->sendto(p_buffer, p_buffer_size, sent, peer_addr, peer_port);
|
||||
|
@ -186,26 +190,25 @@ Error PacketPeerUDP::listen(int p_port, const IP_Address &p_bind_address, int p_
|
|||
return OK;
|
||||
}
|
||||
|
||||
Error PacketPeerUDP::connect_socket(Ref<NetSocket> p_sock) {
|
||||
Error err;
|
||||
int read = 0;
|
||||
uint16_t r_port;
|
||||
IP_Address r_ip;
|
||||
|
||||
err = p_sock->recvfrom(recv_buffer, sizeof(recv_buffer), read, r_ip, r_port, true);
|
||||
ERR_FAIL_COND_V(err != OK, err);
|
||||
err = p_sock->connect_to_host(r_ip, r_port);
|
||||
ERR_FAIL_COND_V(err != OK, err);
|
||||
Error PacketPeerUDP::connect_shared_socket(Ref<NetSocket> p_sock, IP_Address p_ip, uint16_t p_port, UDPServer *p_server) {
|
||||
udp_server = p_server;
|
||||
connected = true;
|
||||
_sock = p_sock;
|
||||
peer_addr = r_ip;
|
||||
peer_port = r_port;
|
||||
peer_addr = p_ip;
|
||||
peer_port = p_port;
|
||||
packet_ip = peer_addr;
|
||||
packet_port = peer_port;
|
||||
connected = true;
|
||||
return OK;
|
||||
}
|
||||
|
||||
void PacketPeerUDP::disconnect_shared_socket() {
|
||||
udp_server = nullptr;
|
||||
_sock = Ref<NetSocket>(NetSocket::create());
|
||||
close();
|
||||
}
|
||||
|
||||
Error PacketPeerUDP::connect_to_host(const IP_Address &p_host, int p_port) {
|
||||
ERR_FAIL_COND_V(udp_server, ERR_LOCKED);
|
||||
ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
|
||||
ERR_FAIL_COND_V(!p_host.is_valid(), ERR_INVALID_PARAMETER);
|
||||
|
||||
|
@ -243,7 +246,11 @@ bool PacketPeerUDP::is_connected_to_host() const {
|
|||
}
|
||||
|
||||
void PacketPeerUDP::close() {
|
||||
if (_sock.is_valid()) {
|
||||
if (udp_server) {
|
||||
udp_server->remove_peer(peer_addr, peer_port);
|
||||
udp_server = nullptr;
|
||||
_sock = Ref<NetSocket>(NetSocket::create());
|
||||
} else if (_sock.is_valid()) {
|
||||
_sock->close();
|
||||
}
|
||||
rb.resize(16);
|
||||
|
@ -262,6 +269,9 @@ Error PacketPeerUDP::_poll() {
|
|||
if (!_sock->is_open()) {
|
||||
return FAILED;
|
||||
}
|
||||
if (udp_server) {
|
||||
return OK; // Handled by UDPServer.
|
||||
}
|
||||
|
||||
Error err;
|
||||
int read;
|
||||
|
@ -284,24 +294,29 @@ Error PacketPeerUDP::_poll() {
|
|||
return FAILED;
|
||||
}
|
||||
|
||||
if (rb.space_left() < read + 24) {
|
||||
err = store_packet(ip, port, recv_buffer, read);
|
||||
#ifdef TOOLS_ENABLED
|
||||
if (err != OK) {
|
||||
WARN_PRINT("Buffer full, dropping packets!");
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t port32 = port;
|
||||
rb.write(ip.get_ipv6(), 16);
|
||||
rb.write((uint8_t *)&port32, 4);
|
||||
rb.write((uint8_t *)&read, 4);
|
||||
rb.write(recv_buffer, read);
|
||||
++queue_count;
|
||||
#endif
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
Error PacketPeerUDP::store_packet(IP_Address p_ip, uint32_t p_port, uint8_t *p_buf, int p_buf_size) {
|
||||
if (rb.space_left() < p_buf_size + 24) {
|
||||
return ERR_OUT_OF_MEMORY;
|
||||
}
|
||||
rb.write(p_ip.get_ipv6(), 16);
|
||||
rb.write((uint8_t *)&p_port, 4);
|
||||
rb.write((uint8_t *)&p_buf_size, 4);
|
||||
rb.write(p_buf, p_buf_size);
|
||||
++queue_count;
|
||||
return OK;
|
||||
}
|
||||
|
||||
bool PacketPeerUDP::is_listening() const {
|
||||
return _sock.is_valid() && _sock->is_open();
|
||||
}
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
#include "core/io/net_socket.h"
|
||||
#include "core/io/packet_peer.h"
|
||||
|
||||
class UDPServer;
|
||||
|
||||
class PacketPeerUDP : public PacketPeer {
|
||||
GDCLASS(PacketPeerUDP, PacketPeer);
|
||||
|
||||
|
@ -55,6 +57,7 @@ protected:
|
|||
bool connected = false;
|
||||
bool blocking = true;
|
||||
bool broadcast = false;
|
||||
UDPServer *udp_server = nullptr;
|
||||
Ref<NetSocket> _sock;
|
||||
|
||||
static void _bind_methods();
|
||||
|
@ -72,7 +75,9 @@ public:
|
|||
Error wait();
|
||||
bool is_listening() const;
|
||||
|
||||
Error connect_socket(Ref<NetSocket> p_sock); // Used by UDPServer
|
||||
Error connect_shared_socket(Ref<NetSocket> p_sock, IP_Address p_ip, uint16_t p_port, UDPServer *ref); // Used by UDPServer
|
||||
void disconnect_shared_socket(); // Used by UDPServer
|
||||
Error store_packet(IP_Address p_ip, uint32_t p_port, uint8_t *p_buf, int p_buf_size); // Used internally and by UDPServer
|
||||
Error connect_to_host(const IP_Address &p_host, int p_port);
|
||||
bool is_connected_to_host() const;
|
||||
|
||||
|
|
|
@ -32,10 +32,58 @@
|
|||
|
||||
void UDPServer::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("listen", "port", "bind_address"), &UDPServer::listen, DEFVAL("*"));
|
||||
ClassDB::bind_method(D_METHOD("poll"), &UDPServer::poll);
|
||||
ClassDB::bind_method(D_METHOD("is_connection_available"), &UDPServer::is_connection_available);
|
||||
ClassDB::bind_method(D_METHOD("is_listening"), &UDPServer::is_listening);
|
||||
ClassDB::bind_method(D_METHOD("take_connection"), &UDPServer::take_connection);
|
||||
ClassDB::bind_method(D_METHOD("stop"), &UDPServer::stop);
|
||||
ClassDB::bind_method(D_METHOD("set_max_pending_connections", "max_pending_connections"), &UDPServer::set_max_pending_connections);
|
||||
ClassDB::bind_method(D_METHOD("get_max_pending_connections"), &UDPServer::get_max_pending_connections);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_pending_connections", PROPERTY_HINT_RANGE, "0,256,1"), "set_max_pending_connections", "get_max_pending_connections");
|
||||
}
|
||||
|
||||
Error UDPServer::poll() {
|
||||
ERR_FAIL_COND_V(!_sock.is_valid(), ERR_UNAVAILABLE);
|
||||
if (!_sock->is_open()) {
|
||||
return ERR_UNCONFIGURED;
|
||||
}
|
||||
Error err;
|
||||
int read;
|
||||
IP_Address ip;
|
||||
uint16_t port;
|
||||
while (true) {
|
||||
err = _sock->recvfrom(recv_buffer, sizeof(recv_buffer), read, ip, port);
|
||||
if (err != OK) {
|
||||
if (err == ERR_BUSY) {
|
||||
break;
|
||||
}
|
||||
return FAILED;
|
||||
}
|
||||
Peer p;
|
||||
p.ip = ip;
|
||||
p.port = port;
|
||||
List<Peer>::Element *E = peers.find(p);
|
||||
if (!E) {
|
||||
E = pending.find(p);
|
||||
}
|
||||
if (E) {
|
||||
E->get().peer->store_packet(ip, port, recv_buffer, read);
|
||||
} else {
|
||||
if (pending.size() >= max_pending_connections) {
|
||||
// Drop connection.
|
||||
continue;
|
||||
}
|
||||
// It's a new peer, add it to the pending list.
|
||||
Peer peer;
|
||||
peer.ip = ip;
|
||||
peer.port = port;
|
||||
peer.peer = memnew(PacketPeerUDP);
|
||||
peer.peer->connect_shared_socket(_sock, ip, port, this);
|
||||
peer.peer->store_packet(ip, port, recv_buffer, read);
|
||||
pending.push_back(peer);
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
Error UDPServer::listen(uint16_t p_port, const IP_Address &p_bind_address) {
|
||||
|
@ -82,8 +130,24 @@ bool UDPServer::is_connection_available() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
Error err = _sock->poll(NetSocket::POLL_TYPE_IN, 0);
|
||||
return (err == OK);
|
||||
return pending.size() > 0;
|
||||
}
|
||||
|
||||
void UDPServer::set_max_pending_connections(int p_max) {
|
||||
ERR_FAIL_COND_MSG(p_max < 0, "Max pending connections value must be a positive number (0 means refuse new connections).");
|
||||
max_pending_connections = p_max;
|
||||
while (p_max > pending.size()) {
|
||||
List<Peer>::Element *E = pending.back();
|
||||
if (!E) {
|
||||
break;
|
||||
}
|
||||
memdelete(E->get().peer);
|
||||
pending.erase(E);
|
||||
}
|
||||
}
|
||||
|
||||
int UDPServer::get_max_pending_connections() const {
|
||||
return max_pending_connections;
|
||||
}
|
||||
|
||||
Ref<PacketPeerUDP> UDPServer::take_connection() {
|
||||
|
@ -92,11 +156,20 @@ Ref<PacketPeerUDP> UDPServer::take_connection() {
|
|||
return conn;
|
||||
}
|
||||
|
||||
conn = Ref<PacketPeerUDP>(memnew(PacketPeerUDP));
|
||||
conn->connect_socket(_sock);
|
||||
_sock = Ref<NetSocket>(NetSocket::create());
|
||||
listen(bind_port, bind_address);
|
||||
return conn;
|
||||
Peer peer = pending[0];
|
||||
pending.pop_front();
|
||||
peers.push_back(peer);
|
||||
return peer.peer;
|
||||
}
|
||||
|
||||
void UDPServer::remove_peer(IP_Address p_ip, int p_port) {
|
||||
Peer peer;
|
||||
peer.ip = p_ip;
|
||||
peer.port = p_port;
|
||||
List<Peer>::Element *E = peers.find(peer);
|
||||
if (E) {
|
||||
peers.erase(E);
|
||||
}
|
||||
}
|
||||
|
||||
void UDPServer::stop() {
|
||||
|
@ -105,6 +178,19 @@ void UDPServer::stop() {
|
|||
}
|
||||
bind_port = 0;
|
||||
bind_address = IP_Address();
|
||||
List<Peer>::Element *E = peers.front();
|
||||
while (E) {
|
||||
E->get().peer->disconnect_shared_socket();
|
||||
E = E->next();
|
||||
}
|
||||
E = pending.front();
|
||||
while (E) {
|
||||
E->get().peer->disconnect_shared_socket();
|
||||
memdelete(E->get().peer);
|
||||
E = E->next();
|
||||
}
|
||||
peers.clear();
|
||||
pending.clear();
|
||||
}
|
||||
|
||||
UDPServer::UDPServer() :
|
||||
|
|
|
@ -38,15 +38,40 @@ class UDPServer : public Reference {
|
|||
GDCLASS(UDPServer, Reference);
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
int bind_port;
|
||||
enum {
|
||||
PACKET_BUFFER_SIZE = 65536
|
||||
};
|
||||
|
||||
struct Peer {
|
||||
PacketPeerUDP *peer;
|
||||
IP_Address ip;
|
||||
uint16_t port = 0;
|
||||
|
||||
bool operator==(const Peer &p_other) const {
|
||||
return (ip == p_other.ip && port == p_other.port);
|
||||
}
|
||||
};
|
||||
uint8_t recv_buffer[PACKET_BUFFER_SIZE];
|
||||
|
||||
int bind_port = 0;
|
||||
IP_Address bind_address;
|
||||
|
||||
List<Peer> peers;
|
||||
List<Peer> pending;
|
||||
int max_pending_connections = 16;
|
||||
|
||||
Ref<NetSocket> _sock;
|
||||
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
void remove_peer(IP_Address p_ip, int p_port);
|
||||
Error listen(uint16_t p_port, const IP_Address &p_bind_address = IP_Address("*"));
|
||||
Error poll();
|
||||
bool is_listening() const;
|
||||
bool is_connection_available() const;
|
||||
void set_max_pending_connections(int p_max);
|
||||
int get_max_pending_connections() const;
|
||||
Ref<PacketPeerUDP> take_connection();
|
||||
|
||||
void stop();
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
</brief_description>
|
||||
<description>
|
||||
A simple server that opens a UDP socket and returns connected [PacketPeerUDP] upon receiving new packets. See also [method PacketPeerUDP.connect_to_host].
|
||||
After starting the server ([method listen]), you will need to [method poll] it at regular intervals (e.g. inside [method Node._process]) for it to process new packets, delivering them to the appropriate [PacketPeerUDP], and taking new connections.
|
||||
Below a small example of how it can be used:
|
||||
[codeblock]
|
||||
# server.gd
|
||||
|
@ -17,6 +18,7 @@
|
|||
server.listen(4242)
|
||||
|
||||
func _process(delta):
|
||||
server.poll() # Important!
|
||||
if server.is_connection_available():
|
||||
var peer : PacketPeerUDP = server.take_connection()
|
||||
var pkt = peer.get_packet()
|
||||
|
@ -57,7 +59,7 @@
|
|||
<return type="bool">
|
||||
</return>
|
||||
<description>
|
||||
Returns [code]true[/code] if a packet with a new address/port combination is received on the socket.
|
||||
Returns [code]true[/code] if a packet with a new address/port combination was received on the socket.
|
||||
</description>
|
||||
</method>
|
||||
<method name="is_listening" qualifiers="const">
|
||||
|
@ -78,21 +80,33 @@
|
|||
Starts the server by opening a UDP socket listening on the given port. You can optionally specify a [code]bind_address[/code] to only listen for packets sent to that address. See also [method PacketPeerUDP.listen].
|
||||
</description>
|
||||
</method>
|
||||
<method name="poll">
|
||||
<return type="int" enum="Error">
|
||||
</return>
|
||||
<description>
|
||||
Call this method at regular intervals (e.g. inside [method Node._process]) to process new packets. And packet from known address/port pair will be delivered to the appropriate [PacketPeerUDP], any packet received from an unknown address/port pair will be added as a pending connection (see [method is_connection_available], [method take_connection]). The maximum number of pending connection is defined via [member max_pending_connections].
|
||||
</description>
|
||||
</method>
|
||||
<method name="stop">
|
||||
<return type="void">
|
||||
</return>
|
||||
<description>
|
||||
Stops the server, closing the UDP socket if open. Will not disconnect any connected [PacketPeerUDP].
|
||||
Stops the server, closing the UDP socket if open. Will close all connected [PacketPeerUDP] accepted via [method take_connection] (remote peers will not be notified).
|
||||
</description>
|
||||
</method>
|
||||
<method name="take_connection">
|
||||
<return type="PacketPeerUDP">
|
||||
</return>
|
||||
<description>
|
||||
Returns a [PacketPeerUDP] connected to the address/port combination of the first packet in queue. Will return [code]null[/code] if no packet is in queue. See also [method PacketPeerUDP.connect_to_host].
|
||||
Returns the first pending connection (connected to the appropriate address/port). Will return [code]null[/code] if no new connection is available. See also [method is_connection_available], [method PacketPeerUDP.connect_to_host].
|
||||
</description>
|
||||
</method>
|
||||
</methods>
|
||||
<members>
|
||||
<member name="max_pending_connections" type="int" setter="set_max_pending_connections" getter="get_max_pending_connections" default="16">
|
||||
Define the maximum number of pending connections, during [method poll], any new pending connection exceeding that value will be automatically dropped. Setting this value to [code]0[/code] effectively prevents any new pending connection to be accepted (e.g. when all your players have connected).
|
||||
</member>
|
||||
</members>
|
||||
<constants>
|
||||
</constants>
|
||||
</class>
|
||||
|
|
|
@ -640,6 +640,9 @@ int NetworkedMultiplayerENet::get_unique_id() const {
|
|||
|
||||
void NetworkedMultiplayerENet::set_refuse_new_connections(bool p_enable) {
|
||||
refuse_connections = p_enable;
|
||||
#ifdef GODOT_ENET
|
||||
enet_host_refuse_new_connections(host, p_enable);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool NetworkedMultiplayerENet::is_refusing_new_connections() const {
|
||||
|
|
|
@ -13,7 +13,16 @@ extern "C"
|
|||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// -- Godot start --
|
||||
#if 0
|
||||
#ifdef _WIN32
|
||||
#include "enet/win32.h"
|
||||
#else
|
||||
#include "enet/unix.h"
|
||||
#endif
|
||||
#endif
|
||||
#include "enet/godot.h"
|
||||
// -- Godot end --
|
||||
|
||||
#include "enet/types.h"
|
||||
#include "enet/protocol.h"
|
||||
|
@ -69,6 +78,7 @@ 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
|
||||
|
||||
|
@ -82,13 +92,15 @@ typedef enum _ENetSocketShutdown
|
|||
* but not for enet_host_create. Once a server responds to a broadcast, the
|
||||
* address is updated from ENET_HOST_BROADCAST to the server's actual IP address.
|
||||
*/
|
||||
// -- Godot start --
|
||||
#if 0
|
||||
typedef struct _ENetAddress
|
||||
{
|
||||
uint8_t host[16];
|
||||
enet_uint32 host;
|
||||
enet_uint16 port;
|
||||
uint8_t wildcard;
|
||||
} ENetAddress;
|
||||
#define enet_host_equal(host_a, host_b) (memcmp(&host_a, &host_b,16) == 0)
|
||||
#endif
|
||||
// -- Godot end --
|
||||
|
||||
/**
|
||||
* Packet flag bit constants.
|
||||
|
@ -535,16 +547,6 @@ ENET_API int enet_address_set_host_ip (ENetAddress * address, const char * hostN
|
|||
*/
|
||||
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
|
||||
|
@ -585,8 +587,6 @@ ENET_API void enet_host_channel_limit (ENetHost *, size_t);
|
|||
ENET_API void enet_host_bandwidth_limit (ENetHost *, enet_uint32, enet_uint32);
|
||||
extern void enet_host_bandwidth_throttle (ENetHost *);
|
||||
extern enet_uint32 enet_host_random_seed (void);
|
||||
ENET_API void enet_host_dtls_server_setup (ENetHost *, void *, void *);
|
||||
ENET_API void enet_host_dtls_client_setup (ENetHost *, void *, uint8_t, const char *);
|
||||
|
||||
ENET_API int enet_peer_send (ENetPeer *, enet_uint8, ENetPacket *);
|
||||
ENET_API ENetPacket * enet_peer_receive (ENetPeer *, enet_uint8 * channelID);
|
||||
|
@ -616,6 +616,10 @@ ENET_API size_t enet_range_coder_decompress (void *, const enet_uint8 *, size_t,
|
|||
|
||||
extern size_t enet_protocol_command_size (enet_uint8);
|
||||
|
||||
// -- Godot start --
|
||||
#include "enet/godot_ext.h"
|
||||
// -- Godot end --
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -69,4 +69,12 @@ typedef struct
|
|||
|
||||
typedef void ENetSocketSet;
|
||||
|
||||
typedef struct _ENetAddress
|
||||
{
|
||||
uint8_t host[16];
|
||||
uint16_t port;
|
||||
uint8_t wildcard;
|
||||
} ENetAddress;
|
||||
#define enet_host_equal(host_a, host_b) (memcmp(&host_a, &host_b,16) == 0)
|
||||
|
||||
#endif /* __ENET_GODOT_H__ */
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
#ifndef __ENET_GODOT_EXT_H__
|
||||
#define __ENET_GODOT_EXT_H__
|
||||
|
||||
/** 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);
|
||||
|
||||
ENET_API void enet_host_dtls_server_setup (ENetHost *, void *, void *);
|
||||
ENET_API void enet_host_dtls_client_setup (ENetHost *, void *, uint8_t, const char *);
|
||||
ENET_API void enet_host_refuse_new_connections (ENetHost *, int);
|
||||
|
||||
#endif // __ENET_GODOT_EXT_H__
|
|
@ -51,6 +51,7 @@ public:
|
|||
virtual Error recvfrom(uint8_t *p_buffer, int p_len, int &r_read, IP_Address &r_ip, uint16_t &r_port) = 0;
|
||||
virtual int set_option(ENetSocketOption p_option, int p_value) = 0;
|
||||
virtual void close() = 0;
|
||||
virtual void set_refuse_new_connections(bool p_refuse) { /* Only used by dtls server */ }
|
||||
virtual ~ENetGodotSocket(){};
|
||||
};
|
||||
|
||||
|
@ -250,6 +251,10 @@ public:
|
|||
close();
|
||||
}
|
||||
|
||||
void set_refuse_new_connections(bool p_refuse) {
|
||||
udp_server->set_max_pending_connections(p_refuse ? 0 : 16);
|
||||
}
|
||||
|
||||
Error bind(IP_Address p_ip, uint16_t p_port) {
|
||||
return udp_server->listen(p_port, p_ip);
|
||||
}
|
||||
|
@ -269,6 +274,7 @@ public:
|
|||
}
|
||||
|
||||
Error recvfrom(uint8_t *p_buffer, int p_len, int &r_read, IP_Address &r_ip, uint16_t &r_port) {
|
||||
udp_server->poll();
|
||||
// TODO limits? Maybe we can better enforce allowed connections!
|
||||
if (udp_server->is_connection_available()) {
|
||||
Ref<PacketPeerUDP> udp = udp_server->take_connection();
|
||||
|
@ -409,6 +415,11 @@ void enet_host_dtls_client_setup(ENetHost *host, void *p_cert, uint8_t p_verify,
|
|||
memdelete(sock);
|
||||
}
|
||||
|
||||
void enet_host_refuse_new_connections(ENetHost *host, int p_refuse) {
|
||||
ERR_FAIL_COND(!host->socket);
|
||||
((ENetGodotSocket *)host->socket)->set_refuse_new_connections(p_refuse);
|
||||
}
|
||||
|
||||
int enet_socket_bind(ENetSocket socket, const ENetAddress *address) {
|
||||
|
||||
IP_Address ip;
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
diff --git a/thirdparty/enet/enet/enet.h b/thirdparty/enet/enet/enet.h
|
||||
index 966e3a465d..ac7552adb2 100644
|
||||
--- a/thirdparty/enet/enet/enet.h
|
||||
+++ b/thirdparty/enet/enet/enet.h
|
||||
@@ -578,6 +578,8 @@ ENET_API void enet_host_channel_limit (ENetHost *, size_t);
|
||||
ENET_API void enet_host_bandwidth_limit (ENetHost *, enet_uint32, enet_uint32);
|
||||
extern void enet_host_bandwidth_throttle (ENetHost *);
|
||||
extern enet_uint32 enet_host_random_seed (void);
|
||||
+ENET_API void enet_host_dtls_server_setup (ENetHost *, void *, void *);
|
||||
+ENET_API void enet_host_dtls_client_setup (ENetHost *, void *, uint8_t, const char *);
|
||||
|
||||
ENET_API int enet_peer_send (ENetPeer *, enet_uint8, ENetPacket *);
|
||||
ENET_API ENetPacket * enet_peer_receive (ENetPeer *, enet_uint8 * channelID);
|
|
@ -1,61 +1,54 @@
|
|||
diff --git a/thirdparty/enet/enet/enet.h b/thirdparty/enet/enet/enet.h
|
||||
index 650b199ee5..246cbb0a62 100644
|
||||
index 54d91b5603..24d36647d9 100644
|
||||
--- a/thirdparty/enet/enet/enet.h
|
||||
+++ b/thirdparty/enet/enet/enet.h
|
||||
@@ -10,13 +10,10 @@ extern "C"
|
||||
@@ -10,13 +10,19 @@ extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
+#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
-#ifdef _WIN32
|
||||
-#include "enet/win32.h"
|
||||
-#else
|
||||
-#include "enet/unix.h"
|
||||
-#endif
|
||||
+// -- Godot start --
|
||||
+#if 0
|
||||
#ifdef _WIN32
|
||||
#include "enet/win32.h"
|
||||
#else
|
||||
#include "enet/unix.h"
|
||||
#endif
|
||||
+#endif
|
||||
+#include "enet/godot.h"
|
||||
+// -- Godot end --
|
||||
|
||||
#include "enet/types.h"
|
||||
#include "enet/protocol.h"
|
||||
@@ -72,7 +69,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 +84,11 @@ typedef enum _ENetSocketShutdown
|
||||
@@ -86,11 +92,15 @@ typedef enum _ENetSocketShutdown
|
||||
* but not for enet_host_create. Once a server responds to a broadcast, the
|
||||
* address is updated from ENET_HOST_BROADCAST to the server's actual IP address.
|
||||
*/
|
||||
+// -- Godot start --
|
||||
+#if 0
|
||||
typedef struct _ENetAddress
|
||||
{
|
||||
- enet_uint32 host;
|
||||
+ uint8_t host[16];
|
||||
enet_uint32 host;
|
||||
enet_uint16 port;
|
||||
+ uint8_t wildcard;
|
||||
} ENetAddress;
|
||||
+#define enet_host_equal(host_a, host_b) (memcmp(&host_a, &host_b,16) == 0)
|
||||
+#endif
|
||||
+// -- Godot end --
|
||||
|
||||
/**
|
||||
* Packet flag bit constants.
|
||||
@@ -519,6 +517,16 @@ ENET_API int enet_socketset_select (ENetSocket, ENetSocketSet *, ENetSock
|
||||
*/
|
||||
ENET_API int enet_address_set_host (ENetAddress * address, const char * hostName);
|
||||
@@ -606,6 +616,10 @@ ENET_API size_t enet_range_coder_decompress (void *, const enet_uint8 *, size_t,
|
||||
|
||||
extern size_t enet_protocol_command_size (enet_uint8);
|
||||
|
||||
+/** 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);
|
||||
+// -- Godot start --
|
||||
+#include "enet/godot_ext.h"
|
||||
+// -- Godot end --
|
||||
+
|
||||
/** 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
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
diff --git a/thirdparty/enet/host.c b/thirdparty/enet/host.c
|
||||
index 3be6c0922c..fc4da4ca67 100644
|
||||
--- a/thirdparty/enet/host.c
|
||||
|
@ -70,10 +63,10 @@ index 3be6c0922c..fc4da4ca67 100644
|
|||
host -> receivedData = NULL;
|
||||
host -> receivedDataLength = 0;
|
||||
diff --git a/thirdparty/enet/protocol.c b/thirdparty/enet/protocol.c
|
||||
index 29d648732d..ab26886de4 100644
|
||||
index 0a60253173..fefc0e6f0a 100644
|
||||
--- a/thirdparty/enet/protocol.c
|
||||
+++ b/thirdparty/enet/protocol.c
|
||||
@@ -298,7 +298,7 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet
|
||||
@@ -307,7 +307,7 @@ enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENet
|
||||
}
|
||||
else
|
||||
if (currentPeer -> state != ENET_PEER_STATE_CONNECTING &&
|
||||
|
@ -82,7 +75,7 @@ index 29d648732d..ab26886de4 100644
|
|||
{
|
||||
if (currentPeer -> address.port == host -> receivedAddress.port &&
|
||||
currentPeer -> connectID == command -> connect.connectID)
|
||||
@@ -1010,9 +1010,8 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
|
||||
@@ -1027,9 +1027,8 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
|
||||
|
||||
if (peer -> state == ENET_PEER_STATE_DISCONNECTED ||
|
||||
peer -> state == ENET_PEER_STATE_ZOMBIE ||
|
||||
|
@ -94,7 +87,7 @@ index 29d648732d..ab26886de4 100644
|
|||
(peer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID &&
|
||||
sessionID != peer -> incomingSessionID))
|
||||
return 0;
|
||||
@@ -1054,7 +1053,7 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
|
||||
@@ -1071,7 +1070,7 @@ enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event)
|
||||
|
||||
if (peer != NULL)
|
||||
{
|
Loading…
Reference in New Issue