diff options
-rw-r--r-- | src/console_cmds.cpp | 26 | ||||
-rw-r--r-- | src/network/core/address.cpp | 4 | ||||
-rw-r--r-- | src/network/core/config.h | 1 | ||||
-rw-r--r-- | src/network/core/tcp_http.cpp | 6 | ||||
-rw-r--r-- | src/network/network.cpp | 117 | ||||
-rw-r--r-- | src/network/network_func.h | 10 | ||||
-rw-r--r-- | src/network/network_gamelist.cpp | 2 | ||||
-rw-r--r-- | src/network/network_gui.cpp | 23 | ||||
-rw-r--r-- | src/openttd.cpp | 40 | ||||
-rw-r--r-- | src/settings_type.h | 5 | ||||
-rw-r--r-- | src/table/settings.ini | 11 |
11 files changed, 108 insertions, 137 deletions
diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index 8cdf9c664..7ab6d3179 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -893,15 +893,16 @@ DEF_CONSOLE_CMD(ConNetworkReconnect) break; } - if (StrEmpty(_settings_client.network.last_host)) { + if (StrEmpty(_settings_client.network.last_joined)) { IConsolePrint(CC_DEFAULT, "No server for reconnecting."); return true; } /* Don't resolve the address first, just print it directly as it comes from the config file. */ - IConsolePrintF(CC_DEFAULT, "Reconnecting to %s:%d...", _settings_client.network.last_host, _settings_client.network.last_port); + IConsolePrintF(CC_DEFAULT, "Reconnecting to %s ...", _settings_client.network.last_joined); - NetworkClientConnectGame(_settings_client.network.last_host, _settings_client.network.last_port, playas); + NetworkAddress address = ParseConnectionString(_settings_client.network.last_joined, NETWORK_DEFAULT_PORT); + NetworkClientConnectGame(address, playas); return true; } @@ -917,18 +918,11 @@ DEF_CONSOLE_CMD(ConNetworkConnect) if (argc < 2) return false; if (_networking) NetworkDisconnect(); // we are in network-mode, first close it! - const char *port = nullptr; - const char *company = nullptr; - char *ip = argv[1]; - /* Default settings: default port and new company */ - uint16 rport = NETWORK_DEFAULT_PORT; CompanyID join_as = COMPANY_NEW_COMPANY; + NetworkAddress address = ParseGameConnectionString(&join_as, argv[1], NETWORK_DEFAULT_PORT); - ParseGameConnectionString(&company, &port, ip); - - IConsolePrintF(CC_DEFAULT, "Connecting to %s...", ip); - if (company != nullptr) { - join_as = (CompanyID)atoi(company); + IConsolePrintF(CC_DEFAULT, "Connecting to %s...", address.GetAddressAsString().c_str()); + if (join_as != COMPANY_NEW_COMPANY) { IConsolePrintF(CC_DEFAULT, " company-no: %d", join_as); /* From a user pov 0 is a new company, internally it's different and all @@ -938,12 +932,8 @@ DEF_CONSOLE_CMD(ConNetworkConnect) join_as--; } } - if (port != nullptr) { - rport = atoi(port); - IConsolePrintF(CC_DEFAULT, " port: %s", port); - } - NetworkClientConnectGame(ip, rport, join_as); + NetworkClientConnectGame(address, join_as); return true; } diff --git a/src/network/core/address.cpp b/src/network/core/address.cpp index 8b51e2c08..e91751c33 100644 --- a/src/network/core/address.cpp +++ b/src/network/core/address.cpp @@ -101,8 +101,8 @@ void NetworkAddress::GetAddressAsString(char *buffer, const char *last, bool wit */ std::string NetworkAddress::GetAddressAsString(bool with_family) { - /* 6 = for the : and 5 for the decimal port number */ - char buf[NETWORK_HOSTNAME_LENGTH + 6 + 7]; + /* 7 extra are for with_family, which adds " (IPvX)". */ + char buf[NETWORK_HOSTNAME_PORT_LENGTH + 7]; this->GetAddressAsString(buf, lastof(buf), with_family); return buf; } diff --git a/src/network/core/config.h b/src/network/core/config.h index 866d1791d..cacc907fa 100644 --- a/src/network/core/config.h +++ b/src/network/core/config.h @@ -56,6 +56,7 @@ static const byte NETWORK_MASTER_SERVER_VERSION = 2; ///< What vers static const uint NETWORK_NAME_LENGTH = 80; ///< The maximum length of the server name and map name, in bytes including '\0' static const uint NETWORK_COMPANY_NAME_LENGTH = 128; ///< The maximum length of the company name, in bytes including '\0' static const uint NETWORK_HOSTNAME_LENGTH = 80; ///< The maximum length of the host name, in bytes including '\0' +static const uint NETWORK_HOSTNAME_PORT_LENGTH = 80 + 6; ///< The maximum length of the host name + port, in bytes including '\0'. The extra six is ":" + port number (with a max of 65536) static const uint NETWORK_SERVER_ID_LENGTH = 33; ///< The maximum length of the network id of the servers, in bytes including '\0' static const uint NETWORK_REVISION_LENGTH = 33; ///< The maximum length of the revision, in bytes including '\0' static const uint NETWORK_PASSWORD_LENGTH = 33; ///< The maximum length of the password, in bytes including '\0' (must be >= NETWORK_SERVER_ID_LENGTH) diff --git a/src/network/core/tcp_http.cpp b/src/network/core/tcp_http.cpp index ee74c4507..99eca1cb7 100644 --- a/src/network/core/tcp_http.cpp +++ b/src/network/core/tcp_http.cpp @@ -203,11 +203,7 @@ int NetworkHTTPSocketHandler::HandleHeader() *url = '\0'; - /* Fetch the hostname, and possible port number. */ - const char *port = nullptr; - ParseConnectionString(&port, hname); - - NetworkAddress address(hname, port == nullptr ? 80 : atoi(port)); + NetworkAddress address = ParseConnectionString(hname, 80); /* Restore the URL. */ *url = '/'; diff --git a/src/network/network.cpp b/src/network/network.cpp index c0b2e06fd..0be46bbf3 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -447,14 +447,14 @@ static void CheckPauseOnJoin() } /** - * Converts a string to ip/port - * Format: IP:port + * Converts a string to ip/port/company + * Format: IP:port#company * * connection_string will be re-terminated to separate out the hostname, port will * be set to the port strings given by the user, inside the memory area originally - * occupied by connection_string. + * occupied by connection_string. Similar for company, if set. */ -void ParseConnectionString(const char **port, char *connection_string) +void ParseFullConnectionString(const char **company, const char **port, char *connection_string) { bool ipv6 = (strchr(connection_string, ':') != strrchr(connection_string, ':')); for (char *p = connection_string; *p != '\0'; p++) { @@ -467,6 +467,12 @@ void ParseConnectionString(const char **port, char *connection_string) ipv6 = false; break; + case '#': + if (company == nullptr) continue; + *company = p + 1; + *p = '\0'; + break; + case ':': if (ipv6) break; *port = p + 1; @@ -477,38 +483,48 @@ void ParseConnectionString(const char **port, char *connection_string) } /** - * Converts a string to ip/port/company - * Format: IP:port#company + * Convert a string containing either "hostname" or "hostname:ip" to a + * NetworkAddress. * - * connection_string will be re-terminated to separate out the hostname, and company and port will - * be set to the company and port strings given by the user, inside the memory area originally - * occupied by connection_string. + * @param connection_string The string to parse. + * @param default_port The default port to set port to if not in connection_string. + * @return A valid NetworkAddress of the parsed information. */ -void ParseGameConnectionString(const char **company, const char **port, char *connection_string) +NetworkAddress ParseConnectionString(const char *connection_string, int default_port) { - bool ipv6 = (strchr(connection_string, ':') != strrchr(connection_string, ':')); - for (char *p = connection_string; *p != '\0'; p++) { - switch (*p) { - case '[': - ipv6 = true; - break; + char internal_connection_string[NETWORK_HOSTNAME_PORT_LENGTH]; + strecpy(internal_connection_string, connection_string, lastof(internal_connection_string)); - case ']': - ipv6 = false; - break; + const char *port = nullptr; + ParseFullConnectionString(nullptr, &port, internal_connection_string); - case '#': - *company = p + 1; - *p = '\0'; - break; + int rport = port != nullptr ? atoi(port) : default_port; + return NetworkAddress(internal_connection_string, rport); +} - case ':': - if (ipv6) break; - *port = p + 1; - *p = '\0'; - break; - } - } +/** + * 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 company Pointer to the company variable to set iff indicted. + * @param connection_string The string to parse. + * @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 char *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, lastof(internal_connection_string)); + + const char *port_s = nullptr; + const char *company_s = nullptr; + ParseFullConnectionString(&company_s, &port_s, internal_connection_string); + + if (company_s != nullptr) *company = (CompanyID)atoi(company_s); + + int port = port_s != nullptr ? atoi(port_s) : default_port; + return NetworkAddress(internal_connection_string, port); } /** @@ -616,26 +632,17 @@ void NetworkTCPQueryServer(NetworkAddress address) new TCPQueryConnecter(address); } -/* Validates an address entered as a string and adds the server to +/** + * Validates an address entered as a string and adds the server to * the list. If you use this function, the games will be marked - * as manually added. */ -void NetworkAddServer(const char *b) + * as manually added. + * @param connection_string The IP:port to add to the list. + */ +void NetworkAddServer(const char *connection_string) { - if (*b != '\0') { - const char *port = nullptr; - char host[NETWORK_HOSTNAME_LENGTH]; - uint16 rport; - - strecpy(host, b, lastof(host)); - - strecpy(_settings_client.network.connect_to_ip, b, lastof(_settings_client.network.connect_to_ip)); - rport = NETWORK_DEFAULT_PORT; + if (StrEmpty(connection_string)) return; - ParseConnectionString(&port, host); - if (port != nullptr) rport = atoi(port); - - NetworkUDPQueryServer(NetworkAddress(host, rport), true); - } + NetworkUDPQueryServer(ParseConnectionString(connection_string, NETWORK_DEFAULT_PORT), true); } /** @@ -688,16 +695,13 @@ public: /* Used by clients, to connect to a server */ -void NetworkClientConnectGame(const char *hostname, uint16 port, CompanyID join_as, const char *join_server_password, const char *join_company_password) +void NetworkClientConnectGame(NetworkAddress &address, CompanyID join_as, const char *join_server_password, const char *join_company_password) { if (!_network_available) return; - - if (port == 0) return; - if (!NetworkValidateClientName()) return; - strecpy(_settings_client.network.last_host, hostname, lastof(_settings_client.network.last_host)); - _settings_client.network.last_port = port; + strecpy(_settings_client.network.last_joined, address.GetAddressAsString(false).c_str(), lastof(_settings_client.network.last_joined)); + _network_join_as = join_as; _network_join_server_password = join_server_password; _network_join_company_password = join_company_password; @@ -708,7 +712,7 @@ void NetworkClientConnectGame(const char *hostname, uint16 port, CompanyID join_ _network_join_status = NETWORK_JOIN_STATUS_CONNECTING; ShowJoinStatusWindow(); - new TCPClientConnecter(NetworkAddress(hostname, port)); + new TCPClientConnecter(address); } static void NetworkInitGameInfo() @@ -1059,13 +1063,12 @@ static void NetworkGenerateServerId() seprintf(_settings_client.network.network_id, lastof(_settings_client.network.network_id), "%s", hex_output); } -void NetworkStartDebugLog(const char *hostname, uint16 port) +void NetworkStartDebugLog(NetworkAddress &address) { extern SOCKET _debug_socket; // Comes from debug.c - DEBUG(net, 0, "Redirecting DEBUG() to %s:%d", hostname, port); + DEBUG(net, 0, "Redirecting DEBUG() to %s", address.GetAddressAsString().c_str()); - NetworkAddress address(hostname, port); SOCKET s = address.Connect(); if (s == INVALID_SOCKET) { DEBUG(net, 0, "Failed to open socket for redirection DEBUG()"); diff --git a/src/network/network_func.h b/src/network/network_func.h index a0f163345..967bb6260 100644 --- a/src/network/network_func.h +++ b/src/network/network_func.h @@ -18,6 +18,7 @@ // #define DEBUG_FAILED_DUMP_COMMANDS #include "network_type.h" +#include "core/address.h" #include "../console_type.h" #include "../gfx_type.h" #include "../openttd.h" @@ -45,14 +46,15 @@ void NetworkReboot(); void NetworkDisconnect(bool blocking = false, bool close_admins = true); void NetworkGameLoop(); void NetworkBackgroundLoop(); -void ParseConnectionString(const char **port, char *connection_string); -void ParseGameConnectionString(const char **company, const char **port, char *connection_string); -void NetworkStartDebugLog(const char *hostname, uint16 port); +void ParseFullConnectionString(const char **company, const char **port, char *connection_string); +NetworkAddress ParseConnectionString(const char *connection_string, int default_port); +NetworkAddress ParseGameConnectionString(CompanyID *company, const char *connection_string, int default_port); +void NetworkStartDebugLog(NetworkAddress &address); void NetworkPopulateCompanyStats(NetworkCompanyStats *stats); void NetworkUpdateClientInfo(ClientID client_id); void NetworkClientsToSpectators(CompanyID cid); -void NetworkClientConnectGame(const char *hostname, uint16 port, CompanyID join_as, const char *join_server_password = nullptr, const char *join_company_password = nullptr); +void NetworkClientConnectGame(NetworkAddress &address, CompanyID join_as, const char *join_server_password = nullptr, const char *join_company_password = nullptr); void NetworkClientRequestMove(CompanyID company, const char *pass = ""); void NetworkClientSendRcon(const char *password, const char *command); void NetworkClientSendChat(NetworkAction action, DestType type, int dest, const char *msg, int64 data = 0); diff --git a/src/network/network_gamelist.cpp b/src/network/network_gamelist.cpp index 3ee5099b7..6d4285c85 100644 --- a/src/network/network_gamelist.cpp +++ b/src/network/network_gamelist.cpp @@ -151,7 +151,7 @@ void NetworkGameListRequery() /* item gets mostly zeroed by NetworkUDPQueryServer */ uint8 retries = item->retries; - NetworkUDPQueryServer(NetworkAddress(item->address)); + NetworkUDPQueryServer(item->address); item->retries = (retries >= REFRESH_GAMEINFO_X_REQUERIES) ? 0 : retries; } } diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index e1f9a791b..3204b2b96 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -472,7 +472,7 @@ public: EM_ASM(if (window["openttd_server_list"]) openttd_server_list()); #endif - this->last_joined = NetworkGameListAddItem(NetworkAddress(_settings_client.network.last_host, _settings_client.network.last_port)); + this->last_joined = NetworkGameListAddItem(ParseConnectionString(_settings_client.network.last_joined, NETWORK_DEFAULT_PORT)); this->server = this->last_joined; if (this->last_joined != nullptr) NetworkUDPQueryServer(this->last_joined->address); @@ -735,7 +735,7 @@ public: ShowQueryString( STR_JUST_RAW_STRING, STR_NETWORK_SERVER_LIST_ENTER_IP, - NETWORK_HOSTNAME_LENGTH, // maximum number of characters including '\0' + NETWORK_HOSTNAME_PORT_LENGTH, // maximum number of characters including '\0' this, CS_ALPHANUMERAL, QSF_ACCEPT_UNCHANGED); break; @@ -745,8 +745,6 @@ public: case WID_NG_JOIN: // Join Game if (this->server != nullptr) { - seprintf(_settings_client.network.last_host, lastof(_settings_client.network.last_host), "%s", this->server->address.GetHostname()); - _settings_client.network.last_port = this->server->address.GetPort(); ShowNetworkLobbyWindow(this->server); } break; @@ -827,7 +825,10 @@ public: void OnQueryTextFinished(char *str) override { - if (!StrEmpty(str)) NetworkAddServer(str); + if (!StrEmpty(str)) { + strecpy(_settings_client.network.connect_to_ip, str, lastof(_settings_client.network.connect_to_ip)); + NetworkAddServer(str); + } } void OnResize() override @@ -1469,22 +1470,22 @@ struct NetworkLobbyWindow : public Window { case WID_NL_JOIN: // Join company /* Button can be clicked only when it is enabled. */ - NetworkClientConnectGame(_settings_client.network.last_host, _settings_client.network.last_port, this->company); + NetworkClientConnectGame(this->server->address, this->company); break; case WID_NL_NEW: // New company - NetworkClientConnectGame(_settings_client.network.last_host, _settings_client.network.last_port, COMPANY_NEW_COMPANY); + NetworkClientConnectGame(this->server->address, COMPANY_NEW_COMPANY); break; case WID_NL_SPECTATE: // Spectate game - NetworkClientConnectGame(_settings_client.network.last_host, _settings_client.network.last_port, COMPANY_SPECTATOR); + NetworkClientConnectGame(this->server->address, 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(NetworkAddress(_settings_client.network.last_host, _settings_client.network.last_port)); + NetworkTCPQueryServer(this->server->address); break; } } @@ -1552,7 +1553,9 @@ static void ShowNetworkLobbyWindow(NetworkGameList *ngl) DeleteWindowById(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_START); DeleteWindowById(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_GAME); - NetworkTCPQueryServer(NetworkAddress(_settings_client.network.last_host, _settings_client.network.last_port)); + strecpy(_settings_client.network.last_joined, ngl->address.GetAddressAsString(false).c_str(), lastof(_settings_client.network.last_joined)); + + NetworkTCPQueryServer(ngl->address); new NetworkLobbyWindow(&_network_lobby_window_desc, ngl); } diff --git a/src/openttd.cpp b/src/openttd.cpp index 016d48287..b12824385 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -473,29 +473,21 @@ struct AfterNewGRFScan : NewGRFScanCallback { if (_switch_mode != SM_NONE) MakeNewgameSettingsLive(); if (_network_available && network_conn != nullptr) { - const char *port = nullptr; - const char *company = nullptr; - uint16 rport = NETWORK_DEFAULT_PORT; CompanyID join_as = COMPANY_NEW_COMPANY; + NetworkAddress address = ParseGameConnectionString(&join_as, network_conn, NETWORK_DEFAULT_PORT); - ParseGameConnectionString(&company, &port, network_conn); - - if (company != nullptr) { - join_as = (CompanyID)atoi(company); - - if (join_as != COMPANY_SPECTATOR) { - join_as--; - if (join_as >= MAX_COMPANIES) { - delete this; - return; - } + if (join_as != COMPANY_NEW_COMPANY && join_as != COMPANY_SPECTATOR) { + join_as--; + if (join_as >= MAX_COMPANIES) { + delete this; + return; } } - if (port != nullptr) rport = atoi(port); LoadIntroGame(); _switch_mode = SM_NONE; - NetworkClientConnectGame(network_conn, rport, join_as, join_server_password, join_company_password); + + NetworkClientConnectGame(address, join_as, join_server_password, join_company_password); } /* After the scan we're not used anymore. */ @@ -585,7 +577,7 @@ int openttd_main(int argc, char *argv[]) SetDebugString("net=6"); if (mgo.opt != nullptr) { const char *port = nullptr; - ParseConnectionString(&port, mgo.opt); + ParseFullConnectionString(nullptr, &port, mgo.opt); if (!StrEmpty(mgo.opt)) scanner->dedicated_host = mgo.opt; if (port != nullptr) scanner->dedicated_port = atoi(port); } @@ -771,15 +763,8 @@ int openttd_main(int argc, char *argv[]) NetworkStartUp(); // initialize network-core if (debuglog_conn != nullptr && _network_available) { - const char *port = nullptr; - uint16 rport; - - rport = NETWORK_DEFAULT_DEBUGLOG_PORT; - - ParseConnectionString(&port, debuglog_conn); - if (port != nullptr) rport = atoi(port); - - NetworkStartDebugLog(debuglog_conn, rport); + NetworkAddress address = ParseConnectionString(debuglog_conn, NETWORK_DEFAULT_DEBUGLOG_PORT); + NetworkStartDebugLog(address); } if (!HandleBootstrap()) { @@ -1491,7 +1476,8 @@ void GameLoop() if (_network_reconnect > 0 && --_network_reconnect == 0) { /* This means that we want to reconnect to the last host * We do this here, because it means that the network is really closed */ - NetworkClientConnectGame(_settings_client.network.last_host, _settings_client.network.last_port, COMPANY_SPECTATOR); + NetworkAddress address = ParseConnectionString(_settings_client.network.last_joined, NETWORK_DEFAULT_PORT); + NetworkClientConnectGame(address, COMPANY_SPECTATOR); } /* Singleplayer */ StateGameLoop(); diff --git a/src/settings_type.h b/src/settings_type.h index bb078205b..5361fc3f1 100644 --- a/src/settings_type.h +++ b/src/settings_type.h @@ -269,7 +269,7 @@ struct NetworkSettings { bool server_advertise; ///< advertise the server to the masterserver char client_name[NETWORK_CLIENT_NAME_LENGTH]; ///< name of the player (as client) char default_company_pass[NETWORK_PASSWORD_LENGTH]; ///< default password for new companies in encrypted form - char connect_to_ip[NETWORK_HOSTNAME_LENGTH]; ///< default for the "Add server" query + char connect_to_ip[NETWORK_HOSTNAME_PORT_LENGTH]; ///< default for the "Add server" query char network_id[NETWORK_SERVER_ID_LENGTH]; ///< network ID for servers bool autoclean_companies; ///< automatically remove companies that are not in use uint8 autoclean_unprotected; ///< remove passwordless companies after this many months @@ -281,8 +281,7 @@ struct NetworkSettings { Year restart_game_year; ///< year the server restarts uint8 min_active_clients; ///< minimum amount of active clients to unpause the game bool reload_cfg; ///< reload the config file before restarting - char last_host[NETWORK_HOSTNAME_LENGTH]; ///< IP address of the last joined server - uint16 last_port; ///< port of the last joined server + char last_joined[NETWORK_HOSTNAME_PORT_LENGTH]; ///< Last joined server bool no_http_content_downloads; ///< do not do content downloads over HTTP }; diff --git a/src/table/settings.ini b/src/table/settings.ini index 391a5b427..4e64bd032 100644 --- a/src/table/settings.ini +++ b/src/table/settings.ini @@ -4069,21 +4069,12 @@ def = false cat = SC_EXPERT [SDTC_STR] -var = network.last_host +var = network.last_joined type = SLE_STRB flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC def = """" cat = SC_EXPERT -[SDTC_VAR] -var = network.last_port -type = SLE_UINT16 -flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC -def = 0 -min = 0 -max = UINT16_MAX -cat = SC_EXPERT - [SDTC_BOOL] var = network.no_http_content_downloads flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC |