Update to 1.10.0-beta1
This commit is contained in:
+51
-91
@@ -14,8 +14,6 @@
|
||||
* communication before the game is being joined.
|
||||
*/
|
||||
|
||||
#ifdef ENABLE_NETWORK
|
||||
|
||||
#include "../stdafx.h"
|
||||
#include "../date_func.h"
|
||||
#include "../map_func.h"
|
||||
@@ -26,18 +24,19 @@
|
||||
#include "network.h"
|
||||
#include "../core/endian_func.hpp"
|
||||
#include "../company_base.h"
|
||||
#include "../thread/thread.h"
|
||||
#include "../thread.h"
|
||||
#include "../rev.h"
|
||||
#include "../newgrf_text.h"
|
||||
#include "../strings_func.h"
|
||||
#include "table/strings.h"
|
||||
#include <mutex>
|
||||
|
||||
#include "core/udp.h"
|
||||
|
||||
#include "../safeguards.h"
|
||||
|
||||
/** Mutex for all out threaded udp resolution and such. */
|
||||
static ThreadMutex *_network_udp_mutex = ThreadMutex::New();
|
||||
static std::mutex _network_udp_mutex;
|
||||
|
||||
/** Session key to register ourselves to the master server */
|
||||
static uint64 _session_key = 0;
|
||||
@@ -46,25 +45,9 @@ static const uint32 ADVERTISE_NORMAL_INTERVAL = 15 * 60 * 1000; ///< interval be
|
||||
static const uint32 ADVERTISE_RETRY_INTERVAL = 10 * 1000; ///< re-advertise when no response after this many ms (10 seconds)
|
||||
static const uint32 ADVERTISE_RETRY_TIMES = 3; ///< give up re-advertising after this much failed retries
|
||||
|
||||
NetworkUDPSocketHandler *_udp_client_socket = NULL; ///< udp client socket
|
||||
NetworkUDPSocketHandler *_udp_server_socket = NULL; ///< udp server socket
|
||||
NetworkUDPSocketHandler *_udp_master_socket = NULL; ///< udp master socket
|
||||
|
||||
/** Simpler wrapper struct for NetworkUDPQueryServerThread */
|
||||
struct NetworkUDPQueryServerInfo : NetworkAddress {
|
||||
bool manually; ///< Did we connect manually or not?
|
||||
|
||||
/**
|
||||
* Create the structure.
|
||||
* @param address The address of the server to query.
|
||||
* @param manually Whether the address was entered manually.
|
||||
*/
|
||||
NetworkUDPQueryServerInfo(const NetworkAddress &address, bool manually) :
|
||||
NetworkAddress(address),
|
||||
manually(manually)
|
||||
{
|
||||
}
|
||||
};
|
||||
NetworkUDPSocketHandler *_udp_client_socket = nullptr; ///< udp client socket
|
||||
NetworkUDPSocketHandler *_udp_server_socket = nullptr; ///< udp server socket
|
||||
NetworkUDPSocketHandler *_udp_master_socket = nullptr; ///< udp master socket
|
||||
|
||||
/**
|
||||
* Helper function doing the actual work for querying the server.
|
||||
@@ -72,33 +55,21 @@ struct NetworkUDPQueryServerInfo : NetworkAddress {
|
||||
* @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 NetworkUDPQueryServer(NetworkAddress *address, bool needs_mutex, bool manually)
|
||||
static void DoNetworkUDPQueryServer(NetworkAddress &address, 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));
|
||||
strecpy(item->info.hostname, address->GetHostname(), lastof(item->info.hostname));
|
||||
item->address = *address;
|
||||
address.GetAddressAsString(item->info.server_name, lastof(item->info.server_name));
|
||||
strecpy(item->info.hostname, address.GetHostname(), lastof(item->info.hostname));
|
||||
item->address = address;
|
||||
item->manually = manually;
|
||||
NetworkGameListAddItemDelayed(item);
|
||||
|
||||
if (needs_mutex) _network_udp_mutex->BeginCritical();
|
||||
std::unique_lock<std::mutex> lock(_network_udp_mutex, std::defer_lock);
|
||||
if (needs_mutex) lock.lock();
|
||||
/* Init the packet */
|
||||
Packet p(PACKET_UDP_CLIENT_FIND_SERVER);
|
||||
if (_udp_client_socket != NULL) _udp_client_socket->SendPacket(&p, address);
|
||||
if (needs_mutex) _network_udp_mutex->EndCritical();
|
||||
}
|
||||
|
||||
/**
|
||||
* Threaded part for resolving the IP of a server and querying it.
|
||||
* @param pntr the NetworkUDPQueryServerInfo.
|
||||
*/
|
||||
static void NetworkUDPQueryServerThread(void *pntr)
|
||||
{
|
||||
NetworkUDPQueryServerInfo *info = (NetworkUDPQueryServerInfo*)pntr;
|
||||
NetworkUDPQueryServer(info, true, info->manually);
|
||||
|
||||
delete info;
|
||||
if (_udp_client_socket != nullptr) _udp_client_socket->SendPacket(&p, &address);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -108,9 +79,8 @@ static void NetworkUDPQueryServerThread(void *pntr)
|
||||
*/
|
||||
void NetworkUDPQueryServer(NetworkAddress address, bool manually)
|
||||
{
|
||||
NetworkUDPQueryServerInfo *info = new NetworkUDPQueryServerInfo(address, manually);
|
||||
if (address.IsResolved() || !ThreadObject::New(NetworkUDPQueryServerThread, info, NULL, "ottd:udp-query")) {
|
||||
NetworkUDPQueryServerThread(info);
|
||||
if (address.IsResolved() || !StartNewThread(nullptr, "ottd:udp-query", &DoNetworkUDPQueryServer, std::move(address), true, std::move(manually))) {
|
||||
DoNetworkUDPQueryServer(address, true, manually);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,8 +89,8 @@ void NetworkUDPQueryServer(NetworkAddress address, bool manually)
|
||||
/** Helper class for connecting to the master server. */
|
||||
class MasterNetworkUDPSocketHandler : public NetworkUDPSocketHandler {
|
||||
protected:
|
||||
virtual void Receive_MASTER_ACK_REGISTER(Packet *p, NetworkAddress *client_addr);
|
||||
virtual void Receive_MASTER_SESSION_KEY(Packet *p, NetworkAddress *client_addr);
|
||||
void Receive_MASTER_ACK_REGISTER(Packet *p, NetworkAddress *client_addr) override;
|
||||
void Receive_MASTER_SESSION_KEY(Packet *p, NetworkAddress *client_addr) override;
|
||||
public:
|
||||
/**
|
||||
* Create the socket.
|
||||
@@ -150,9 +120,9 @@ void MasterNetworkUDPSocketHandler::Receive_MASTER_SESSION_KEY(Packet *p, Networ
|
||||
/** Helper class for handling all server side communication. */
|
||||
class ServerNetworkUDPSocketHandler : public NetworkUDPSocketHandler {
|
||||
protected:
|
||||
virtual void Receive_CLIENT_FIND_SERVER(Packet *p, NetworkAddress *client_addr);
|
||||
virtual void Receive_CLIENT_DETAIL_INFO(Packet *p, NetworkAddress *client_addr);
|
||||
virtual void Receive_CLIENT_GET_NEWGRFS(Packet *p, NetworkAddress *client_addr);
|
||||
void Receive_CLIENT_FIND_SERVER(Packet *p, NetworkAddress *client_addr) override;
|
||||
void Receive_CLIENT_DETAIL_INFO(Packet *p, NetworkAddress *client_addr) override;
|
||||
void Receive_CLIENT_GET_NEWGRFS(Packet *p, NetworkAddress *client_addr) override;
|
||||
public:
|
||||
/**
|
||||
* Create the socket.
|
||||
@@ -291,7 +261,7 @@ void ServerNetworkUDPSocketHandler::Receive_CLIENT_GET_NEWGRFS(Packet *p, Networ
|
||||
|
||||
/* Find the matching GRF file */
|
||||
f = FindGRFConfig(c.grfid, FGCM_EXACT, c.md5sum);
|
||||
if (f == NULL) continue; // The GRF is unknown to this server
|
||||
if (f == nullptr) continue; // The GRF is unknown to this server
|
||||
|
||||
/* If the reply might exceed the size of the packet, only reply
|
||||
* the current list and do not send the other data.
|
||||
@@ -326,10 +296,10 @@ void ServerNetworkUDPSocketHandler::Receive_CLIENT_GET_NEWGRFS(Packet *p, Networ
|
||||
/** Helper class for handling all client side communication. */
|
||||
class ClientNetworkUDPSocketHandler : public NetworkUDPSocketHandler {
|
||||
protected:
|
||||
virtual void Receive_SERVER_RESPONSE(Packet *p, NetworkAddress *client_addr);
|
||||
virtual void Receive_MASTER_RESPONSE_LIST(Packet *p, NetworkAddress *client_addr);
|
||||
virtual void Receive_SERVER_NEWGRFS(Packet *p, NetworkAddress *client_addr);
|
||||
virtual void HandleIncomingNetworkGameInfoGRFConfig(GRFConfig *config);
|
||||
void Receive_SERVER_RESPONSE(Packet *p, NetworkAddress *client_addr) override;
|
||||
void Receive_MASTER_RESPONSE_LIST(Packet *p, NetworkAddress *client_addr) override;
|
||||
void Receive_SERVER_NEWGRFS(Packet *p, NetworkAddress *client_addr) override;
|
||||
void HandleIncomingNetworkGameInfoGRFConfig(GRFConfig *config) override;
|
||||
public:
|
||||
virtual ~ClientNetworkUDPSocketHandler() {}
|
||||
};
|
||||
@@ -362,7 +332,7 @@ void ClientNetworkUDPSocketHandler::Receive_SERVER_RESPONSE(Packet *p, NetworkAd
|
||||
const GRFConfig *c;
|
||||
uint in_request_count = 0;
|
||||
|
||||
for (c = item->info.grfconfig; c != NULL; c = c->next) {
|
||||
for (c = item->info.grfconfig; c != nullptr; c = c->next) {
|
||||
if (c->status == GCS_NOT_FOUND) item->info.compatible = false;
|
||||
if (c->status != GCS_NOT_FOUND || strcmp(c->GetName(), UNKNOWN_GRF_NAME_PLACEHOLDER) != 0) continue;
|
||||
in_request[in_request_count] = c;
|
||||
@@ -430,7 +400,7 @@ void ClientNetworkUDPSocketHandler::Receive_MASTER_RESPONSE_LIST(Packet *p, Netw
|
||||
/* Somehow we reached the end of the packet */
|
||||
if (this->HasClientQuit()) return;
|
||||
|
||||
NetworkUDPQueryServer(&addr, false, false);
|
||||
DoNetworkUDPQueryServer(addr, false, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -461,7 +431,7 @@ void ClientNetworkUDPSocketHandler::Receive_SERVER_NEWGRFS(Packet *p, NetworkAdd
|
||||
* If it exists and not resolved yet, then name of the fake GRF is
|
||||
* overwritten with the name from the reply. */
|
||||
GRFTextWrapper *unknown_name = FindUnknownGRFName(c.grfid, c.md5sum, false);
|
||||
if (unknown_name != NULL && strcmp(GetGRFStringFromGRFText(unknown_name->text), UNKNOWN_GRF_NAME_PLACEHOLDER) == 0) {
|
||||
if (unknown_name != nullptr && strcmp(GetGRFStringFromGRFText(unknown_name->text), UNKNOWN_GRF_NAME_PLACEHOLDER) == 0) {
|
||||
AddGRFTextToList(&unknown_name->text, name);
|
||||
}
|
||||
}
|
||||
@@ -471,7 +441,7 @@ void ClientNetworkUDPSocketHandler::HandleIncomingNetworkGameInfoGRFConfig(GRFCo
|
||||
{
|
||||
/* Find the matching GRF file */
|
||||
const GRFConfig *f = FindGRFConfig(config->ident.grfid, FGCM_EXACT, config->ident.md5sum);
|
||||
if (f == NULL) {
|
||||
if (f == nullptr) {
|
||||
/* Don't know the GRF, so mark game incompatible and the (possibly)
|
||||
* already resolved name for this GRF (another server has sent the
|
||||
* name of the GRF already */
|
||||
@@ -497,12 +467,12 @@ void ClientNetworkUDPSocketHandler::HandleIncomingNetworkGameInfoGRFConfig(GRFCo
|
||||
/** Broadcast to all ips */
|
||||
static void NetworkUDPBroadCast(NetworkUDPSocketHandler *socket)
|
||||
{
|
||||
for (NetworkAddress *addr = _broadcast_list.Begin(); addr != _broadcast_list.End(); addr++) {
|
||||
for (NetworkAddress &addr : _broadcast_list) {
|
||||
Packet p(PACKET_UDP_CLIENT_FIND_SERVER);
|
||||
|
||||
DEBUG(net, 4, "[udp] broadcasting to %s", addr->GetHostname());
|
||||
DEBUG(net, 4, "[udp] broadcasting to %s", addr.GetHostname());
|
||||
|
||||
socket->SendPacket(&p, addr, true, true);
|
||||
socket->SendPacket(&p, &addr, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -536,9 +506,8 @@ void NetworkUDPSearchGame()
|
||||
|
||||
/**
|
||||
* Thread entry point for de-advertising.
|
||||
* @param pntr unused.
|
||||
*/
|
||||
static void NetworkUDPRemoveAdvertiseThread(void *pntr)
|
||||
static void NetworkUDPRemoveAdvertiseThread()
|
||||
{
|
||||
DEBUG(net, 1, "[udp] removing advertise from master server");
|
||||
|
||||
@@ -551,9 +520,8 @@ static void NetworkUDPRemoveAdvertiseThread(void *pntr)
|
||||
p.Send_uint8 (NETWORK_MASTER_SERVER_VERSION);
|
||||
p.Send_uint16(_settings_client.network.server_port);
|
||||
|
||||
_network_udp_mutex->BeginCritical();
|
||||
if (_udp_master_socket != NULL) _udp_master_socket->SendPacket(&p, &out_addr, true);
|
||||
_network_udp_mutex->EndCritical();
|
||||
std::lock_guard<std::mutex> lock(_network_udp_mutex);
|
||||
if (_udp_master_socket != nullptr) _udp_master_socket->SendPacket(&p, &out_addr, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -565,16 +533,15 @@ void NetworkUDPRemoveAdvertise(bool blocking)
|
||||
/* Check if we are advertising */
|
||||
if (!_networking || !_network_server || !_network_udp_server) return;
|
||||
|
||||
if (blocking || !ThreadObject::New(NetworkUDPRemoveAdvertiseThread, NULL, NULL, "ottd:udp-advert")) {
|
||||
NetworkUDPRemoveAdvertiseThread(NULL);
|
||||
if (blocking || !StartNewThread(nullptr, "ottd:udp-advert", &NetworkUDPRemoveAdvertiseThread)) {
|
||||
NetworkUDPRemoveAdvertiseThread();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Thread entry point for advertising.
|
||||
* @param pntr unused.
|
||||
*/
|
||||
static void NetworkUDPAdvertiseThread(void *pntr)
|
||||
static void NetworkUDPAdvertiseThread()
|
||||
{
|
||||
/* Find somewhere to send */
|
||||
NetworkAddress out_addr(NETWORK_MASTER_SERVER_HOST, NETWORK_MASTER_SERVER_PORT);
|
||||
@@ -605,9 +572,8 @@ static void NetworkUDPAdvertiseThread(void *pntr)
|
||||
p.Send_uint16(_settings_client.network.server_port);
|
||||
p.Send_uint64(_session_key);
|
||||
|
||||
_network_udp_mutex->BeginCritical();
|
||||
if (_udp_master_socket != NULL) _udp_master_socket->SendPacket(&p, &out_addr, true);
|
||||
_network_udp_mutex->EndCritical();
|
||||
std::lock_guard<std::mutex> lock(_network_udp_mutex);
|
||||
if (_udp_master_socket != nullptr) _udp_master_socket->SendPacket(&p, &out_addr, true);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -648,8 +614,8 @@ void NetworkUDPAdvertise()
|
||||
if (_next_advertisement < _last_advertisement) _next_advertisement = UINT32_MAX;
|
||||
if (_next_retry < _last_advertisement) _next_retry = UINT32_MAX;
|
||||
|
||||
if (!ThreadObject::New(NetworkUDPAdvertiseThread, NULL, NULL, "ottd:udp-advert")) {
|
||||
NetworkUDPAdvertiseThread(NULL);
|
||||
if (!StartNewThread(nullptr, "ottd:udp-advert", &NetworkUDPAdvertiseThread)) {
|
||||
NetworkUDPAdvertiseThread();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -657,12 +623,12 @@ void NetworkUDPAdvertise()
|
||||
void NetworkUDPInitialize()
|
||||
{
|
||||
/* If not closed, then do it. */
|
||||
if (_udp_server_socket != NULL) NetworkUDPClose();
|
||||
if (_udp_server_socket != nullptr) NetworkUDPClose();
|
||||
|
||||
DEBUG(net, 1, "[udp] initializing listeners");
|
||||
assert(_udp_client_socket == NULL && _udp_server_socket == NULL && _udp_master_socket == NULL);
|
||||
assert(_udp_client_socket == nullptr && _udp_server_socket == nullptr && _udp_master_socket == nullptr);
|
||||
|
||||
_network_udp_mutex->BeginCritical();
|
||||
std::lock_guard<std::mutex> lock(_network_udp_mutex);
|
||||
|
||||
_udp_client_socket = new ClientNetworkUDPSocketHandler();
|
||||
|
||||
@@ -670,29 +636,27 @@ void NetworkUDPInitialize()
|
||||
GetBindAddresses(&server, _settings_client.network.server_port);
|
||||
_udp_server_socket = new ServerNetworkUDPSocketHandler(&server);
|
||||
|
||||
server.Clear();
|
||||
server.clear();
|
||||
GetBindAddresses(&server, 0);
|
||||
_udp_master_socket = new MasterNetworkUDPSocketHandler(&server);
|
||||
|
||||
_network_udp_server = false;
|
||||
_network_udp_broadcast = 0;
|
||||
_network_udp_mutex->EndCritical();
|
||||
}
|
||||
|
||||
/** Close all UDP related stuff. */
|
||||
void NetworkUDPClose()
|
||||
{
|
||||
_network_udp_mutex->BeginCritical();
|
||||
std::lock_guard<std::mutex> lock(_network_udp_mutex);
|
||||
_udp_server_socket->Close();
|
||||
_udp_master_socket->Close();
|
||||
_udp_client_socket->Close();
|
||||
delete _udp_client_socket;
|
||||
delete _udp_server_socket;
|
||||
delete _udp_master_socket;
|
||||
_udp_client_socket = NULL;
|
||||
_udp_server_socket = NULL;
|
||||
_udp_master_socket = NULL;
|
||||
_network_udp_mutex->EndCritical();
|
||||
_udp_client_socket = nullptr;
|
||||
_udp_server_socket = nullptr;
|
||||
_udp_master_socket = nullptr;
|
||||
|
||||
_network_udp_server = false;
|
||||
_network_udp_broadcast = 0;
|
||||
@@ -702,7 +666,7 @@ void NetworkUDPClose()
|
||||
/** Receive the UDP packets. */
|
||||
void NetworkBackgroundUDPLoop()
|
||||
{
|
||||
_network_udp_mutex->BeginCritical();
|
||||
std::lock_guard<std::mutex> lock(_network_udp_mutex);
|
||||
|
||||
if (_network_udp_server) {
|
||||
_udp_server_socket->ReceivePackets();
|
||||
@@ -711,8 +675,4 @@ void NetworkBackgroundUDPLoop()
|
||||
_udp_client_socket->ReceivePackets();
|
||||
if (_network_udp_broadcast > 0) _network_udp_broadcast--;
|
||||
}
|
||||
|
||||
_network_udp_mutex->EndCritical();
|
||||
}
|
||||
|
||||
#endif /* ENABLE_NETWORK */
|
||||
|
||||
Reference in New Issue
Block a user