Merge branch 'master' into jgrpp-beta

# Conflicts:
#	src/lang/arabic_egypt.txt
#	src/lang/english.txt
#	src/lang/greek.txt
#	src/network/core/tcp_connect.cpp
#	src/network/network_client.cpp
#	src/network/network_client.h
#	src/pathfinder/npf/npf.cpp
#	src/pathfinder/yapf/yapf_ship.cpp
#	src/rail_gui.cpp
#	src/settings_table.cpp
#	src/settings_type.h
#	src/station_cmd.cpp
#	src/table/settings/gui_settings.ini
#	src/town_cmd.cpp
#	src/widgets/rail_widget.h
This commit is contained in:
Jonathan G Rennison
2021-11-02 19:23:24 +00:00
99 changed files with 1632 additions and 1336 deletions

View File

@@ -22,6 +22,8 @@ add_files(
network_gui.cpp
network_gui.h
network_internal.h
network_query.cpp
network_query.h
network_server.cpp
network_server.h
network_stun.cpp

View File

@@ -205,9 +205,13 @@ void TCPConnecter::OnResolved(addrinfo *ai)
}
if (_debug_net_level >= 6) {
DEBUG(net, 6, "%s resolved in:", this->connection_string.c_str());
for (const auto &address : this->addresses) {
DEBUG(net, 6, "- %s", NetworkAddress(address->ai_addr, (int)address->ai_addrlen).GetAddressAsString().c_str());
if (this->addresses.size() == 0) {
DEBUG(net, 6, "%s did not resolve", this->connection_string.c_str());
} else {
DEBUG(net, 6, "%s resolved in:", this->connection_string.c_str());
for (const auto &address : this->addresses) {
DEBUG(net, 6, "- %s", NetworkAddress(address->ai_addr, (int)address->ai_addrlen).GetAddressAsString().c_str());
}
}
}

View File

@@ -14,6 +14,7 @@
#include "../date_func.h"
#include "network_admin.h"
#include "network_client.h"
#include "network_query.h"
#include "network_server.h"
#include "network_content.h"
#include "network_udp.h"
@@ -661,16 +662,14 @@ public:
void OnFailure() override
{
NetworkGameList *item = NetworkGameListAddItem(connection_string);
item->online = false;
item->status = NGLS_OFFLINE;
UpdateNetworkGameWindow();
}
void OnConnect(SOCKET s) override
{
_networking = true;
new ClientNetworkGameSocketHandler(s, this->connection_string);
MyClient::SendInformationQuery();
QueryNetworkGameSocketHandler::QueryServer(s, this->connection_string);
}
};
@@ -682,8 +681,6 @@ void NetworkQueryServer(const std::string &connection_string)
{
if (!_network_available) return;
NetworkInitialize();
new TCPQueryConnecter(connection_string);
}
@@ -1050,6 +1047,7 @@ void NetworkBackgroundLoop()
_network_coordinator_client.SendReceive();
TCPConnecter::CheckCallbacks();
NetworkHTTPSocketHandler::HTTPReceive();
QueryNetworkGameSocketHandler::SendReceive();
NetworkBackgroundUDPLoop();
}

View File

@@ -23,7 +23,6 @@
#include "../gfx_func.h"
#include "../error.h"
#include "../rev.h"
#include "core/game_info.h"
#include "network.h"
#include "network_base.h"
#include "network_client.h"
@@ -394,23 +393,6 @@ static_assert(NETWORK_SERVER_ID_LENGTH == 16 * 2 + 1);
* DEF_CLIENT_SEND_COMMAND has no parameters
************/
/**
* Query the server for server information.
*/
NetworkRecvStatus ClientNetworkGameSocketHandler::SendInformationQuery()
{
my_client->status = STATUS_GAME_INFO;
Packet *p = new Packet(PACKET_CLIENT_GAME_INFO);
p->Send_uint32(FIND_SERVER_EXTENDED_TOKEN);
p->Send_uint8(PACKET_SERVER_GAME_INFO_EXTENDED); // reply type
p->Send_uint16(0); // flags
p->Send_uint16(0); // version
my_client->SendPacket(p);
return NETWORK_RECV_STATUS_OKAY;
}
/** Tell the server we would like to join. */
NetworkRecvStatus ClientNetworkGameSocketHandler::SendJoin()
{
@@ -681,46 +663,6 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_BANNED(Packet *
return NETWORK_RECV_STATUS_SERVER_BANNED;
}
NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_GAME_INFO(Packet *p)
{
if (this->status != STATUS_GAME_INFO) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
NetworkGameList *item = NetworkGameListAddItem(this->connection_string);
/* Clear any existing GRFConfig chain. */
ClearGRFConfigList(&item->info.grfconfig);
/* Retrieve the NetworkGameInfo from the packet. */
DeserializeNetworkGameInfo(p, &item->info);
/* Check for compatability with the client. */
CheckGameCompatibility(item->info);
/* Ensure we consider the server online. */
item->online = true;
UpdateNetworkGameWindow();
return NETWORK_RECV_STATUS_CLOSE_QUERY;
}
NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_GAME_INFO_EXTENDED(Packet *p)
{
if (this->status != STATUS_GAME_INFO) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
NetworkGameList *item = NetworkGameListAddItem(this->connection_string);
/* Clear any existing GRFConfig chain. */
ClearGRFConfigList(&item->info.grfconfig);
/* Retrieve the NetworkGameInfo from the packet. */
DeserializeNetworkGameInfoExtended(p, &item->info);
/* Check for compatability with the client. */
CheckGameCompatibility(item->info, true);
/* Ensure we consider the server online. */
item->online = true;
UpdateNetworkGameWindow();
return NETWORK_RECV_STATUS_CLOSE_QUERY;
}
/* This packet contains info about the client (playas and name)
* as client we save this in NetworkClientInfo, linked via 'client_id'
* which is always an unique number on a server. */
@@ -809,15 +751,6 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_ERROR(Packet *p
NetworkErrorCode error = (NetworkErrorCode)p->Recv_uint8();
/* If we query a server that is 1.11.1 or older, we get an
* NETWORK_ERROR_NOT_EXPECTED on requesting the game info. Show a special
* error popup in that case.
*/
if (error == NETWORK_ERROR_NOT_EXPECTED && this->status == STATUS_GAME_INFO) {
ShowErrorMessage(STR_NETWORK_ERROR_SERVER_TOO_OLD, INVALID_STRING_ID, WL_CRITICAL);
return NETWORK_RECV_STATUS_CLOSE_QUERY;
}
StringID err = STR_NETWORK_ERROR_LOSTCONNECTION;
if (error < (ptrdiff_t)lengthof(network_error_strings)) err = network_error_strings[error];
/* In case of kicking a client, we assume there is a kick message in the packet if we can read one byte */
@@ -1370,7 +1303,6 @@ const char *ClientNetworkGameSocketHandler::GetServerStatusName(ServerStatus sta
{
static const char* _server_status_names[] {
"INACTIVE",
"GAME_INFO",
"JOIN",
"NEWGRFS_CHECK",
"AUTH_GAME",

View File

@@ -22,7 +22,6 @@ private:
/** Status of the connection with the server. */
enum ServerStatus {
STATUS_INACTIVE, ///< The client is not connected nor active.
STATUS_GAME_INFO, ///< We are trying to get the game information.
STATUS_JOIN, ///< We are trying to join a server.
STATUS_NEWGRFS_CHECK, ///< Last action was checking NewGRFs.
STATUS_AUTH_GAME, ///< Last action was requesting game (server) password.
@@ -51,8 +50,6 @@ protected:
NetworkRecvStatus Receive_SERVER_FULL(Packet *p) override;
NetworkRecvStatus Receive_SERVER_BANNED(Packet *p) override;
NetworkRecvStatus Receive_SERVER_ERROR(Packet *p) override;
NetworkRecvStatus Receive_SERVER_GAME_INFO(Packet *p) override;
NetworkRecvStatus Receive_SERVER_GAME_INFO_EXTENDED(Packet *p) override;
NetworkRecvStatus Receive_SERVER_CLIENT_INFO(Packet *p) override;
NetworkRecvStatus Receive_SERVER_NEED_GAME_PASSWORD(Packet *p) override;
NetworkRecvStatus Receive_SERVER_NEED_COMPANY_PASSWORD(Packet *p) override;
@@ -92,8 +89,6 @@ public:
std::string GetDebugInfo() const override;
static NetworkRecvStatus SendInformationQuery();
static NetworkRecvStatus SendJoin();
static NetworkRecvStatus SendCommand(const CommandPacket *cp);
static NetworkRecvStatus SendError(NetworkErrorCode errorno, NetworkRecvStatus recvstatus = NETWORK_RECV_STATUS_OKAY);

View File

@@ -152,7 +152,7 @@ bool ClientNetworkCoordinatorSocketHandler::Receive_GC_ERROR(Packet *p)
/* Mark the server as offline. */
NetworkGameList *item = NetworkGameListAddItem(detail);
item->online = false;
item->status = NGLS_OFFLINE;
UpdateNetworkGameWindow();
return true;
@@ -257,7 +257,7 @@ bool ClientNetworkCoordinatorSocketHandler::Receive_GC_LISTING(Packet *p)
/* Check for compatability with the client. */
CheckGameCompatibility(item->info);
/* Mark server as online. */
item->online = true;
item->status = NGLS_ONLINE;
/* Mark the item as up-to-date. */
item->version = _network_game_list_version;
}

View File

@@ -43,6 +43,7 @@ NetworkGameList *NetworkGameListAddItem(const std::string &connection_string)
}
item = new NetworkGameList(resolved_connection_string);
item->info.gamescript_version = -1;
item->version = _network_game_list_version;
if (prev_item == nullptr) {

View File

@@ -14,17 +14,26 @@
#include "core/game_info.h"
#include "network_type.h"
/** The status a server can be in. */
enum NetworkGameListStatus {
NGLS_OFFLINE, ///< Server is offline (or cannot be queried).
NGLS_ONLINE, ///< Server is online.
NGLS_FULL, ///< Server is full and cannot be queried.
NGLS_BANNED, ///< You are banned from this server.
NGLS_TOO_OLD, ///< Server is too old to query.
};
/** Structure with information shown in the game list (GUI) */
struct NetworkGameList {
NetworkGameList(const std::string &connection_string) : connection_string(connection_string) {}
NetworkGameInfo info = {}; ///< The game information of this server
std::string connection_string; ///< Address of the server
bool online = false; ///< False if the server did not respond (default status)
bool manually = false; ///< True if the server was added manually
uint8 retries = 0; ///< Number of retries (to stop requerying)
int version = 0; ///< Used to see which servers are no longer available on the Game Coordinator and can be removed.
NetworkGameList *next = nullptr; ///< Next pointer to make a linked game list
NetworkGameInfo info = {}; ///< The game information of this server.
std::string connection_string; ///< Address of the server.
NetworkGameListStatus status = NGLS_OFFLINE; ///< Stats of the server.
bool manually = false; ///< True if the server was added manually.
uint8 retries = 0; ///< Number of retries (to stop requerying).
int version = 0; ///< Used to see which servers are no longer available on the Game Coordinator and can be removed.
NetworkGameList *next = nullptr; ///< Next pointer to make a linked game list.
};
extern NetworkGameList *_network_game_list;

View File

@@ -264,15 +264,21 @@ protected:
this->servers.clear();
bool found_current_server = false;
bool found_last_joined = false;
for (NetworkGameList *ngl = _network_game_list; ngl != nullptr; ngl = ngl->next) {
this->servers.push_back(ngl);
if (ngl == this->server) {
found_current_server = true;
}
if (ngl == this->last_joined) {
found_last_joined = true;
}
}
/* A refresh can cause the current server to be delete; so unselect. */
if (!found_last_joined) {
this->last_joined = nullptr;
}
if (!found_current_server) {
if (this->server == this->last_joined) this->last_joined = nullptr;
this->server = nullptr;
this->list_pos = SLP_INVALID;
}
@@ -416,7 +422,7 @@ protected:
DrawString(nwi_name->pos_x + WD_FRAMERECT_LEFT, nwi_name->pos_x + nwi_name->current_x - WD_FRAMERECT_RIGHT, y + text_y_offset, cur_item->info.server_name, TC_BLACK);
/* only draw details if the server is online */
if (cur_item->online) {
if (cur_item->status == NGLS_ONLINE) {
const NWidgetServerListHeader *nwi_header = this->GetWidget<NWidgetServerListHeader>(WID_NG_HEADER);
if (nwi_header->IsWidgetVisible(WID_NG_CLIENTS)) {
@@ -618,13 +624,13 @@ public:
this->SetWidgetDisabledState(WID_NG_REFRESH, sel == nullptr);
/* 'Join' button disabling conditions */
this->SetWidgetDisabledState(WID_NG_JOIN, sel == nullptr || // no Selected Server
!sel->online || // Server offline
sel->status != NGLS_ONLINE || // Server offline
sel->info.clients_on >= sel->info.clients_max || // Server full
!sel->info.compatible); // Revision mismatch
/* 'NewGRF Settings' button invisible if no NewGRF is used */
this->GetWidget<NWidgetStacked>(WID_NG_NEWGRF_SEL)->SetDisplayedPlane(sel == nullptr || !sel->online || sel->info.grfconfig == nullptr);
this->GetWidget<NWidgetStacked>(WID_NG_NEWGRF_MISSING_SEL)->SetDisplayedPlane(sel == nullptr || !sel->online || sel->info.grfconfig == nullptr || !sel->info.version_compatible || sel->info.compatible);
this->GetWidget<NWidgetStacked>(WID_NG_NEWGRF_SEL)->SetDisplayedPlane(sel == nullptr || sel->status != NGLS_ONLINE || sel->info.grfconfig == nullptr);
this->GetWidget<NWidgetStacked>(WID_NG_NEWGRF_MISSING_SEL)->SetDisplayedPlane(sel == nullptr || sel->status != NGLS_ONLINE || sel->info.grfconfig == nullptr || !sel->info.version_compatible || sel->info.compatible);
#ifdef __EMSCRIPTEN__
this->SetWidgetDisabledState(WID_NG_SEARCH_INTERNET, true);
@@ -646,10 +652,20 @@ public:
GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.top + detail_height - 1, PC_DARK_BLUE);
if (sel == nullptr) {
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + 6 + 4 + FONT_HEIGHT_NORMAL, STR_NETWORK_SERVER_LIST_GAME_INFO, TC_FROMSTRING, SA_HOR_CENTER);
} else if (!sel->online) {
} else if (sel->status != NGLS_ONLINE) {
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + 6 + 4 + FONT_HEIGHT_NORMAL, sel->info.server_name, TC_ORANGE, SA_HOR_CENTER); // game name
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + detail_height + 4, STR_NETWORK_SERVER_LIST_SERVER_OFFLINE, TC_FROMSTRING, SA_HOR_CENTER); // server offline
StringID message = INVALID_STRING_ID;
switch (sel->status) {
case NGLS_OFFLINE: message = STR_NETWORK_SERVER_LIST_SERVER_OFFLINE; break;
case NGLS_FULL: message = STR_NETWORK_SERVER_LIST_SERVER_FULL; break;
case NGLS_BANNED: message = STR_NETWORK_SERVER_LIST_SERVER_BANNED; break;
case NGLS_TOO_OLD: message = STR_NETWORK_SERVER_LIST_SERVER_TOO_OLD; break;
/* Handled by the if-case above. */
case NGLS_ONLINE: NOT_REACHED();
}
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + detail_height + 4, message, TC_FROMSTRING, SA_HOR_CENTER); // server offline
} else { // show game info
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + 6, STR_NETWORK_SERVER_LIST_GAME_INFO, TC_FROMSTRING, SA_HOR_CENTER);

View File

@@ -0,0 +1,179 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file network_query.cpp Query part of the network protocol. */
#include "../stdafx.h"
#include "core/game_info.h"
#include "network_query.h"
#include "network_gamelist.h"
#include "../error.h"
#include "table/strings.h"
#include "../safeguards.h"
std::vector<std::unique_ptr<QueryNetworkGameSocketHandler>> QueryNetworkGameSocketHandler::queries = {};
NetworkRecvStatus QueryNetworkGameSocketHandler::CloseConnection(NetworkRecvStatus status)
{
assert(status != NETWORK_RECV_STATUS_OKAY);
assert(this->sock != INVALID_SOCKET);
return status;
}
/**
* Check the connection's state, i.e. is the connection still up?
*/
bool QueryNetworkGameSocketHandler::CheckConnection()
{
std::chrono::steady_clock::duration lag = std::chrono::steady_clock::now() - this->last_packet;
/* If there was no response in 5 seconds, terminate the query. */
if (lag > std::chrono::seconds(5)) {
this->CloseConnection(NETWORK_RECV_STATUS_CONNECTION_LOST);
return false;
}
return true;
}
/**
* Check whether we received/can send some data from/to the server and
* when that's the case handle it appropriately.
* @return true when everything went okay.
*/
bool QueryNetworkGameSocketHandler::Receive()
{
if (this->CanSendReceive()) {
NetworkRecvStatus res = this->ReceivePackets();
if (res != NETWORK_RECV_STATUS_OKAY) {
this->CloseConnection(res);
return false;
}
}
return true;
}
/** Send the packets of this socket handler. */
void QueryNetworkGameSocketHandler::Send()
{
this->SendPackets();
}
/**
* Query the server for server information.
*/
NetworkRecvStatus QueryNetworkGameSocketHandler::SendGameInfo()
{
Packet *p = new Packet(PACKET_CLIENT_GAME_INFO);
p->Send_uint32(FIND_SERVER_EXTENDED_TOKEN);
p->Send_uint8(PACKET_SERVER_GAME_INFO_EXTENDED); // reply type
p->Send_uint16(0); // flags
p->Send_uint16(0); // version
this->SendPacket(p);
return NETWORK_RECV_STATUS_OKAY;
}
NetworkRecvStatus QueryNetworkGameSocketHandler::Receive_SERVER_FULL(Packet *p)
{
NetworkGameList *item = NetworkGameListAddItem(this->connection_string);
item->status = NGLS_FULL;
UpdateNetworkGameWindow();
return NETWORK_RECV_STATUS_CLOSE_QUERY;
}
NetworkRecvStatus QueryNetworkGameSocketHandler::Receive_SERVER_BANNED(Packet *p)
{
NetworkGameList *item = NetworkGameListAddItem(this->connection_string);
item->status = NGLS_BANNED;
UpdateNetworkGameWindow();
return NETWORK_RECV_STATUS_CLOSE_QUERY;
}
NetworkRecvStatus QueryNetworkGameSocketHandler::Receive_SERVER_GAME_INFO(Packet *p)
{
NetworkGameList *item = NetworkGameListAddItem(this->connection_string);
/* Clear any existing GRFConfig chain. */
ClearGRFConfigList(&item->info.grfconfig);
/* Retrieve the NetworkGameInfo from the packet. */
DeserializeNetworkGameInfo(p, &item->info);
/* Check for compatability with the client. */
CheckGameCompatibility(item->info);
/* Ensure we consider the server online. */
item->status = NGLS_ONLINE;
UpdateNetworkGameWindow();
return NETWORK_RECV_STATUS_CLOSE_QUERY;
}
NetworkRecvStatus QueryNetworkGameSocketHandler::Receive_SERVER_GAME_INFO_EXTENDED(Packet *p)
{
NetworkGameList *item = NetworkGameListAddItem(this->connection_string);
/* Clear any existing GRFConfig chain. */
ClearGRFConfigList(&item->info.grfconfig);
/* Retrieve the NetworkGameInfo from the packet. */
DeserializeNetworkGameInfoExtended(p, &item->info);
/* Check for compatability with the client. */
CheckGameCompatibility(item->info, true);
/* Ensure we consider the server online. */
item->status = NGLS_ONLINE;
UpdateNetworkGameWindow();
return NETWORK_RECV_STATUS_CLOSE_QUERY;
}
NetworkRecvStatus QueryNetworkGameSocketHandler::Receive_SERVER_ERROR(Packet *p)
{
NetworkErrorCode error = (NetworkErrorCode)p->Recv_uint8();
NetworkGameList *item = NetworkGameListAddItem(this->connection_string);
if (error == NETWORK_ERROR_NOT_EXPECTED) {
/* If we query a server that is 1.11.1 or older, we get an
* NETWORK_ERROR_NOT_EXPECTED on requesting the game info. Show to the
* user this server is too old to query.
*/
item->status = NGLS_TOO_OLD;
} else {
item->status = NGLS_OFFLINE;
}
UpdateNetworkGameWindow();
return NETWORK_RECV_STATUS_CLOSE_QUERY;
}
/**
* Check if any query needs to send or receive.
*/
/* static */ void QueryNetworkGameSocketHandler::SendReceive()
{
for (auto it = QueryNetworkGameSocketHandler::queries.begin(); it != QueryNetworkGameSocketHandler::queries.end(); /* nothing */) {
if (!(*it)->Receive()) {
it = QueryNetworkGameSocketHandler::queries.erase(it);
} else if (!(*it)->CheckConnection()) {
it = QueryNetworkGameSocketHandler::queries.erase(it);
} else {
it++;
}
}
for (auto &query : QueryNetworkGameSocketHandler::queries) {
query->Send();
}
}

View File

@@ -0,0 +1,60 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file network_query.h Query part of the network protocol. */
#ifndef NETWORK_QUERY_H
#define NETWORK_QUERY_H
#include "network_internal.h"
/** Class for handling the client side of quering a game server. */
class QueryNetworkGameSocketHandler : public ZeroedMemoryAllocator, public NetworkGameSocketHandler {
private:
static std::vector<std::unique_ptr<QueryNetworkGameSocketHandler>> queries; ///< Pending queries.
std::string connection_string; ///< Address we are connected to.
protected:
NetworkRecvStatus Receive_SERVER_FULL(Packet *p) override;
NetworkRecvStatus Receive_SERVER_BANNED(Packet *p) override;
NetworkRecvStatus Receive_SERVER_ERROR(Packet *p) override;
NetworkRecvStatus Receive_SERVER_GAME_INFO(Packet *p) override;
NetworkRecvStatus Receive_SERVER_GAME_INFO_EXTENDED(Packet *p) override;
NetworkRecvStatus SendGameInfo();
bool CheckConnection();
void Send();
bool Receive();
public:
/**
* Create a new socket for the client side of quering game server.
* @param s The socket to connect with.
* @param connection_string The connection string of the server.
*/
QueryNetworkGameSocketHandler(SOCKET s, const std::string &connection_string) : NetworkGameSocketHandler(s), connection_string(connection_string) {}
/**
* Start to query a server based on an open socket.
* @param s The socket to connect with.
* @param connection_string The connection string of the server.
*/
static void QueryServer(SOCKET s, const std::string &connection_string)
{
auto query = std::make_unique<QueryNetworkGameSocketHandler>(s, connection_string);
query->SendGameInfo();
QueryNetworkGameSocketHandler::queries.push_back(std::move(query));
}
static void SendReceive();
NetworkRecvStatus CloseConnection(NetworkRecvStatus status) override;
};
#endif /* NETWORK_QUERY_H */

View File

@@ -304,7 +304,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::CloseConnection(NetworkRecvSta
/* static */ bool ServerNetworkGameSocketHandler::AllowConnection()
{
extern byte _network_clients_connected;
bool accept = _network_clients_connected < MAX_CLIENTS && _network_game_info.clients_on < _settings_client.network.max_clients;
bool accept = _network_clients_connected < MAX_CLIENTS;
/* We can't go over the MAX_CLIENTS limit here. However, the
* pool must have place for all clients and ourself. */
@@ -863,6 +863,11 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_JOIN(Packet *p)
return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
}
if (_network_game_info.clients_on >= _settings_client.network.max_clients) {
/* Turns out we are full. Inform the user about this. */
return this->SendError(NETWORK_ERROR_FULL);
}
std::string client_revision = p->Recv_string(NETWORK_REVISION_LENGTH);
uint32 newgrf_version = p->Recv_uint32();

View File

@@ -100,9 +100,7 @@ NetworkRecvStatus ClientNetworkStunSocketHandler::CloseConnection(bool error)
{
NetworkStunSocketHandler::CloseConnection(error);
/* If our connecter is still pending, shut it down too. Otherwise the
* callback of the connecter can call into us, and our object is most
* likely about to be destroyed. */
/* Also make sure any pending connecter is killed ASAP. */
if (this->connecter != nullptr) {
this->connecter->Kill();
this->connecter = nullptr;
@@ -111,6 +109,14 @@ NetworkRecvStatus ClientNetworkStunSocketHandler::CloseConnection(bool error)
return NETWORK_RECV_STATUS_OKAY;
}
ClientNetworkStunSocketHandler::~ClientNetworkStunSocketHandler()
{
if (this->connecter != nullptr) {
this->connecter->Kill();
this->connecter = nullptr;
}
}
/**
* Check whether we received/can send some data from/to the STUN server and
* when that's the case handle it appropriately.

View File

@@ -24,6 +24,7 @@ public:
NetworkAddress local_addr; ///< Local addresses of the socket.
NetworkRecvStatus CloseConnection(bool error = true) override;
~ClientNetworkStunSocketHandler() override;
void SendReceive();
void Connect(const std::string &token, uint8 family);

View File

@@ -108,9 +108,7 @@ NetworkRecvStatus ClientNetworkTurnSocketHandler::CloseConnection(bool error)
{
NetworkTurnSocketHandler::CloseConnection(error);
/* If our connecter is still pending, shut it down too. Otherwise the
* callback of the connecter can call into us, and our object is most
* likely about to be destroyed. */
/* Also make sure any pending connecter is killed ASAP. */
if (this->connecter != nullptr) {
this->connecter->Kill();
this->connecter = nullptr;
@@ -119,6 +117,14 @@ NetworkRecvStatus ClientNetworkTurnSocketHandler::CloseConnection(bool error)
return NETWORK_RECV_STATUS_OKAY;
}
ClientNetworkTurnSocketHandler::~ClientNetworkTurnSocketHandler()
{
if (this->connecter != nullptr) {
this->connecter->Kill();
this->connecter = nullptr;
}
}
/**
* Check whether we received/can send some data from/to the TURN server and
* when that's the case handle it appropriately

View File

@@ -30,6 +30,7 @@ public:
ClientNetworkTurnSocketHandler(const std::string &token, uint8 tracking_number, const std::string &connection_string) : token(token), tracking_number(tracking_number), connection_string(connection_string) {}
NetworkRecvStatus CloseConnection(bool error = true) override;
~ClientNetworkTurnSocketHandler() override;
void SendReceive();
void Connect();