From ba409e8c4502cc435d0d3f4bec7ba5f5fe28b658 Mon Sep 17 00:00:00 2001 From: rubidium42 Date: Tue, 27 Apr 2021 21:25:52 +0200 Subject: [PATCH 01/22] Add: [Network] Writing std::string to a packet --- src/network/core/packet.cpp | 9 ++++----- src/network/core/packet.h | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/network/core/packet.cpp b/src/network/core/packet.cpp index 644490e0fb..6f56e4a567 100644 --- a/src/network/core/packet.cpp +++ b/src/network/core/packet.cpp @@ -178,12 +178,11 @@ void Packet::Send_uint64(uint64 data) * the string + '\0'. No size-byte or something. * @param data The string to send */ -void Packet::Send_string(const char *data) +void Packet::Send_string(const std::string_view data) { - assert(data != nullptr); - /* Length of the string + 1 for the '\0' termination. */ - assert(this->CanWriteToPacket(strlen(data) + 1)); - while (this->buffer.emplace_back(*data++) != '\0') {} + assert(this->CanWriteToPacket(data.size() + 1)); + this->buffer.insert(this->buffer.end(), data.begin(), data.end()); + this->buffer.emplace_back('\0'); } /** diff --git a/src/network/core/packet.h b/src/network/core/packet.h index bc7bab6c4f..0f58d3be84 100644 --- a/src/network/core/packet.h +++ b/src/network/core/packet.h @@ -71,7 +71,7 @@ public: void Send_uint16(uint16 data); void Send_uint32(uint32 data); void Send_uint64(uint64 data); - void Send_string(const char *data); + void Send_string(const std::string_view data); size_t Send_bytes (const byte *begin, const byte *end); /* Reading/receiving of packets */ From 7bcc472f73c774163285f71c235852ba0911e88e Mon Sep 17 00:00:00 2001 From: rubidium42 Date: Sun, 2 May 2021 08:43:11 +0200 Subject: [PATCH 02/22] Add: [Network] Reading std::string from a packet --- src/network/core/packet.cpp | 29 +++++++++++++++++++++++++++++ src/network/core/packet.h | 1 + 2 files changed, 30 insertions(+) diff --git a/src/network/core/packet.cpp b/src/network/core/packet.cpp index 6f56e4a567..7369707910 100644 --- a/src/network/core/packet.cpp +++ b/src/network/core/packet.cpp @@ -396,6 +396,35 @@ void Packet::Recv_string(char *buffer, size_t size, StringValidationSettings set str_validate(bufp, last, settings); } +/** + * Reads characters (bytes) from the packet until it finds a '\0', or reaches a + * maximum of \c length characters. + * When the '\0' has not been reached in the first \c length read characters, + * more characters are read from the packet until '\0' has been reached. However, + * these characters will not end up in the returned string. + * The length of the returned string will be at most \c length - 1 characters. + * @param length The maximum length of the string including '\0'. + * @param settings The string validation settings. + * @return The validated string. + */ +std::string Packet::Recv_string(size_t length, StringValidationSettings settings) +{ + assert(length > 1); + + /* Both loops with Recv_uint8 terminate when reading past the end of the + * packet as Recv_uint8 then closes the connection and returns 0. */ + std::string str; + char character; + while (--length > 0 && (character = this->Recv_uint8()) != '\0') str.push_back(character); + + if (length == 0) { + /* The string in the packet was longer. Read until the termination. */ + while (this->Recv_uint8() != '\0') {} + } + + return str_validate(str, settings); +} + /** * Get the amount of bytes that are still available for the Transfer functions. * @return The number of bytes that still have to be transfered. diff --git a/src/network/core/packet.h b/src/network/core/packet.h index 0f58d3be84..21a88e3ea9 100644 --- a/src/network/core/packet.h +++ b/src/network/core/packet.h @@ -88,6 +88,7 @@ public: uint32 Recv_uint32(); uint64 Recv_uint64(); void Recv_string(char *buffer, size_t size, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK); + std::string Recv_string(size_t length, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK); size_t RemainingBytesToTransfer() const; From 34215f7faa2de08d767b4f6945443a8f3175acbf Mon Sep 17 00:00:00 2001 From: glx22 Date: Fri, 30 Apr 2021 01:13:50 +0200 Subject: [PATCH 03/22] Codechange: Replace FOR_ALL_TARS with range-based for loops --- src/fileio.cpp | 9 ++++----- src/game/game_text.cpp | 11 +++++------ src/script/script_scanner.cpp | 9 ++++----- src/tar_type.h | 2 -- 4 files changed, 13 insertions(+), 18 deletions(-) diff --git a/src/fileio.cpp b/src/fileio.cpp index f2a2b14f3a..651fddff90 100644 --- a/src/fileio.cpp +++ b/src/fileio.cpp @@ -1345,12 +1345,12 @@ static uint ScanPath(FileScanner *fs, const char *extension, const char *path, s * @param extension the extension of files to search for. * @param tar the tar to search in. */ -static uint ScanTar(FileScanner *fs, const char *extension, TarFileList::iterator tar) +static uint ScanTar(FileScanner *fs, const char *extension, const TarFileList::value_type &tar) { uint num = 0; - const auto &filename = (*tar).first; + const auto &filename = tar.first; - if (MatchesExtension(extension, filename.c_str()) && fs->AddFile(filename, 0, (*tar).second.tar_filename)) num++; + if (MatchesExtension(extension, filename.c_str()) && fs->AddFile(filename, 0, tar.second.tar_filename)) num++; return num; } @@ -1369,7 +1369,6 @@ uint FileScanner::Scan(const char *extension, Subdirectory sd, bool tars, bool r this->subdir = sd; Searchpath sp; - TarFileList::iterator tar; uint num = 0; FOR_ALL_SEARCHPATHS(sp) { @@ -1381,7 +1380,7 @@ uint FileScanner::Scan(const char *extension, Subdirectory sd, bool tars, bool r } if (tars && sd != NO_DIRECTORY) { - FOR_ALL_TARS(tar, sd) { + for (const auto &tar : _tar_filelist[sd]) { num += ScanTar(this, extension, tar); } } diff --git a/src/game/game_text.cpp b/src/game/game_text.cpp index 24f41c93ac..ce20c1ee70 100644 --- a/src/game/game_text.cpp +++ b/src/game/game_text.cpp @@ -249,16 +249,15 @@ GameStrings *LoadTranslations() if (!tar_filename.empty() && (iter = _tar_list[GAME_DIR].find(tar_filename)) != _tar_list[GAME_DIR].end()) { /* The main script is in a tar file, so find all files that * are in the same tar and add them to the langfile scanner. */ - TarFileList::iterator tar; - FOR_ALL_TARS(tar, GAME_DIR) { + for (const auto &tar : _tar_filelist[GAME_DIR]) { /* Not in the same tar. */ - if (tar->second.tar_filename != iter->first) continue; + if (tar.second.tar_filename != iter->first) continue; /* Check the path and extension. */ - if (tar->first.size() <= ldir.size() || tar->first.compare(0, ldir.size(), ldir) != 0) continue; - if (tar->first.compare(tar->first.size() - 4, 4, ".txt") != 0) continue; + if (tar.first.size() <= ldir.size() || tar.first.compare(0, ldir.size(), ldir) != 0) continue; + if (tar.first.compare(tar.first.size() - 4, 4, ".txt") != 0) continue; - scanner.AddFile(tar->first, 0, tar_filename); + scanner.AddFile(tar.first, 0, tar_filename); } } else { /* Scan filesystem */ diff --git a/src/script/script_scanner.cpp b/src/script/script_scanner.cpp index 8b48809bf7..bdde99f6c3 100644 --- a/src/script/script_scanner.cpp +++ b/src/script/script_scanner.cpp @@ -224,16 +224,15 @@ static bool IsSameScript(const ContentInfo *ci, bool md5sum, ScriptInfo *info, S if (!tar_filename.empty() && (iter = _tar_list[dir].find(tar_filename)) != _tar_list[dir].end()) { /* The main script is in a tar file, so find all files that * are in the same tar and add them to the MD5 checksumming. */ - TarFileList::iterator tar; - FOR_ALL_TARS(tar, dir) { + for (const auto &tar : _tar_filelist[dir]) { /* Not in the same tar. */ - if (tar->second.tar_filename != iter->first) continue; + if (tar.second.tar_filename != iter->first) continue; /* Check the extension. */ - const char *ext = strrchr(tar->first.c_str(), '.'); + const char *ext = strrchr(tar.first.c_str(), '.'); if (ext == nullptr || strcasecmp(ext, ".nut") != 0) continue; - checksum.AddFile(tar->first, 0, tar_filename); + checksum.AddFile(tar.first, 0, tar_filename); } } else { char path[MAX_PATH]; diff --git a/src/tar_type.h b/src/tar_type.h index c4e72df851..4266f23623 100644 --- a/src/tar_type.h +++ b/src/tar_type.h @@ -28,6 +28,4 @@ typedef std::map TarFileList; extern std::array _tar_list; extern TarFileList _tar_filelist[NUM_SUBDIRS]; -#define FOR_ALL_TARS(tar, sd) for (tar = _tar_filelist[sd].begin(); tar != _tar_filelist[sd].end(); tar++) - #endif /* TAR_TYPE_H */ From 983c7ade60f82a49d8c23c1f295add1fd9a913b0 Mon Sep 17 00:00:00 2001 From: glx22 Date: Fri, 30 Apr 2021 15:41:58 +0200 Subject: [PATCH 04/22] Codechange: Replace FOR_ALL_SEARCHPATHS with range-based for loops --- src/fileio.cpp | 29 +++++++++++++++++------------ src/fileio_func.h | 12 ++---------- src/fios.cpp | 3 +-- src/script/script_instance.cpp | 3 +-- src/strings.cpp | 4 +--- 5 files changed, 22 insertions(+), 29 deletions(-) diff --git a/src/fileio.cpp b/src/fileio.cpp index 651fddff90..810f3f34ef 100644 --- a/src/fileio.cpp +++ b/src/fileio.cpp @@ -241,6 +241,7 @@ static_assert(lengthof(_subdirs) == NUM_SUBDIRS); * current operating system. */ std::array _searchpaths; +std::vector _valid_searchpaths; std::array _tar_list; TarFileList _tar_filelist[NUM_SUBDIRS]; @@ -252,11 +253,19 @@ static TarLinkList _tar_linklist[NUM_SUBDIRS]; ///< List of directory links * @param sp the search path to check * @return true if the search path is valid */ -bool IsValidSearchPath(Searchpath sp) +static bool IsValidSearchPath(Searchpath sp) { return sp < _searchpaths.size() && !_searchpaths[sp].empty(); } +static void FillValidSearchPaths() +{ + _valid_searchpaths.clear(); + for (Searchpath sp = SP_FIRST_DIR; sp < NUM_SEARCHPATHS; sp++) { + if (IsValidSearchPath(sp)) _valid_searchpaths.emplace_back(sp); + } +} + /** * Check whether the given file exists * @param filename the file to try for existence. @@ -298,10 +307,9 @@ void FioFCloseFile(FILE *f) */ std::string FioFindFullPath(Subdirectory subdir, const char *filename) { - Searchpath sp; assert(subdir < NUM_SUBDIRS); - FOR_ALL_SEARCHPATHS(sp) { + for (Searchpath sp : _valid_searchpaths) { std::string buf = FioGetDirectory(sp, subdir); buf += filename; if (FileExists(buf)) return buf; @@ -326,10 +334,8 @@ std::string FioGetDirectory(Searchpath sp, Subdirectory subdir) std::string FioFindDirectory(Subdirectory subdir) { - Searchpath sp; - /* Find and return the first valid directory */ - FOR_ALL_SEARCHPATHS(sp) { + for (Searchpath sp : _valid_searchpaths) { std::string ret = FioGetDirectory(sp, subdir); if (FileExists(ret)) return ret; } @@ -406,11 +412,10 @@ FILE *FioFOpenFileTar(const TarFileListEntry &entry, size_t *filesize) FILE *FioFOpenFile(const std::string &filename, const char *mode, Subdirectory subdir, size_t *filesize) { FILE *f = nullptr; - Searchpath sp; assert(subdir < NUM_SUBDIRS || subdir == NO_DIRECTORY); - FOR_ALL_SEARCHPATHS(sp) { + for (Searchpath sp : _valid_searchpaths) { f = FioFOpenFileSp(filename, mode, sp, subdir, filesize); if (f != nullptr || subdir == NO_DIRECTORY) break; } @@ -1130,6 +1135,7 @@ std::string _personal_dir; void DeterminePaths(const char *exe) { DetermineBasePaths(exe); + FillValidSearchPaths(); #ifdef USE_XDG std::string config_home; @@ -1148,8 +1154,7 @@ void DeterminePaths(const char *exe) AppendPathSeparator(config_home); #endif - Searchpath sp; - FOR_ALL_SEARCHPATHS(sp) { + for (Searchpath sp : _valid_searchpaths) { if (sp == SP_WORKING_DIR && !_do_scan_working_directory) continue; DEBUG(misc, 4, "%s added as search path", _searchpaths[sp].c_str()); } @@ -1222,6 +1227,7 @@ void DeterminePaths(const char *exe) /* If we have network we make a directory for the autodownloading of content */ _searchpaths[SP_AUTODOWNLOAD_DIR] = _personal_dir + "content_download" PATHSEP; FioCreateDirectory(_searchpaths[SP_AUTODOWNLOAD_DIR]); + FillValidSearchPaths(); /* Create the directory for each of the types of content */ const Subdirectory dirs[] = { SCENARIO_DIR, HEIGHTMAP_DIR, BASESET_DIR, NEWGRF_DIR, AI_DIR, AI_LIBRARY_DIR, GAME_DIR, GAME_LIBRARY_DIR }; @@ -1368,10 +1374,9 @@ uint FileScanner::Scan(const char *extension, Subdirectory sd, bool tars, bool r { this->subdir = sd; - Searchpath sp; uint num = 0; - FOR_ALL_SEARCHPATHS(sp) { + for (Searchpath sp : _valid_searchpaths) { /* Don't search in the working directory */ if (sp == SP_WORKING_DIR && !_do_scan_working_directory) continue; diff --git a/src/fileio_func.h b/src/fileio_func.h index 1428356506..4b9b2dd9ee 100644 --- a/src/fileio_func.h +++ b/src/fileio_func.h @@ -13,6 +13,7 @@ #include "core/enum_type.hpp" #include "fileio_type.h" #include +#include void FioSeekTo(size_t pos, int mode); void FioSeekToFile(uint8 slot, size_t pos); @@ -26,16 +27,6 @@ void FioOpenFile(int slot, const std::string &filename, Subdirectory subdir); void FioReadBlock(void *ptr, size_t size); void FioSkipBytes(int n); -/** - * Checks whether the given search path is a valid search path - * @param sp the search path to check - * @return true if the search path is valid - */ -bool IsValidSearchPath(Searchpath sp); - -/** Iterator for all the search paths */ -#define FOR_ALL_SEARCHPATHS(sp) for (sp = SP_FIRST_DIR; sp < NUM_SEARCHPATHS; sp++) if (IsValidSearchPath(sp)) - void FioFCloseFile(FILE *f); FILE *FioFOpenFile(const std::string &filename, const char *mode, Subdirectory subdir, size_t *filesize = nullptr); bool FioCheckFileExists(const std::string &filename, Subdirectory subdir); @@ -54,6 +45,7 @@ bool FileExists(const std::string &filename); bool ExtractTar(const std::string &tar_filename, Subdirectory subdir); extern std::string _personal_dir; ///< custom directory for personal settings, saves, newgrf, etc. +extern std::vector _valid_searchpaths; /** Helper for scanning for files with a given name */ class FileScanner { diff --git a/src/fios.cpp b/src/fios.cpp index 8528e8c622..3b11bcbe02 100644 --- a/src/fios.cpp +++ b/src/fios.cpp @@ -582,8 +582,7 @@ static FiosType FiosGetHeightmapListCallback(SaveLoadOperation fop, const std::s * collections of NewGRFs or 32 bpp graphics replacement PNGs. */ bool match = false; - Searchpath sp; - FOR_ALL_SEARCHPATHS(sp) { + for (Searchpath sp : _valid_searchpaths) { std::string buf = FioGetDirectory(sp, HEIGHTMAP_DIR); if (buf.compare(0, buf.size(), it->second.tar_filename, 0, buf.size()) == 0) { diff --git a/src/script/script_instance.cpp b/src/script/script_instance.cpp index f7f9de4fc8..fadbba70dd 100644 --- a/src/script/script_instance.cpp +++ b/src/script/script_instance.cpp @@ -116,8 +116,7 @@ bool ScriptInstance::LoadCompatibilityScripts(const char *api_version, Subdirect { char script_name[32]; seprintf(script_name, lastof(script_name), "compat_%s.nut", api_version); - Searchpath sp; - FOR_ALL_SEARCHPATHS(sp) { + for (Searchpath sp : _valid_searchpaths) { std::string buf = FioGetDirectory(sp, dir); buf += script_name; if (!FileExists(buf)) continue; diff --git a/src/strings.cpp b/src/strings.cpp index e340a2b1c4..0489714590 100644 --- a/src/strings.cpp +++ b/src/strings.cpp @@ -1949,9 +1949,7 @@ static void GetLanguageList(const char *path) */ void InitializeLanguagePacks() { - Searchpath sp; - - FOR_ALL_SEARCHPATHS(sp) { + for (Searchpath sp : _valid_searchpaths) { std::string path = FioGetDirectory(sp, LANG_DIR); GetLanguageList(path.c_str()); } From 2feb801e56f5f36121bcc44d04cb46937987c490 Mon Sep 17 00:00:00 2001 From: glx22 Date: Fri, 30 Apr 2021 17:01:26 +0200 Subject: [PATCH 05/22] Codechange: Replace FOR_ALL_ROADTRAMTYPES with range-based for loops --- src/road.h | 2 +- src/road_cmd.cpp | 6 +++--- src/saveload/afterload.cpp | 2 +- src/saveload/company_sl.cpp | 6 +++--- src/station_cmd.cpp | 6 +++--- src/tunnelbridge_cmd.cpp | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/road.h b/src/road.h index becbf40512..6a2af6698f 100644 --- a/src/road.h +++ b/src/road.h @@ -32,7 +32,7 @@ enum RoadTramTypes : uint8 { }; DECLARE_ENUM_AS_BIT_SET(RoadTramTypes) -#define FOR_ALL_ROADTRAMTYPES(x) for (RoadTramType x : { RTT_ROAD, RTT_TRAM }) +static const RoadTramType _roadtramtypes[] = { RTT_ROAD, RTT_TRAM }; /** Roadtype flags. Starts with RO instead of R because R is used for rails */ enum RoadTypeFlags { diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index 830f9dd4fc..82e944f6e6 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.cpp @@ -1238,7 +1238,7 @@ static CommandCost ClearTile_Road(TileIndex tile, DoCommandFlag flags) /* Clear the road if only one piece is on the tile OR we are not using the DC_AUTO flag */ if ((HasExactlyOneBit(b) && GetRoadBits(tile, RTT_TRAM) == ROAD_NONE) || !(flags & DC_AUTO)) { CommandCost ret(EXPENSES_CONSTRUCTION); - FOR_ALL_ROADTRAMTYPES(rtt) { + for (RoadTramType rtt : _roadtramtypes) { if (!MayHaveRoad(tile) || GetRoadType(tile, rtt) == INVALID_ROADTYPE) continue; CommandCost tmp_ret = RemoveRoad(tile, flags, GetRoadBits(tile, rtt), rtt, true); @@ -2203,7 +2203,7 @@ static void ChangeTileOwner_Road(TileIndex tile, Owner old_owner, Owner new_owne Company::Get(new_owner)->infrastructure.road[rt] += 2; SetTileOwner(tile, new_owner); - FOR_ALL_ROADTRAMTYPES(rtt) { + for (RoadTramType rtt : _roadtramtypes) { if (GetRoadOwner(tile, rtt) == old_owner) { SetRoadOwner(tile, rtt, new_owner); } @@ -2213,7 +2213,7 @@ static void ChangeTileOwner_Road(TileIndex tile, Owner old_owner, Owner new_owne return; } - FOR_ALL_ROADTRAMTYPES(rtt) { + for (RoadTramType rtt : _roadtramtypes) { /* Update all roadtypes, no matter if they are present */ if (GetRoadOwner(tile, rtt) == old_owner) { RoadType rt = GetRoadType(tile, rtt); diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 56680511cb..7fd2204943 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -1855,7 +1855,7 @@ bool AfterLoadGame() } } else if (IsTileType(t, MP_ROAD)) { /* works for all RoadTileType */ - FOR_ALL_ROADTRAMTYPES(rtt) { + for (RoadTramType rtt : _roadtramtypes) { /* update even non-existing road types to update tile owner too */ Owner o = GetRoadOwner(t, rtt); if (o < MAX_COMPANIES && !Company::IsValidID(o)) SetRoadOwner(t, rtt, OWNER_NONE); diff --git a/src/saveload/company_sl.cpp b/src/saveload/company_sl.cpp index fb2742a186..5770f9791e 100644 --- a/src/saveload/company_sl.cpp +++ b/src/saveload/company_sl.cpp @@ -128,7 +128,7 @@ void AfterLoadCompanyStats() } /* Iterate all present road types as each can have a different owner. */ - FOR_ALL_ROADTRAMTYPES(rtt) { + for (RoadTramType rtt : _roadtramtypes) { RoadType rt = GetRoadType(tile, rtt); if (rt == INVALID_ROADTYPE) continue; c = Company::GetIfValid(IsRoadDepot(tile) ? GetTileOwner(tile) : GetRoadOwner(tile, rtt)); @@ -151,7 +151,7 @@ void AfterLoadCompanyStats() case STATION_BUS: case STATION_TRUCK: { /* Iterate all present road types as each can have a different owner. */ - FOR_ALL_ROADTRAMTYPES(rtt) { + for (RoadTramType rtt : _roadtramtypes) { RoadType rt = GetRoadType(tile, rtt); if (rt == INVALID_ROADTYPE) continue; c = Company::GetIfValid(GetRoadOwner(tile, rtt)); @@ -209,7 +209,7 @@ void AfterLoadCompanyStats() case TRANSPORT_ROAD: { /* Iterate all present road types as each can have a different owner. */ - FOR_ALL_ROADTRAMTYPES(rtt) { + for (RoadTramType rtt : _roadtramtypes) { RoadType rt = GetRoadType(tile, rtt); if (rt == INVALID_ROADTYPE) continue; c = Company::GetIfValid(GetRoadOwner(tile, rtt)); diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 451dedbad4..39efb710e6 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -2029,7 +2029,7 @@ static CommandCost RemoveRoadStop(TileIndex tile, DoCommandFlag flags) } /* Update company infrastructure counts. */ - FOR_ALL_ROADTRAMTYPES(rtt) { + for (RoadTramType rtt : _roadtramtypes) { RoadType rt = GetRoadType(tile, rtt); UpdateCompanyRoadInfrastructure(rt, GetRoadOwner(tile, rtt), -static_cast(ROAD_STOP_TRACKBIT_FACTOR)); } @@ -2110,7 +2110,7 @@ CommandCost CmdRemoveRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, ui RoadType road_type[] = { INVALID_ROADTYPE, INVALID_ROADTYPE }; Owner road_owner[] = { OWNER_NONE, OWNER_NONE }; if (IsDriveThroughStopTile(cur_tile)) { - FOR_ALL_ROADTRAMTYPES(rtt) { + for (RoadTramType rtt : _roadtramtypes) { road_type[rtt] = GetRoadType(cur_tile, rtt); if (road_type[rtt] == INVALID_ROADTYPE) continue; road_owner[rtt] = GetRoadOwner(cur_tile, rtt); @@ -4178,7 +4178,7 @@ void DeleteOilRig(TileIndex tile) static void ChangeTileOwner_Station(TileIndex tile, Owner old_owner, Owner new_owner) { if (IsRoadStopTile(tile)) { - FOR_ALL_ROADTRAMTYPES(rtt) { + for (RoadTramType rtt : _roadtramtypes) { /* Update all roadtypes, no matter if they are present */ if (GetRoadOwner(tile, rtt) == old_owner) { RoadType rt = GetRoadType(tile, rtt); diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 2f76dbcef9..dd8d731ee9 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.cpp @@ -1811,7 +1811,7 @@ static void ChangeTileOwner_TunnelBridge(TileIndex tile, Owner old_owner, Owner * don't want to update the infrastructure counts twice. */ uint num_pieces = tile < other_end ? (GetTunnelBridgeLength(tile, other_end) + 2) * TUNNELBRIDGE_TRACKBIT_FACTOR : 0; - FOR_ALL_ROADTRAMTYPES(rtt) { + for (RoadTramType rtt : _roadtramtypes) { /* Update all roadtypes, no matter if they are present */ if (GetRoadOwner(tile, rtt) == old_owner) { RoadType rt = GetRoadType(tile, rtt); From 176d65b47240be9be0fece2c56019f66cf4b8692 Mon Sep 17 00:00:00 2001 From: Tyler Trahan Date: Tue, 4 May 2021 07:28:01 -0400 Subject: [PATCH 06/22] Change: Use gender-neutral pronouns in english.txt (#9189) --- src/lang/english.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lang/english.txt b/src/lang/english.txt index f8e3618e51..f0ac1df382 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -2269,7 +2269,7 @@ STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {RAW_STRING STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {RAW_STRING} has joined spectators STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {RAW_STRING} has started a new company (#{2:NUM}) STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {RAW_STRING} has left the game ({2:STRING}) -STR_NETWORK_MESSAGE_NAME_CHANGE :*** {RAW_STRING} has changed his/her name to {RAW_STRING} +STR_NETWORK_MESSAGE_NAME_CHANGE :*** {RAW_STRING} has changed their name to {RAW_STRING} STR_NETWORK_MESSAGE_GIVE_MONEY :*** {RAW_STRING} gave {2:CURRENCY_LONG} to {1:RAW_STRING} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}The server closed the session STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}The server is restarting...{}Please wait... From fa206bf2e3fb7869af7797be008d7b35704d8177 Mon Sep 17 00:00:00 2001 From: translators Date: Tue, 4 May 2021 18:58:09 +0000 Subject: [PATCH 07/22] Update: Translations from eints english (us): 1 change by 2TallTyler estonian: 49 changes by siimsoni korean: 1 change by telk5093 hungarian: 45 changes by baliball finnish: 12 changes by hpiirai spanish: 1 change by JohnBoyFan --- src/lang/english_US.txt | 1 + src/lang/estonian.txt | 50 ++++++++++++++++++++++++++++++++++++++++- src/lang/finnish.txt | 23 ++++++++++--------- src/lang/hungarian.txt | 47 ++++++++++++++++++++++++++++++++++++-- src/lang/korean.txt | 2 +- src/lang/spanish.txt | 1 + 6 files changed, 109 insertions(+), 15 deletions(-) diff --git a/src/lang/english_US.txt b/src/lang/english_US.txt index dd81df78e3..14ad4e9aae 100644 --- a/src/lang/english_US.txt +++ b/src/lang/english_US.txt @@ -2217,6 +2217,7 @@ STR_NETWORK_ERROR_TIMEOUT_COMPUTER :{WHITE}Your com STR_NETWORK_ERROR_TIMEOUT_MAP :{WHITE}Your computer took too long to download the map STR_NETWORK_ERROR_TIMEOUT_JOIN :{WHITE}Your computer took too long to join the server STR_NETWORK_ERROR_INVALID_CLIENT_NAME :{WHITE}Your player name is not valid +STR_NETWORK_ERROR_SERVER_TOO_OLD :{WHITE}The queried server is too old for this client ############ Leave those lines in this order!! STR_NETWORK_ERROR_CLIENT_GENERAL :general error diff --git a/src/lang/estonian.txt b/src/lang/estonian.txt index d4b7d94dbe..c9acfd0e7d 100644 --- a/src/lang/estonian.txt +++ b/src/lang/estonian.txt @@ -1050,6 +1050,7 @@ STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_12_MONTHS :12 kuud STR_GAME_OPTIONS_LANGUAGE :{BLACK}Keel STR_GAME_OPTIONS_LANGUAGE_TOOLTIP :{BLACK}Valib kasutajaliideses kasutatava keele +STR_GAME_OPTIONS_LANGUAGE_PERCENTAGE :{STRING} ({NUM}% valmis) STR_GAME_OPTIONS_FULLSCREEN :{BLACK}Täisekraan STR_GAME_OPTIONS_FULLSCREEN_TOOLTIP :{BLACK}Märgi see kast, et OpenTTD täisekraanirežiimis mängida @@ -1063,6 +1064,8 @@ STR_GAME_OPTIONS_VIDEO_ACCELERATION :{BLACK}Riistvar STR_GAME_OPTIONS_VIDEO_ACCELERATION_TOOLTIP :{BLACK}Märkides selle ruudu, lubad OpenTTD-l üritada kasutada riistvarakiirendust. Muudetud seade omab mõju pärast mängu taaskäivitust STR_GAME_OPTIONS_VIDEO_ACCELERATION_RESTART :{WHITE}Seade omab mõju alles pärast mängu taaskäivitust +STR_GAME_OPTIONS_VIDEO_VSYNC :{BLACK}VSync +STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Märgi, et ekraani v-sync sisse lülitada. Seade kohaldub alles pärast mängu taaskäivitust. Töötab vaid, kui riistvarakiirendus on peal STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Liidese suurus STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Vali kasutatav liideseelementide suurus @@ -1196,6 +1199,7 @@ STR_CONFIG_SETTING_TREE_CAPTION :{WHITE}Seaded STR_CONFIG_SETTING_FILTER_TITLE :{BLACK}Märksõna: STR_CONFIG_SETTING_EXPAND_ALL :{BLACK}Ava kõik STR_CONFIG_SETTING_COLLAPSE_ALL :{BLACK}Sulge kõik +STR_CONFIG_SETTING_RESET_ALL :{BLACK}Nulli kõik väärtused STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT :(seletus puudub) STR_CONFIG_SETTING_DEFAULT_VALUE :{LTBLUE}Vaikeväärtus: {ORANGE}{STRING} STR_CONFIG_SETTING_TYPE :{LTBLUE}Seade liik: {ORANGE}{STRING} @@ -1204,6 +1208,8 @@ STR_CONFIG_SETTING_TYPE_GAME_MENU :Mängu seade (s STR_CONFIG_SETTING_TYPE_GAME_INGAME :Mängu seaded (hoitakse salvestuses; mõjutab ainult praegust mängu) STR_CONFIG_SETTING_TYPE_COMPANY_MENU :Ettevõtte seaded (hoitakse salvestuses; mõjutab ainult uusi mänge) STR_CONFIG_SETTING_TYPE_COMPANY_INGAME :Ettevõtte seaded (hoitakse salvestuses; mõjutab ainult praegust ettevõtet) +STR_CONFIG_SETTING_RESET_ALL_CONFIRMATION_DIALOG_CAPTION :{WHITE}Ettevaatust! +STR_CONFIG_SETTING_RESET_ALL_CONFIRMATION_DIALOG_TEXT :{WHITE}See toiming nullib kõik mänguseaded.{}Oled sa kindel, et jätkata? STR_CONFIG_SETTING_RESTRICT_CATEGORY :{BLACK}Jagu: STR_CONFIG_SETTING_RESTRICT_TYPE :{BLACK}Liik: @@ -2042,6 +2048,8 @@ STR_FACE_TIE :Lips: STR_FACE_EARRING :Kõrvarõngas: STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Vaheta kraed või kõrvarõngast +STR_NETWORK_SERVER_VISIBILITY_PRIVATE :Privaatne +STR_NETWORK_SERVER_VISIBILITY_PUBLIC :Avalik # Network server list STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Mitmikmäng @@ -2105,6 +2113,8 @@ STR_NETWORK_START_SERVER_NEW_GAME_NAME_TOOLTIP :{BLACK}Serveril STR_NETWORK_START_SERVER_SET_PASSWORD :{BLACK}Määra salasõna STR_NETWORK_START_SERVER_PASSWORD_TOOLTIP :{BLACK}Et server ei oleks avalik, kaitse oma mäng salasõnaga +STR_NETWORK_START_SERVER_VISIBILITY_LABEL :{BLACK}Nähtavus +STR_NETWORK_START_SERVER_VISIBILITY_TOOLTIP :{BLACK}Kas sinu server on kõikidele teistele avalikult nähtav STR_NETWORK_START_SERVER_CLIENTS_SELECT :{BLACK}{NUM} klient{P "" i} STR_NETWORK_START_SERVER_NUMBER_OF_CLIENTS :{BLACK}Kliente kuni: STR_NETWORK_START_SERVER_NUMBER_OF_CLIENTS.in :sees @@ -2169,11 +2179,44 @@ STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Server o STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Ettevõte on kaitstud. Sisesta salasõna # Network company list added strings -STR_NETWORK_COMPANY_LIST_CLIENT_LIST :Klientide nimekiri +STR_NETWORK_COMPANY_LIST_CLIENT_LIST :Ühendatud mängijad # Network client list +STR_NETWORK_CLIENT_LIST_CAPTION :{WHITE}Mitmikmäng +STR_NETWORK_CLIENT_LIST_SERVER :{BLACK}Server +STR_NETWORK_CLIENT_LIST_SERVER_NAME :{BLACK}Nimi +STR_NETWORK_CLIENT_LIST_SERVER_NAME_TOOLTIP :{BLACK}Serveri nimi, kus sa mängid +STR_NETWORK_CLIENT_LIST_SERVER_NAME_EDIT_TOOLTIP :{BLACK}Muuda oma serveri nime +STR_NETWORK_CLIENT_LIST_SERVER_NAME_QUERY_CAPTION :Serveri nimi +STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY :{BLACK}Nähtavus +STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY_TOOLTIP :{BLACK}Kas sinu server on kõikidele teistele avalikult nähtav +STR_NETWORK_CLIENT_LIST_PLAYER :{BLACK}Mängija +STR_NETWORK_CLIENT_LIST_PLAYER_NAME :{BLACK}Nimi +STR_NETWORK_CLIENT_LIST_PLAYER_NAME_TOOLTIP :{BLACK}Sinu mängija nimi +STR_NETWORK_CLIENT_LIST_PLAYER_NAME_EDIT_TOOLTIP :{BLACK}Muuda oma mängija nime +STR_NETWORK_CLIENT_LIST_PLAYER_NAME_QUERY_CAPTION :Sinu mängija nimi +STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_TOOLTIP :{BLACK}Haldustegevused, mida teha selle ettevõtte peal +STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_TOOLTIP :{BLACK}Haldustegevused, mida teha selle ettevõtte peal +STR_NETWORK_CLIENT_LIST_JOIN_TOOLTIP :{BLACK}Liitu selle ettevõttega +STR_NETWORK_CLIENT_LIST_CHAT_CLIENT_TOOLTIP :{BLACK}Saada sellele mängijale sõnum +STR_NETWORK_CLIENT_LIST_CHAT_COMPANY_TOOLTIP :{BLACK}Saada sõnum igale selle ettevõtte mängijale +STR_NETWORK_CLIENT_LIST_CHAT_SPECTATOR_TOOLTIP :{BLACK}Saada sõnum igale vaatlejale +STR_NETWORK_CLIENT_LIST_SPECTATORS :Vaatlejad +STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Uus ettevõte) +STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Loo uus ettevõte ja liitu sellega +STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Tema oled sina +STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Tema on mängu korraldaja +STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :Viska välja +STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Keela +STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET :Kustuta +STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_UNLOCK :Salasõnaga avamine +STR_NETWORK_CLIENT_LIST_ASK_CAPTION :{WHITE}Haldustoiming +STR_NETWORK_CLIENT_LIST_ASK_CLIENT_KICK :{YELLOW}Kas oled kindel, et välja visata mängija '{STRING}'? +STR_NETWORK_CLIENT_LIST_ASK_CLIENT_BAN :{YELLOW}Kas oled kindel, et sa tahad keelata mängija '{STRING}'? +STR_NETWORK_CLIENT_LIST_ASK_COMPANY_RESET :{YELLOW}Kas oled kindel, et tahad kustutada ettevõtte '{COMPANY}'? +STR_NETWORK_CLIENT_LIST_ASK_COMPANY_UNLOCK :{YELLOW}Kas oled kindel, et soovid nullida ettevõtte '{COMPANY}' salasõna? STR_NETWORK_SERVER :Server STR_NETWORK_CLIENT :Klient @@ -2218,6 +2261,7 @@ STR_NETWORK_ERROR_SERVER_START :{WHITE}Ei saa u STR_NETWORK_ERROR_CLIENT_START :{WHITE}Ei õnnestu ühendada STR_NETWORK_ERROR_TIMEOUT :{WHITE}Ühendus nr {NUM} aegus STR_NETWORK_ERROR_SERVER_ERROR :{WHITE}Tekkis protokolliviga ja ühendus katkes +STR_NETWORK_ERROR_BAD_PLAYER_NAME :{WHITE}Sinu mängijale ei ole nime määratud. Nime saab määrata mitmikmägu akna ülaosas STR_NETWORK_ERROR_WRONG_REVISION :{WHITE}Kliendi osa ei vasta serveri osaga STR_NETWORK_ERROR_WRONG_PASSWORD :{WHITE}Vale salasõna STR_NETWORK_ERROR_SERVER_FULL :{WHITE}Server on täis @@ -2230,6 +2274,8 @@ STR_NETWORK_ERROR_TIMEOUT_PASSWORD :{WHITE}Sisestas STR_NETWORK_ERROR_TIMEOUT_COMPUTER :{WHITE}Arvutil võttis liitumisega liiga kaua aega STR_NETWORK_ERROR_TIMEOUT_MAP :{WHITE}Kaardi allalaadimine võttis liiga kaua aega STR_NETWORK_ERROR_TIMEOUT_JOIN :{WHITE}Serveriga liitumine võttis liiga kaua aega +STR_NETWORK_ERROR_INVALID_CLIENT_NAME :{WHITE}Sinu mängija nimi ei vasta nõuetele +STR_NETWORK_ERROR_SERVER_TOO_OLD :{WHITE}Päritud server kasutab liiga vana versiooni ############ Leave those lines in this order!! STR_NETWORK_ERROR_CLIENT_GENERAL :üldine viga @@ -2252,6 +2298,7 @@ STR_NETWORK_ERROR_CLIENT_TIMEOUT_PASSWORD :ei saanud õige STR_NETWORK_ERROR_CLIENT_TIMEOUT_COMPUTER :üldine aegumine STR_NETWORK_ERROR_CLIENT_TIMEOUT_MAP :kaardi laadimine võttis liiga kaua aega STR_NETWORK_ERROR_CLIENT_TIMEOUT_JOIN :kaardi töötlemine võttis liiga kaua aega +STR_NETWORK_ERROR_CLIENT_INVALID_CLIENT_NAME :kliendinimi ei vasta nõuetele ############ End of leave-in-this-order STR_NETWORK_ERROR_CLIENT_GUI_LOST_CONNECTION_CAPTION :{WHITE}Võimalik ühenduse katkemine @@ -3091,6 +3138,7 @@ STR_NEWGRF_ERROR_MSG_WARNING :{RED}Hoiatus: { STR_NEWGRF_ERROR_MSG_ERROR :{RED}Viga: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Saatuslik viga: {SILVER}{STRING} STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Esines raske NewGRF-i tõrge:{}{STRING} +STR_NEWGRF_ERROR_POPUP :{WHITE}Esines viga NewGRF-iga:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :OpenTTD väitel {1:STRING} ei tööta selle TTDPatch versiooniga. STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} on {STRING} TTD osa jaoks. STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} on mõeldud kasutamiseks {STRING} diff --git a/src/lang/finnish.txt b/src/lang/finnish.txt index 4435cca260..8f1b82c784 100644 --- a/src/lang/finnish.txt +++ b/src/lang/finnish.txt @@ -1170,9 +1170,9 @@ STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_MENU :Pelin asetukset STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_INGAME :Pelin asetukset (tallennetaan pelitallenteeseen; vaikuttavat vain nykyiseen peliin) STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_MENU :Yhtiön asetukset (tallennetaan pelitallenteisiin; vaikuttavat vain uusiin peleihin) STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_INGAME :Yhtiön asetukset (tallennetaan pelitallenteeseen; vaikuttavat ainoastaan nykyiseen yhtiöön) -STR_CONFIG_SETTING_CATEGORY_HIDES :{BLACK}Näytä kaikki tulokset muuttamalla{}{SILVER}Kategoriaksi {WHITE}{STRING} +STR_CONFIG_SETTING_CATEGORY_HIDES :{BLACK}Näytä kaikki tulokset muuttamalla{}{SILVER}kategoriaksi {WHITE}{STRING} STR_CONFIG_SETTING_TYPE_HIDES :{BLACK}Näytä kaikki hakutulokset muuttamalla{}{SILVER}Tyypiksi {WHITE}Kaikki asetustyypit -STR_CONFIG_SETTING_CATEGORY_AND_TYPE_HIDES :{BLACK}Näytä kaikki tulokset muuttamalla{}{SILVER}Kategoriaksi {WHITE}{STRING} {BLACK}ja {SILVER}Tyypiksi {WHITE}Kaikki asetustyypit +STR_CONFIG_SETTING_CATEGORY_AND_TYPE_HIDES :{BLACK}Näytä kaikki tulokset muuttamalla{}{SILVER}kategoriaksi {WHITE}{STRING} {BLACK}ja {SILVER}tyypiksi {WHITE}kaikki asetustyypit STR_CONFIG_SETTINGS_NONE :{WHITE}- Ei mitään - STR_CONFIG_SETTING_OFF :pois @@ -1334,7 +1334,7 @@ STR_CONFIG_SETTING_AUTORENEW_MONTHS_HELPTEXT :Suhteellinen ik STR_CONFIG_SETTING_AUTORENEW_MONTHS_VALUE_BEFORE :{COMMA} kuukau{P 0 si tta} ennen kulkuneuvon käyttöiän loppua STR_CONFIG_SETTING_AUTORENEW_MONTHS_VALUE_AFTER :{COMMA} kuukau{P 0 si tta} jälkeen kulkuneuvon käyttöiän lopun STR_CONFIG_SETTING_AUTORENEW_MONEY :Vähimmäisrahamäärä kulkuneuvon automaattiseen uudistukseen: {STRING} -STR_CONFIG_SETTING_AUTORENEW_MONEY_HELPTEXT :Pienin rahamäärä, joka on oltava pankissa ennen kulkuneuvojen automaattista uudistamista +STR_CONFIG_SETTING_AUTORENEW_MONEY_HELPTEXT :Vähimmäisrahamäärä, jonka on jäätävä pankkiin kulkuneuvoja automaattisesti uudistettaessa STR_CONFIG_SETTING_ERRMSG_DURATION :Virheilmoitusten näyttöaika: {STRING} STR_CONFIG_SETTING_ERRMSG_DURATION_HELPTEXT :Aika virheilmoitusten näyttämiseen punaisessa ikkunassa. Huomaa, että jotkut (kriittiset) virheilmoitukset eivät sulkeudu automaattisesti tämän ajan jälkeen, vaan ne on suljettava käsin STR_CONFIG_SETTING_ERRMSG_DURATION_VALUE :{COMMA} sekunti{P 0 "" a} @@ -1458,7 +1458,7 @@ STR_CONFIG_SETTING_PAUSE_ON_NEW_GAME_HELPTEXT :Mikäli käytö STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL :Salli pelin ollessa pysäytettynä: {STRING} STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_HELPTEXT :Valitse käytössä olevat toiminnot pelin ollessa pysäytettynä STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_NO_ACTIONS :Ei mitään toimintoja -STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_ALL_NON_CONSTRUCTION :Kaikki ei-rakennustoiminnot +STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_ALL_NON_CONSTRUCTION :Kaikki paitsi rakennustoiminnot STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_ALL_NON_LANDSCAPING :Kaikki paitsi maastonmuokkaustoiminnot STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_ALL_ACTIONS :Kaikki toiminnot STR_CONFIG_SETTING_ADVANCED_VEHICLE_LISTS :Käytä ryhmiä kulkuneuvolistassa: {STRING} @@ -1595,7 +1595,7 @@ STR_CONFIG_SETTING_NEWS_MESSAGES_SUMMARY :Tiivistelmä STR_CONFIG_SETTING_NEWS_MESSAGES_FULL :Täysi STR_CONFIG_SETTING_COLOURED_NEWS_YEAR :Värilliset uutiset ilmestyvät: {STRING} -STR_CONFIG_SETTING_COLOURED_NEWS_YEAR_HELPTEXT :Vuosi, jonka jälkeen sanomalehdet ovat värillisiä. Ennen tätä vuotta sanomalehdet käyttävät mustavalkoisia kuvia +STR_CONFIG_SETTING_COLOURED_NEWS_YEAR_HELPTEXT :Vuosi, josta alkaen sanomalehdet painetaan värillisinä. Ennen tätä vuotta lehdet ovat mustavalkoiset. STR_CONFIG_SETTING_STARTING_YEAR :Aloitusvuosi: {STRING} STR_CONFIG_SETTING_ENDING_YEAR :Pistelaskun päättymisvuosi: {STRING} STR_CONFIG_SETTING_ENDING_YEAR_HELPTEXT :Pelin päättymisvuosi pisteiden laskemista varten. Tämän vuoden lopussa talletetaan yhtiön pistemäärä ja näytetään ennätysluettelo; pelaajat voivat jatkaa pelaamista tämän jälkeenkin.{}Jos päättymisvuosi on ennen alkamisvuotta, ennätyksiä ei näytetä koskaan. @@ -1771,7 +1771,7 @@ STR_CONFIG_SETTING_INTERFACE :{ORANGE}Käytt STR_CONFIG_SETTING_INTERFACE_GENERAL :{ORANGE}Yleinen STR_CONFIG_SETTING_INTERFACE_VIEWPORTS :{ORANGE}Näkymät STR_CONFIG_SETTING_INTERFACE_CONSTRUCTION :{ORANGE}Rakentaminen -STR_CONFIG_SETTING_ADVISORS :{ORANGE}Uutiset / Neuvonantajat +STR_CONFIG_SETTING_ADVISORS :{ORANGE}Uutiset ja neuvonantajat STR_CONFIG_SETTING_COMPANY :{ORANGE}Yhtiö STR_CONFIG_SETTING_ACCOUNTING :{ORANGE}Talous STR_CONFIG_SETTING_VEHICLES :{ORANGE}Kulkuneuvot @@ -1876,7 +1876,7 @@ STR_QUIT_NO :{BLACK}Ei # Abandon game STR_ABANDON_GAME_CAPTION :{WHITE}Pelin lopetus STR_ABANDON_GAME_QUERY :{YELLOW}Lopetetaanko peli? -STR_ABANDON_SCENARIO_QUERY :{YELLOW}Lopetetaanko skenaario? +STR_ABANDON_SCENARIO_QUERY :{YELLOW}Haluatko varmasti hylätä tämän skenaarion? # Cheat window STR_CHEATS :{WHITE}Huijaukset @@ -2207,7 +2207,7 @@ STR_NETWORK_ERROR_BAD_PLAYER_NAME :{WHITE}Et ole a STR_NETWORK_ERROR_WRONG_REVISION :{WHITE}Tämän asiakkaan versio ei vastaa palvelimen versiota STR_NETWORK_ERROR_WRONG_PASSWORD :{WHITE}Väärä salasana STR_NETWORK_ERROR_SERVER_FULL :{WHITE}Palvelin on täynnä -STR_NETWORK_ERROR_SERVER_BANNED :{WHITE}Sinut on kielletty palvelimelta +STR_NETWORK_ERROR_SERVER_BANNED :{WHITE}Sinut on estetty palvelimelta STR_NETWORK_ERROR_KICKED :{WHITE}Sinut potkittiin pihalle palvelimelta STR_NETWORK_ERROR_KICK_MESSAGE :{WHITE}Syy: {STRING} STR_NETWORK_ERROR_CHEATER :{WHITE}Huijaaminen ei ole sallittua tällä palvelimella @@ -2217,6 +2217,7 @@ STR_NETWORK_ERROR_TIMEOUT_COMPUTER :{WHITE}Tietokon STR_NETWORK_ERROR_TIMEOUT_MAP :{WHITE}Kartan lataus kesti liian kauan STR_NETWORK_ERROR_TIMEOUT_JOIN :{WHITE}Palvelimelle liittyminen kesti liian kauan STR_NETWORK_ERROR_INVALID_CLIENT_NAME :{WHITE}Pelaajanimesi ei kelpaa +STR_NETWORK_ERROR_SERVER_TOO_OLD :{WHITE}Kysytty palvelin on liian vanha tälle asiakkaalle ############ Leave those lines in this order!! STR_NETWORK_ERROR_CLIENT_GENERAL :yleinen virhe @@ -2800,7 +2801,7 @@ STR_LAI_OBJECT_DESCRIPTION_COMPANY_OWNED_LAND :Yhtiön omistam STR_ABOUT_OPENTTD :{WHITE}Tietoja OpenTTD:stä STR_ABOUT_ORIGINAL_COPYRIGHT :{BLACK}Alkuperäiset oikeudet {COPYRIGHT} 1995 Chris Sawyer, kaikki oikeudet pidätetään STR_ABOUT_VERSION :{BLACK}OpenTTD-versio {REV} -STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-{STRING} The OpenTTD team +STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002–{STRING} The OpenTTD team # Framerate display window STR_FRAMERATE_CAPTION :{WHITE}Kuvataajuus @@ -3502,8 +3503,8 @@ STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Tarvitse STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} odottamassa{STRING} -STR_CONFIG_GAME_PRODUCTION :{WHITE}Muokkaa tuotantoa (8:n kerroin, 2040 asti) -STR_CONFIG_GAME_PRODUCTION_LEVEL :{WHITE}Muuta tuotantotasoa (prosentteina, 800{NBSP}% asti) +STR_CONFIG_GAME_PRODUCTION :{WHITE}Muokkaa tuotantoa (8:n kerroin, 2040:een asti) +STR_CONFIG_GAME_PRODUCTION_LEVEL :{WHITE}Muuta tuotantotasoa (prosentteina, 800{NBSP}%:iin asti) # Vehicle lists STR_VEHICLE_LIST_TRAIN_CAPTION :{WHITE}{STRING} – {COMMA} juna{P "" a} diff --git a/src/lang/hungarian.txt b/src/lang/hungarian.txt index 5aa64101a3..b34b36e94a 100644 --- a/src/lang/hungarian.txt +++ b/src/lang/hungarian.txt @@ -1017,7 +1017,7 @@ STR_GAME_OPTIONS_CURRENCY_MYR :Maláj ringgit STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Balra hajtás STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Jobbra hajtás -STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Városnevek +STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Városnevek: STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}A városnevek stílusának kiválasztása ############ start of townname region @@ -1057,6 +1057,7 @@ STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_EVERY_12_MONTHS :12 havonta STR_GAME_OPTIONS_LANGUAGE :{BLACK}Nyelv STR_GAME_OPTIONS_LANGUAGE_TOOLTIP :{BLACK}Válassz nyelvet +STR_GAME_OPTIONS_LANGUAGE_PERCENTAGE :{STRING} ({NUM}% teljesítve) STR_GAME_OPTIONS_FULLSCREEN :{BLACK}Teljes képernyő STR_GAME_OPTIONS_FULLSCREEN_TOOLTIP :{BLACK}Jelöld be ezt, ha teljes képernyős módban szeretnél játszani az OpenTTD-vel @@ -2054,6 +2055,8 @@ STR_FACE_TIE :Nyakkendő: STR_FACE_EARRING :Fülbevaló: STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Nyakkendő vagy fülbevaló cseréje +STR_NETWORK_SERVER_VISIBILITY_PRIVATE :Privát +STR_NETWORK_SERVER_VISIBILITY_PUBLIC :Nyilvános # Network server list STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}Hálózati játék @@ -2117,6 +2120,8 @@ STR_NETWORK_START_SERVER_NEW_GAME_NAME_TOOLTIP :{BLACK}A játé STR_NETWORK_START_SERVER_SET_PASSWORD :{BLACK}Jelszó beállítása STR_NETWORK_START_SERVER_PASSWORD_TOOLTIP :{BLACK}Védd le a játékodat jelszóval, ha nem akarod hogy illetéktelenek csatlakozzanak +STR_NETWORK_START_SERVER_VISIBILITY_LABEL :{BLACK}Láthatóság +STR_NETWORK_START_SERVER_VISIBILITY_TOOLTIP :{BLACK}Mások láthassák-e a szerveredet a publikus listában STR_NETWORK_START_SERVER_CLIENTS_SELECT :{BLACK}{NUM} kliens STR_NETWORK_START_SERVER_NUMBER_OF_CLIENTS :{BLACK}Játékosok max. száma: STR_NETWORK_START_SERVER_NUMBER_OF_CLIENTS_TOOLTIP :{BLACK}A maximálisan felcsatlakozható kliensek számának kiválasztása. Nem szükséges pont ennyi embernek éppen kapcsolódva lennie @@ -2180,11 +2185,44 @@ STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}A szerve STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}A vállalat jelszóval van védve. Írd be # Network company list added strings -STR_NETWORK_COMPANY_LIST_CLIENT_LIST :Kliens lista +STR_NETWORK_COMPANY_LIST_CLIENT_LIST :Online játékosok # Network client list +STR_NETWORK_CLIENT_LIST_CAPTION :{WHITE}Többjátékos +STR_NETWORK_CLIENT_LIST_SERVER :{BLACK}Szerver +STR_NETWORK_CLIENT_LIST_SERVER_NAME :{BLACK}Név +STR_NETWORK_CLIENT_LIST_SERVER_NAME_TOOLTIP :{BLACK}A szerver neve amin játszol +STR_NETWORK_CLIENT_LIST_SERVER_NAME_EDIT_TOOLTIP :{BLACK}A szervered nevének szerkesztése +STR_NETWORK_CLIENT_LIST_SERVER_NAME_QUERY_CAPTION :Szerver neve +STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY :{BLACK}Láthatóság +STR_NETWORK_CLIENT_LIST_SERVER_VISIBILITY_TOOLTIP :{BLACK}Mások láthassák-e a szerveredet a publikus listában +STR_NETWORK_CLIENT_LIST_PLAYER :{BLACK}Játékos +STR_NETWORK_CLIENT_LIST_PLAYER_NAME :{BLACK}Név +STR_NETWORK_CLIENT_LIST_PLAYER_NAME_TOOLTIP :{BLACK}A játékos neved +STR_NETWORK_CLIENT_LIST_PLAYER_NAME_EDIT_TOOLTIP :{BLACK}A játékos neved szerkesztése +STR_NETWORK_CLIENT_LIST_PLAYER_NAME_QUERY_CAPTION :Játékos neve +STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_TOOLTIP :{BLACK}Adminisztrátori műveletek ehhez a vállalathoz +STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_TOOLTIP :{BLACK}Adminisztrátori műveletek ehhez a vállalathoz +STR_NETWORK_CLIENT_LIST_JOIN_TOOLTIP :Csatlakozz ehhez a vállalathoz +STR_NETWORK_CLIENT_LIST_CHAT_CLIENT_TOOLTIP :{BLACK}Üzenet küldése ennek a játékosnak +STR_NETWORK_CLIENT_LIST_CHAT_COMPANY_TOOLTIP :{BLACK}Üzenet küldése az összes játékosnak ebben a vállalatban +STR_NETWORK_CLIENT_LIST_CHAT_SPECTATOR_TOOLTIP :{BLACK}Üzenet küldése az összes megfigyelőnek +STR_NETWORK_CLIENT_LIST_SPECTATORS :Megfigyelők +STR_NETWORK_CLIENT_LIST_NEW_COMPANY :(Új vállalat) +STR_NETWORK_CLIENT_LIST_NEW_COMPANY_TOOLTIP :{BLACK}Hozz létre egy új vállalatot és csatlakozz +STR_NETWORK_CLIENT_LIST_PLAYER_ICON_SELF_TOOLTIP :{BLACK}Ez vagy te +STR_NETWORK_CLIENT_LIST_PLAYER_ICON_HOST_TOOLTIP :{BLACK}Ez a játék elindítója +STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_KICK :Kirúgás +STR_NETWORK_CLIENT_LIST_ADMIN_CLIENT_BAN :Tiltás +STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_RESET :Törlés +STR_NETWORK_CLIENT_LIST_ADMIN_COMPANY_UNLOCK :Jelszó feloldása +STR_NETWORK_CLIENT_LIST_ASK_CAPTION :{WHITE}Adminisztrátori művelet +STR_NETWORK_CLIENT_LIST_ASK_CLIENT_KICK :{YELLOW}Biztos ki akarod rúgni ezt a játékost: '{STRING}'? +STR_NETWORK_CLIENT_LIST_ASK_CLIENT_BAN :{YELLOW}Biztos ki akarod tiltani ezt a játékost: '{STRING}'? +STR_NETWORK_CLIENT_LIST_ASK_COMPANY_RESET :{YELLOW}Biztos ki akarod törölni a '{COMPANY}' vállalatot? +STR_NETWORK_CLIENT_LIST_ASK_COMPANY_UNLOCK :{YELLOW}Biztos vissza akarod állítani a '{COMPANY}' vállalat jelszavát? STR_NETWORK_SERVER :Szerver STR_NETWORK_CLIENT :Kliens @@ -2229,6 +2267,7 @@ STR_NETWORK_ERROR_SERVER_START :{WHITE}Nem tudt STR_NETWORK_ERROR_CLIENT_START :{WHITE}Nem tudtam kapcsolódni STR_NETWORK_ERROR_TIMEOUT :{WHITE}A(z) {NUM}. játékos kapcsolata elveszett STR_NETWORK_ERROR_SERVER_ERROR :{WHITE}Protokoll-hiba keletkezett és megszakadt a kapcsolat +STR_NETWORK_ERROR_BAD_PLAYER_NAME :{WHITE}A játékos neved nem lett megadva. A nevet a többjátékos ablak tetején tudod beállítani. STR_NETWORK_ERROR_WRONG_REVISION :{WHITE}A gépeden és a szerveren lévő programnak nem egyezik meg a verziója STR_NETWORK_ERROR_WRONG_PASSWORD :{WHITE}Rossz jelszó STR_NETWORK_ERROR_SERVER_FULL :{WHITE}A szerver tele van @@ -2241,6 +2280,8 @@ STR_NETWORK_ERROR_TIMEOUT_PASSWORD :{WHITE}Túl sok STR_NETWORK_ERROR_TIMEOUT_COMPUTER :{WHITE}A számítógéped túl lassú, hogy tartsa a szerver sebességét STR_NETWORK_ERROR_TIMEOUT_MAP :{WHITE}Túl sokáig tartott a térkép letöltése a számítógépednek STR_NETWORK_ERROR_TIMEOUT_JOIN :{WHITE}Túl sokáig tartott a szerverhez való csatlakozása a számítógépednek +STR_NETWORK_ERROR_INVALID_CLIENT_NAME :{WHITE}A játékos neved nem megfelelő +STR_NETWORK_ERROR_SERVER_TOO_OLD :{WHITE}A lekérdezett szerver túl régi ehhez a klienshez ############ Leave those lines in this order!! STR_NETWORK_ERROR_CLIENT_GENERAL :általános hiba @@ -2263,6 +2304,7 @@ STR_NETWORK_ERROR_CLIENT_TIMEOUT_PASSWORD :nem érkezett j STR_NETWORK_ERROR_CLIENT_TIMEOUT_COMPUTER :általános időtúllépés STR_NETWORK_ERROR_CLIENT_TIMEOUT_MAP :térkép letöltés túl sokáig tartott STR_NETWORK_ERROR_CLIENT_TIMEOUT_JOIN :térkép feldolgozás túl sokáig tartott +STR_NETWORK_ERROR_CLIENT_INVALID_CLIENT_NAME :Érvénytelen kliens név ############ End of leave-in-this-order STR_NETWORK_ERROR_CLIENT_GUI_LOST_CONNECTION_CAPTION :{WHITE}Lehetséges, hogy elveszett a kapcsolat @@ -3102,6 +3144,7 @@ STR_NEWGRF_ERROR_MSG_WARNING :{RED}Figyelmezt STR_NEWGRF_ERROR_MSG_ERROR :{RED}Hiba: {SILVER}{STRING} STR_NEWGRF_ERROR_MSG_FATAL :{RED}Végzetes hiba: {SILVER}{STRING} STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Egy végzetes NewGRF hiba történt:{}{STRING} +STR_NEWGRF_ERROR_POPUP :{WHITE}NewGRF hiba történt:{}{STRING} STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} nem fog működni az OpenTTD által jelentett TTDPatch verzióval STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} a TTD {STRING} verziójához van STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} úgy lett tervezve, hogy együtt lesz használva ezzel: {STRING} diff --git a/src/lang/korean.txt b/src/lang/korean.txt index 78a46e95eb..6bf90700c5 100644 --- a/src/lang/korean.txt +++ b/src/lang/korean.txt @@ -397,7 +397,7 @@ STR_SETTINGS_MENU_SIGNS_DISPLAYED :팻말을 표 STR_SETTINGS_MENU_SHOW_COMPETITOR_SIGNS :경쟁사의 팻말과 역 이름을 표시 STR_SETTINGS_MENU_FULL_ANIMATION :완전한 애니메이션 STR_SETTINGS_MENU_FULL_DETAIL :그래픽을 아주 상세하게 -STR_SETTINGS_MENU_TRANSPARENT_BUILDINGS :건물 숨기기 +STR_SETTINGS_MENU_TRANSPARENT_BUILDINGS :건물 감추기 STR_SETTINGS_MENU_TRANSPARENT_SIGNS :역명판 감추기 ############ range ends here diff --git a/src/lang/spanish.txt b/src/lang/spanish.txt index 3ff09a3674..e891400928 100644 --- a/src/lang/spanish.txt +++ b/src/lang/spanish.txt @@ -2218,6 +2218,7 @@ STR_NETWORK_ERROR_TIMEOUT_COMPUTER :{WHITE}Su orden STR_NETWORK_ERROR_TIMEOUT_MAP :{WHITE}Su ordenador necesitó demasiado tiempo para descargar el mapa STR_NETWORK_ERROR_TIMEOUT_JOIN :{WHITE}Su ordenador necesitó demasiado tiempo para conectar al servidor STR_NETWORK_ERROR_INVALID_CLIENT_NAME :{WHITE}Tu nombre de jugador no es válido +STR_NETWORK_ERROR_SERVER_TOO_OLD :{WHITE}El servidor es demasiado antiguo para este cliente. ############ Leave those lines in this order!! STR_NETWORK_ERROR_CLIENT_GENERAL :error general From a432009f06321009ee1c480ec4034f5faffde75c Mon Sep 17 00:00:00 2001 From: rubidium42 Date: Tue, 4 May 2021 20:50:52 +0200 Subject: [PATCH 08/22] Cleanup: [Fluidsynth] Comply better with the coding style --- src/music/fluidsynth.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/music/fluidsynth.cpp b/src/music/fluidsynth.cpp index b5cbf46aa1..061ade3456 100644 --- a/src/music/fluidsynth.cpp +++ b/src/music/fluidsynth.cpp @@ -18,9 +18,9 @@ #include static struct { - fluid_settings_t* settings; ///< FluidSynth settings handle - fluid_synth_t* synth; ///< FluidSynth synthesizer handle - fluid_player_t* player; ///< FluidSynth MIDI player handle + fluid_settings_t *settings; ///< FluidSynth settings handle + fluid_synth_t *synth; ///< FluidSynth synthesizer handle + fluid_player_t *player; ///< FluidSynth MIDI player handle std::mutex synth_mutex; ///< Guard mutex for synth access } _midi; ///< Metadata about the midi we're playing. @@ -54,7 +54,7 @@ static void RenderMusicStream(int16 *buffer, size_t samples) { std::unique_lock lock{ _midi.synth_mutex, std::try_to_lock }; - if (!lock.owns_lock() || !_midi.synth || !_midi.player) return; + if (!lock.owns_lock() || _midi.synth == nullptr || _midi.player == nullptr) return; fluid_synth_write_s16(_midi.synth, samples, buffer, 0, 2, buffer, 1, 2); } @@ -69,7 +69,7 @@ const char *MusicDriver_FluidSynth::Start(const StringList ¶m) /* Create the settings. */ _midi.settings = new_fluid_settings(); - if (!_midi.settings) return "Could not create midi settings"; + if (_midi.settings == nullptr) return "Could not create midi settings"; /* Don't try to lock sample data in memory, OTTD usually does not run with privileges allowing that */ fluid_settings_setint(_midi.settings, "synth.lock-memory", 0); @@ -80,11 +80,11 @@ const char *MusicDriver_FluidSynth::Start(const StringList ¶m) /* Create the synthesizer. */ _midi.synth = new_fluid_synth(_midi.settings); - if (!_midi.synth) return "Could not open synth"; + if (_midi.synth == nullptr) return "Could not open synth"; /* Load a SoundFont and reset presets (so that new instruments * get used from the SoundFont) */ - if (!sfont_name) { + if (sfont_name == nullptr) { sfont_id = FLUID_FAILED; /* Try loading the default soundfont registered with FluidSynth. */ @@ -142,7 +142,7 @@ void MusicDriver_FluidSynth::PlaySong(const MusicSongInfo &song) std::lock_guard lock{ _midi.synth_mutex }; _midi.player = new_fluid_player(_midi.synth); - if (!_midi.player) { + if (_midi.player == nullptr) { DEBUG(driver, 0, "Could not create midi player"); return; } @@ -166,7 +166,7 @@ void MusicDriver_FluidSynth::StopSong() { std::lock_guard lock{ _midi.synth_mutex }; - if (!_midi.player) return; + if (_midi.player == nullptr) return; fluid_player_stop(_midi.player); } @@ -187,7 +187,7 @@ void MusicDriver_FluidSynth::StopSong() bool MusicDriver_FluidSynth::IsSongPlaying() { std::lock_guard lock{ _midi.synth_mutex }; - if (!_midi.player) return false; + if (_midi.player == nullptr) return false; return fluid_player_get_status(_midi.player) == FLUID_PLAYER_PLAYING; } From 605bd246746b0d6b47e54bbdb1f2a96b782fb371 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Guilloux?= Date: Wed, 5 May 2021 16:32:41 +0200 Subject: [PATCH 09/22] Cleanup: Leftover static const variable from a3b356e (#9194) --- src/newgrf_config.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/newgrf_config.cpp b/src/newgrf_config.cpp index d7919e32ae..a4ec52f0f8 100644 --- a/src/newgrf_config.cpp +++ b/src/newgrf_config.cpp @@ -835,9 +835,6 @@ char *GRFBuildParamList(char *dst, const GRFConfig *c, const char *last) return dst; } -/** Base GRF ID for OpenTTD's base graphics GRFs. */ -static const uint32 OPENTTD_GRAPHICS_BASE_GRF_ID = BSWAP32(0xFF4F5400); - /** * Search a textfile file next to this NewGRF. * @param type The type of the textfile to search for. From 24e7cb494738a8e0117dbd8c4a148a9ee532e129 Mon Sep 17 00:00:00 2001 From: translators Date: Wed, 5 May 2021 18:58:22 +0000 Subject: [PATCH 10/22] Update: Translations from eints english (us): 1 change by 2TallTyler russian: 1 change by Ln-Wolf finnish: 4 changes by hpiirai --- src/lang/english_US.txt | 2 +- src/lang/finnish.txt | 8 ++++---- src/lang/russian.txt | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/lang/english_US.txt b/src/lang/english_US.txt index 14ad4e9aae..4aebf0230f 100644 --- a/src/lang/english_US.txt +++ b/src/lang/english_US.txt @@ -2269,7 +2269,7 @@ STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} ha STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} has joined spectators STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} has started a new company (#{2:NUM}) STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} has left the game ({2:STRING}) -STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} has changed his/her name to {STRING} +STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} has changed their name to {STRING} STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} gave {2:CURRENCY_LONG} to {1:STRING} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}The server closed the session STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}The server is restarting...{}Please wait... diff --git a/src/lang/finnish.txt b/src/lang/finnish.txt index 8f1b82c784..b8a219fb5e 100644 --- a/src/lang/finnish.txt +++ b/src/lang/finnish.txt @@ -1711,13 +1711,13 @@ STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :manuaalinen STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :epäsymmetrinen STR_CONFIG_SETTING_DISTRIBUTION_SYMMETRIC :symmetrinen STR_CONFIG_SETTING_DISTRIBUTION_PAX :Matkustajien jakautuminen: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"symmetrinen" tarkoittaa, että suunnilleen sama määrä matkustajia kulkee asemalta A asemalle B kuin asemalta B asemalle A. "epäsymmetrinen" tarkoittaa, että eri suuntiin voi kulkea eriävä määrä matkustajia. "manuaalinen" tarkoittaa, että automaattinen rahdin jakautuminen on pois käytöstä matkustajilla. +STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :”Symmetrinen” tarkoittaa, että suunnilleen sama määrä matkustajia kulkee asemalta A asemalle B kuin asemalta B asemalle A. ”Epäsymmetrinen” tarkoittaa, että eri suuntiin voi kulkea eriävä määrä matkustajia. ”Manuaalinen” tarkoittaa, että automaattinen rahdin jakautuminen on pois käytöstä matkustajilla. STR_CONFIG_SETTING_DISTRIBUTION_MAIL :Postin jakautuminen: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :"symmetrinen" tarkoittaa, että suunnilleen sama määrä postia lähetetään asemalta A asemalle B kuin asemalta B asemalle A. "epäsymmetrinen" tarkoittaa, että eri suuntiin voidaan lähettää eriävä määrä postia. "manuaalinen" tarkoittaa, että automaattinen rahdin jakautuminen on pois käytöstä postilla. +STR_CONFIG_SETTING_DISTRIBUTION_MAIL_HELPTEXT :”Symmetrinen” tarkoittaa, että suunnilleen sama määrä postia lähetetään asemalta A asemalle B kuin asemalta B asemalle A. ”Epäsymmetrinen” tarkoittaa, että eri suuntiin voidaan lähettää eriävä määrä postia. ”Manuaalinen” tarkoittaa, että automaattinen rahdin jakautuminen on pois käytöstä postilla. STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED :Arvokuljetusten jakautuminen: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :Arvokuljetuksiin kuuluvat arvotavarat lauhkeassa ilmastossa, timantit subtrooppisessa ilmastossa ja kulta pohjoisessa ilmastossa. NewGRF:t voivat kuitenkin muuttaa näitä rahteja. "symmetrinen" tarkoittaa, että suunnilleen sama määrä rahtia lähetetään asemalta A asemalle B kuin asemalta B asemalle A. "epäsymmetrinen" tarkoittaa, että eri suuntiin voidaan lähettää eriävä määrä rahtia. "manuaalinen" tarkoittaa, että automaattinen rahdin jakautuminen on poistettu käytöstä rahdilta. Suositeltavia asetuksia ovat "epäsymmetrinen" tai "manuaalinen" pelattaessa pohjoisessa ilmastossa, sillä pankit eivät lähetä kultaa takaisin kaivoksille. Lauhkeassa ja subtrooppisessa ilmastossa pelatessa voidaan myös valita "symmetrinen", sillä pankit lähettävät arvotavaroita takaisin alkuperäiselle pankille. +STR_CONFIG_SETTING_DISTRIBUTION_ARMOURED_HELPTEXT :Arvokuljetuksiin kuuluvat arvotavarat lauhkeassa ilmastossa, timantit subtrooppisessa ilmastossa ja kulta pohjoisessa ilmastossa. NewGRF:t voivat kuitenkin muuttaa näitä rahteja. ”Symmetrinen” tarkoittaa, että suunnilleen sama määrä rahtia lähetetään asemalta A asemalle B kuin asemalta B asemalle A. ”Epäsymmetrinen” tarkoittaa, että eri suuntiin voidaan lähettää eriävä määrä rahtia. ”Manuaalinen” tarkoittaa, että automaattinen rahdin jakautuminen on poistettu käytöstä rahdilta. Suositeltavia asetuksia ovat ”epäsymmetrinen” tai ”manuaalinen” pelattaessa pohjoisessa ilmastossa, sillä pankit eivät lähetä kultaa takaisin kaivoksille. Lauhkeassa ja subtrooppisessa ilmastossa pelatessa voidaan myös valita ”symmetrinen”, sillä pankit lähettävät arvotavaroita takaisin alkuperäiselle pankille. STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Muiden rahtityyppien jakautuminen: {STRING} -STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :"epäsymmetrinen" tarkoittaa, että eri suuntiin voidaan lähettää eriäviä määriä rahtia. "manuaalinen" tarkoittaa, että automaattinen jakautuminen ei ole käytössä rahdille. +STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT_HELPTEXT :”Epäsymmetrinen” tarkoittaa, että eri suuntiin voidaan lähettää eriäviä määriä rahtia. ”Manuaalinen” tarkoittaa, että automaattinen jakautuminen ei ole käytössä rahdille. STR_CONFIG_SETTING_LINKGRAPH_ACCURACY :Jakautumisen tarkkuus: {STRING} STR_CONFIG_SETTING_LINKGRAPH_ACCURACY_HELPTEXT :Mitä suuremmaksi tämä asetus on määritetty, sitä enemmän prosessoriaikaa yhteyskuvaajan laskemiseen kuluu. Mikäli tähän kuluu liian paljon aikaa, saatat havaita pelin nykimistä. Jos arvo on määritetty liian pieneksi, jakauman laskeminen ei ole tarkka ja rahtia ei välttämättä lähetetä odotetuille asemille. STR_CONFIG_SETTING_DEMAND_DISTANCE :Välimatkan vaikutus kysyntään: {STRING} diff --git a/src/lang/russian.txt b/src/lang/russian.txt index 337d79ce9c..49828c53e5 100644 --- a/src/lang/russian.txt +++ b/src/lang/russian.txt @@ -2420,7 +2420,7 @@ STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} п STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} подключился в качестве зрителя STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} основал новую компанию (#{2:NUM}) STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} покинул игру ({2:STRING}) -STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} изменил имя на {STRING} +STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} сменил(а) имя на {STRING} STR_NETWORK_MESSAGE_GIVE_MONEY :*** Компания «{STRING}» передала «{STRING}» {CURRENCY_LONG} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Сервер закрыл сессию STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Сервер перезапускается...{}Пожалуйста, подождите... From 72bd62fd705c495d90f08adc964ff8d7f84c6cc1 Mon Sep 17 00:00:00 2001 From: rubidium42 Date: Wed, 5 May 2021 19:15:37 +0200 Subject: [PATCH 11/22] Codechange: [Network] Use a single NetworkServerGameInfo object at server side and serialize that for the clients --- src/network/core/game_info.cpp | 48 +++++++++++++++++----------------- src/network/core/game_info.h | 30 ++++++++++----------- src/network/network_gui.cpp | 2 +- src/network/network_server.cpp | 5 +--- src/network/network_udp.cpp | 5 +--- 5 files changed, 42 insertions(+), 48 deletions(-) diff --git a/src/network/core/game_info.cpp b/src/network/core/game_info.cpp index 55b5d1749a..e5e85105e3 100644 --- a/src/network/core/game_info.cpp +++ b/src/network/core/game_info.cpp @@ -122,30 +122,30 @@ void CheckGameCompatibility(NetworkGameInfo &ngi) } /** - * Fill a NetworkGameInfo structure with the latest information of the server. - * @param ngi the NetworkGameInfo struct to fill with data. + * Get the NetworkServerGameInfo structure with the latest information of the server. + * @return The current NetworkServerGameInfo. */ -void FillNetworkGameInfo(NetworkGameInfo &ngi) +const NetworkServerGameInfo *GetCurrentNetworkServerGameInfo() { - /* Update some game_info */ - ngi.clients_on = _network_game_info.clients_on; - ngi.start_date = ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1); + _network_game_info.use_password = !StrEmpty(_settings_client.network.server_password); + _network_game_info.start_date = ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1); + _network_game_info.clients_max = _settings_client.network.max_clients; + _network_game_info.companies_max = _settings_client.network.max_companies; + _network_game_info.spectators_max = _settings_client.network.max_spectators; + _network_game_info.map_width = MapSizeX(); + _network_game_info.map_height = MapSizeY(); + _network_game_info.landscape = _settings_game.game_creation.landscape; + _network_game_info.dedicated = _network_dedicated; + _network_game_info.grfconfig = _grfconfig; - ngi.use_password = !StrEmpty(_settings_client.network.server_password); - ngi.clients_max = _settings_client.network.max_clients; - ngi.companies_on = (byte)Company::GetNumItems(); - ngi.companies_max = _settings_client.network.max_companies; - ngi.spectators_on = NetworkSpectatorCount(); - ngi.spectators_max = _settings_client.network.max_spectators; - ngi.game_date = _date; - ngi.map_width = MapSizeX(); - ngi.map_height = MapSizeY(); - ngi.map_set = _settings_game.game_creation.landscape; - ngi.dedicated = _network_dedicated; - ngi.grfconfig = _grfconfig; + strecpy(_network_game_info.server_name, _settings_client.network.server_name, lastof(_network_game_info.server_name)); + strecpy(_network_game_info.server_revision, GetNetworkRevisionString(), lastof(_network_game_info.server_revision)); - strecpy(ngi.server_name, _settings_client.network.server_name, lastof(ngi.server_name)); - strecpy(ngi.server_revision, GetNetworkRevisionString(), lastof(ngi.server_revision)); + /* Client_on is used as global variable to keep track on the number of clients. */ + _network_game_info.companies_on = (byte)Company::GetNumItems(); + _network_game_info.spectators_on = NetworkSpectatorCount(); + _network_game_info.game_date = _date; + return &_network_game_info; } /** @@ -179,7 +179,7 @@ static void HandleIncomingNetworkGameInfoGRFConfig(GRFConfig *config) * @param p the packet to write the data to. * @param info the NetworkGameInfo struct to serialize from. */ -void SerializeNetworkGameInfo(Packet *p, const NetworkGameInfo *info) +void SerializeNetworkGameInfo(Packet *p, const NetworkServerGameInfo *info) { p->Send_uint8 (NETWORK_GAME_INFO_VERSION); @@ -232,7 +232,7 @@ void SerializeNetworkGameInfo(Packet *p, const NetworkGameInfo *info) p->Send_string(""); // Used to be map-name. p->Send_uint16(info->map_width); p->Send_uint16(info->map_height); - p->Send_uint8 (info->map_set); + p->Send_uint8 (info->landscape); p->Send_bool (info->dedicated); } @@ -302,10 +302,10 @@ void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info) while (p->Recv_uint8() != 0) {} // Used to contain the map-name. info->map_width = p->Recv_uint16(); info->map_height = p->Recv_uint16(); - info->map_set = p->Recv_uint8 (); + info->landscape = p->Recv_uint8 (); info->dedicated = p->Recv_bool (); - if (info->map_set >= NETWORK_NUM_LANDSCAPES) info->map_set = 0; + if (info->landscape >= NETWORK_NUM_LANDSCAPES) info->landscape = 0; } } diff --git a/src/network/core/game_info.h b/src/network/core/game_info.h index 324c6ea4aa..10f922f318 100644 --- a/src/network/core/game_info.h +++ b/src/network/core/game_info.h @@ -57,17 +57,9 @@ */ /** - * The game information that is not generated on-the-fly and has to - * be sent to the clients. + * The game information that is sent from the server to the client. */ struct NetworkServerGameInfo { - byte clients_on; ///< Current count of clients on server -}; - -/** - * The game information that is sent from the server to the clients. - */ -struct NetworkGameInfo : NetworkServerGameInfo { GRFConfig *grfconfig; ///< List of NewGRF files used Date start_date; ///< When the game started Date game_date; ///< Current date @@ -76,16 +68,24 @@ struct NetworkGameInfo : NetworkServerGameInfo { char server_name[NETWORK_NAME_LENGTH]; ///< Server name char server_revision[NETWORK_REVISION_LENGTH]; ///< The version number the server is using (e.g.: 'r304' or 0.5.0) bool dedicated; ///< Is this a dedicated server? - bool version_compatible; ///< Can we connect to this server or not? (based on server_revision) - bool compatible; ///< Can we connect to this server or not? (based on server_revision _and_ grf_match bool use_password; ///< Is this server passworded? - byte game_info_version; ///< Version of the game info + byte clients_on; ///< Current count of clients on server byte clients_max; ///< Max clients allowed on server byte companies_on; ///< How many started companies do we have byte companies_max; ///< Max companies allowed on server byte spectators_on; ///< How many spectators do we have? byte spectators_max; ///< Max spectators allowed on server - byte map_set; ///< Graphical set + byte landscape; ///< The used landscape +}; + +/** + * The game information that is sent from the server to the clients + * with extra information only required at the client side. + */ +struct NetworkGameInfo : NetworkServerGameInfo { + bool version_compatible; ///< Can we connect to this server or not? (based on server_revision) + bool compatible; ///< Can we connect to this server or not? (based on server_revision _and_ grf_match + byte game_info_version; ///< Version of the game info }; extern NetworkServerGameInfo _network_game_info; @@ -94,12 +94,12 @@ const char *GetNetworkRevisionString(); bool IsNetworkCompatibleVersion(const char *other); void CheckGameCompatibility(NetworkGameInfo &ngi); -void FillNetworkGameInfo(NetworkGameInfo &ngi); +const NetworkServerGameInfo *GetCurrentNetworkServerGameInfo(); void DeserializeGRFIdentifier(Packet *p, GRFIdentifier *grf); void SerializeGRFIdentifier(Packet *p, const GRFIdentifier *grf); void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info); -void SerializeNetworkGameInfo(Packet *p, const NetworkGameInfo *info); +void SerializeNetworkGameInfo(Packet *p, const NetworkServerGameInfo *info); #endif /* NETWORK_CORE_GAME_INFO_H */ diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index b2feacc955..ac86b868c6 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -633,7 +633,7 @@ public: DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_CLIENTS); y += FONT_HEIGHT_NORMAL; - SetDParam(0, STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE + sel->info.map_set); + SetDParam(0, STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE + sel->info.landscape); DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_LANDSCAPE); // landscape y += FONT_HEIGHT_NORMAL; diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index fd69a8d37a..905290bfc5 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -356,11 +356,8 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendClientInfo(NetworkClientIn /** Send the client information about the server. */ NetworkRecvStatus ServerNetworkGameSocketHandler::SendGameInfo() { - NetworkGameInfo ngi; - FillNetworkGameInfo(ngi); - Packet *p = new Packet(PACKET_SERVER_GAME_INFO); - SerializeNetworkGameInfo(p, &ngi); + SerializeNetworkGameInfo(p, GetCurrentNetworkServerGameInfo()); this->SendPacket(p); diff --git a/src/network/network_udp.cpp b/src/network/network_udp.cpp index bb71e5ceaa..de69e4a9af 100644 --- a/src/network/network_udp.cpp +++ b/src/network/network_udp.cpp @@ -170,11 +170,8 @@ void ServerNetworkUDPSocketHandler::Receive_CLIENT_FIND_SERVER(Packet *p, Networ return; } - NetworkGameInfo ngi; - FillNetworkGameInfo(ngi); - Packet packet(PACKET_UDP_SERVER_RESPONSE); - SerializeNetworkGameInfo(&packet, &ngi); + SerializeNetworkGameInfo(&packet, GetCurrentNetworkServerGameInfo()); /* Let the client know that we are here */ this->SendPacket(&packet, client_addr); From e7581fd42d9740ca68adfc2ec55edb49d51af237 Mon Sep 17 00:00:00 2001 From: rubidium42 Date: Wed, 5 May 2021 19:21:12 +0200 Subject: [PATCH 12/22] Change: [Network] Update server's NetworkServerGameInfo only when needed Split the updating in a "static" version that only needs to be called when a new map is loaded or some settings are changed, and a "dynamic" version that updates everything that changes regularly such as the current game date or the number of spectators. --- src/network/core/game_info.cpp | 13 ++++++++++--- src/network/core/game_info.h | 1 + src/network/network.cpp | 1 + src/network/network_func.h | 1 + src/network/network_server.cpp | 6 ++++++ src/openttd.cpp | 29 +++++++++++++++++++---------- src/settings.cpp | 2 ++ src/table/settings.ini | 2 ++ 8 files changed, 42 insertions(+), 13 deletions(-) diff --git a/src/network/core/game_info.cpp b/src/network/core/game_info.cpp index e5e85105e3..9f4d23b3b4 100644 --- a/src/network/core/game_info.cpp +++ b/src/network/core/game_info.cpp @@ -122,10 +122,10 @@ void CheckGameCompatibility(NetworkGameInfo &ngi) } /** - * Get the NetworkServerGameInfo structure with the latest information of the server. - * @return The current NetworkServerGameInfo. + * Fill a NetworkServerGameInfo structure with the static content, or things + * that are so static they can be updated on request from a settings change. */ -const NetworkServerGameInfo *GetCurrentNetworkServerGameInfo() +void FillStaticNetworkServerGameInfo() { _network_game_info.use_password = !StrEmpty(_settings_client.network.server_password); _network_game_info.start_date = ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1); @@ -140,7 +140,14 @@ const NetworkServerGameInfo *GetCurrentNetworkServerGameInfo() strecpy(_network_game_info.server_name, _settings_client.network.server_name, lastof(_network_game_info.server_name)); strecpy(_network_game_info.server_revision, GetNetworkRevisionString(), lastof(_network_game_info.server_revision)); +} +/** + * Get the NetworkServerGameInfo structure with the latest information of the server. + * @return The current NetworkServerGameInfo. + */ +const NetworkServerGameInfo *GetCurrentNetworkServerGameInfo() +{ /* Client_on is used as global variable to keep track on the number of clients. */ _network_game_info.companies_on = (byte)Company::GetNumItems(); _network_game_info.spectators_on = NetworkSpectatorCount(); diff --git a/src/network/core/game_info.h b/src/network/core/game_info.h index 10f922f318..7c84d7b154 100644 --- a/src/network/core/game_info.h +++ b/src/network/core/game_info.h @@ -94,6 +94,7 @@ const char *GetNetworkRevisionString(); bool IsNetworkCompatibleVersion(const char *other); void CheckGameCompatibility(NetworkGameInfo &ngi); +void FillStaticNetworkServerGameInfo(); const NetworkServerGameInfo *GetCurrentNetworkServerGameInfo(); void DeserializeGRFIdentifier(Packet *p, GRFIdentifier *grf); diff --git a/src/network/network.cpp b/src/network/network.cpp index c00a3650fb..4708151865 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -805,6 +805,7 @@ static void NetworkInitGameInfo() strecpy(_settings_client.network.server_name, "Unnamed Server", lastof(_settings_client.network.server_name)); } + FillStaticNetworkServerGameInfo(); /* The server is a client too */ _network_game_info.clients_on = _network_dedicated ? 0 : 1; diff --git a/src/network/network_func.h b/src/network/network_func.h index 5f3e27c12f..ba26e06c09 100644 --- a/src/network/network_func.h +++ b/src/network/network_func.h @@ -68,6 +68,7 @@ void NetworkServerDailyLoop(); void NetworkServerMonthlyLoop(); void NetworkServerYearlyLoop(); void NetworkServerSendConfigUpdate(); +void NetworkServerUpdateGameInfo(); void NetworkServerShowStatusToConsole(); bool NetworkServerStart(); void NetworkServerNewCompany(const Company *company, NetworkClientInfo *ci); diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index 905290bfc5..1a9ddecfbc 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -1992,6 +1992,12 @@ void NetworkServerSendConfigUpdate() } } +/** Update the server's NetworkServerGameInfo due to changes in settings. */ +void NetworkServerUpdateGameInfo() +{ + if (_network_server) FillStaticNetworkServerGameInfo(); +} + /** * Tell that a particular company is (not) passworded. * @param company_id The company that got/removed the password. diff --git a/src/openttd.cpp b/src/openttd.cpp index 234e3a4197..d4c7da6e4c 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -832,15 +832,30 @@ void HandleExitGameRequest() } } +/** + * Triggers everything that should be triggered when starting a game. + * @param dedicated_server Whether this is a dedicated server or not. + */ +static void OnStartGame(bool dedicated_server) +{ + /* Update the local company for a loaded game. It is either always + * company #1 (eg 0) or in the case of a dedicated server a spectator */ + SetLocalCompany(dedicated_server ? COMPANY_SPECTATOR : COMPANY_FIRST); + + /* Update the static game info to set the values from the new game. */ + NetworkServerUpdateGameInfo(); + /* Execute the game-start script */ + IConsoleCmdExec("exec scripts/game_start.scr 0"); +} + static void MakeNewGameDone() { SettingsDisableElrail(_settings_game.vehicle.disable_elrails); /* In a dedicated server, the server does not play */ if (!VideoDriver::GetInstance()->HasGUI()) { - SetLocalCompany(COMPANY_SPECTATOR); + OnStartGame(true); if (_settings_client.gui.pause_on_newgame) DoCommandP(0, PM_PAUSED_NORMAL, 1, CMD_PAUSE); - IConsoleCmdExec("exec scripts/game_start.scr 0"); return; } @@ -858,9 +873,7 @@ static void MakeNewGameDone() _company_colours[c->index] = (Colours)c->colour; } - IConsoleCmdExec("exec scripts/game_start.scr 0"); - - SetLocalCompany(COMPANY_FIRST); + OnStartGame(false); InitializeRailGUI(); InitializeRoadGUI(); @@ -1032,11 +1045,7 @@ void SwitchToMode(SwitchMode new_mode) /* Reset engine pool to simplify changing engine NewGRFs in scenario editor. */ EngineOverrideManager::ResetToCurrentNewGRFConfig(); } - /* Update the local company for a loaded game. It is either always - * company #1 (eg 0) or in the case of a dedicated server a spectator */ - SetLocalCompany(_network_dedicated ? COMPANY_SPECTATOR : COMPANY_FIRST); - /* Execute the game-start script */ - IConsoleCmdExec("exec scripts/game_start.scr 0"); + OnStartGame(_network_dedicated); /* Decrease pause counter (was increased from opening load dialog) */ DoCommandP(0, PM_PAUSED_SAVELOAD, 0, CMD_PAUSE); } diff --git a/src/settings.cpp b/src/settings.cpp index c5819297fc..c0b0dd8edd 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1416,6 +1416,7 @@ static bool UpdateServerPassword(int32 p1) _settings_client.network.server_password[0] = '\0'; } + NetworkServerUpdateGameInfo(); return true; } @@ -1430,6 +1431,7 @@ static bool UpdateRconPassword(int32 p1) static bool UpdateClientConfigValues(int32 p1) { + NetworkServerUpdateGameInfo(); if (_network_server) NetworkServerSendConfigUpdate(); return true; diff --git a/src/table/settings.ini b/src/table/settings.ini index 4e64bd0326..d12f58236d 100644 --- a/src/table/settings.ini +++ b/src/table/settings.ini @@ -3962,6 +3962,7 @@ type = SLE_STRB flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC guiflags = SGF_NETWORK_ONLY def = nullptr +proc = UpdateClientConfigValues cat = SC_BASIC [SDTC_STR] @@ -4029,6 +4030,7 @@ guiflags = SGF_NETWORK_ONLY def = 25 min = 2 max = MAX_CLIENTS +proc = UpdateClientConfigValues cat = SC_BASIC [SDTC_VAR] From ead30dc725c60cac8bc13c86d18b179dac684bec Mon Sep 17 00:00:00 2001 From: Rubidium Date: Wed, 5 May 2021 20:38:18 +0200 Subject: [PATCH 13/22] Cleanup: [Network] Remove variable from NetworkGameInfo that is only used during deserialisation --- src/network/core/game_info.cpp | 6 +++--- src/network/core/game_info.h | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/network/core/game_info.cpp b/src/network/core/game_info.cpp index 9f4d23b3b4..47e6f221ef 100644 --- a/src/network/core/game_info.cpp +++ b/src/network/core/game_info.cpp @@ -252,7 +252,7 @@ void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info) { static const Date MAX_DATE = ConvertYMDToDate(MAX_YEAR, 11, 31); // December is month 11 - info->game_info_version = p->Recv_uint8(); + byte game_info_version = p->Recv_uint8(); /* * Please observe the order. @@ -262,7 +262,7 @@ void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info) /* Update the documentation in game_info.h on changes * to the NetworkGameInfo wire-protocol! */ - switch (info->game_info_version) { + switch (game_info_version) { case 4: { GRFConfig **dst = &info->grfconfig; uint i; @@ -302,7 +302,7 @@ void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info) info->clients_max = p->Recv_uint8 (); info->clients_on = p->Recv_uint8 (); info->spectators_on = p->Recv_uint8 (); - if (info->game_info_version < 3) { // 16 bits dates got scrapped and are read earlier + if (game_info_version < 3) { // 16 bits dates got scrapped and are read earlier info->game_date = p->Recv_uint16() + DAYS_TILL_ORIGINAL_BASE_YEAR; info->start_date = p->Recv_uint16() + DAYS_TILL_ORIGINAL_BASE_YEAR; } diff --git a/src/network/core/game_info.h b/src/network/core/game_info.h index 7c84d7b154..ef83e4d053 100644 --- a/src/network/core/game_info.h +++ b/src/network/core/game_info.h @@ -85,7 +85,6 @@ struct NetworkServerGameInfo { struct NetworkGameInfo : NetworkServerGameInfo { bool version_compatible; ///< Can we connect to this server or not? (based on server_revision) bool compatible; ///< Can we connect to this server or not? (based on server_revision _and_ grf_match - byte game_info_version; ///< Version of the game info }; extern NetworkServerGameInfo _network_game_info; From f94fb9377910c63fc8e1ea0ede1d96603e4d8862 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Wed, 5 May 2021 23:21:14 +0200 Subject: [PATCH 14/22] Codechange: use connection_string in favour of NetworkAddress (#9197) We now resolve the connection_string to a NetworkAddress in a much later state. This means there are fewer places constructing a NetworkAddress. The main benefit of this is in later PRs that introduce different types of NetworkAddresses. Storing this in things like NetworkGameList is rather complex, especially as NetworkAddress has to be mutable at all times. Additionally, the NetworkAddress is a complex object to store simple information: how to connect to this server. --- src/network/core/tcp.h | 2 +- src/network/core/tcp_connect.cpp | 10 +++-- src/network/core/tcp_http.cpp | 4 +- src/network/core/tcp_http.h | 16 +++---- src/network/network.cpp | 75 +++++++++++++++----------------- src/network/network_client.cpp | 4 +- src/network/network_client.h | 12 ++--- src/network/network_content.cpp | 7 ++- src/network/network_gamelist.cpp | 13 +++--- src/network/network_gamelist.h | 14 +++--- src/network/network_gui.cpp | 21 ++++----- src/network/network_internal.h | 4 +- src/network/network_udp.cpp | 24 +++++----- src/network/network_udp.h | 2 +- 14 files changed, 101 insertions(+), 107 deletions(-) diff --git a/src/network/core/tcp.h b/src/network/core/tcp.h index ffa231497e..5acf9d12e6 100644 --- a/src/network/core/tcp.h +++ b/src/network/core/tcp.h @@ -77,7 +77,7 @@ protected: NetworkAddress address; public: - TCPConnecter(const NetworkAddress &address); + TCPConnecter(const std::string &connection_string, uint16 default_port); /** Silence the warnings */ virtual ~TCPConnecter() {} diff --git a/src/network/core/tcp_connect.cpp b/src/network/core/tcp_connect.cpp index b4485cfe96..81c4d8c264 100644 --- a/src/network/core/tcp_connect.cpp +++ b/src/network/core/tcp_connect.cpp @@ -13,6 +13,7 @@ #include "../../thread.h" #include "tcp.h" +#include "../network_internal.h" #include "../../safeguards.h" @@ -21,15 +22,16 @@ static std::vector _tcp_connecters; /** * Create a new connecter for the given address - * @param address the (un)resolved address to connect to + * @param connection_string the address to connect to */ -TCPConnecter::TCPConnecter(const NetworkAddress &address) : +TCPConnecter::TCPConnecter(const std::string &connection_string, uint16 default_port) : connected(false), aborted(false), killed(false), - sock(INVALID_SOCKET), - address(address) + sock(INVALID_SOCKET) { + this->address = ParseConnectionString(connection_string, default_port); + _tcp_connecters.push_back(this); if (!StartNewThread(nullptr, "ottd:tcp", &TCPConnecter::ThreadEntry, this)) { this->Connect(); diff --git a/src/network/core/tcp_http.cpp b/src/network/core/tcp_http.cpp index 4f29df1912..3b7579fcea 100644 --- a/src/network/core/tcp_http.cpp +++ b/src/network/core/tcp_http.cpp @@ -203,11 +203,9 @@ int NetworkHTTPSocketHandler::HandleHeader() *url = '\0'; - NetworkAddress address = ParseConnectionString(hname, 80); - /* Restore the URL. */ *url = '/'; - new NetworkHTTPContentConnecter(address, callback, url, data, depth); + new NetworkHTTPContentConnecter(hname, callback, url, data, depth); return 0; } diff --git a/src/network/core/tcp_http.h b/src/network/core/tcp_http.h index 1a1edaf87a..cc9a3adac2 100644 --- a/src/network/core/tcp_http.h +++ b/src/network/core/tcp_http.h @@ -81,16 +81,14 @@ class NetworkHTTPContentConnecter : TCPConnecter { public: /** * Start the connecting. - * @param address the address to connect to - * @param callback the callback for HTTP retrieval - * @param url the url at the server - * @param data the data to send - * @param depth the depth (redirect recursion) of the queries + * @param connection_string The address to connect to. + * @param callback The callback for HTTP retrieval. + * @param url The url at the server. + * @param data The data to send. + * @param depth The depth (redirect recursion) of the queries. */ - NetworkHTTPContentConnecter(const NetworkAddress &address, - HTTPCallback *callback, const char *url, - const char *data = nullptr, int depth = 0) : - TCPConnecter(address), + NetworkHTTPContentConnecter(const std::string &connection_string, HTTPCallback *callback, const char *url, const char *data = nullptr, int depth = 0) : + TCPConnecter(connection_string, 80), callback(callback), url(stredup(url)), data(data), diff --git a/src/network/network.cpp b/src/network/network.cpp index 4708151865..98b49e81fe 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -515,7 +515,7 @@ NetworkAddress ParseConnectionString(const std::string &connection_string, int d * @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 std::string &connection_string, int default_port) +static NetworkAddress ParseGameConnectionString(CompanyID *company, const std::string &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.c_str(), lastof(internal_connection_string)); @@ -524,7 +524,20 @@ NetworkAddress ParseGameConnectionString(CompanyID *company, const std::string & const char *company_s = nullptr; ParseFullConnectionString(&company_s, &port_s, internal_connection_string); - if (company_s != nullptr) *company = (CompanyID)atoi(company_s); + if (company_s != nullptr) { + uint company_value = atoi(company_s); + + if (company_value != COMPANY_NEW_COMPANY && company_value != COMPANY_SPECTATOR) { + if (company_value > MAX_COMPANIES || company_value == 0) { + *company = COMPANY_SPECTATOR; + } else { + /* "#1" means the first company, which has index 0. */ + *company = (CompanyID)(company_value - 1); + } + } else { + *company = (CompanyID)company_value; + } + } int port = port_s != nullptr ? atoi(port_s) : default_port; return NetworkAddress(internal_connection_string, port); @@ -607,9 +620,10 @@ static void NetworkInitialize(bool close_admins = true) class TCPQueryConnecter : TCPConnecter { private: bool request_company_info; + std::string connection_string; public: - TCPQueryConnecter(const NetworkAddress &address, bool request_company_info) : TCPConnecter(address), request_company_info(request_company_info) {} + TCPQueryConnecter(const std::string &connection_string, bool request_company_info) : TCPConnecter(connection_string, NETWORK_DEFAULT_PORT), request_company_info(request_company_info), connection_string(connection_string) {} void OnFailure() override { @@ -619,24 +633,24 @@ public: void OnConnect(SOCKET s) override { _networking = true; - new ClientNetworkGameSocketHandler(s, address); + new ClientNetworkGameSocketHandler(s, this->connection_string); MyClient::SendInformationQuery(request_company_info); } }; /** * Query a server to fetch his game-info. - * @param address the address to query. + * @param connection_string the address to query. * @param request_company_info Whether to request company info too. */ -void NetworkTCPQueryServer(NetworkAddress address, bool request_company_info) +void NetworkTCPQueryServer(const std::string &connection_string, bool request_company_info) { if (!_network_available) return; NetworkDisconnect(); NetworkInitialize(); - new TCPQueryConnecter(address, request_company_info); + new TCPQueryConnecter(connection_string, request_company_info); } /** @@ -650,20 +664,18 @@ NetworkGameList *NetworkAddServer(const std::string &connection_string) { if (connection_string.empty()) return nullptr; - NetworkAddress address = ParseConnectionString(connection_string, NETWORK_DEFAULT_PORT); - /* Ensure the item already exists in the list */ - NetworkGameList *item = NetworkGameListAddItem(address); + NetworkGameList *item = NetworkGameListAddItem(connection_string); if (StrEmpty(item->info.server_name)) { ClearGRFConfigList(&item->info.grfconfig); - address.GetAddressAsString(item->info.server_name, lastof(item->info.server_name)); + strecpy(item->info.server_name, connection_string.c_str(), lastof(item->info.server_name)); item->manually = true; NetworkRebuildHostList(); UpdateNetworkGameWindow(); } - NetworkTCPQueryServer(address); + NetworkTCPQueryServer(connection_string); return item; } @@ -693,14 +705,17 @@ void NetworkRebuildHostList() _network_host_list.clear(); for (NetworkGameList *item = _network_game_list; item != nullptr; item = item->next) { - if (item->manually) _network_host_list.emplace_back(item->address.GetAddressAsString(false)); + if (item->manually) _network_host_list.emplace_back(item->connection_string); } } /** Non blocking connection create to actually connect to servers */ class TCPClientConnecter : TCPConnecter { +private: + std::string connection_string; + public: - TCPClientConnecter(const NetworkAddress &address) : TCPConnecter(address) {} + TCPClientConnecter(const std::string &connection_string) : TCPConnecter(connection_string, NETWORK_DEFAULT_PORT), connection_string(connection_string) {} void OnFailure() override { @@ -710,7 +725,7 @@ public: void OnConnect(SOCKET s) override { _networking = true; - new ClientNetworkGameSocketHandler(s, this->address); + new ClientNetworkGameSocketHandler(s, this->connection_string); IConsoleCmdExec("exec scripts/on_client.scr 0"); NetworkClient_Connected(); } @@ -736,34 +751,12 @@ public: bool NetworkClientConnectGame(const std::string &connection_string, CompanyID default_company, const char *join_server_password, const char *join_company_password) { CompanyID join_as = default_company; - NetworkAddress address = ParseGameConnectionString(&join_as, connection_string, NETWORK_DEFAULT_PORT); + std::string resolved_connection_string = ParseGameConnectionString(&join_as, connection_string, NETWORK_DEFAULT_PORT).GetAddressAsString(false); - if (join_as != COMPANY_NEW_COMPANY && join_as != COMPANY_SPECTATOR) { - join_as--; - if (join_as >= MAX_COMPANIES) { - return false; - } - } - - return NetworkClientConnectGame(address, join_as, join_server_password, join_company_password); -} - -/** - * Join a client to the server at the given address. - * See the overloaded NetworkClientConnectGame for more details. - * - * @param address The network address of the server to join to. - * @param join_as The company number to join as. - * @param join_server_password The password for the server. - * @param join_company_password The password for the company. - * @return Whether the join has started. - */ -bool NetworkClientConnectGame(NetworkAddress &address, CompanyID join_as, const char *join_server_password, const char *join_company_password) -{ if (!_network_available) return false; if (!NetworkValidateClientName()) return false; - _network_join.address = address; + _network_join.connection_string = resolved_connection_string; _network_join.company = join_as; _network_join.server_password = join_server_password; _network_join.company_password = join_company_password; @@ -792,11 +785,11 @@ void NetworkClientJoinGame() NetworkDisconnect(); NetworkInitialize(); - strecpy(_settings_client.network.last_joined, _network_join.address.GetAddressAsString(false).c_str(), lastof(_settings_client.network.last_joined)); + strecpy(_settings_client.network.last_joined, _network_join.connection_string.c_str(), lastof(_settings_client.network.last_joined)); _network_join_status = NETWORK_JOIN_STATUS_CONNECTING; ShowJoinStatusWindow(); - new TCPClientConnecter(_network_join.address); + new TCPClientConnecter(_network_join.connection_string); } static void NetworkInitGameInfo() diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp index d288c71a6e..190bb29450 100644 --- a/src/network/network_client.cpp +++ b/src/network/network_client.cpp @@ -145,7 +145,7 @@ void ClientNetworkEmergencySave() * Create a new socket for the client side of the game connection. * @param s The socket to connect with. */ -ClientNetworkGameSocketHandler::ClientNetworkGameSocketHandler(SOCKET s, NetworkAddress address) : NetworkGameSocketHandler(s), address(address), savegame(nullptr), status(STATUS_INACTIVE) +ClientNetworkGameSocketHandler::ClientNetworkGameSocketHandler(SOCKET s, const std::string &connection_string) : NetworkGameSocketHandler(s), connection_string(connection_string), savegame(nullptr), status(STATUS_INACTIVE) { assert(ClientNetworkGameSocketHandler::my_client == nullptr); ClientNetworkGameSocketHandler::my_client = this; @@ -581,7 +581,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_GAME_INFO(Packe NetworkGameList *item = GetLobbyGameInfo(); if (item == nullptr) { /* This is not the lobby, so add it to the game list. */ - item = NetworkGameListAddItem(this->address); + item = NetworkGameListAddItem(this->connection_string); } /* Clear any existing GRFConfig chain. */ diff --git a/src/network/network_client.h b/src/network/network_client.h index 81d5b720cd..ddc0e362c8 100644 --- a/src/network/network_client.h +++ b/src/network/network_client.h @@ -15,7 +15,7 @@ /** Class for handling the client side of the game connection. */ class ClientNetworkGameSocketHandler : public ZeroedMemoryAllocator, public NetworkGameSocketHandler { private: - NetworkAddress address; ///< Address we are connected to. + std::string connection_string; ///< Address we are connected to. struct PacketReader *savegame; ///< Packet reader for reading the savegame. byte token; ///< The token we need to send back to the server to prove we're the right client. @@ -76,7 +76,7 @@ protected: static NetworkRecvStatus SendMapOk(); void CheckConnection(); public: - ClientNetworkGameSocketHandler(SOCKET s, NetworkAddress address); + ClientNetworkGameSocketHandler(SOCKET s, const std::string &connection_string); ~ClientNetworkGameSocketHandler(); NetworkRecvStatus CloseConnection(NetworkRecvStatus status) override; @@ -115,10 +115,10 @@ void NetworkClientSetCompanyPassword(const char *password); /** Information required to join a server. */ struct NetworkJoinInfo { NetworkJoinInfo() : company(COMPANY_SPECTATOR), server_password(nullptr), company_password(nullptr) {} - NetworkAddress address; ///< The address of the server to join. - CompanyID company; ///< The company to join. - const char *server_password; ///< The password of the server to join. - const char *company_password; ///< The password of the company to join. + std::string connection_string; ///< The address of the server to join. + CompanyID company; ///< The company to join. + const char *server_password; ///< The password of the server to join. + const char *company_password; ///< The password of the company to join. }; extern NetworkJoinInfo _network_join; diff --git a/src/network/network_content.cpp b/src/network/network_content.cpp index a208f3c6e2..528b7bd777 100644 --- a/src/network/network_content.cpp +++ b/src/network/network_content.cpp @@ -343,8 +343,7 @@ void ClientNetworkContentSocketHandler::DownloadSelectedContentHTTP(const Conten this->http_response_index = -1; - NetworkAddress address(NETWORK_CONTENT_MIRROR_HOST, NETWORK_CONTENT_MIRROR_PORT); - new NetworkHTTPContentConnecter(address, this, NETWORK_CONTENT_MIRROR_URL, content_request); + new NetworkHTTPContentConnecter(NETWORK_CONTENT_MIRROR_HOST, this, NETWORK_CONTENT_MIRROR_URL, content_request); /* NetworkHTTPContentConnecter takes over freeing of content_request! */ } @@ -744,7 +743,7 @@ public: * Initiate the connecting. * @param address The address of the server. */ - NetworkContentConnecter(const NetworkAddress &address) : TCPConnecter(address) {} + NetworkContentConnecter(const std::string &connection_string) : TCPConnecter(connection_string, NETWORK_CONTENT_SERVER_PORT) {} void OnFailure() override { @@ -770,7 +769,7 @@ void ClientNetworkContentSocketHandler::Connect() { if (this->sock != INVALID_SOCKET || this->isConnecting) return; this->isConnecting = true; - new NetworkContentConnecter(NetworkAddress(NETWORK_CONTENT_SERVER_HOST, NETWORK_CONTENT_SERVER_PORT, AF_UNSPEC)); + new NetworkContentConnecter(NETWORK_CONTENT_SERVER_HOST); } /** diff --git a/src/network/network_gamelist.cpp b/src/network/network_gamelist.cpp index 12dbbce615..1edbafc328 100644 --- a/src/network/network_gamelist.cpp +++ b/src/network/network_gamelist.cpp @@ -44,7 +44,7 @@ static void NetworkGameListHandleDelayedInsert() while (ins_item != nullptr && !_network_game_delayed_insertion_list.compare_exchange_weak(ins_item, ins_item->next, std::memory_order_acq_rel)) {} if (ins_item == nullptr) break; // No item left. - NetworkGameList *item = NetworkGameListAddItem(ins_item->address); + NetworkGameList *item = NetworkGameListAddItem(ins_item->connection_string); if (item != nullptr) { if (StrEmpty(item->info.server_name)) { @@ -67,19 +67,22 @@ static void NetworkGameListHandleDelayedInsert() * @param address the address of the to-be added item * @return a point to the newly added or already existing item */ -NetworkGameList *NetworkGameListAddItem(NetworkAddress address) +NetworkGameList *NetworkGameListAddItem(const std::string &connection_string) { NetworkGameList *item, *prev_item; + /* Parse the connection string to ensure the default port is there. */ + const std::string resolved_connection_string = ParseConnectionString(connection_string, NETWORK_DEFAULT_PORT).GetAddressAsString(false); + prev_item = nullptr; for (item = _network_game_list; item != nullptr; item = item->next) { - if (item->address == address) return item; + if (item->connection_string == resolved_connection_string) return item; prev_item = item; } item = CallocT(1); item->next = nullptr; - item->address = address; + item->connection_string = resolved_connection_string; if (prev_item == nullptr) { _network_game_list = item; @@ -141,7 +144,7 @@ void NetworkGameListRequery() /* item gets mostly zeroed by NetworkUDPQueryServer */ uint8 retries = item->retries; - NetworkUDPQueryServer(item->address); + NetworkUDPQueryServer(item->connection_string); item->retries = (retries >= REFRESH_GAMEINFO_X_REQUERIES) ? 0 : retries; } } diff --git a/src/network/network_gamelist.h b/src/network/network_gamelist.h index ce35c01d8b..31b3bc3e64 100644 --- a/src/network/network_gamelist.h +++ b/src/network/network_gamelist.h @@ -16,19 +16,19 @@ /** Structure with information shown in the game list (GUI) */ struct NetworkGameList { - NetworkGameInfo info; ///< The game information of this server - NetworkAddress address; ///< The connection info of the game server - bool online; ///< False if the server did not respond (default status) - bool manually; ///< True if the server was added manually - uint8 retries; ///< Number of retries (to stop requerying) - NetworkGameList *next; ///< Next pointer to make a linked game list + NetworkGameInfo info; ///< The game information of this server + std::string connection_string; ///< Address of the server + bool online; ///< False if the server did not respond (default status) + bool manually; ///< True if the server was added manually + uint8 retries; ///< Number of retries (to stop requerying) + NetworkGameList *next; ///< Next pointer to make a linked game list }; /** Game list of this client */ extern NetworkGameList *_network_game_list; void NetworkGameListAddItemDelayed(NetworkGameList *item); -NetworkGameList *NetworkGameListAddItem(NetworkAddress address); +NetworkGameList *NetworkGameListAddItem(const std::string &connection_string); void NetworkGameListRemoveItem(NetworkGameList *remove); void NetworkGameListRequery(); diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index ac86b868c6..526f141cde 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -272,7 +272,9 @@ protected: static bool NGameNameSorter(NetworkGameList * const &a, NetworkGameList * const &b) { int r = strnatcmp(a->info.server_name, b->info.server_name, true); // Sort by name (natural sorting). - return r == 0 ? a->address.CompareTo(b->address) < 0: r < 0; + if (r == 0) r = a->connection_string.compare(b->connection_string); + + return r < 0; } /** @@ -646,8 +648,7 @@ public: DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_SERVER_VERSION); // server version y += FONT_HEIGHT_NORMAL; - std::string address = sel->address.GetAddressAsString(); - SetDParamStr(0, address.c_str()); + SetDParamStr(0, sel->connection_string.c_str()); DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_SERVER_ADDRESS); // server address y += FONT_HEIGHT_NORMAL; @@ -751,7 +752,7 @@ public: break; case WID_NG_REFRESH: // Refresh - if (this->server != nullptr) NetworkTCPQueryServer(this->server->address); + if (this->server != nullptr) NetworkTCPQueryServer(this->server->connection_string); break; case WID_NG_NEWGRF: // NewGRF Settings @@ -1471,22 +1472,22 @@ struct NetworkLobbyWindow : public Window { case WID_NL_JOIN: // Join company /* Button can be clicked only when it is enabled. */ - NetworkClientConnectGame(this->server->address, this->company); + NetworkClientConnectGame(this->server->connection_string, this->company); break; case WID_NL_NEW: // New company - NetworkClientConnectGame(this->server->address, COMPANY_NEW_COMPANY); + NetworkClientConnectGame(this->server->connection_string, COMPANY_NEW_COMPANY); break; case WID_NL_SPECTATE: // Spectate game - NetworkClientConnectGame(this->server->address, COMPANY_SPECTATOR); + NetworkClientConnectGame(this->server->connection_string, 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(this->server->address, true); + NetworkTCPQueryServer(this->server->connection_string, true); break; } } @@ -1554,9 +1555,9 @@ static void ShowNetworkLobbyWindow(NetworkGameList *ngl) DeleteWindowById(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_START); DeleteWindowById(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_GAME); - strecpy(_settings_client.network.last_joined, ngl->address.GetAddressAsString(false).c_str(), lastof(_settings_client.network.last_joined)); + strecpy(_settings_client.network.last_joined, ngl->connection_string.c_str(), lastof(_settings_client.network.last_joined)); - NetworkTCPQueryServer(ngl->address, true); + NetworkTCPQueryServer(ngl->connection_string, true); new NetworkLobbyWindow(&_network_lobby_window_desc, ngl); } diff --git a/src/network/network_internal.h b/src/network/network_internal.h index 1fba1228a5..ef414c46a3 100644 --- a/src/network/network_internal.h +++ b/src/network/network_internal.h @@ -87,7 +87,7 @@ extern uint8 _network_reconnect; extern CompanyMask _network_company_passworded; -void NetworkTCPQueryServer(NetworkAddress address, bool request_company_info = false); +void NetworkTCPQueryServer(const std::string &connection_string, bool request_company_info = false); void GetBindAddresses(NetworkAddressList *addresses, uint16 port); struct NetworkGameList *NetworkAddServer(const std::string &connection_string); @@ -119,8 +119,6 @@ StringID GetNetworkErrorMsg(NetworkErrorCode err); bool NetworkFindName(char *new_name, const char *last); const char *GenerateCompanyPasswordHash(const char *password, const char *password_server_id, uint32 password_game_seed); -bool NetworkClientConnectGame(NetworkAddress &address, CompanyID join_as, const char *join_server_password = nullptr, const char *join_company_password = nullptr); NetworkAddress ParseConnectionString(const std::string &connection_string, int default_port); -NetworkAddress ParseGameConnectionString(CompanyID *company, const std::string &connection_string, int default_port); #endif /* NETWORK_INTERNAL_H */ diff --git a/src/network/network_udp.cpp b/src/network/network_udp.cpp index de69e4a9af..558b51f993 100644 --- a/src/network/network_udp.cpp +++ b/src/network/network_udp.cpp @@ -83,35 +83,36 @@ static UDPSocket _udp_master("Master"); ///< udp master socket /** * Helper function doing the actual work for querying the server. - * @param address The address of the server. + * @param connection_string The address of the server. * @param needs_mutex Whether we need to acquire locks when sending the packet or not. * @param manually Whether the address was entered manually. */ -static void DoNetworkUDPQueryServer(NetworkAddress &address, bool needs_mutex, bool manually) +static void DoNetworkUDPQueryServer(const std::string &connection_string, bool needs_mutex, bool manually) { /* Clear item in gamelist */ NetworkGameList *item = CallocT(1); - address.GetAddressAsString(item->info.server_name, lastof(item->info.server_name)); - item->address = address; + strecpy(item->info.server_name, connection_string.c_str(), lastof(item->info.server_name)); + item->connection_string = connection_string; item->manually = manually; NetworkGameListAddItemDelayed(item); std::unique_lock lock(_udp_client.mutex, std::defer_lock); if (needs_mutex) lock.lock(); /* Init the packet */ + NetworkAddress address = NetworkAddress(ParseConnectionString(connection_string, NETWORK_DEFAULT_PORT)); Packet p(PACKET_UDP_CLIENT_FIND_SERVER); if (_udp_client.socket != nullptr) _udp_client.socket->SendPacket(&p, &address); } /** * Query a specific server. - * @param address The address of the server. + * @param connection_string The address of the server. * @param manually Whether the address was entered manually. */ -void NetworkUDPQueryServer(NetworkAddress address, bool manually) +void NetworkUDPQueryServer(const std::string &connection_string, bool manually) { - if (address.IsResolved() || !StartNewThread(nullptr, "ottd:udp-query", &DoNetworkUDPQueryServer, std::move(address), true, std::move(manually))) { - DoNetworkUDPQueryServer(address, true, manually); + if (!StartNewThread(nullptr, "ottd:udp-query", &DoNetworkUDPQueryServer, std::move(connection_string), true, std::move(manually))) { + DoNetworkUDPQueryServer(connection_string, true, manually); } } @@ -318,7 +319,7 @@ void ClientNetworkUDPSocketHandler::Receive_SERVER_RESPONSE(Packet *p, NetworkAd DEBUG(net, 4, "[udp] server response from %s", client_addr->GetAddressAsString().c_str()); /* Find next item */ - item = NetworkGameListAddItem(*client_addr); + item = NetworkGameListAddItem(client_addr->GetAddressAsString(false)); /* Clear any existing GRFConfig chain. */ ClearGRFConfigList(&item->info.grfconfig); @@ -357,7 +358,8 @@ void ClientNetworkUDPSocketHandler::Receive_SERVER_RESPONSE(Packet *p, NetworkAd SerializeGRFIdentifier(&packet, &in_request[i]->ident); } - this->SendPacket(&packet, &item->address); + NetworkAddress address = NetworkAddress(ParseConnectionString(item->connection_string, NETWORK_DEFAULT_PORT)); + this->SendPacket(&packet, &address); } } @@ -398,7 +400,7 @@ void ClientNetworkUDPSocketHandler::Receive_MASTER_RESPONSE_LIST(Packet *p, Netw /* Somehow we reached the end of the packet */ if (this->HasClientQuit()) return; - DoNetworkUDPQueryServer(addr, false, false); + DoNetworkUDPQueryServer(addr.GetAddressAsString(false), false, false); } } } diff --git a/src/network/network_udp.h b/src/network/network_udp.h index 189657bc87..ced949cd32 100644 --- a/src/network/network_udp.h +++ b/src/network/network_udp.h @@ -15,7 +15,7 @@ void NetworkUDPInitialize(); void NetworkUDPSearchGame(); void NetworkUDPQueryMasterServer(); -void NetworkUDPQueryServer(NetworkAddress address, bool manually = false); +void NetworkUDPQueryServer(const std::string &connection_string, bool manually = false); void NetworkUDPAdvertise(); void NetworkUDPRemoveAdvertise(bool blocking); void NetworkUDPClose(); From dc0591728739c2c8fa68dbfeb418239fbfb39383 Mon Sep 17 00:00:00 2001 From: rubidium42 Date: Sun, 2 May 2021 07:14:19 +0200 Subject: [PATCH 15/22] Add: [[nodiscard]] to std::string str_validate --- src/string_func.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/string_func.h b/src/string_func.h index 4fe9d7b825..787fd6413e 100644 --- a/src/string_func.h +++ b/src/string_func.h @@ -40,7 +40,7 @@ int CDECL vseprintf(char *str, const char *last, const char *format, va_list ap) char *CDECL str_fmt(const char *str, ...) WARN_FORMAT(1, 2); void str_validate(char *str, const char *last, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK) NOACCESS(2); -std::string str_validate(const std::string &str, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK); +[[nodiscard]] std::string str_validate(const std::string &str, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK); void ValidateString(const char *str); void str_fix_scc_encoded(char *str, const char *last) NOACCESS(2); From dcef3209a61acf818f3114d07e3378bc7e61a9c1 Mon Sep 17 00:00:00 2001 From: rubidium42 Date: Tue, 4 May 2021 19:30:25 +0200 Subject: [PATCH 16/22] Codechange: [Network] Use new/delete instead of calloc/free for NetworkGameList --- src/network/network_gamelist.cpp | 9 +++------ src/network/network_gamelist.h | 17 +++++++++++------ src/network/network_udp.cpp | 4 +--- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/network/network_gamelist.cpp b/src/network/network_gamelist.cpp index 1edbafc328..e4e2d17412 100644 --- a/src/network/network_gamelist.cpp +++ b/src/network/network_gamelist.cpp @@ -57,7 +57,7 @@ static void NetworkGameListHandleDelayedInsert() if (item->manually) NetworkRebuildHostList(); UpdateNetworkGameWindow(); } - free(ins_item); + delete ins_item; } } @@ -80,9 +80,7 @@ NetworkGameList *NetworkGameListAddItem(const std::string &connection_string) prev_item = item; } - item = CallocT(1); - item->next = nullptr; - item->connection_string = resolved_connection_string; + item = new NetworkGameList(resolved_connection_string); if (prev_item == nullptr) { _network_game_list = item; @@ -112,8 +110,7 @@ void NetworkGameListRemoveItem(NetworkGameList *remove) /* Remove GRFConfig information */ ClearGRFConfigList(&remove->info.grfconfig); - free(remove); - remove = nullptr; + delete remove; DEBUG(net, 4, "[gamelist] removed server from list"); NetworkRebuildHostList(); diff --git a/src/network/network_gamelist.h b/src/network/network_gamelist.h index 31b3bc3e64..6ef9d8e41f 100644 --- a/src/network/network_gamelist.h +++ b/src/network/network_gamelist.h @@ -16,12 +16,17 @@ /** Structure with information shown in the game list (GUI) */ struct NetworkGameList { - NetworkGameInfo info; ///< The game information of this server - std::string connection_string; ///< Address of the server - bool online; ///< False if the server did not respond (default status) - bool manually; ///< True if the server was added manually - uint8 retries; ///< Number of retries (to stop requerying) - NetworkGameList *next; ///< Next pointer to make a linked game list + NetworkGameList(const std::string &connection_string, bool manually = false) : + connection_string(connection_string), manually(manually) + { + } + + 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) + NetworkGameList *next = nullptr; ///< Next pointer to make a linked game list }; /** Game list of this client */ diff --git a/src/network/network_udp.cpp b/src/network/network_udp.cpp index 558b51f993..4e4f4a37e7 100644 --- a/src/network/network_udp.cpp +++ b/src/network/network_udp.cpp @@ -90,10 +90,8 @@ static UDPSocket _udp_master("Master"); ///< udp master socket static void DoNetworkUDPQueryServer(const std::string &connection_string, bool needs_mutex, bool manually) { /* Clear item in gamelist */ - NetworkGameList *item = CallocT(1); + NetworkGameList *item = new NetworkGameList(connection_string, manually); strecpy(item->info.server_name, connection_string.c_str(), lastof(item->info.server_name)); - item->connection_string = connection_string; - item->manually = manually; NetworkGameListAddItemDelayed(item); std::unique_lock lock(_udp_client.mutex, std::defer_lock); From 6c4a65eeb80431ce35e91affee865419e7d7af34 Mon Sep 17 00:00:00 2001 From: rubidium42 Date: Tue, 4 May 2021 19:31:12 +0200 Subject: [PATCH 17/22] Codechange: [Network] Use std::string for NetworkAddress' host name --- src/network/core/address.cpp | 24 +++++++++++++----------- src/network/core/address.h | 23 ++++++++++------------- src/network/core/udp.cpp | 6 +++--- 3 files changed, 26 insertions(+), 27 deletions(-) diff --git a/src/network/core/address.cpp b/src/network/core/address.cpp index d3e373ef76..d40a72420b 100644 --- a/src/network/core/address.cpp +++ b/src/network/core/address.cpp @@ -23,11 +23,13 @@ static const int DEFAULT_CONNECT_TIMEOUT_SECONDS = 3; ///< Allow connect() three */ const char *NetworkAddress::GetHostname() { - if (StrEmpty(this->hostname) && this->address.ss_family != AF_UNSPEC) { + if (this->hostname.empty() && this->address.ss_family != AF_UNSPEC) { assert(this->address_length != 0); - getnameinfo((struct sockaddr *)&this->address, this->address_length, this->hostname, sizeof(this->hostname), nullptr, 0, NI_NUMERICHOST); + char buffer[NETWORK_HOSTNAME_LENGTH]; + getnameinfo((struct sockaddr *)&this->address, this->address_length, buffer, sizeof(buffer), nullptr, 0, NI_NUMERICHOST); + this->hostname = buffer; } - return this->hostname; + return this->hostname.c_str(); } /** @@ -234,32 +236,32 @@ SOCKET NetworkAddress::Resolve(int family, int socktype, int flags, SocketList * /* Setting both hostname to nullptr and port to 0 is not allowed. * As port 0 means bind to any port, the other must mean that * we want to bind to 'all' IPs. */ - if (StrEmpty(this->hostname) && this->address_length == 0 && this->GetPort() == 0) { + if (this->hostname.empty() && this->address_length == 0 && this->GetPort() == 0) { reset_hostname = true; int fam = this->address.ss_family; if (fam == AF_UNSPEC) fam = family; - strecpy(this->hostname, fam == AF_INET ? "0.0.0.0" : "::", lastof(this->hostname)); + this->hostname = fam == AF_INET ? "0.0.0.0" : "::"; } static bool _resolve_timeout_error_message_shown = false; auto start = std::chrono::steady_clock::now(); - int e = getaddrinfo(StrEmpty(this->hostname) ? nullptr : this->hostname, port_name, &hints, &ai); + int e = getaddrinfo(this->hostname.empty() ? nullptr : this->hostname.c_str(), port_name, &hints, &ai); auto end = std::chrono::steady_clock::now(); std::chrono::seconds duration = std::chrono::duration_cast(end - start); if (!_resolve_timeout_error_message_shown && duration >= std::chrono::seconds(5)) { DEBUG(net, 0, "getaddrinfo for hostname \"%s\", port %s, address family %s and socket type %s took %i seconds", - this->hostname, port_name, AddressFamilyAsString(family), SocketTypeAsString(socktype), (int)duration.count()); + this->hostname.c_str(), port_name, AddressFamilyAsString(family), SocketTypeAsString(socktype), (int)duration.count()); DEBUG(net, 0, " this is likely an issue in the DNS name resolver's configuration causing it to time out"); _resolve_timeout_error_message_shown = true; } - if (reset_hostname) strecpy(this->hostname, "", lastof(this->hostname)); + if (reset_hostname) this->hostname.clear(); if (e != 0) { if (func != ResolveLoopProc) { DEBUG(net, 0, "getaddrinfo for hostname \"%s\", port %s, address family %s and socket type %s failed: %s", - this->hostname, port_name, AddressFamilyAsString(family), SocketTypeAsString(socktype), FS2OTTD(gai_strerror(e)).c_str()); + this->hostname.c_str(), port_name, AddressFamilyAsString(family), SocketTypeAsString(socktype), FS2OTTD(gai_strerror(e)).c_str()); } return INVALID_SOCKET; } @@ -442,11 +444,11 @@ void NetworkAddress::Listen(int socktype, SocketList *sockets) { assert(sockets != nullptr); - /* Setting both hostname to nullptr and port to 0 is not allowed. + /* Setting both hostname to "" and port to 0 is not allowed. * As port 0 means bind to any port, the other must mean that * we want to bind to 'all' IPs. */ if (this->address_length == 0 && this->address.ss_family == AF_UNSPEC && - StrEmpty(this->hostname) && this->GetPort() == 0) { + this->hostname.empty() && this->GetPort() == 0) { this->Resolve(AF_INET, socktype, AI_ADDRCONFIG | AI_PASSIVE, sockets, ListenLoopProc); this->Resolve(AF_INET6, socktype, AI_ADDRCONFIG | AI_PASSIVE, sockets, ListenLoopProc); } else { diff --git a/src/network/core/address.h b/src/network/core/address.h index 65546818b2..b4364c95ab 100644 --- a/src/network/core/address.h +++ b/src/network/core/address.h @@ -28,10 +28,10 @@ typedef SmallMap SocketList; ///< Type for a mapping */ class NetworkAddress { private: - char hostname[NETWORK_HOSTNAME_LENGTH]; ///< The hostname - int address_length; ///< The length of the resolved address - sockaddr_storage address; ///< The resolved address - bool resolved; ///< Whether the address has been (tried to be) resolved + std::string hostname; ///< The hostname + int address_length; ///< The length of the resolved address + sockaddr_storage address; ///< The resolved address + bool resolved; ///< Whether the address has been (tried to be) resolved /** * Helper function to resolve something to a socket. @@ -52,7 +52,6 @@ public: address(address), resolved(address_length != 0) { - *this->hostname = '\0'; } /** @@ -64,7 +63,6 @@ public: address_length(address_length), resolved(address_length != 0) { - *this->hostname = '\0'; memset(&this->address, 0, sizeof(this->address)); memcpy(&this->address, address, address_length); } @@ -75,16 +73,15 @@ public: * @param port the port * @param family the address family */ - NetworkAddress(const char *hostname = "", uint16 port = 0, int family = AF_UNSPEC) : + NetworkAddress(std::string_view hostname = "", uint16 port = 0, int family = AF_UNSPEC) : address_length(0), resolved(false) { - /* Also handle IPv6 bracket enclosed hostnames */ - if (StrEmpty(hostname)) hostname = ""; - if (*hostname == '[') hostname++; - strecpy(this->hostname, StrEmpty(hostname) ? "" : hostname, lastof(this->hostname)); - char *tmp = strrchr(this->hostname, ']'); - if (tmp != nullptr) *tmp = '\0'; + if (!hostname.empty() && hostname.front() == '[' && hostname.back() == ']') { + hostname.remove_prefix(1); + hostname.remove_suffix(1); + } + this->hostname = hostname; memset(&this->address, 0, sizeof(this->address)); this->address.ss_family = family; diff --git a/src/network/core/udp.cpp b/src/network/core/udp.cpp index e7b99a53e8..c4d448f268 100644 --- a/src/network/core/udp.cpp +++ b/src/network/core/udp.cpp @@ -28,11 +28,11 @@ NetworkUDPSocketHandler::NetworkUDPSocketHandler(NetworkAddressList *bind) this->bind.push_back(addr); } } else { - /* As hostname nullptr and port 0/nullptr don't go well when + /* As an empty hostname and port 0 don't go well when * resolving it we need to add an address for each of * the address families we support. */ - this->bind.emplace_back(nullptr, 0, AF_INET); - this->bind.emplace_back(nullptr, 0, AF_INET6); + this->bind.emplace_back("", 0, AF_INET); + this->bind.emplace_back("", 0, AF_INET6); } } From 3d91eee919de2ecec11102b4ba1f4caafa4d7a83 Mon Sep 17 00:00:00 2001 From: rubidium42 Date: Tue, 4 May 2021 19:32:37 +0200 Subject: [PATCH 18/22] Codechange: [Network] Move connection string parsing away from C-strings --- src/network/network.cpp | 112 +++++++++++++++------------------ src/network/network_func.h | 2 +- src/network/network_internal.h | 2 +- src/openttd.cpp | 11 ++-- 4 files changed, 57 insertions(+), 70 deletions(-) diff --git a/src/network/network.cpp b/src/network/network.cpp index 98b49e81fe..a90f8197e7 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -33,6 +33,7 @@ #include "../core/pool_func.hpp" #include "../gfx_func.h" #include "../error.h" +#include #include "../safeguards.h" @@ -453,36 +454,51 @@ static void CheckPauseOnJoin() * 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. Similar for company, if set. + * Returns the IP part as a string view into the passed string. This view is + * valid as long the passed connection string is valid. If there is no port + * present in the connection string, the port reference will not be touched. + * When there is no company ID present in the connection string or company_id + * is nullptr, then company ID will not be touched. + * + * @param connection_string The string with the connection data. + * @param port The port reference to set. + * @param company_id The company ID to set, if available. + * @return A std::string_view into the connection string with the (IP) address part. */ -void ParseFullConnectionString(const char **company, const char **port, char *connection_string) +std::string_view ParseFullConnectionString(const std::string &connection_string, uint16 &port, CompanyID *company_id) { - bool ipv6 = (strchr(connection_string, ':') != strrchr(connection_string, ':')); - for (char *p = connection_string; *p != '\0'; p++) { - switch (*p) { - case '[': - ipv6 = true; - break; + 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); - case ']': - ipv6 = false; - break; - - case '#': - if (company == nullptr) continue; - *company = p + 1; - *p = '\0'; - break; - - case ':': - if (ipv6) break; - *port = p + 1; - *p = '\0'; - break; + 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; + } + } } } + + size_t port_offset = ip.find_last_of(':'); + size_t ipv6_close = ip.find_last_of(']'); + if (port_offset != std::string::npos && (ipv6_close == std::string::npos || ipv6_close < port_offset)) { + std::string_view port_string = ip.substr(port_offset + 1); + ip = ip.substr(0, port_offset); + std::from_chars(port_string.data(), port_string.data() + port_string.size(), port); + } + return ip; } /** @@ -493,16 +509,11 @@ void ParseFullConnectionString(const char **company, const char **port, char *co * @param default_port The default port to set port to if not in connection_string. * @return A valid NetworkAddress of the parsed information. */ -NetworkAddress ParseConnectionString(const std::string &connection_string, int default_port) +NetworkAddress ParseConnectionString(const std::string &connection_string, uint16 default_port) { - char internal_connection_string[NETWORK_HOSTNAME_PORT_LENGTH]; - strecpy(internal_connection_string, connection_string.c_str(), lastof(internal_connection_string)); - - const char *port = nullptr; - ParseFullConnectionString(nullptr, &port, internal_connection_string); - - int rport = port != nullptr ? atoi(port) : default_port; - return NetworkAddress(internal_connection_string, rport); + uint16 port = default_port; + std::string_view ip = ParseFullConnectionString(connection_string, port); + return NetworkAddress(ip, port); } /** @@ -510,37 +521,16 @@ NetworkAddress ParseConnectionString(const std::string &connection_string, int d * 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. + * @param company Pointer to the company variable to set iff indicted. * @return A valid NetworkAddress of the parsed information. */ -static NetworkAddress ParseGameConnectionString(CompanyID *company, const std::string &connection_string, int default_port) +static NetworkAddress ParseGameConnectionString(const std::string &connection_string, uint16 default_port, CompanyID *company) { - char internal_connection_string[NETWORK_HOSTNAME_PORT_LENGTH + 4]; // 4 extra for the "#" and company - strecpy(internal_connection_string, connection_string.c_str(), 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) { - uint company_value = atoi(company_s); - - if (company_value != COMPANY_NEW_COMPANY && company_value != COMPANY_SPECTATOR) { - if (company_value > MAX_COMPANIES || company_value == 0) { - *company = COMPANY_SPECTATOR; - } else { - /* "#1" means the first company, which has index 0. */ - *company = (CompanyID)(company_value - 1); - } - } else { - *company = (CompanyID)company_value; - } - } - - int port = port_s != nullptr ? atoi(port_s) : default_port; - return NetworkAddress(internal_connection_string, port); + uint16 port = default_port; + std::string_view ip = ParseFullConnectionString(connection_string, port, company); + return NetworkAddress(ip, port); } /** @@ -751,7 +741,7 @@ public: bool NetworkClientConnectGame(const std::string &connection_string, CompanyID default_company, const char *join_server_password, const char *join_company_password) { CompanyID join_as = default_company; - std::string resolved_connection_string = ParseGameConnectionString(&join_as, connection_string, NETWORK_DEFAULT_PORT).GetAddressAsString(false); + std::string resolved_connection_string = ParseGameConnectionString(connection_string, NETWORK_DEFAULT_PORT, &join_as).GetAddressAsString(false); if (!_network_available) return false; if (!NetworkValidateClientName()) return false; diff --git a/src/network/network_func.h b/src/network/network_func.h index ba26e06c09..ef81b0fb16 100644 --- a/src/network/network_func.h +++ b/src/network/network_func.h @@ -45,7 +45,7 @@ void NetworkReboot(); void NetworkDisconnect(bool blocking = false, bool close_admins = true); void NetworkGameLoop(); void NetworkBackgroundLoop(); -void ParseFullConnectionString(const char **company, const char **port, char *connection_string); +std::string_view ParseFullConnectionString(const std::string &connection_string, uint16 &port, CompanyID *company_id = nullptr); void NetworkStartDebugLog(const std::string &connection_string); void NetworkPopulateCompanyStats(NetworkCompanyStats *stats); diff --git a/src/network/network_internal.h b/src/network/network_internal.h index ef414c46a3..2a2024bac5 100644 --- a/src/network/network_internal.h +++ b/src/network/network_internal.h @@ -119,6 +119,6 @@ StringID GetNetworkErrorMsg(NetworkErrorCode err); bool NetworkFindName(char *new_name, const char *last); const char *GenerateCompanyPasswordHash(const char *password, const char *password_server_id, uint32 password_game_seed); -NetworkAddress ParseConnectionString(const std::string &connection_string, int default_port); +NetworkAddress ParseConnectionString(const std::string &connection_string, uint16 default_port); #endif /* NETWORK_INTERNAL_H */ diff --git a/src/openttd.cpp b/src/openttd.cpp index d4c7da6e4c..d9e0b835e0 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -405,7 +405,7 @@ void OpenBrowser(const char *url) struct AfterNewGRFScan : NewGRFScanCallback { Year startyear; ///< The start year. uint32 generation_seed; ///< Seed for the new game. - char *dedicated_host; ///< Hostname for the dedicated server. + std::string dedicated_host; ///< Hostname for the dedicated server. uint16 dedicated_port; ///< Port for the dedicated server. char *network_conn; ///< Information about the server to connect to, or nullptr. const char *join_server_password; ///< The password to join the server with. @@ -417,7 +417,7 @@ struct AfterNewGRFScan : NewGRFScanCallback { */ AfterNewGRFScan() : startyear(INVALID_YEAR), generation_seed(GENERATE_NEW_SEED), - dedicated_host(nullptr), dedicated_port(0), network_conn(nullptr), + dedicated_port(0), network_conn(nullptr), join_server_password(nullptr), join_company_password(nullptr), save_config(true) { @@ -458,7 +458,7 @@ struct AfterNewGRFScan : NewGRFScanCallback { if (startyear != INVALID_YEAR) IConsoleSetSetting("game_creation.starting_year", startyear); if (generation_seed != GENERATE_NEW_SEED) _settings_newgame.game_creation.generation_seed = generation_seed; - if (dedicated_host != nullptr) { + if (!dedicated_host.empty()) { _network_bind_list.clear(); _network_bind_list.emplace_back(dedicated_host); } @@ -565,10 +565,7 @@ int openttd_main(int argc, char *argv[]) dedicated = true; SetDebugString("net=6"); if (mgo.opt != nullptr) { - const char *port = nullptr; - ParseFullConnectionString(nullptr, &port, mgo.opt); - if (!StrEmpty(mgo.opt)) scanner->dedicated_host = mgo.opt; - if (port != nullptr) scanner->dedicated_port = atoi(port); + scanner->dedicated_host = ParseFullConnectionString(mgo.opt, scanner->dedicated_port); } break; case 'f': _dedicated_forks = true; break; From f313a539a54efe09850bcab0680d281e3cc54444 Mon Sep 17 00:00:00 2001 From: translators Date: Thu, 6 May 2021 18:59:49 +0000 Subject: [PATCH 19/22] Update: Translations from eints portuguese: 1 change by azulcosta --- src/lang/portuguese.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lang/portuguese.txt b/src/lang/portuguese.txt index 4473b1cb39..2e7f686ac2 100644 --- a/src/lang/portuguese.txt +++ b/src/lang/portuguese.txt @@ -2270,7 +2270,7 @@ STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} en STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} entrou como espectador STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} iniciou uma nova empresa (#{2:NUM}) STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} deixou o jogo ({2:STRING}) -STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} mudou o seu nome para {STRING} +STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} mudou o nome para {STRING} STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} deu {2:CURRENCY_LONG} a {1:STRING} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}O servidor fechou a sessão STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}O servidor está a reiniciar...{}Por favor espere... From 6bca9e090dc6637fd7b6ed6a5a37d65f151849e9 Mon Sep 17 00:00:00 2001 From: rubidium42 Date: Tue, 27 Apr 2021 20:58:17 +0200 Subject: [PATCH 20/22] Codechange: add SetDParamStr that accepts std::string& --- src/fios.cpp | 2 +- src/fios_gui.cpp | 2 +- src/industry_gui.cpp | 2 +- src/music_gui.cpp | 2 +- src/newgrf_gui.cpp | 12 ++++++------ src/settings.cpp | 2 +- src/settings_gui.cpp | 8 ++++---- src/strings.cpp | 11 +++++++++++ src/strings_func.h | 1 + src/town_gui.cpp | 4 ++-- src/widgets/dropdown.cpp | 2 +- 11 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/fios.cpp b/src/fios.cpp index 3b11bcbe02..c56e505fa0 100644 --- a/src/fios.cpp +++ b/src/fios.cpp @@ -392,7 +392,7 @@ static void FiosGetFileList(SaveLoadOperation fop, fios_getlist_callback_proc *c fios->mtime = 0; strecpy(fios->name, d_name, lastof(fios->name)); std::string dirname = std::string(d_name) + PATHSEP; - SetDParamStr(0, dirname.c_str()); + SetDParamStr(0, dirname); GetString(fios->title, STR_SAVELOAD_DIRECTORY, lastof(fios->title)); str_validate(fios->title, lastof(fios->title)); } diff --git a/src/fios_gui.cpp b/src/fios_gui.cpp index 8de6235d62..e4de1acaaa 100644 --- a/src/fios_gui.cpp +++ b/src/fios_gui.cpp @@ -537,7 +537,7 @@ public: const CompanyProperties &c = *pair.second; if (!c.name.empty()) { SetDParam(1, STR_JUST_RAW_STRING); - SetDParamStr(2, c.name.c_str()); + SetDParamStr(2, c.name); } else { SetDParam(1, c.name_1); SetDParam(2, c.name_2); diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index aa4d86da6c..d0c916ef7c 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -972,7 +972,7 @@ public: } if (!i->text.empty()) { - SetDParamStr(0, i->text.c_str()); + SetDParamStr(0, i->text); y += WD_PAR_VSEP_WIDE; y = DrawStringMultiLine(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, y, UINT16_MAX, STR_JUST_RAW_STRING, TC_BLACK); } diff --git a/src/music_gui.cpp b/src/music_gui.cpp index 28cb6ce4e1..16245a0b24 100644 --- a/src/music_gui.cpp +++ b/src/music_gui.cpp @@ -462,7 +462,7 @@ struct MusicTrackSelectionWindow : public Window { SetDParam(0, STR_MUSIC_PLAYLIST_ALL + _settings_client.music.playlist); break; case WID_MTS_CAPTION: - SetDParamStr(0, BaseMusic::GetUsedSet()->name.c_str()); + SetDParamStr(0, BaseMusic::GetUsedSet()->name); break; } } diff --git a/src/newgrf_gui.cpp b/src/newgrf_gui.cpp index 6316a7c4bf..9e86a575f0 100644 --- a/src/newgrf_gui.cpp +++ b/src/newgrf_gui.cpp @@ -51,9 +51,9 @@ void ShowNewGRFError() if (c->error == nullptr || (c->error->severity != STR_NEWGRF_ERROR_MSG_FATAL && c->error->severity != STR_NEWGRF_ERROR_MSG_ERROR)) continue; SetDParam (0, c->error->message != STR_NULL ? c->error->message : STR_JUST_RAW_STRING); - SetDParamStr(1, c->error->custom_message.c_str()); + SetDParamStr(1, c->error->custom_message); SetDParamStr(2, c->filename); - SetDParamStr(3, c->error->data.c_str()); + SetDParamStr(3, c->error->data); for (uint i = 0; i < lengthof(c->error->param_value); i++) { SetDParam(4 + i, c->error->param_value[i]); } @@ -70,9 +70,9 @@ static void ShowNewGRFInfo(const GRFConfig *c, uint x, uint y, uint right, uint { if (c->error != nullptr) { char message[512]; - SetDParamStr(0, c->error->custom_message.c_str()); // is skipped by built-in messages + SetDParamStr(0, c->error->custom_message); // is skipped by built-in messages SetDParamStr(1, c->filename); - SetDParamStr(2, c->error->data.c_str()); + SetDParamStr(2, c->error->data); for (uint i = 0; i < lengthof(c->error->param_value); i++) { SetDParam(3 + i, c->error->param_value[i]); } @@ -750,7 +750,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { case WID_NS_PRESET_LIST: { Dimension d = GetStringBoundingBox(STR_NUM_CUSTOM); for (const auto &i : this->grf_presets) { - SetDParamStr(0, i.c_str()); + SetDParamStr(0, i); d = maxdim(d, GetStringBoundingBox(STR_JUST_RAW_STRING)); } d.width += padding.width; @@ -783,7 +783,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { SetDParam(0, STR_NUM_CUSTOM); } else { SetDParam(0, STR_JUST_RAW_STRING); - SetDParamStr(1, this->grf_presets[this->preset].c_str()); + SetDParamStr(1, this->grf_presets[this->preset]); } break; } diff --git a/src/settings.cpp b/src/settings.cpp index c0b0dd8edd..855bedd18d 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1631,7 +1631,7 @@ static GRFConfig *GRFLoadConfig(IniFile *ini, const char *grpname, bool is_stati SetDParam(1, STR_CONFIG_ERROR_INVALID_GRF_UNKNOWN); } - SetDParamStr(0, StrEmpty(filename) ? item->name.c_str() : filename); + SetDParamStr(0, StrEmpty(filename) ? item->name : filename); ShowErrorMessage(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_GRF, WL_CRITICAL); delete c; continue; diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index 34c073fe92..9935d596c0 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -123,7 +123,7 @@ struct BaseSetTextfileWindow : public TextfileWindow { { if (widget == WID_TF_CAPTION) { SetDParam(0, content_type); - SetDParamStr(1, this->baseset->name.c_str()); + SetDParamStr(1, this->baseset->name); } } }; @@ -304,10 +304,10 @@ struct GameOptionsWindow : Window { case WID_GO_LANG_DROPDOWN: SetDParamStr(0, _current_language->own_name); break; case WID_GO_GUI_ZOOM_DROPDOWN: SetDParam(0, _gui_zoom_dropdown[_gui_zoom_cfg != ZOOM_LVL_CFG_AUTO ? ZOOM_LVL_OUT_4X - _gui_zoom_cfg + 1 : 0]); break; case WID_GO_FONT_ZOOM_DROPDOWN: SetDParam(0, _font_zoom_dropdown[_font_zoom_cfg != ZOOM_LVL_CFG_AUTO ? ZOOM_LVL_OUT_4X - _font_zoom_cfg + 1 : 0]); break; - case WID_GO_BASE_GRF_DROPDOWN: SetDParamStr(0, BaseGraphics::GetUsedSet()->name.c_str()); break; + case WID_GO_BASE_GRF_DROPDOWN: SetDParamStr(0, BaseGraphics::GetUsedSet()->name); break; case WID_GO_BASE_GRF_STATUS: SetDParam(0, BaseGraphics::GetUsedSet()->GetNumInvalid()); break; - case WID_GO_BASE_SFX_DROPDOWN: SetDParamStr(0, BaseSounds::GetUsedSet()->name.c_str()); break; - case WID_GO_BASE_MUSIC_DROPDOWN: SetDParamStr(0, BaseMusic::GetUsedSet()->name.c_str()); break; + case WID_GO_BASE_SFX_DROPDOWN: SetDParamStr(0, BaseSounds::GetUsedSet()->name); break; + case WID_GO_BASE_MUSIC_DROPDOWN: SetDParamStr(0, BaseMusic::GetUsedSet()->name); break; case WID_GO_BASE_MUSIC_STATUS: SetDParam(0, BaseMusic::GetUsedSet()->GetNumInvalid()); break; case WID_GO_REFRESH_RATE_DROPDOWN: SetDParam(0, _settings_client.gui.refresh_rate); break; case WID_GO_RESOLUTION_DROPDOWN: { diff --git a/src/strings.cpp b/src/strings.cpp index 0489714590..2b6dbc3ef9 100644 --- a/src/strings.cpp +++ b/src/strings.cpp @@ -296,6 +296,17 @@ void SetDParamStr(uint n, const char *str) SetDParam(n, (uint64)(size_t)str); } +/** + * This function is used to "bind" the C string of a std::string to a OpenTTD dparam slot. + * The caller has to ensure that the std::string reference remains valid while the string is shown. + * @param n slot of the string + * @param str string to bind + */ +void SetDParamStr(uint n, const std::string &str) +{ + SetDParamStr(n, str.c_str()); +} + /** * Shift the string parameters in the global string parameter array by \a amount positions, making room at the beginning. * @param amount Number of positions to shift. diff --git a/src/strings_func.h b/src/strings_func.h index e4b7791052..be59b091a2 100644 --- a/src/strings_func.h +++ b/src/strings_func.h @@ -205,6 +205,7 @@ void SetDParamMaxValue(uint n, uint64 max_value, uint min_count = 0, FontSize si void SetDParamMaxDigits(uint n, uint count, FontSize size = FS_NORMAL); void SetDParamStr(uint n, const char *str); +void SetDParamStr(uint n, const std::string &str); void CopyInDParam(int offs, const uint64 *src, int num); void CopyOutDParam(uint64 *dst, int offs, int num); diff --git a/src/town_gui.cpp b/src/town_gui.cpp index a189c7ccb3..22f8b757f8 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.cpp @@ -435,7 +435,7 @@ public: } if (!this->town->text.empty()) { - SetDParamStr(0, this->town->text.c_str()); + SetDParamStr(0, this->town->text); DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y += FONT_HEIGHT_NORMAL, UINT16_MAX, STR_JUST_RAW_STRING, TC_BLACK); } } @@ -517,7 +517,7 @@ public: if (_settings_game.economy.station_noise_level) aimed_height += FONT_HEIGHT_NORMAL; if (!this->town->text.empty()) { - SetDParamStr(0, this->town->text.c_str()); + SetDParamStr(0, this->town->text); aimed_height += GetStringHeight(STR_JUST_RAW_STRING, width - WD_FRAMERECT_LEFT - WD_FRAMERECT_RIGHT); } diff --git a/src/widgets/dropdown.cpp b/src/widgets/dropdown.cpp index 8f4a8634ee..4b89b48092 100644 --- a/src/widgets/dropdown.cpp +++ b/src/widgets/dropdown.cpp @@ -65,7 +65,7 @@ StringID DropDownListParamStringItem::String() const StringID DropDownListCharStringItem::String() const { - SetDParamStr(0, this->raw_string.c_str()); + SetDParamStr(0, this->raw_string); return this->string; } From cb89d22cf248841f93d257983770a08aa0a64561 Mon Sep 17 00:00:00 2001 From: rubidium42 Date: Thu, 6 May 2021 16:32:57 +0200 Subject: [PATCH 21/22] Codechange: add DrawString(Multiline) that accepts std::string& --- src/gfx.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/gfx_func.h | 2 ++ src/industry_gui.cpp | 4 ++-- 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/src/gfx.cpp b/src/gfx.cpp index 1f4b40a54c..a4bac6e13f 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -656,6 +656,28 @@ int DrawString(int left, int right, int top, const char *str, TextColour colour, return DrawLayoutLine(*layout.front(), top, left, right, align, underline, true); } +/** + * Draw string, possibly truncated to make it fit in its allocated space + * + * @param left The left most position to draw on. + * @param right The right most position to draw on. + * @param top The top most position to draw on. + * @param str String to draw. + * @param colour Colour used for drawing the string, for details see _string_colourmap in + * table/palettes.h or docs/ottd-colourtext-palette.png or the enum TextColour in gfx_type.h + * @param align The alignment of the string when drawing left-to-right. In the + * case a right-to-left language is chosen this is inverted so it + * will be drawn in the right direction. + * @param underline Whether to underline what has been drawn or not. + * @param fontsize The size of the initial characters. + * @return In case of left or center alignment the right most pixel we have drawn to. + * In case of right alignment the left most pixel we have drawn to. + */ +int DrawString(int left, int right, int top, const std::string &str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize) +{ + return DrawString(left, right, top, str.c_str(), colour, align, underline, fontsize); +} + /** * Draw string, possibly truncated to make it fit in its allocated space * @@ -806,6 +828,28 @@ int DrawStringMultiLine(int left, int right, int top, int bottom, const char *st return ((align & SA_VERT_MASK) == SA_BOTTOM) ? first_line : last_line; } + +/** + * Draw string, possibly over multiple lines. + * + * @param left The left most position to draw on. + * @param right The right most position to draw on. + * @param top The top most position to draw on. + * @param bottom The bottom most position to draw on. + * @param str String to draw. + * @param colour Colour used for drawing the string, for details see _string_colourmap in + * table/palettes.h or docs/ottd-colourtext-palette.png or the enum TextColour in gfx_type.h + * @param align The horizontal and vertical alignment of the string. + * @param underline Whether to underline all strings + * @param fontsize The size of the initial characters. + * + * @return If \a align is #SA_BOTTOM, the top to where we have written, else the bottom to where we have written. + */ +int DrawStringMultiLine(int left, int right, int top, int bottom, const std::string &str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize) +{ + return DrawStringMultiLine(left, right, top, bottom, str.c_str(), colour, align, underline, fontsize); +} + /** * Draw string, possibly over multiple lines. * diff --git a/src/gfx_func.h b/src/gfx_func.h index 18b1966f9b..3deb4f3eb6 100644 --- a/src/gfx_func.h +++ b/src/gfx_func.h @@ -92,8 +92,10 @@ void DrawSpriteViewport(SpriteID img, PaletteID pal, int x, int y, const SubSpri void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub = nullptr, ZoomLevel zoom = ZOOM_LVL_GUI); int DrawString(int left, int right, int top, const char *str, TextColour colour = TC_FROMSTRING, StringAlignment align = SA_LEFT, bool underline = false, FontSize fontsize = FS_NORMAL); +int DrawString(int left, int right, int top, const std::string &str, TextColour colour = TC_FROMSTRING, StringAlignment align = SA_LEFT, bool underline = false, FontSize fontsize = FS_NORMAL); int DrawString(int left, int right, int top, StringID str, TextColour colour = TC_FROMSTRING, StringAlignment align = SA_LEFT, bool underline = false, FontSize fontsize = FS_NORMAL); int DrawStringMultiLine(int left, int right, int top, int bottom, const char *str, TextColour colour = TC_FROMSTRING, StringAlignment align = (SA_TOP | SA_LEFT), bool underline = false, FontSize fontsize = FS_NORMAL); +int DrawStringMultiLine(int left, int right, int top, int bottom, const std::string &str, TextColour colour = TC_FROMSTRING, StringAlignment align = (SA_TOP | SA_LEFT), bool underline = false, FontSize fontsize = FS_NORMAL); int DrawStringMultiLine(int left, int right, int top, int bottom, StringID str, TextColour colour = TC_FROMSTRING, StringAlignment align = (SA_TOP | SA_LEFT), bool underline = false, FontSize fontsize = FS_NORMAL); void DrawCharCentered(WChar c, const Rect &r, TextColour colour); diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index d0c916ef7c..147d4dc777 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -572,12 +572,12 @@ public: /* Draw the accepted cargoes, if any. Otherwise, will print "Nothing". */ GetAllCargoSuffixes(CARGOSUFFIX_IN, CST_FUND, nullptr, this->selected_type, indsp, indsp->accepts_cargo, cargo_suffix); std::string cargostring = this->MakeCargoListString(indsp->accepts_cargo, cargo_suffix, lengthof(indsp->accepts_cargo), STR_INDUSTRY_VIEW_REQUIRES_N_CARGO); - y = DrawStringMultiLine(left, right, y, bottom, cargostring.c_str()); + y = DrawStringMultiLine(left, right, y, bottom, cargostring); /* Draw the produced cargoes, if any. Otherwise, will print "Nothing". */ GetAllCargoSuffixes(CARGOSUFFIX_OUT, CST_FUND, nullptr, this->selected_type, indsp, indsp->produced_cargo, cargo_suffix); cargostring = this->MakeCargoListString(indsp->produced_cargo, cargo_suffix, lengthof(indsp->produced_cargo), STR_INDUSTRY_VIEW_PRODUCES_N_CARGO); - y = DrawStringMultiLine(left, right, y, bottom, cargostring.c_str()); + y = DrawStringMultiLine(left, right, y, bottom, cargostring); /* Get the additional purchase info text, if it has not already been queried. */ if (HasBit(indsp->callback_mask, CBM_IND_FUND_MORE_TEXT)) { From f1dfa661a1898cde06a38ab4cb230c95912b245b Mon Sep 17 00:00:00 2001 From: rubidium42 Date: Thu, 6 May 2021 16:19:00 +0200 Subject: [PATCH 22/22] Codechange: [Network] Use std::string for NetworkGameInfo --- src/network/core/game_info.cpp | 10 +++++----- src/network/core/game_info.h | 32 ++++++++++++++++---------------- src/network/network.cpp | 6 +++--- src/network/network_gamelist.cpp | 6 +++--- src/network/network_gui.cpp | 6 +++--- src/network/network_udp.cpp | 4 ++-- 6 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/network/core/game_info.cpp b/src/network/core/game_info.cpp index 47e6f221ef..f7044a3fce 100644 --- a/src/network/core/game_info.cpp +++ b/src/network/core/game_info.cpp @@ -112,7 +112,7 @@ bool IsNetworkCompatibleVersion(const char *other) void CheckGameCompatibility(NetworkGameInfo &ngi) { /* Check if we are allowed on this server based on the revision-check. */ - ngi.version_compatible = IsNetworkCompatibleVersion(ngi.server_revision); + ngi.version_compatible = IsNetworkCompatibleVersion(ngi.server_revision.c_str()); ngi.compatible = ngi.version_compatible; /* Check if we have all the GRFs on the client-system too. */ @@ -138,8 +138,8 @@ void FillStaticNetworkServerGameInfo() _network_game_info.dedicated = _network_dedicated; _network_game_info.grfconfig = _grfconfig; - strecpy(_network_game_info.server_name, _settings_client.network.server_name, lastof(_network_game_info.server_name)); - strecpy(_network_game_info.server_revision, GetNetworkRevisionString(), lastof(_network_game_info.server_revision)); + _network_game_info.server_name = _settings_client.network.server_name; + _network_game_info.server_revision = GetNetworkRevisionString(); } /** @@ -295,8 +295,8 @@ void DeserializeNetworkGameInfo(Packet *p, NetworkGameInfo *info) FALLTHROUGH; case 1: - p->Recv_string(info->server_name, sizeof(info->server_name)); - p->Recv_string(info->server_revision, sizeof(info->server_revision)); + info->server_name = p->Recv_string(NETWORK_NAME_LENGTH); + info->server_revision = p->Recv_string(NETWORK_REVISION_LENGTH); p->Recv_uint8 (); // Used to contain server-lang. info->use_password = p->Recv_bool (); info->clients_max = p->Recv_uint8 (); diff --git a/src/network/core/game_info.h b/src/network/core/game_info.h index ef83e4d053..668b9801da 100644 --- a/src/network/core/game_info.h +++ b/src/network/core/game_info.h @@ -60,22 +60,22 @@ * The game information that is sent from the server to the client. */ struct NetworkServerGameInfo { - GRFConfig *grfconfig; ///< List of NewGRF files used - Date start_date; ///< When the game started - Date game_date; ///< Current date - uint16 map_width; ///< Map width - uint16 map_height; ///< Map height - char server_name[NETWORK_NAME_LENGTH]; ///< Server name - char server_revision[NETWORK_REVISION_LENGTH]; ///< The version number the server is using (e.g.: 'r304' or 0.5.0) - bool dedicated; ///< Is this a dedicated server? - bool use_password; ///< Is this server passworded? - byte clients_on; ///< Current count of clients on server - byte clients_max; ///< Max clients allowed on server - byte companies_on; ///< How many started companies do we have - byte companies_max; ///< Max companies allowed on server - byte spectators_on; ///< How many spectators do we have? - byte spectators_max; ///< Max spectators allowed on server - byte landscape; ///< The used landscape + GRFConfig *grfconfig; ///< List of NewGRF files used + Date start_date; ///< When the game started + Date game_date; ///< Current date + uint16 map_width; ///< Map width + uint16 map_height; ///< Map height + std::string server_name; ///< Server name + std::string server_revision; ///< The version number the server is using (e.g.: 'r304' or 0.5.0) + bool dedicated; ///< Is this a dedicated server? + bool use_password; ///< Is this server passworded? + byte clients_on; ///< Current count of clients on server + byte clients_max; ///< Max clients allowed on server + byte companies_on; ///< How many started companies do we have + byte companies_max; ///< Max companies allowed on server + byte spectators_on; ///< How many spectators do we have? + byte spectators_max; ///< Max spectators allowed on server + byte landscape; ///< The used landscape }; /** diff --git a/src/network/network.cpp b/src/network/network.cpp index a90f8197e7..83a93a22ea 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -656,9 +656,9 @@ NetworkGameList *NetworkAddServer(const std::string &connection_string) /* Ensure the item already exists in the list */ NetworkGameList *item = NetworkGameListAddItem(connection_string); - if (StrEmpty(item->info.server_name)) { + if (item->info.server_name.empty()) { ClearGRFConfigList(&item->info.grfconfig); - strecpy(item->info.server_name, connection_string.c_str(), lastof(item->info.server_name)); + item->info.server_name = connection_string; item->manually = true; NetworkRebuildHostList(); @@ -1163,7 +1163,7 @@ void NetworkStartUp() /* Generate an server id when there is none yet */ if (StrEmpty(_settings_client.network.network_id)) NetworkGenerateServerId(); - memset(&_network_game_info, 0, sizeof(_network_game_info)); + _network_game_info = {}; NetworkInitialize(); DEBUG(net, 3, "[core] network online, multiplayer available"); diff --git a/src/network/network_gamelist.cpp b/src/network/network_gamelist.cpp index e4e2d17412..20fbb19a7c 100644 --- a/src/network/network_gamelist.cpp +++ b/src/network/network_gamelist.cpp @@ -47,10 +47,10 @@ static void NetworkGameListHandleDelayedInsert() NetworkGameList *item = NetworkGameListAddItem(ins_item->connection_string); if (item != nullptr) { - if (StrEmpty(item->info.server_name)) { + if (item->info.server_name.empty()) { ClearGRFConfigList(&item->info.grfconfig); - memset(&item->info, 0, sizeof(item->info)); - strecpy(item->info.server_name, ins_item->info.server_name, lastof(item->info.server_name)); + item->info = {}; + item->info.server_name = ins_item->info.server_name; item->online = false; } item->manually |= ins_item->manually; diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index 526f141cde..cf16d06b13 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -271,7 +271,7 @@ protected: /** Sort servers by name. */ static bool NGameNameSorter(NetworkGameList * const &a, NetworkGameList * const &b) { - int r = strnatcmp(a->info.server_name, b->info.server_name, true); // Sort by name (natural sorting). + int r = strnatcmp(a->info.server_name.c_str(), b->info.server_name.c_str(), true); // Sort by name (natural sorting). if (r == 0) r = a->connection_string.compare(b->connection_string); return r < 0; @@ -324,7 +324,7 @@ protected: static bool NGameAllowedSorter(NetworkGameList * const &a, NetworkGameList * const &b) { /* The servers we do not know anything about (the ones that did not reply) should be at the bottom) */ - int r = StrEmpty(a->info.server_revision) - StrEmpty(b->info.server_revision); + int r = a->info.server_revision.empty() - b->info.server_revision.empty(); /* Reverse default as we are interested in version-compatible clients first */ if (r == 0) r = b->info.version_compatible - a->info.version_compatible; @@ -361,7 +361,7 @@ protected: assert((*item) != nullptr); sf.ResetState(); - sf.AddLine((*item)->info.server_name); + sf.AddLine((*item)->info.server_name.c_str()); return sf.GetState(); } diff --git a/src/network/network_udp.cpp b/src/network/network_udp.cpp index 4e4f4a37e7..8a95596c17 100644 --- a/src/network/network_udp.cpp +++ b/src/network/network_udp.cpp @@ -91,7 +91,7 @@ static void DoNetworkUDPQueryServer(const std::string &connection_string, bool n { /* Clear item in gamelist */ NetworkGameList *item = new NetworkGameList(connection_string, manually); - strecpy(item->info.server_name, connection_string.c_str(), lastof(item->info.server_name)); + item->info.server_name = connection_string; NetworkGameListAddItemDelayed(item); std::unique_lock lock(_udp_client.mutex, std::defer_lock); @@ -362,7 +362,7 @@ void ClientNetworkUDPSocketHandler::Receive_SERVER_RESPONSE(Packet *p, NetworkAd } if (client_addr->GetAddress()->ss_family == AF_INET6) { - strecat(item->info.server_name, " (IPv6)", lastof(item->info.server_name)); + item->info.server_name.append(" (IPv6)"); } UpdateNetworkGameWindow();