# HG changeset patch # User rubidium42 # Date 2021-04-27 20:02:40 # Node ID b2a279799858cd336b63f51ac37fcfcec4455cc3 # Parent a9b079004e01c9622d83403ade489a0dbd13a7a3 Codechange: move client name in settings to std::string diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -717,14 +717,14 @@ DEF_CONSOLE_CMD(ConClientNickChange) return true; } - char *client_name = argv[2]; + std::string client_name(argv[2]); StrTrimInPlace(client_name); if (!NetworkIsValidClientName(client_name)) { IConsoleError("Cannot give a client an empty name"); return true; } - if (!NetworkServerChangeClientName(client_id, client_name)) { + if (!NetworkServerChangeClientName(client_id, client_name.c_str())) { IConsoleError("Cannot give a client a duplicate name"); } diff --git a/src/network/network.cpp b/src/network/network.cpp --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -846,7 +846,7 @@ static void NetworkInitGameInfo() NetworkClientInfo *ci = new NetworkClientInfo(CLIENT_ID_SERVER); ci->client_playas = _network_dedicated ? COMPANY_SPECTATOR : COMPANY_FIRST; - strecpy(ci->client_name, _settings_client.network.client_name, lastof(ci->client_name)); + strecpy(ci->client_name, _settings_client.network.client_name.c_str(), lastof(ci->client_name)); } /** @@ -857,10 +857,10 @@ static void NetworkInitGameInfo() */ static void CheckClientAndServerName() { - static const char *fallback_client_name = "Unnamed Client"; - if (StrEmpty(_settings_client.network.client_name) || strcmp(_settings_client.network.client_name, fallback_client_name) == 0) { - DEBUG(net, 1, "No \"client_name\" has been set, using \"%s\" instead. Please set this now using the \"name \" command", fallback_client_name); - strecpy(_settings_client.network.client_name, fallback_client_name, lastof(_settings_client.network.client_name)); + static const std::string fallback_client_name = "Unnamed Client"; + if (_settings_client.network.client_name.empty() || _settings_client.network.client_name.compare(fallback_client_name) == 0) { + DEBUG(net, 1, "No \"client_name\" has been set, using \"%s\" instead. Please set this now using the \"name \" command", fallback_client_name.c_str()); + _settings_client.network.client_name = fallback_client_name; } static const std::string fallback_server_name = "Unnamed Server"; 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 @@ -1305,10 +1305,10 @@ void NetworkClientsToSpectators(CompanyI * @param client_name The client name to check for validity. * @return True iff the name is valid. */ -bool NetworkIsValidClientName(const char *client_name) +bool NetworkIsValidClientName(const std::string_view client_name) { - if (StrEmpty(client_name)) return false; - if (*client_name == ' ') return false; + if (client_name.empty()) return false; + if (client_name[0] == ' ') return false; return true; } @@ -1327,7 +1327,7 @@ bool NetworkIsValidClientName(const char * and trailing spaces. * @return True iff the client name is valid. */ -bool NetworkValidateClientName(char *client_name) +bool NetworkValidateClientName(std::string &client_name) { StrTrimInPlace(client_name); if (NetworkIsValidClientName(client_name)) return true; @@ -1363,13 +1363,16 @@ void NetworkUpdateClientName() if (!NetworkValidateClientName()) return; /* Don't change the name if it is the same as the old name */ - if (strcmp(ci->client_name, _settings_client.network.client_name) != 0) { + if (_settings_client.network.client_name.compare(ci->client_name) != 0) { if (!_network_server) { - MyClient::SendSetName(_settings_client.network.client_name); + MyClient::SendSetName(_settings_client.network.client_name.c_str()); } else { - if (NetworkFindName(_settings_client.network.client_name, lastof(_settings_client.network.client_name))) { - NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, _settings_client.network.client_name); - strecpy(ci->client_name, _settings_client.network.client_name, lastof(ci->client_name)); + /* Copy to a temporary buffer so no #n gets added after our name in the settings when there are duplicate names. */ + char temporary_name[NETWORK_CLIENT_NAME_LENGTH]; + strecpy(temporary_name, _settings_client.network.client_name.c_str(), lastof(temporary_name)); + if (NetworkFindName(temporary_name, lastof(temporary_name))) { + NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, temporary_name); + strecpy(ci->client_name, temporary_name, lastof(ci->client_name)); NetworkUpdateClientInfo(CLIENT_ID_SERVER); } } 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 @@ -35,9 +35,9 @@ extern StringList _network_host_list; extern StringList _network_ban_list; byte NetworkSpectatorCount(); -bool NetworkIsValidClientName(const char *client_name); +bool NetworkIsValidClientName(const std::string_view client_name); bool NetworkValidateClientName(); -bool NetworkValidateClientName(char *client_name); +bool NetworkValidateClientName(std::string &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 @@ -462,7 +462,7 @@ public: this->FinishInitNested(WN_NETWORK_WINDOW_GAME); this->querystrings[WID_NG_CLIENT] = &this->name_editbox; - this->name_editbox.text.Assign(_settings_client.network.client_name); + this->name_editbox.text.Assign(_settings_client.network.client_name.c_str()); this->querystrings[WID_NG_FILTER] = &this->filter_editbox; this->filter_editbox.cancel_button = QueryString::ACTION_CLEAR; @@ -820,7 +820,7 @@ public: case WID_NG_CLIENT: /* 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)); + _settings_client.network.client_name = this->name_editbox.text.buf; break; } } @@ -2207,11 +2207,12 @@ public: } case WID_CL_CLIENT_NAME_EDIT: { - if (!NetworkValidateClientName(str)) break; + std::string client_name(str); + if (!NetworkValidateClientName(client_name)) break; uint index; GetSettingFromName("network.client_name", &index); - SetSettingValue(index, str); + SetSettingValue(index, client_name.c_str()); this->InvalidateData(); break; } diff --git a/src/newgrf_storage.h b/src/newgrf_storage.h --- a/src/newgrf_storage.h +++ b/src/newgrf_storage.h @@ -21,7 +21,7 @@ enum PersistentStorageMode { PSM_LEAVE_GAMELOOP, ///< Leave the gameloop, changes will be temporary. PSM_ENTER_COMMAND, ///< Enter command scope, changes will be permanent. PSM_LEAVE_COMMAND, ///< Leave command scope, revert to previous mode. - PSM_ENTER_TESTMODE, ///< Enter command test mode, changes will be tempoary. + PSM_ENTER_TESTMODE, ///< Enter command test mode, changes will be temporary. PSM_LEAVE_TESTMODE, ///< Leave command test mode, revert to previous mode. }; diff --git a/src/settings_type.h b/src/settings_type.h --- a/src/settings_type.h +++ b/src/settings_type.h @@ -267,7 +267,7 @@ struct NetworkSettings { std::string rcon_password; ///< password for rconsole (server side) std::string admin_password; ///< password for the admin network bool server_advertise; ///< advertise the server to the masterserver - char client_name[NETWORK_CLIENT_NAME_LENGTH]; ///< name of the player (as client) + std::string client_name; ///< name of the player (as client) std::string default_company_pass; ///< default password for new companies in encrypted form std::string connect_to_ip; ///< default for the "Add server" query std::string network_id; ///< network ID for servers diff --git a/src/string.cpp b/src/string.cpp --- a/src/string.cpp +++ b/src/string.cpp @@ -326,19 +326,10 @@ bool StrValid(const char *str, const cha * When there are spaces at the begin, the whole string is moved forward. * @param str The string to perform the in place left trimming on. */ -static void StrLeftTrimInPlace(char *str) +static void StrLeftTrimInPlace(std::string &str) { - if (StrEmpty(str)) return; - - char *first_non_space = str; - while (*first_non_space == ' ') first_non_space++; - - if (first_non_space == str) return; - - /* The source will reach '\0' first, but set the '\0' on the destination afterwards. */ - char *dst = str; - for (char *src = first_non_space; *src != '\0'; dst++, src++) *dst = *src; - *dst = '\0'; + size_t pos = str.find_first_not_of(' '); + str.erase(0, pos); } /** @@ -347,24 +338,10 @@ static void StrLeftTrimInPlace(char *str * When there are spaces at the end, the '\0' will be moved forward. * @param str The string to perform the in place left trimming on. */ -static void StrRightTrimInPlace(char *str) +static void StrRightTrimInPlace(std::string &str) { - if (StrEmpty(str)) return; - - char *end = str; - while (*end != '\0') end++; - - char *last_non_space = end - 1; - while (last_non_space >= str && *last_non_space == ' ') last_non_space--; - - /* The last non space points to the last character of the string that is not - * a space. For a string with only spaces or an empty string this would be - * the position before the begin of the string. The previous search ensures - * that this location before the string is not read. - * In any case, the character after the last non space character will be - * either a space or the existing termination, so it can be set to '\0'. - */ - last_non_space[1] = '\0'; + size_t pos = str.find_last_not_of(' '); + if (pos != std::string::npos) str.erase(pos + 1); } /** @@ -374,7 +351,7 @@ static void StrRightTrimInPlace(char *st * and when there are spaces at the back the '\0' termination is moved. * @param str The string to perform the in place trimming on. */ -void StrTrimInPlace(char *str) +void StrTrimInPlace(std::string &str) { StrLeftTrimInPlace(str); StrRightTrimInPlace(str); diff --git a/src/string_func.h b/src/string_func.h --- a/src/string_func.h +++ b/src/string_func.h @@ -49,7 +49,7 @@ bool strtolower(char *str); bool strtolower(std::string &str, std::string::size_type offs = 0); bool StrValid(const char *str, const char *last) NOACCESS(2); -void StrTrimInPlace(char *str); +void StrTrimInPlace(std::string &str); /** * Check if a string buffer is empty. diff --git a/src/table/settings.h.preamble b/src/table/settings.h.preamble --- a/src/table/settings.h.preamble +++ b/src/table/settings.h.preamble @@ -126,9 +126,6 @@ static size_t ConvertLandscape(const cha #define SDTC_LIST(var, type, flags, guiflags, def, str, strhelp, strval, proc, from, to, cat, extra, startup)\ SDTG_GENERAL(#var, SDT_INTLIST, SL_ARR, type, flags, guiflags, _settings_client.var, lengthof(_settings_client.var), def, 0, 0, 0, nullptr, str, strhelp, strval, proc, from, to, cat, extra, startup) -#define SDTC_STR(var, type, flags, guiflags, def, str, strhelp, strval, proc, from, to, cat, extra, startup)\ - SDTG_GENERAL(#var, SDT_STRING, SL_STR, type, flags, guiflags, _settings_client.var, sizeof(_settings_client.var), def, 0, 0, 0, nullptr, str, strhelp, strval, proc, from, to, cat, extra, startup) - #define SDTC_SSTR(var, type, flags, guiflags, def, max_length, str, strhelp, strval, proc, from, to, cat, extra, startup)\ SDTG_GENERAL(#var, SDT_STDSTRING, SL_STDSTR, type, flags, guiflags, _settings_client.var, sizeof(_settings_client.var), def, 0, max_length, 0, nullptr, str, strhelp, strval, proc, from, to, cat, extra, startup) diff --git a/src/table/settings.ini b/src/table/settings.ini --- a/src/table/settings.ini +++ b/src/table/settings.ini @@ -69,7 +69,6 @@ SDTG_OMANY = SDTG_OMANY($name, $ty SDTC_BOOL = SDTC_BOOL( $var, $flags, $guiflags, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extra, $startup), SDTC_LIST = SDTC_LIST( $var, $type, $flags, $guiflags, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extra, $startup), SDTC_OMANY = SDTC_OMANY( $var, $type, $flags, $guiflags, $def, $max, $full, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extra, $startup), -SDTC_STR = SDTC_STR( $var, $type, $flags, $guiflags, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extra, $startup), SDTC_SSTR = SDTC_SSTR( $var, $type, $flags, $guiflags, $def, $length, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extra, $startup), SDTC_VAR = SDTC_VAR( $var, $type, $flags, $guiflags, $def, $min, $max, $interval, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extra, $startup), SDT_BOOL = SDT_BOOL($base, $var, $flags, $guiflags, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat, $extra, $startup), @@ -3917,9 +3916,10 @@ flags = SLF_NOT_IN_SAVE | SLF_NO_NETW guiflags = SGF_NETWORK_ONLY def = false -[SDTC_STR] +[SDTC_SSTR] var = network.client_name -type = SLE_STRB +type = SLE_STR +length = NETWORK_CLIENT_NAME_LENGTH flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC def = nullptr proc = UpdateClientName