Codechange: use connection_string in favour of NetworkAddress (#9197)

We now resolve the connection_string to a NetworkAddress in a much
later state. This means there are fewer places constructing a NetworkAddress.

The main benefit of this is in later PRs that introduce different types
of NetworkAddresses. Storing this in things like NetworkGameList is
rather complex, especially as NetworkAddress has to be mutable at all
times.

Additionally, the NetworkAddress is a complex object to store simple
information: how to connect to this server.
pull/332/head
Patric Stout 3 years ago committed by GitHub
parent ead30dc725
commit f94fb93779
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -77,7 +77,7 @@ protected:
NetworkAddress address;
public:
TCPConnecter(const NetworkAddress &address);
TCPConnecter(const std::string &connection_string, uint16 default_port);
/** Silence the warnings */
virtual ~TCPConnecter() {}

@ -13,6 +13,7 @@
#include "../../thread.h"
#include "tcp.h"
#include "../network_internal.h"
#include "../../safeguards.h"
@ -21,15 +22,16 @@ static std::vector<TCPConnecter *> _tcp_connecters;
/**
* Create a new connecter for the given address
* @param address the (un)resolved address to connect to
* @param connection_string the address to connect to
*/
TCPConnecter::TCPConnecter(const NetworkAddress &address) :
TCPConnecter::TCPConnecter(const std::string &connection_string, uint16 default_port) :
connected(false),
aborted(false),
killed(false),
sock(INVALID_SOCKET),
address(address)
sock(INVALID_SOCKET)
{
this->address = ParseConnectionString(connection_string, default_port);
_tcp_connecters.push_back(this);
if (!StartNewThread(nullptr, "ottd:tcp", &TCPConnecter::ThreadEntry, this)) {
this->Connect();

@ -203,11 +203,9 @@ int NetworkHTTPSocketHandler::HandleHeader()
*url = '\0';
NetworkAddress address = ParseConnectionString(hname, 80);
/* Restore the URL. */
*url = '/';
new NetworkHTTPContentConnecter(address, callback, url, data, depth);
new NetworkHTTPContentConnecter(hname, callback, url, data, depth);
return 0;
}

@ -81,16 +81,14 @@ class NetworkHTTPContentConnecter : TCPConnecter {
public:
/**
* Start the connecting.
* @param address the address to connect to
* @param callback the callback for HTTP retrieval
* @param url the url at the server
* @param data the data to send
* @param depth the depth (redirect recursion) of the queries
* @param connection_string The address to connect to.
* @param callback The callback for HTTP retrieval.
* @param url The url at the server.
* @param data The data to send.
* @param depth The depth (redirect recursion) of the queries.
*/
NetworkHTTPContentConnecter(const NetworkAddress &address,
HTTPCallback *callback, const char *url,
const char *data = nullptr, int depth = 0) :
TCPConnecter(address),
NetworkHTTPContentConnecter(const std::string &connection_string, HTTPCallback *callback, const char *url, const char *data = nullptr, int depth = 0) :
TCPConnecter(connection_string, 80),
callback(callback),
url(stredup(url)),
data(data),

@ -515,7 +515,7 @@ NetworkAddress ParseConnectionString(const std::string &connection_string, int d
* @param default_port The default port to set port to if not in connection_string.
* @return A valid NetworkAddress of the parsed information.
*/
NetworkAddress ParseGameConnectionString(CompanyID *company, const std::string &connection_string, int default_port)
static NetworkAddress ParseGameConnectionString(CompanyID *company, const std::string &connection_string, int default_port)
{
char internal_connection_string[NETWORK_HOSTNAME_PORT_LENGTH + 4]; // 4 extra for the "#" and company
strecpy(internal_connection_string, connection_string.c_str(), lastof(internal_connection_string));
@ -524,7 +524,20 @@ NetworkAddress ParseGameConnectionString(CompanyID *company, const std::string &
const char *company_s = nullptr;
ParseFullConnectionString(&company_s, &port_s, internal_connection_string);
if (company_s != nullptr) *company = (CompanyID)atoi(company_s);
if (company_s != nullptr) {
uint company_value = atoi(company_s);
if (company_value != COMPANY_NEW_COMPANY && company_value != COMPANY_SPECTATOR) {
if (company_value > MAX_COMPANIES || company_value == 0) {
*company = COMPANY_SPECTATOR;
} else {
/* "#1" means the first company, which has index 0. */
*company = (CompanyID)(company_value - 1);
}
} else {
*company = (CompanyID)company_value;
}
}
int port = port_s != nullptr ? atoi(port_s) : default_port;
return NetworkAddress(internal_connection_string, port);
@ -607,9 +620,10 @@ static void NetworkInitialize(bool close_admins = true)
class TCPQueryConnecter : TCPConnecter {
private:
bool request_company_info;
std::string connection_string;
public:
TCPQueryConnecter(const NetworkAddress &address, bool request_company_info) : TCPConnecter(address), request_company_info(request_company_info) {}
TCPQueryConnecter(const std::string &connection_string, bool request_company_info) : TCPConnecter(connection_string, NETWORK_DEFAULT_PORT), request_company_info(request_company_info), connection_string(connection_string) {}
void OnFailure() override
{
@ -619,24 +633,24 @@ public:
void OnConnect(SOCKET s) override
{
_networking = true;
new ClientNetworkGameSocketHandler(s, address);
new ClientNetworkGameSocketHandler(s, this->connection_string);
MyClient::SendInformationQuery(request_company_info);
}
};
/**
* Query a server to fetch his game-info.
* @param address the address to query.
* @param connection_string the address to query.
* @param request_company_info Whether to request company info too.
*/
void NetworkTCPQueryServer(NetworkAddress address, bool request_company_info)
void NetworkTCPQueryServer(const std::string &connection_string, bool request_company_info)
{
if (!_network_available) return;
NetworkDisconnect();
NetworkInitialize();
new TCPQueryConnecter(address, request_company_info);
new TCPQueryConnecter(connection_string, request_company_info);
}
/**
@ -650,20 +664,18 @@ NetworkGameList *NetworkAddServer(const std::string &connection_string)
{
if (connection_string.empty()) return nullptr;
NetworkAddress address = ParseConnectionString(connection_string, NETWORK_DEFAULT_PORT);
/* Ensure the item already exists in the list */
NetworkGameList *item = NetworkGameListAddItem(address);
NetworkGameList *item = NetworkGameListAddItem(connection_string);
if (StrEmpty(item->info.server_name)) {
ClearGRFConfigList(&item->info.grfconfig);
address.GetAddressAsString(item->info.server_name, lastof(item->info.server_name));
strecpy(item->info.server_name, connection_string.c_str(), lastof(item->info.server_name));
item->manually = true;
NetworkRebuildHostList();
UpdateNetworkGameWindow();
}
NetworkTCPQueryServer(address);
NetworkTCPQueryServer(connection_string);
return item;
}
@ -693,14 +705,17 @@ void NetworkRebuildHostList()
_network_host_list.clear();
for (NetworkGameList *item = _network_game_list; item != nullptr; item = item->next) {
if (item->manually) _network_host_list.emplace_back(item->address.GetAddressAsString(false));
if (item->manually) _network_host_list.emplace_back(item->connection_string);
}
}
/** Non blocking connection create to actually connect to servers */
class TCPClientConnecter : TCPConnecter {
private:
std::string connection_string;
public:
TCPClientConnecter(const NetworkAddress &address) : TCPConnecter(address) {}
TCPClientConnecter(const std::string &connection_string) : TCPConnecter(connection_string, NETWORK_DEFAULT_PORT), connection_string(connection_string) {}
void OnFailure() override
{
@ -710,7 +725,7 @@ public:
void OnConnect(SOCKET s) override
{
_networking = true;
new ClientNetworkGameSocketHandler(s, this->address);
new ClientNetworkGameSocketHandler(s, this->connection_string);
IConsoleCmdExec("exec scripts/on_client.scr 0");
NetworkClient_Connected();
}
@ -736,34 +751,12 @@ public:
bool NetworkClientConnectGame(const std::string &connection_string, CompanyID default_company, const char *join_server_password, const char *join_company_password)
{
CompanyID join_as = default_company;
NetworkAddress address = ParseGameConnectionString(&join_as, connection_string, NETWORK_DEFAULT_PORT);
std::string resolved_connection_string = ParseGameConnectionString(&join_as, connection_string, NETWORK_DEFAULT_PORT).GetAddressAsString(false);
if (join_as != COMPANY_NEW_COMPANY && join_as != COMPANY_SPECTATOR) {
join_as--;
if (join_as >= MAX_COMPANIES) {
return false;
}
}
return NetworkClientConnectGame(address, join_as, join_server_password, join_company_password);
}
/**
* Join a client to the server at the given address.
* See the overloaded NetworkClientConnectGame for more details.
*
* @param address The network address of the server to join to.
* @param join_as The company number to join as.
* @param join_server_password The password for the server.
* @param join_company_password The password for the company.
* @return Whether the join has started.
*/
bool NetworkClientConnectGame(NetworkAddress &address, CompanyID join_as, const char *join_server_password, const char *join_company_password)
{
if (!_network_available) return false;
if (!NetworkValidateClientName()) return false;
_network_join.address = address;
_network_join.connection_string = resolved_connection_string;
_network_join.company = join_as;
_network_join.server_password = join_server_password;
_network_join.company_password = join_company_password;
@ -792,11 +785,11 @@ void NetworkClientJoinGame()
NetworkDisconnect();
NetworkInitialize();
strecpy(_settings_client.network.last_joined, _network_join.address.GetAddressAsString(false).c_str(), lastof(_settings_client.network.last_joined));
strecpy(_settings_client.network.last_joined, _network_join.connection_string.c_str(), lastof(_settings_client.network.last_joined));
_network_join_status = NETWORK_JOIN_STATUS_CONNECTING;
ShowJoinStatusWindow();
new TCPClientConnecter(_network_join.address);
new TCPClientConnecter(_network_join.connection_string);
}
static void NetworkInitGameInfo()

@ -145,7 +145,7 @@ void ClientNetworkEmergencySave()
* Create a new socket for the client side of the game connection.
* @param s The socket to connect with.
*/
ClientNetworkGameSocketHandler::ClientNetworkGameSocketHandler(SOCKET s, NetworkAddress address) : NetworkGameSocketHandler(s), address(address), savegame(nullptr), status(STATUS_INACTIVE)
ClientNetworkGameSocketHandler::ClientNetworkGameSocketHandler(SOCKET s, const std::string &connection_string) : NetworkGameSocketHandler(s), connection_string(connection_string), savegame(nullptr), status(STATUS_INACTIVE)
{
assert(ClientNetworkGameSocketHandler::my_client == nullptr);
ClientNetworkGameSocketHandler::my_client = this;
@ -581,7 +581,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_GAME_INFO(Packe
NetworkGameList *item = GetLobbyGameInfo();
if (item == nullptr) {
/* This is not the lobby, so add it to the game list. */
item = NetworkGameListAddItem(this->address);
item = NetworkGameListAddItem(this->connection_string);
}
/* Clear any existing GRFConfig chain. */

@ -15,7 +15,7 @@
/** Class for handling the client side of the game connection. */
class ClientNetworkGameSocketHandler : public ZeroedMemoryAllocator, public NetworkGameSocketHandler {
private:
NetworkAddress address; ///< Address we are connected to.
std::string connection_string; ///< Address we are connected to.
struct PacketReader *savegame; ///< Packet reader for reading the savegame.
byte token; ///< The token we need to send back to the server to prove we're the right client.
@ -76,7 +76,7 @@ protected:
static NetworkRecvStatus SendMapOk();
void CheckConnection();
public:
ClientNetworkGameSocketHandler(SOCKET s, NetworkAddress address);
ClientNetworkGameSocketHandler(SOCKET s, const std::string &connection_string);
~ClientNetworkGameSocketHandler();
NetworkRecvStatus CloseConnection(NetworkRecvStatus status) override;
@ -115,10 +115,10 @@ void NetworkClientSetCompanyPassword(const char *password);
/** Information required to join a server. */
struct NetworkJoinInfo {
NetworkJoinInfo() : company(COMPANY_SPECTATOR), server_password(nullptr), company_password(nullptr) {}
NetworkAddress address; ///< The address of the server to join.
CompanyID company; ///< The company to join.
const char *server_password; ///< The password of the server to join.
const char *company_password; ///< The password of the company to join.
std::string connection_string; ///< The address of the server to join.
CompanyID company; ///< The company to join.
const char *server_password; ///< The password of the server to join.
const char *company_password; ///< The password of the company to join.
};
extern NetworkJoinInfo _network_join;

@ -343,8 +343,7 @@ void ClientNetworkContentSocketHandler::DownloadSelectedContentHTTP(const Conten
this->http_response_index = -1;
NetworkAddress address(NETWORK_CONTENT_MIRROR_HOST, NETWORK_CONTENT_MIRROR_PORT);
new NetworkHTTPContentConnecter(address, this, NETWORK_CONTENT_MIRROR_URL, content_request);
new NetworkHTTPContentConnecter(NETWORK_CONTENT_MIRROR_HOST, this, NETWORK_CONTENT_MIRROR_URL, content_request);
/* NetworkHTTPContentConnecter takes over freeing of content_request! */
}
@ -744,7 +743,7 @@ public:
* Initiate the connecting.
* @param address The address of the server.
*/
NetworkContentConnecter(const NetworkAddress &address) : TCPConnecter(address) {}
NetworkContentConnecter(const std::string &connection_string) : TCPConnecter(connection_string, NETWORK_CONTENT_SERVER_PORT) {}
void OnFailure() override
{
@ -770,7 +769,7 @@ void ClientNetworkContentSocketHandler::Connect()
{
if (this->sock != INVALID_SOCKET || this->isConnecting) return;
this->isConnecting = true;
new NetworkContentConnecter(NetworkAddress(NETWORK_CONTENT_SERVER_HOST, NETWORK_CONTENT_SERVER_PORT, AF_UNSPEC));
new NetworkContentConnecter(NETWORK_CONTENT_SERVER_HOST);
}
/**

@ -44,7 +44,7 @@ static void NetworkGameListHandleDelayedInsert()
while (ins_item != nullptr && !_network_game_delayed_insertion_list.compare_exchange_weak(ins_item, ins_item->next, std::memory_order_acq_rel)) {}
if (ins_item == nullptr) break; // No item left.
NetworkGameList *item = NetworkGameListAddItem(ins_item->address);
NetworkGameList *item = NetworkGameListAddItem(ins_item->connection_string);
if (item != nullptr) {
if (StrEmpty(item->info.server_name)) {
@ -67,19 +67,22 @@ static void NetworkGameListHandleDelayedInsert()
* @param address the address of the to-be added item
* @return a point to the newly added or already existing item
*/
NetworkGameList *NetworkGameListAddItem(NetworkAddress address)
NetworkGameList *NetworkGameListAddItem(const std::string &connection_string)
{
NetworkGameList *item, *prev_item;
/* Parse the connection string to ensure the default port is there. */
const std::string resolved_connection_string = ParseConnectionString(connection_string, NETWORK_DEFAULT_PORT).GetAddressAsString(false);
prev_item = nullptr;
for (item = _network_game_list; item != nullptr; item = item->next) {
if (item->address == address) return item;
if (item->connection_string == resolved_connection_string) return item;
prev_item = item;
}
item = CallocT<NetworkGameList>(1);
item->next = nullptr;
item->address = address;
item->connection_string = resolved_connection_string;
if (prev_item == nullptr) {
_network_game_list = item;
@ -141,7 +144,7 @@ void NetworkGameListRequery()
/* item gets mostly zeroed by NetworkUDPQueryServer */
uint8 retries = item->retries;
NetworkUDPQueryServer(item->address);
NetworkUDPQueryServer(item->connection_string);
item->retries = (retries >= REFRESH_GAMEINFO_X_REQUERIES) ? 0 : retries;
}
}

@ -16,19 +16,19 @@
/** Structure with information shown in the game list (GUI) */
struct NetworkGameList {
NetworkGameInfo info; ///< The game information of this server
NetworkAddress address; ///< The connection info of the game server
bool online; ///< False if the server did not respond (default status)
bool manually; ///< True if the server was added manually
uint8 retries; ///< Number of retries (to stop requerying)
NetworkGameList *next; ///< Next pointer to make a linked game list
NetworkGameInfo info; ///< The game information of this server
std::string connection_string; ///< Address of the server
bool online; ///< False if the server did not respond (default status)
bool manually; ///< True if the server was added manually
uint8 retries; ///< Number of retries (to stop requerying)
NetworkGameList *next; ///< Next pointer to make a linked game list
};
/** Game list of this client */
extern NetworkGameList *_network_game_list;
void NetworkGameListAddItemDelayed(NetworkGameList *item);
NetworkGameList *NetworkGameListAddItem(NetworkAddress address);
NetworkGameList *NetworkGameListAddItem(const std::string &connection_string);
void NetworkGameListRemoveItem(NetworkGameList *remove);
void NetworkGameListRequery();

@ -272,7 +272,9 @@ protected:
static bool NGameNameSorter(NetworkGameList * const &a, NetworkGameList * const &b)
{
int r = strnatcmp(a->info.server_name, b->info.server_name, true); // Sort by name (natural sorting).
return r == 0 ? a->address.CompareTo(b->address) < 0: r < 0;
if (r == 0) r = a->connection_string.compare(b->connection_string);
return r < 0;
}
/**
@ -646,8 +648,7 @@ public:
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_SERVER_VERSION); // server version
y += FONT_HEIGHT_NORMAL;
std::string address = sel->address.GetAddressAsString();
SetDParamStr(0, address.c_str());
SetDParamStr(0, sel->connection_string.c_str());
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_SERVER_ADDRESS); // server address
y += FONT_HEIGHT_NORMAL;
@ -751,7 +752,7 @@ public:
break;
case WID_NG_REFRESH: // Refresh
if (this->server != nullptr) NetworkTCPQueryServer(this->server->address);
if (this->server != nullptr) NetworkTCPQueryServer(this->server->connection_string);
break;
case WID_NG_NEWGRF: // NewGRF Settings
@ -1471,22 +1472,22 @@ struct NetworkLobbyWindow : public Window {
case WID_NL_JOIN: // Join company
/* Button can be clicked only when it is enabled. */
NetworkClientConnectGame(this->server->address, this->company);
NetworkClientConnectGame(this->server->connection_string, this->company);
break;
case WID_NL_NEW: // New company
NetworkClientConnectGame(this->server->address, COMPANY_NEW_COMPANY);
NetworkClientConnectGame(this->server->connection_string, COMPANY_NEW_COMPANY);
break;
case WID_NL_SPECTATE: // Spectate game
NetworkClientConnectGame(this->server->address, COMPANY_SPECTATOR);
NetworkClientConnectGame(this->server->connection_string, COMPANY_SPECTATOR);
break;
case WID_NL_REFRESH: // Refresh
/* Clear the information so removed companies don't remain */
for (auto &company : this->company_info) company = {};
NetworkTCPQueryServer(this->server->address, true);
NetworkTCPQueryServer(this->server->connection_string, true);
break;
}
}
@ -1554,9 +1555,9 @@ static void ShowNetworkLobbyWindow(NetworkGameList *ngl)
DeleteWindowById(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_START);
DeleteWindowById(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_GAME);
strecpy(_settings_client.network.last_joined, ngl->address.GetAddressAsString(false).c_str(), lastof(_settings_client.network.last_joined));
strecpy(_settings_client.network.last_joined, ngl->connection_string.c_str(), lastof(_settings_client.network.last_joined));
NetworkTCPQueryServer(ngl->address, true);
NetworkTCPQueryServer(ngl->connection_string, true);
new NetworkLobbyWindow(&_network_lobby_window_desc, ngl);
}

@ -87,7 +87,7 @@ extern uint8 _network_reconnect;
extern CompanyMask _network_company_passworded;
void NetworkTCPQueryServer(NetworkAddress address, bool request_company_info = false);
void NetworkTCPQueryServer(const std::string &connection_string, bool request_company_info = false);
void GetBindAddresses(NetworkAddressList *addresses, uint16 port);
struct NetworkGameList *NetworkAddServer(const std::string &connection_string);
@ -119,8 +119,6 @@ StringID GetNetworkErrorMsg(NetworkErrorCode err);
bool NetworkFindName(char *new_name, const char *last);
const char *GenerateCompanyPasswordHash(const char *password, const char *password_server_id, uint32 password_game_seed);
bool NetworkClientConnectGame(NetworkAddress &address, CompanyID join_as, const char *join_server_password = nullptr, const char *join_company_password = nullptr);
NetworkAddress ParseConnectionString(const std::string &connection_string, int default_port);
NetworkAddress ParseGameConnectionString(CompanyID *company, const std::string &connection_string, int default_port);
#endif /* NETWORK_INTERNAL_H */

@ -83,35 +83,36 @@ static UDPSocket _udp_master("Master"); ///< udp master socket
/**
* Helper function doing the actual work for querying the server.
* @param address The address of the server.
* @param connection_string The address of the server.
* @param needs_mutex Whether we need to acquire locks when sending the packet or not.
* @param manually Whether the address was entered manually.
*/
static void DoNetworkUDPQueryServer(NetworkAddress &address, bool needs_mutex, bool manually)
static void DoNetworkUDPQueryServer(const std::string &connection_string, bool needs_mutex, bool manually)
{
/* Clear item in gamelist */
NetworkGameList *item = CallocT<NetworkGameList>(1);
address.GetAddressAsString(item->info.server_name, lastof(item->info.server_name));
item->address = address;
strecpy(item->info.server_name, connection_string.c_str(), lastof(item->info.server_name));
item->connection_string = connection_string;
item->manually = manually;
NetworkGameListAddItemDelayed(item);
std::unique_lock<std::mutex> lock(_udp_client.mutex, std::defer_lock);
if (needs_mutex) lock.lock();
/* Init the packet */
NetworkAddress address = NetworkAddress(ParseConnectionString(connection_string, NETWORK_DEFAULT_PORT));
Packet p(PACKET_UDP_CLIENT_FIND_SERVER);
if (_udp_client.socket != nullptr) _udp_client.socket->SendPacket(&p, &address);
}
/**
* Query a specific server.
* @param address The address of the server.
* @param connection_string The address of the server.
* @param manually Whether the address was entered manually.
*/
void NetworkUDPQueryServer(NetworkAddress address, bool manually)
void NetworkUDPQueryServer(const std::string &connection_string, bool manually)
{
if (address.IsResolved() || !StartNewThread(nullptr, "ottd:udp-query", &DoNetworkUDPQueryServer, std::move(address), true, std::move(manually))) {
DoNetworkUDPQueryServer(address, true, manually);
if (!StartNewThread(nullptr, "ottd:udp-query", &DoNetworkUDPQueryServer, std::move(connection_string), true, std::move(manually))) {
DoNetworkUDPQueryServer(connection_string, true, manually);
}
}
@ -318,7 +319,7 @@ void ClientNetworkUDPSocketHandler::Receive_SERVER_RESPONSE(Packet *p, NetworkAd
DEBUG(net, 4, "[udp] server response from %s", client_addr->GetAddressAsString().c_str());
/* Find next item */
item = NetworkGameListAddItem(*client_addr);
item = NetworkGameListAddItem(client_addr->GetAddressAsString(false));
/* Clear any existing GRFConfig chain. */
ClearGRFConfigList(&item->info.grfconfig);
@ -357,7 +358,8 @@ void ClientNetworkUDPSocketHandler::Receive_SERVER_RESPONSE(Packet *p, NetworkAd
SerializeGRFIdentifier(&packet, &in_request[i]->ident);
}
this->SendPacket(&packet, &item->address);
NetworkAddress address = NetworkAddress(ParseConnectionString(item->connection_string, NETWORK_DEFAULT_PORT));
this->SendPacket(&packet, &address);
}
}
@ -398,7 +400,7 @@ void ClientNetworkUDPSocketHandler::Receive_MASTER_RESPONSE_LIST(Packet *p, Netw
/* Somehow we reached the end of the packet */
if (this->HasClientQuit()) return;
DoNetworkUDPQueryServer(addr, false, false);
DoNetworkUDPQueryServer(addr.GetAddressAsString(false), false, false);
}
}
}

@ -15,7 +15,7 @@
void NetworkUDPInitialize();
void NetworkUDPSearchGame();
void NetworkUDPQueryMasterServer();
void NetworkUDPQueryServer(NetworkAddress address, bool manually = false);
void NetworkUDPQueryServer(const std::string &connection_string, bool manually = false);
void NetworkUDPAdvertise();
void NetworkUDPRemoveAdvertise(bool blocking);
void NetworkUDPClose();

Loading…
Cancel
Save