mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-09 07:29:44 +00:00
(svn r15971) -Codechange: make it possible for UDP socket handlers to bind to multiple sockets.
This commit is contained in:
parent
6db7f15b3a
commit
2a6e9288fd
@ -37,12 +37,9 @@ struct Packet;
|
|||||||
*/
|
*/
|
||||||
class NetworkSocketHandler {
|
class NetworkSocketHandler {
|
||||||
bool has_quit; ///< Whether the current client has quit/send a bad packet
|
bool has_quit; ///< Whether the current client has quit/send a bad packet
|
||||||
public:
|
|
||||||
/* TODO: make socket protected once the TCP stuff is in a real class too */
|
|
||||||
SOCKET sock; ///< The socket currently connected to
|
|
||||||
public:
|
public:
|
||||||
/** Create a new unbound socket */
|
/** Create a new unbound socket */
|
||||||
NetworkSocketHandler(SOCKET s = INVALID_SOCKET) { this->sock = s; this->has_quit = false; }
|
NetworkSocketHandler() { this->has_quit = false; }
|
||||||
|
|
||||||
/** Close the socket when distructing the socket handler */
|
/** Close the socket when distructing the socket handler */
|
||||||
virtual ~NetworkSocketHandler() { this->Close(); }
|
virtual ~NetworkSocketHandler() { this->Close(); }
|
||||||
@ -57,12 +54,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual NetworkRecvStatus CloseConnection() { this->has_quit = true; return NETWORK_RECV_STATUS_OKAY; }
|
virtual NetworkRecvStatus CloseConnection() { this->has_quit = true; return NETWORK_RECV_STATUS_OKAY; }
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether this socket is currently bound to a socket.
|
|
||||||
* @return true when the socket is bound, false otherwise
|
|
||||||
*/
|
|
||||||
bool IsConnected() const { return this->sock != INVALID_SOCKET; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the current client connected to the socket has quit.
|
* Whether the current client connected to the socket has quit.
|
||||||
* In the case of UDP, for example, once a client quits (send bad
|
* In the case of UDP, for example, once a client quits (send bad
|
||||||
|
@ -13,8 +13,9 @@
|
|||||||
#include "tcp.h"
|
#include "tcp.h"
|
||||||
|
|
||||||
NetworkTCPSocketHandler::NetworkTCPSocketHandler(SOCKET s) :
|
NetworkTCPSocketHandler::NetworkTCPSocketHandler(SOCKET s) :
|
||||||
NetworkSocketHandler(s),
|
NetworkSocketHandler(),
|
||||||
packet_queue(NULL), packet_recv(NULL), writable(false)
|
packet_queue(NULL), packet_recv(NULL),
|
||||||
|
sock(s), writable(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,8 +20,15 @@ private:
|
|||||||
Packet *packet_queue; ///< Packets that are awaiting delivery
|
Packet *packet_queue; ///< Packets that are awaiting delivery
|
||||||
Packet *packet_recv; ///< Partially received packet
|
Packet *packet_recv; ///< Partially received packet
|
||||||
public:
|
public:
|
||||||
|
SOCKET sock; ///< The socket currently connected to
|
||||||
bool writable; ///< Can we write to this socket?
|
bool writable; ///< Can we write to this socket?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this socket is currently bound to a socket.
|
||||||
|
* @return true when the socket is bound, false otherwise
|
||||||
|
*/
|
||||||
|
bool IsConnected() const { return this->sock != INVALID_SOCKET; }
|
||||||
|
|
||||||
virtual NetworkRecvStatus CloseConnection();
|
virtual NetworkRecvStatus CloseConnection();
|
||||||
void Send_Packet(Packet *packet);
|
void Send_Packet(Packet *packet);
|
||||||
bool Send_Packets();
|
bool Send_Packets();
|
||||||
|
@ -16,29 +16,39 @@
|
|||||||
#include "udp.h"
|
#include "udp.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start listening on the given host and port.
|
* Create an UDP socket but don't listen yet.
|
||||||
* @param address the host to listen on
|
* @param bind the addresses to bind to.
|
||||||
* @param broadcast whether to allow broadcast sending/receiving
|
|
||||||
* @return true if the listening succeeded
|
|
||||||
*/
|
*/
|
||||||
bool NetworkUDPSocketHandler::Listen(NetworkAddress address, bool broadcast)
|
NetworkUDPSocketHandler::NetworkUDPSocketHandler(NetworkAddressList *bind)
|
||||||
|
{
|
||||||
|
if (bind != NULL) {
|
||||||
|
for (NetworkAddress *addr = bind->Begin(); addr != bind->End(); addr++) {
|
||||||
|
*this->bind.Append() = *addr;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*this->bind.Append() = NetworkAddress(NULL, 0, AF_INET);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start listening on the given host and port.
|
||||||
|
* @return true if at least one port is listening
|
||||||
|
*/
|
||||||
|
bool NetworkUDPSocketHandler::Listen()
|
||||||
{
|
{
|
||||||
/* Make sure socket is closed */
|
/* Make sure socket is closed */
|
||||||
this->Close();
|
this->Close();
|
||||||
|
|
||||||
this->sock = address.Listen(AF_INET, SOCK_DGRAM);
|
for (NetworkAddress *addr = this->bind.Begin(); addr != this->bind.End(); addr++) {
|
||||||
|
addr->Listen(AF_UNSPEC, SOCK_DGRAM, &this->sockets);
|
||||||
if (broadcast) {
|
|
||||||
/* Enable broadcast */
|
|
||||||
unsigned long val = 1;
|
|
||||||
#ifndef BEOS_NET_SERVER /* will work around this, some day; maybe. */
|
|
||||||
setsockopt(this->sock, SOL_SOCKET, SO_BROADCAST, (char *) &val, sizeof(val));
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG(net, 1, "[udp] listening on port %s", address.GetAddressAsString());
|
for (SocketList::iterator s = this->sockets.Begin(); s != this->sockets.End(); s++) {
|
||||||
|
DEBUG(net, 1, "[udp] listening on port %s", s->first.GetAddressAsString());
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return this->sockets.Length() != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -46,10 +56,10 @@ bool NetworkUDPSocketHandler::Listen(NetworkAddress address, bool broadcast)
|
|||||||
*/
|
*/
|
||||||
void NetworkUDPSocketHandler::Close()
|
void NetworkUDPSocketHandler::Close()
|
||||||
{
|
{
|
||||||
if (!this->IsConnected()) return;
|
for (SocketList::iterator s = this->sockets.Begin(); s != this->sockets.End(); s++) {
|
||||||
|
closesocket(s->second);
|
||||||
closesocket(this->sock);
|
}
|
||||||
this->sock = INVALID_SOCKET;
|
this->sockets.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkRecvStatus NetworkUDPSocketHandler::CloseConnection()
|
NetworkRecvStatus NetworkUDPSocketHandler::CloseConnection()
|
||||||
@ -62,18 +72,35 @@ NetworkRecvStatus NetworkUDPSocketHandler::CloseConnection()
|
|||||||
* Send a packet over UDP
|
* Send a packet over UDP
|
||||||
* @param p the packet to send
|
* @param p the packet to send
|
||||||
* @param recv the receiver (target) of the packet
|
* @param recv the receiver (target) of the packet
|
||||||
|
* @param all send the packet using all sockets that can send it
|
||||||
|
* @param broadcast whether to send a broadcast message
|
||||||
*/
|
*/
|
||||||
void NetworkUDPSocketHandler::SendPacket(Packet *p, NetworkAddress *recv)
|
void NetworkUDPSocketHandler::SendPacket(Packet *p, NetworkAddress *recv, bool all, bool broadcast)
|
||||||
{
|
{
|
||||||
int res;
|
if (this->sockets.Length() == 0) this->Listen();
|
||||||
|
|
||||||
p->PrepareToSend();
|
for (SocketList::iterator s = this->sockets.Begin(); s != this->sockets.End(); s++) {
|
||||||
|
/* Not the same type */
|
||||||
|
if (s->first.GetAddress()->ss_family != recv->GetAddress()->ss_family) continue;
|
||||||
|
|
||||||
/* Send the buffer */
|
p->PrepareToSend();
|
||||||
res = sendto(this->sock, (const char*)p->buffer, p->size, 0, (struct sockaddr *)recv->GetAddress(), recv->GetAddressLength());
|
|
||||||
|
|
||||||
/* Check for any errors, but ignore it otherwise */
|
#ifndef BEOS_NET_SERVER /* will work around this, some day; maybe. */
|
||||||
if (res == -1) DEBUG(net, 1, "[udp] sendto failed with: %i", GET_LAST_ERROR());
|
if (broadcast) {
|
||||||
|
/* Enable broadcast */
|
||||||
|
unsigned long val = 1;
|
||||||
|
setsockopt(s->second, SOL_SOCKET, SO_BROADCAST, (char *) &val, sizeof(val));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Send the buffer */
|
||||||
|
int res = sendto(s->second, (const char*)p->buffer, p->size, 0, (struct sockaddr *)recv->GetAddress(), recv->GetAddressLength());
|
||||||
|
|
||||||
|
/* Check for any errors, but ignore it otherwise */
|
||||||
|
if (res == -1) DEBUG(net, 1, "[udp] sendto(%s) failed with: %i", recv->GetAddressAsString(), GET_LAST_ERROR());
|
||||||
|
|
||||||
|
if (!all) break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -81,37 +108,33 @@ void NetworkUDPSocketHandler::SendPacket(Packet *p, NetworkAddress *recv)
|
|||||||
*/
|
*/
|
||||||
void NetworkUDPSocketHandler::ReceivePackets()
|
void NetworkUDPSocketHandler::ReceivePackets()
|
||||||
{
|
{
|
||||||
struct sockaddr_storage client_addr;
|
for (SocketList::iterator s = this->sockets.Begin(); s != this->sockets.End(); s++) {
|
||||||
memset(&client_addr, 0, sizeof(client_addr));
|
struct sockaddr_storage client_addr;
|
||||||
|
memset(&client_addr, 0, sizeof(client_addr));
|
||||||
|
|
||||||
socklen_t client_len;
|
Packet p(this);
|
||||||
int nbytes;
|
int packet_len = sizeof(p.buffer);
|
||||||
Packet p(this);
|
socklen_t client_len = sizeof(client_addr);
|
||||||
int packet_len;
|
|
||||||
|
|
||||||
if (!this->IsConnected()) return;
|
/* Try to receive anything */
|
||||||
|
SetNonBlocking(s->second); // Some OSes seem to lose the non-blocking status of the socket
|
||||||
|
int nbytes = recvfrom(s->second, (char*)p.buffer, packet_len, 0, (struct sockaddr *)&client_addr, &client_len);
|
||||||
|
|
||||||
packet_len = sizeof(p.buffer);
|
/* We got some bytes for the base header of the packet. */
|
||||||
client_len = sizeof(client_addr);
|
if (nbytes > 2) {
|
||||||
|
NetworkAddress address(client_addr, client_len);
|
||||||
|
p.PrepareToRead();
|
||||||
|
|
||||||
/* Try to receive anything */
|
/* If the size does not match the packet must be corrupted.
|
||||||
SetNonBlocking(this->sock); // Some OSes seem to lose the non-blocking status of the socket
|
* Otherwise it will be marked as corrupted later on. */
|
||||||
nbytes = recvfrom(this->sock, (char*)p.buffer, packet_len, 0, (struct sockaddr *)&client_addr, &client_len);
|
if (nbytes != p.size) {
|
||||||
|
DEBUG(net, 1, "received a packet with mismatching size from %s", address.GetAddressAsString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* We got some bytes for the base header of the packet. */
|
/* Handle the packet */
|
||||||
if (nbytes > 2) {
|
this->HandleUDPPacket(&p, &address);
|
||||||
NetworkAddress address(client_addr, client_len);
|
|
||||||
p.PrepareToRead();
|
|
||||||
|
|
||||||
/* If the size does not match the packet must be corrupted.
|
|
||||||
* Otherwise it will be marked as corrupted later on. */
|
|
||||||
if (nbytes != p.size) {
|
|
||||||
DEBUG(net, 1, "received a packet with mismatching size from %s", address.GetAddressAsString());
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle the packet */
|
|
||||||
this->HandleUDPPacket(&p, &address);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,6 +96,11 @@ enum PacketUDPType {
|
|||||||
/** Base socket handler for all UDP sockets */
|
/** Base socket handler for all UDP sockets */
|
||||||
class NetworkUDPSocketHandler : public NetworkSocketHandler {
|
class NetworkUDPSocketHandler : public NetworkSocketHandler {
|
||||||
protected:
|
protected:
|
||||||
|
/** The address to bind to. */
|
||||||
|
NetworkAddressList bind;
|
||||||
|
/** The opened sockets. */
|
||||||
|
SocketList sockets;
|
||||||
|
|
||||||
NetworkRecvStatus CloseConnection();
|
NetworkRecvStatus CloseConnection();
|
||||||
|
|
||||||
/* Declare all possible packets here. If it can be received by the
|
/* Declare all possible packets here. If it can be received by the
|
||||||
@ -124,13 +129,15 @@ protected:
|
|||||||
*/
|
*/
|
||||||
virtual void HandleIncomingNetworkGameInfoGRFConfig(GRFConfig *config) { NOT_REACHED(); }
|
virtual void HandleIncomingNetworkGameInfoGRFConfig(GRFConfig *config) { NOT_REACHED(); }
|
||||||
public:
|
public:
|
||||||
|
NetworkUDPSocketHandler(NetworkAddressList *bind = NULL);
|
||||||
|
|
||||||
/** On destructing of this class, the socket needs to be closed */
|
/** On destructing of this class, the socket needs to be closed */
|
||||||
virtual ~NetworkUDPSocketHandler() { this->Close(); }
|
virtual ~NetworkUDPSocketHandler() { this->Close(); }
|
||||||
|
|
||||||
bool Listen(NetworkAddress address, bool broadcast);
|
bool Listen();
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
void SendPacket(Packet *p, NetworkAddress *recv);
|
void SendPacket(Packet *p, NetworkAddress *recv, bool all = false, bool broadcast = false);
|
||||||
void ReceivePackets();
|
void ReceivePackets();
|
||||||
|
|
||||||
void Send_NetworkGameInfo(Packet *p, const NetworkGameInfo *info);
|
void Send_NetworkGameInfo(Packet *p, const NetworkGameInfo *info);
|
||||||
|
@ -274,7 +274,7 @@ static void NetworkClientError(NetworkRecvStatus res, NetworkClientSocket *cs)
|
|||||||
|
|
||||||
/* We just want to close the connection.. */
|
/* We just want to close the connection.. */
|
||||||
if (res == NETWORK_RECV_STATUS_CLOSE_QUERY) {
|
if (res == NETWORK_RECV_STATUS_CLOSE_QUERY) {
|
||||||
cs->CloseConnection();
|
cs->NetworkSocketHandler::CloseConnection();
|
||||||
NetworkCloseClient(cs);
|
NetworkCloseClient(cs);
|
||||||
_networking = false;
|
_networking = false;
|
||||||
|
|
||||||
@ -738,8 +738,7 @@ bool NetworkServerStart()
|
|||||||
if (!NetworkListen()) return false;
|
if (!NetworkListen()) return false;
|
||||||
|
|
||||||
/* Try to start UDP-server */
|
/* Try to start UDP-server */
|
||||||
_network_udp_server = true;
|
_network_udp_server = _udp_server_socket->Listen();
|
||||||
_network_udp_server = _udp_server_socket->Listen(NetworkAddress(_settings_client.network.server_bind_ip, _settings_client.network.server_port), false);
|
|
||||||
|
|
||||||
_network_company_states = CallocT<NetworkCompanyState>(MAX_COMPANIES);
|
_network_company_states = CallocT<NetworkCompanyState>(MAX_COMPANIES);
|
||||||
_network_server = true;
|
_network_server = true;
|
||||||
|
@ -74,6 +74,7 @@ protected:
|
|||||||
DECLARE_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_DETAIL_INFO);
|
DECLARE_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_DETAIL_INFO);
|
||||||
DECLARE_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_GET_NEWGRFS);
|
DECLARE_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_GET_NEWGRFS);
|
||||||
public:
|
public:
|
||||||
|
ServerNetworkUDPSocketHandler(NetworkAddressList *addresses) : NetworkUDPSocketHandler(addresses) {}
|
||||||
virtual ~ServerNetworkUDPSocketHandler() {}
|
virtual ~ServerNetworkUDPSocketHandler() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -376,7 +377,7 @@ static void NetworkUDPBroadCast(NetworkUDPSocketHandler *socket)
|
|||||||
|
|
||||||
DEBUG(net, 4, "[udp] broadcasting to %s", addr->GetHostname());
|
DEBUG(net, 4, "[udp] broadcasting to %s", addr->GetHostname());
|
||||||
|
|
||||||
socket->SendPacket(&p, addr);
|
socket->SendPacket(&p, addr, true, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,10 +385,6 @@ static void NetworkUDPBroadCast(NetworkUDPSocketHandler *socket)
|
|||||||
/* Request the the server-list from the master server */
|
/* Request the the server-list from the master server */
|
||||||
void NetworkUDPQueryMasterServer()
|
void NetworkUDPQueryMasterServer()
|
||||||
{
|
{
|
||||||
if (!_udp_client_socket->IsConnected()) {
|
|
||||||
if (!_udp_client_socket->Listen(NetworkAddress(), true)) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Packet p(PACKET_UDP_CLIENT_GET_LIST);
|
Packet p(PACKET_UDP_CLIENT_GET_LIST);
|
||||||
NetworkAddress out_addr(NETWORK_MASTER_SERVER_HOST, NETWORK_MASTER_SERVER_PORT);
|
NetworkAddress out_addr(NETWORK_MASTER_SERVER_HOST, NETWORK_MASTER_SERVER_PORT);
|
||||||
|
|
||||||
@ -405,11 +402,6 @@ void NetworkUDPSearchGame()
|
|||||||
/* We are still searching.. */
|
/* We are still searching.. */
|
||||||
if (_network_udp_broadcast > 0) return;
|
if (_network_udp_broadcast > 0) return;
|
||||||
|
|
||||||
/* No UDP-socket yet.. */
|
|
||||||
if (!_udp_client_socket->IsConnected()) {
|
|
||||||
if (!_udp_client_socket->Listen(NetworkAddress(), true)) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG(net, 0, "[udp] searching server");
|
DEBUG(net, 0, "[udp] searching server");
|
||||||
|
|
||||||
NetworkUDPBroadCast(_udp_client_socket);
|
NetworkUDPBroadCast(_udp_client_socket);
|
||||||
@ -453,11 +445,6 @@ void NetworkUDPQueryServerThread(void *pntr)
|
|||||||
|
|
||||||
void NetworkUDPQueryServer(NetworkAddress address, bool manually)
|
void NetworkUDPQueryServer(NetworkAddress address, bool manually)
|
||||||
{
|
{
|
||||||
/* No UDP-socket yet.. */
|
|
||||||
if (!_udp_client_socket->IsConnected()) {
|
|
||||||
if (!_udp_client_socket->Listen(NetworkAddress(), true)) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
NetworkUDPQueryServerInfo *info = new NetworkUDPQueryServerInfo(address, manually);
|
NetworkUDPQueryServerInfo *info = new NetworkUDPQueryServerInfo(address, manually);
|
||||||
if (address.IsResolved() || !ThreadObject::New(NetworkUDPQueryServerThread, info)) {
|
if (address.IsResolved() || !ThreadObject::New(NetworkUDPQueryServerThread, info)) {
|
||||||
NetworkUDPQueryServerThread(info);
|
NetworkUDPQueryServerThread(info);
|
||||||
@ -488,11 +475,6 @@ void NetworkUDPRemoveAdvertise()
|
|||||||
/* Check if we are advertising */
|
/* Check if we are advertising */
|
||||||
if (!_networking || !_network_server || !_network_udp_server) return;
|
if (!_networking || !_network_server || !_network_udp_server) return;
|
||||||
|
|
||||||
/* check for socket */
|
|
||||||
if (!_udp_master_socket->IsConnected()) {
|
|
||||||
if (!_udp_master_socket->Listen(NetworkAddress(_settings_client.network.server_bind_ip, 0), false)) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ThreadObject::New(NetworkUDPRemoveAdvertiseThread, NULL)) {
|
if (!ThreadObject::New(NetworkUDPRemoveAdvertiseThread, NULL)) {
|
||||||
NetworkUDPRemoveAdvertiseThread(NULL);
|
NetworkUDPRemoveAdvertiseThread(NULL);
|
||||||
}
|
}
|
||||||
@ -526,11 +508,6 @@ void NetworkUDPAdvertise()
|
|||||||
if (!_networking || !_network_server || !_network_udp_server || !_settings_client.network.server_advertise)
|
if (!_networking || !_network_server || !_network_udp_server || !_settings_client.network.server_advertise)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* check for socket */
|
|
||||||
if (!_udp_master_socket->IsConnected()) {
|
|
||||||
if (!_udp_master_socket->Listen(NetworkAddress(_settings_client.network.server_bind_ip, 0), false)) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_network_need_advertise) {
|
if (_network_need_advertise) {
|
||||||
_network_need_advertise = false;
|
_network_need_advertise = false;
|
||||||
_network_advertise_retries = ADVERTISE_RETRY_TIMES;
|
_network_advertise_retries = ADVERTISE_RETRY_TIMES;
|
||||||
@ -559,8 +536,12 @@ void NetworkUDPInitialize()
|
|||||||
assert(_udp_client_socket == NULL && _udp_server_socket == NULL && _udp_master_socket == NULL);
|
assert(_udp_client_socket == NULL && _udp_server_socket == NULL && _udp_master_socket == NULL);
|
||||||
|
|
||||||
_network_udp_mutex->BeginCritical();
|
_network_udp_mutex->BeginCritical();
|
||||||
|
|
||||||
|
NetworkAddressList server;
|
||||||
|
*server.Append() = NetworkAddress(_settings_client.network.server_bind_ip, _settings_client.network.server_port);
|
||||||
|
|
||||||
_udp_client_socket = new ClientNetworkUDPSocketHandler();
|
_udp_client_socket = new ClientNetworkUDPSocketHandler();
|
||||||
_udp_server_socket = new ServerNetworkUDPSocketHandler();
|
_udp_server_socket = new ServerNetworkUDPSocketHandler(&server);
|
||||||
_udp_master_socket = new MasterNetworkUDPSocketHandler();
|
_udp_master_socket = new MasterNetworkUDPSocketHandler();
|
||||||
|
|
||||||
_network_udp_server = false;
|
_network_udp_server = false;
|
||||||
|
Loading…
Reference in New Issue
Block a user