diff --git a/src/lang/english.txt b/src/lang/english.txt --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -2175,6 +2175,7 @@ STR_NETWORK_ERROR_SERVER_START STR_NETWORK_ERROR_CLIENT_START :{WHITE}Could not connect STR_NETWORK_ERROR_TIMEOUT :{WHITE}Connection #{NUM} timed out STR_NETWORK_ERROR_SERVER_ERROR :{WHITE}A protocol error was detected and the connection was closed +STR_NETWORK_ERROR_BAD_PLAYER_NAME :{WHITE}Your player name has not been set. The name can be set at the top of the Multiplayer window STR_NETWORK_ERROR_WRONG_REVISION :{WHITE}The revision of this client does not match the server's revision STR_NETWORK_ERROR_WRONG_PASSWORD :{WHITE}Wrong password STR_NETWORK_ERROR_SERVER_FULL :{WHITE}The server is full diff --git a/src/network/network.cpp b/src/network/network.cpp --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -692,6 +692,8 @@ void NetworkClientConnectGame(NetworkAdd if (address.GetPort() == 0) return; + if (!NetworkValidateClientName()) return; + strecpy(_settings_client.network.last_host, address.GetHostname(), lastof(_settings_client.network.last_host)); _settings_client.network.last_port = address.GetPort(); _network_join_as = join_as; diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp --- a/src/network/network_client.cpp +++ b/src/network/network_client.cpp @@ -1265,6 +1265,42 @@ bool NetworkIsValidClientName(const char } /** + * Trim the given client name in place, i.e. remove leading and trailing spaces. + * After the trim check whether the client name is valid. A client name is valid + * whenever the name is not empty and does not start with spaces. This check is + * done via \c NetworkIsValidClientName. + * When the client name is valid, this function returns true. + * When the client name is not valid a GUI error message is shown telling the + * user to set the client name and this function returns false. + * + * This function is not suitable for ensuring a valid client name at the server + * as the error message will then be shown to the host instead of the client. + * @param client_name The client name to validate. It will be trimmed of leading + * and trailing spaces. + * @return True iff the client name is valid. + */ +bool NetworkValidateClientName(char *client_name) +{ + StrTrimInPlace(client_name); + if (NetworkIsValidClientName(client_name)) return true; + + ShowErrorMessage(STR_NETWORK_ERROR_BAD_PLAYER_NAME, INVALID_STRING_ID, WL_ERROR); + return false; +} + +/** + * Convenience method for NetworkValidateClientName on _settings_client.network.client_name. + * It trims the client name and checks whether it is empty. When it is empty + * an error message is shown to the GUI user. + * See \c NetworkValidateClientName(char*) for details about the functionality. + * @return True iff the client name is valid. + */ +bool NetworkValidateClientName() +{ + return NetworkValidateClientName(_settings_client.network.client_name); +} + +/** * Send the server our name. */ void NetworkUpdateClientName() diff --git a/src/network/network_func.h b/src/network/network_func.h --- a/src/network/network_func.h +++ b/src/network/network_func.h @@ -37,6 +37,8 @@ extern StringList _network_ban_list; byte NetworkSpectatorCount(); bool NetworkIsValidClientName(const char *client_name); +bool NetworkValidateClientName(); +bool NetworkValidateClientName(char *client_name); void NetworkUpdateClientName(); bool NetworkCompanyHasClients(CompanyID company); const char *NetworkChangeCompanyPassword(CompanyID company_id, const char *password); diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -808,11 +808,9 @@ public: } case WID_NG_CLIENT: - if (NetworkIsValidClientName(this->name_editbox.text.buf)) { - strecpy(_settings_client.network.client_name, this->name_editbox.text.buf, lastof(_settings_client.network.client_name)); - } else { - strecpy(_settings_client.network.client_name, "Player", lastof(_settings_client.network.client_name)); - } + /* Validation of the name will happen once the user tries to join or start a game, as getting + * error messages while typing (e.g. when you clear the name) defeats the purpose of the check. */ + strecpy(_settings_client.network.client_name, this->name_editbox.text.buf, lastof(_settings_client.network.client_name)); break; } } @@ -1245,6 +1243,8 @@ static WindowDesc _network_start_server_ static void ShowNetworkStartServerWindow() { + if (!NetworkValidateClientName()) return; + DeleteWindowById(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_GAME); DeleteWindowById(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_LOBBY); @@ -1537,6 +1537,8 @@ static WindowDesc _network_lobby_window_ */ static void ShowNetworkLobbyWindow(NetworkGameList *ngl) { + if (!NetworkValidateClientName()) return; + DeleteWindowById(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_START); DeleteWindowById(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_GAME);