Merge branch 'master' into jgrpp-beta
# Conflicts: # src/console_cmds.cpp # src/debug.cpp # src/lang/vietnamese.txt # src/network/core/address.cpp # src/network/core/address.h # src/network/core/config.h # src/network/core/os_abstraction.cpp # src/network/core/os_abstraction.h # src/network/core/tcp_listen.h # src/network/core/udp.cpp # src/network/core/udp.h # src/network/network.cpp # src/network/network_client.cpp # src/network/network_gamelist.cpp # src/network/network_server.cpp # src/network/network_udp.cpp # src/newgrf.cpp # src/openttd.cpp # src/saveload/saveload.h # src/settings.cpp # src/settings_table.cpp # src/settings_type.h # src/table/settings/network_settings.ini
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
#include "network_udp.h"
|
||||
#include "network_gamelist.h"
|
||||
#include "network_base.h"
|
||||
#include "network_coordinator.h"
|
||||
#include "core/udp.h"
|
||||
#include "core/host.h"
|
||||
#include "network_gui.h"
|
||||
@@ -62,7 +63,6 @@ bool _network_settings_access; ///< Can this client change server settings?
|
||||
NetworkCompanyState *_network_company_states = nullptr; ///< Statistics about some companies.
|
||||
ClientID _network_own_client_id; ///< Our client identifier.
|
||||
ClientID _redirect_console_to_client; ///< If not invalid, redirect the console output to a client.
|
||||
bool _network_need_advertise; ///< Whether we need to advertise.
|
||||
uint8 _network_reconnect; ///< Reconnect timeout
|
||||
StringList _network_bind_list; ///< The addresses to bind on.
|
||||
StringList _network_host_list; ///< The servers we know.
|
||||
@@ -478,6 +478,41 @@ static void CheckPauseOnJoin()
|
||||
CheckPauseHelper(NetworkHasJoiningClient(), PM_PAUSED_JOIN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the company part ("#company" postfix) of a connecting string.
|
||||
* @param connection_string The string with the connection data.
|
||||
* @param company_id The company ID to set, if available.
|
||||
* @return A std::string_view into the connection string without the company part.
|
||||
*/
|
||||
std::string_view ParseCompanyFromConnectionString(const std::string &connection_string, CompanyID *company_id)
|
||||
{
|
||||
std::string_view ip = connection_string;
|
||||
if (company_id == nullptr) return ip;
|
||||
|
||||
size_t offset = ip.find_last_of('#');
|
||||
if (offset != std::string::npos) {
|
||||
std::string_view company_string = ip.substr(offset + 1);
|
||||
ip = ip.substr(0, offset);
|
||||
|
||||
uint8 company_value;
|
||||
auto [_, err] = std::from_chars(company_string.data(), company_string.data() + company_string.size(), company_value);
|
||||
if (err == std::errc()) {
|
||||
if (company_value != COMPANY_NEW_COMPANY && company_value != COMPANY_SPECTATOR) {
|
||||
if (company_value > MAX_COMPANIES || company_value == 0) {
|
||||
*company_id = COMPANY_SPECTATOR;
|
||||
} else {
|
||||
/* "#1" means the first company, which has index 0. */
|
||||
*company_id = (CompanyID)(company_value - 1);
|
||||
}
|
||||
} else {
|
||||
*company_id = (CompanyID)company_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a string to ip/port/company
|
||||
* Format: IP:port#company
|
||||
@@ -495,29 +530,7 @@ static void CheckPauseOnJoin()
|
||||
*/
|
||||
std::string_view ParseFullConnectionString(const std::string &connection_string, uint16 &port, CompanyID *company_id)
|
||||
{
|
||||
std::string_view ip = connection_string;
|
||||
if (company_id != nullptr) {
|
||||
size_t offset = ip.find_last_of('#');
|
||||
if (offset != std::string::npos) {
|
||||
std::string_view company_string = ip.substr(offset + 1);
|
||||
ip = ip.substr(0, offset);
|
||||
|
||||
uint8 company_value;
|
||||
auto [_, err] = std::from_chars(company_string.data(), company_string.data() + company_string.size(), company_value);
|
||||
if (err == std::errc()) {
|
||||
if (company_value != COMPANY_NEW_COMPANY && company_value != COMPANY_SPECTATOR) {
|
||||
if (company_value > MAX_COMPANIES || company_value == 0) {
|
||||
*company_id = COMPANY_SPECTATOR;
|
||||
} else {
|
||||
/* "#1" means the first company, which has index 0. */
|
||||
*company_id = (CompanyID)(company_value - 1);
|
||||
}
|
||||
} else {
|
||||
*company_id = (CompanyID)company_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
std::string_view ip = ParseCompanyFromConnectionString(connection_string, company_id);
|
||||
|
||||
size_t port_offset = ip.find_last_of(':');
|
||||
size_t ipv6_close = ip.find_last_of(']');
|
||||
@@ -557,23 +570,6 @@ NetworkAddress ParseConnectionString(const std::string &connection_string, uint1
|
||||
return NetworkAddress(ip, port);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a string containing either "hostname" or "hostname:ip" to a
|
||||
* NetworkAddress, where the string can be postfixed with "#company" to
|
||||
* indicate the requested company.
|
||||
*
|
||||
* @param connection_string The string to parse.
|
||||
* @param default_port The default port to set port to if not in connection_string.
|
||||
* @param company Pointer to the company variable to set iff indicted.
|
||||
* @return A valid NetworkAddress of the parsed information.
|
||||
*/
|
||||
static NetworkAddress ParseGameConnectionString(const std::string &connection_string, uint16 default_port, CompanyID *company)
|
||||
{
|
||||
uint16 port = default_port;
|
||||
std::string_view ip = ParseFullConnectionString(connection_string, port, company);
|
||||
return NetworkAddress(ip, port);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the accepting of a connection to the server.
|
||||
* @param s The socket of the new connection.
|
||||
@@ -617,9 +613,15 @@ void NetworkClose(bool close_admins)
|
||||
}
|
||||
ServerNetworkGameSocketHandler::CloseListeners();
|
||||
ServerNetworkAdminSocketHandler::CloseListeners();
|
||||
} else if (MyClient::my_client != nullptr) {
|
||||
MyClient::SendQuit();
|
||||
MyClient::my_client->CloseConnection(NETWORK_RECV_STATUS_CLIENT_QUIT);
|
||||
|
||||
_network_coordinator_client.CloseConnection();
|
||||
} else {
|
||||
if (MyClient::my_client != nullptr) {
|
||||
MyClient::SendQuit();
|
||||
MyClient::my_client->CloseConnection(NETWORK_RECV_STATUS_CLIENT_QUIT);
|
||||
}
|
||||
|
||||
_network_coordinator_client.CloseAllTokens();
|
||||
}
|
||||
|
||||
TCPConnecter::KillAll();
|
||||
@@ -639,7 +641,6 @@ void NetworkClose(bool close_admins)
|
||||
static void NetworkInitialize(bool close_admins = true)
|
||||
{
|
||||
InitializeNetworkPools(close_admins);
|
||||
NetworkUDPInitialize();
|
||||
|
||||
_sync_frame = 0;
|
||||
_network_first_time = true;
|
||||
@@ -652,12 +653,12 @@ static void NetworkInitialize(bool close_admins = true)
|
||||
}
|
||||
|
||||
/** Non blocking connection to query servers for their game info. */
|
||||
class TCPQueryConnecter : TCPConnecter {
|
||||
class TCPQueryConnecter : TCPServerConnecter {
|
||||
private:
|
||||
std::string connection_string;
|
||||
|
||||
public:
|
||||
TCPQueryConnecter(const std::string &connection_string) : TCPConnecter(connection_string, NETWORK_DEFAULT_PORT), connection_string(connection_string) {}
|
||||
TCPQueryConnecter(const std::string &connection_string) : TCPServerConnecter(connection_string, NETWORK_DEFAULT_PORT), connection_string(connection_string) {}
|
||||
|
||||
void OnFailure() override
|
||||
{
|
||||
@@ -689,12 +690,12 @@ void NetworkQueryServer(const std::string &connection_string)
|
||||
}
|
||||
|
||||
/** Non blocking connection to query servers for their game and company info. */
|
||||
class TCPLobbyQueryConnecter : TCPConnecter {
|
||||
class TCPLobbyQueryConnecter : TCPServerConnecter {
|
||||
private:
|
||||
std::string connection_string;
|
||||
|
||||
public:
|
||||
TCPLobbyQueryConnecter(const std::string &connection_string) : TCPConnecter(connection_string, NETWORK_DEFAULT_PORT), connection_string(connection_string) {}
|
||||
TCPLobbyQueryConnecter(const std::string &connection_string) : TCPServerConnecter(connection_string, NETWORK_DEFAULT_PORT), connection_string(connection_string) {}
|
||||
|
||||
void OnFailure() override
|
||||
{
|
||||
@@ -729,9 +730,11 @@ void NetworkQueryLobbyServer(const std::string &connection_string)
|
||||
* the list. If you use this function, the games will be marked
|
||||
* as manually added.
|
||||
* @param connection_string The IP:port of the server to add.
|
||||
* @param manually Whether the enter should be marked as manual added.
|
||||
* @param never_expire Whether the entry can expire (removed when no longer found in the public listing).
|
||||
* @return The entry on the game list.
|
||||
*/
|
||||
NetworkGameList *NetworkAddServer(const std::string &connection_string, bool manually)
|
||||
NetworkGameList *NetworkAddServer(const std::string &connection_string, bool manually, bool never_expire)
|
||||
{
|
||||
if (connection_string.empty()) return nullptr;
|
||||
|
||||
@@ -747,6 +750,7 @@ NetworkGameList *NetworkAddServer(const std::string &connection_string, bool man
|
||||
}
|
||||
|
||||
if (manually) item->manually = true;
|
||||
if (never_expire) item->version = INT32_MAX;
|
||||
|
||||
return item;
|
||||
}
|
||||
@@ -781,12 +785,12 @@ void NetworkRebuildHostList()
|
||||
}
|
||||
|
||||
/** Non blocking connection create to actually connect to servers */
|
||||
class TCPClientConnecter : TCPConnecter {
|
||||
class TCPClientConnecter : TCPServerConnecter {
|
||||
private:
|
||||
std::string connection_string;
|
||||
|
||||
public:
|
||||
TCPClientConnecter(const std::string &connection_string) : TCPConnecter(connection_string, NETWORK_DEFAULT_PORT), connection_string(connection_string) {}
|
||||
TCPClientConnecter(const std::string &connection_string) : TCPServerConnecter(connection_string, NETWORK_DEFAULT_PORT), connection_string(connection_string) {}
|
||||
|
||||
void OnFailure() override
|
||||
{
|
||||
@@ -822,7 +826,7 @@ public:
|
||||
bool NetworkClientConnectGame(const std::string &connection_string, CompanyID default_company, const std::string &join_server_password, const std::string &join_company_password)
|
||||
{
|
||||
CompanyID join_as = default_company;
|
||||
std::string resolved_connection_string = ParseGameConnectionString(connection_string, NETWORK_DEFAULT_PORT, &join_as).GetAddressAsString(false);
|
||||
std::string resolved_connection_string = ServerAddress::Parse(connection_string, NETWORK_DEFAULT_PORT, &join_as).connection_string;
|
||||
|
||||
if (!_network_available) return false;
|
||||
if (!NetworkValidateOurClientName()) return false;
|
||||
@@ -932,6 +936,7 @@ bool NetworkServerStart()
|
||||
|
||||
NetworkDisconnect(false, false);
|
||||
NetworkInitialize(false);
|
||||
NetworkUDPInitialize();
|
||||
DEBUG(net, 5, "Starting listeners for clients");
|
||||
if (!ServerNetworkGameSocketHandler::Listen(_settings_client.network.server_port)) return false;
|
||||
|
||||
@@ -959,15 +964,15 @@ bool NetworkServerStart()
|
||||
|
||||
NetworkInitGameInfo();
|
||||
|
||||
if (_settings_client.network.server_game_type != SERVER_GAME_TYPE_LOCAL) {
|
||||
_network_coordinator_client.Register();
|
||||
}
|
||||
|
||||
/* execute server initialization script */
|
||||
IConsoleCmdExec("exec scripts/on_server.scr 0");
|
||||
/* if the server is dedicated ... add some other script */
|
||||
if (_network_dedicated) IConsoleCmdExec("exec scripts/on_dedicated.scr 0");
|
||||
|
||||
/* Try to register us to the master server */
|
||||
_network_need_advertise = true;
|
||||
NetworkUDPAdvertise();
|
||||
|
||||
/* welcome possibly still connected admins - this can only happen on a dedicated server. */
|
||||
if (_network_dedicated) ServerNetworkAdminSocketHandler::WelcomeAll();
|
||||
|
||||
@@ -1016,8 +1021,6 @@ void NetworkDisconnect(bool blocking, bool close_admins)
|
||||
}
|
||||
}
|
||||
|
||||
if (_settings_client.network.server_advertise) NetworkUDPRemoveAdvertise(blocking);
|
||||
|
||||
DeleteWindowById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN);
|
||||
|
||||
NetworkClose(close_admins);
|
||||
@@ -1026,6 +1029,29 @@ void NetworkDisconnect(bool blocking, bool close_admins)
|
||||
NetworkUDPInitialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* The setting server_game_type was updated; possibly we need to take some
|
||||
* action.
|
||||
*/
|
||||
void NetworkUpdateServerGameType()
|
||||
{
|
||||
if (!_networking) return;
|
||||
|
||||
switch (_settings_client.network.server_game_type) {
|
||||
case SERVER_GAME_TYPE_LOCAL:
|
||||
_network_coordinator_client.CloseConnection();
|
||||
break;
|
||||
|
||||
case SERVER_GAME_TYPE_INVITE_ONLY:
|
||||
case SERVER_GAME_TYPE_PUBLIC:
|
||||
_network_coordinator_client.Register();
|
||||
break;
|
||||
|
||||
default:
|
||||
NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Receives something from the network.
|
||||
* @return true if everything went fine, false when the connection got closed.
|
||||
@@ -1059,6 +1085,7 @@ static void NetworkSend()
|
||||
void NetworkBackgroundLoop()
|
||||
{
|
||||
_network_content_client.SendReceive();
|
||||
_network_coordinator_client.SendReceive();
|
||||
TCPConnecter::CheckCallbacks();
|
||||
NetworkHTTPSocketHandler::HTTPReceive();
|
||||
|
||||
@@ -1297,7 +1324,6 @@ void NetworkStartUp()
|
||||
/* Network is available */
|
||||
_network_available = NetworkCoreInitialize();
|
||||
_network_dedicated = false;
|
||||
_network_need_advertise = true;
|
||||
|
||||
/* Generate an server id when there is none yet */
|
||||
if (_settings_client.network.network_id.empty()) NetworkGenerateServerId();
|
||||
@@ -1305,6 +1331,7 @@ void NetworkStartUp()
|
||||
_network_game_info = {};
|
||||
|
||||
NetworkInitialize();
|
||||
NetworkUDPInitialize();
|
||||
DEBUG(net, 3, "Network online, multiplayer available");
|
||||
NetworkFindBroadcastIPs(&_broadcast_list);
|
||||
}
|
||||
@@ -1327,7 +1354,7 @@ extern "C" {
|
||||
|
||||
void CDECL em_openttd_add_server(const char *connection_string)
|
||||
{
|
||||
NetworkAddServer(connection_string, false);
|
||||
NetworkAddServer(connection_string, false, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user