diff --git a/src/ai/ai_scanner.cpp b/src/ai/ai_scanner.cpp index 89dea93185..150aafd34d 100644 --- a/src/ai/ai_scanner.cpp +++ b/src/ai/ai_scanner.cpp @@ -92,39 +92,35 @@ AIInfo *AIScannerInfo::SelectRandomAI() const #undef GetAIInfo } -AIInfo *AIScannerInfo::FindInfo(const char *nameParam, int versionParam, bool force_exact_match) +AIInfo *AIScannerInfo::FindInfo(const char *name, int version, bool force_exact_match) { if (this->info_list.size() == 0) return nullptr; - if (nameParam == nullptr) return nullptr; + if (name == nullptr) return nullptr; - char ai_name[1024]; - strecpy(ai_name, nameParam, lastof(ai_name)); - strtolower(ai_name); - - if (versionParam == -1) { + if (version == -1) { /* We want to load the latest version of this AI; so find it */ - if (this->info_single_list.find(ai_name) != this->info_single_list.end()) return static_cast(this->info_single_list[ai_name]); + auto it = this->info_single_list.find(name); + if (it != this->info_single_list.end()) return static_cast(it->second); return nullptr; } if (force_exact_match) { /* Try to find a direct 'name.version' match */ - char ai_name_tmp[1024]; - seprintf(ai_name_tmp, lastof(ai_name_tmp), "%s.%d", ai_name, versionParam); - strtolower(ai_name_tmp); - if (this->info_list.find(ai_name_tmp) != this->info_list.end()) return static_cast(this->info_list[ai_name_tmp]); + std::string name_with_version = fmt::format("{}.{}", name, version); + auto it = this->info_list.find(name_with_version); + if (it != this->info_list.end()) return static_cast(it->second); return nullptr; } AIInfo *info = nullptr; - int version = -1; + int highest_version = -1; /* See if there is a compatible AI which goes by that name, with the highest * version which allows loading the requested version */ for (const auto &item : this->info_list) { AIInfo *i = static_cast(item.second); - if (StrEqualsIgnoreCase(ai_name, i->GetName()) && i->CanLoadFromVersion(versionParam) && (version == -1 || i->GetVersion() > version)) { - version = item.second->GetVersion(); + if (StrEqualsIgnoreCase(name, i->GetName()) && i->CanLoadFromVersion(version) && (highest_version == -1 || i->GetVersion() > highest_version)) { + highest_version = item.second->GetVersion(); info = i; } } @@ -152,9 +148,7 @@ void AIScannerLibrary::RegisterAPI(class Squirrel *engine) AILibrary *AIScannerLibrary::FindLibrary(const char *library, int version) { /* Internally we store libraries as 'library.version' */ - char library_name[1024]; - seprintf(library_name, lastof(library_name), "%s.%d", library, version); - strtolower(library_name); + std::string library_name = fmt::format("{}.{}", library, version); /* Check if the library + version exists */ ScriptInfoList::iterator it = this->info_list.find(library_name); diff --git a/src/ai/ai_scanner.hpp b/src/ai/ai_scanner.hpp index fafd585e75..4a6a065142 100644 --- a/src/ai/ai_scanner.hpp +++ b/src/ai/ai_scanner.hpp @@ -27,12 +27,12 @@ public: /** * Check if we have an AI by name and version available in our list. - * @param nameParam The name of the AI. - * @param versionParam The version of the AI, or -1 if you want the latest. + * @param name The name of the AI. + * @param version The version of the AI, or -1 if you want the latest. * @param force_exact_match Only match name+version, never latest. * @return nullptr if no match found, otherwise the AI that matched. */ - class AIInfo *FindInfo(const char *nameParam, int versionParam, bool force_exact_match); + class AIInfo *FindInfo(const char *name, int version, bool force_exact_match); /** * Set the Dummy AI. diff --git a/src/game/game_scanner.cpp b/src/game/game_scanner.cpp index 030a078220..85b2a77ea5 100644 --- a/src/game/game_scanner.cpp +++ b/src/game/game_scanner.cpp @@ -33,39 +33,35 @@ void GameScannerInfo::RegisterAPI(class Squirrel *engine) GameInfo::RegisterAPI(engine); } -GameInfo *GameScannerInfo::FindInfo(const char *nameParam, int versionParam, bool force_exact_match) +GameInfo *GameScannerInfo::FindInfo(const char *name, int version, bool force_exact_match) { if (this->info_list.size() == 0) return nullptr; - if (nameParam == nullptr) return nullptr; + if (name == nullptr) return nullptr; - char game_name[1024]; - strecpy(game_name, nameParam, lastof(game_name)); - strtolower(game_name); - - if (versionParam == -1) { + if (version == -1) { /* We want to load the latest version of this Game script; so find it */ - if (this->info_single_list.find(game_name) != this->info_single_list.end()) return static_cast(this->info_single_list[game_name]); + auto it = this->info_single_list.find(name); + if (it != this->info_single_list.end()) return static_cast(it->second); return nullptr; } if (force_exact_match) { /* Try to find a direct 'name.version' match */ - char game_name_tmp[1024]; - seprintf(game_name_tmp, lastof(game_name_tmp), "%s.%d", game_name, versionParam); - strtolower(game_name_tmp); - if (this->info_list.find(game_name_tmp) != this->info_list.end()) return static_cast(this->info_list[game_name_tmp]); + std::string name_with_version = fmt::format("{}.{}", name, version); + auto it = this->info_list.find(name_with_version); + if (it != this->info_list.end()) return static_cast(it->second); return nullptr; } GameInfo *info = nullptr; - int version = -1; + int highest_version = -1; /* See if there is a compatible Game script which goes by that name, with the highest * version which allows loading the requested version */ for (const auto &item : this->info_list) { GameInfo *i = static_cast(item.second); - if (StrEqualsIgnoreCase(game_name, i->GetName()) && i->CanLoadFromVersion(versionParam) && (version == -1 || i->GetVersion() > version)) { - version = item.second->GetVersion(); + if (StrEqualsIgnoreCase(name, i->GetName()) && i->CanLoadFromVersion(version) && (highest_version == -1 || i->GetVersion() > highest_version)) { + highest_version = item.second->GetVersion(); info = i; } } @@ -93,9 +89,7 @@ void GameScannerLibrary::RegisterAPI(class Squirrel *engine) GameLibrary *GameScannerLibrary::FindLibrary(const char *library, int version) { /* Internally we store libraries as 'library.version' */ - char library_name[1024]; - seprintf(library_name, lastof(library_name), "%s.%d", library, version); - strtolower(library_name); + std::string library_name = fmt::format("{}.{}", library, version); /* Check if the library + version exists */ ScriptInfoList::iterator it = this->info_list.find(library_name); diff --git a/src/game/game_scanner.hpp b/src/game/game_scanner.hpp index 0608581504..c0628fc6a7 100644 --- a/src/game/game_scanner.hpp +++ b/src/game/game_scanner.hpp @@ -18,12 +18,12 @@ public: /** * Check if we have a game by name and version available in our list. - * @param nameParam The name of the game script. - * @param versionParam The version of the game script, or -1 if you want the latest. + * @param name The name of the game script. + * @param version The version of the game script, or -1 if you want the latest. * @param force_exact_match Only match name+version, never latest. * @return nullptr if no match found, otherwise the game script that matched. */ - class GameInfo *FindInfo(const char *nameParam, int versionParam, bool force_exact_match); + class GameInfo *FindInfo(const char *name, int version, bool force_exact_match); protected: std::string GetScriptName(ScriptInfo *info) override; diff --git a/src/script/api/script_controller.cpp b/src/script/api/script_controller.cpp index 23568df621..b226362376 100644 --- a/src/script/api/script_controller.cpp +++ b/src/script/api/script_controller.cpp @@ -76,16 +76,6 @@ ScriptController::ScriptController(CompanyID company) : ScriptObject::SetCompany(company); } -ScriptController::~ScriptController() -{ - for (const auto &item : this->loaded_library) { - free(item.second); - free(item.first); - } - - this->loaded_library.clear(); -} - /* static */ uint ScriptController::GetTick() { return ScriptObject::GetActiveInstance()->GetController()->ticks; @@ -120,24 +110,22 @@ ScriptController::~ScriptController() } /* Internally we store libraries as 'library.version' */ - char library_name[1024]; - seprintf(library_name, lastof(library_name), "%s.%d", library, version); - strtolower(library_name); + std::string library_name = fmt::format("{}.{}", library, version); /* Get the current table/class we belong to */ HSQOBJECT parent; sq_getstackobj(vm, 1, &parent); - char fake_class[1024]; + std::string fake_class; LoadedLibraryList::iterator it = controller->loaded_library.find(library_name); if (it != controller->loaded_library.end()) { - strecpy(fake_class, (*it).second, lastof(fake_class)); + fake_class = (*it).second; } else { int next_number = ++controller->loaded_library_count; /* Create a new fake internal name */ - seprintf(fake_class, lastof(fake_class), "_internalNA%d", next_number); + fake_class = fmt::format("_internalNA{}", next_number); /* Load the library in a 'fake' namespace, so we can link it to the name the user requested */ sq_pushroottable(vm); @@ -153,7 +141,7 @@ ScriptController::~ScriptController() sq_newslot(vm, -3, SQFalse); sq_pop(vm, 1); - controller->loaded_library[stredup(library_name)] = stredup(fake_class); + controller->loaded_library[library_name] = fake_class; } /* Find the real class inside the fake class (like 'sets.Vector') */ diff --git a/src/script/api/script_controller.hpp b/src/script/api/script_controller.hpp index 89d46f8c90..dd0c00e57b 100644 --- a/src/script/api/script_controller.hpp +++ b/src/script/api/script_controller.hpp @@ -55,11 +55,6 @@ public: */ ScriptController(CompanyID company); - /** - * Destructor of the ScriptController. - */ - ~ScriptController(); - #else /** * This function is called to start your script. Your script starts here. If you @@ -210,7 +205,7 @@ public: static HSQOBJECT Import(const char *library, const char *class_name, int version); private: - typedef std::map LoadedLibraryList; ///< The type for loaded libraries. + typedef std::map LoadedLibraryList; ///< The type for loaded libraries. uint ticks; ///< The amount of ticks we're sleeping. LoadedLibraryList loaded_library; ///< The libraries we loaded. diff --git a/src/script/script_config.cpp b/src/script/script_config.cpp index a36d7046f0..ee876ced9a 100644 --- a/src/script/script_config.cpp +++ b/src/script/script_config.cpp @@ -53,7 +53,7 @@ ScriptConfig::ScriptConfig(const ScriptConfig *config) this->to_load_data.reset(); for (const auto &item : config->settings) { - this->settings[stredup(item.first)] = item.second; + this->settings[item.first] = item.second; } /* Virtual functions get called statically in constructors, so make it explicit to remove any confusion. */ @@ -84,9 +84,6 @@ const ScriptConfigItemList *ScriptConfig::GetConfigList() void ScriptConfig::ClearConfigList() { - for (const auto &item : this->settings) { - free(item.first); - } this->settings.clear(); } @@ -116,19 +113,11 @@ void ScriptConfig::SetSetting(const char *name, int value) value = Clamp(value, config_item->min_value, config_item->max_value); - const auto it = this->settings.find(name); - if (it != this->settings.end()) { - (*it).second = value; - } else { - this->settings[stredup(name)] = value; - } + this->settings[name] = value; } void ScriptConfig::ResetSettings() { - for (const auto &item : this->settings) { - free(item.first); - } this->settings.clear(); } @@ -137,14 +126,13 @@ void ScriptConfig::ResetEditableSettings(bool yet_to_start) if (this->info == nullptr) return ResetSettings(); for (SettingValueList::iterator it = this->settings.begin(); it != this->settings.end();) { - const ScriptConfigItem *config_item = this->info->GetConfigItem(it->first); + const ScriptConfigItem *config_item = this->info->GetConfigItem(it->first.c_str()); assert(config_item != nullptr); bool editable = yet_to_start || (config_item->flags & SCRIPTCONFIG_INGAME) != 0; bool visible = _settings_client.gui.ai_developer_tools || (config_item->flags & SCRIPTCONFIG_DEVELOPER) == 0; if (editable && visible) { - free(it->first); it = this->settings.erase(it); } else { it++; @@ -209,29 +197,16 @@ void ScriptConfig::StringToSettings(const std::string &value) std::string ScriptConfig::SettingsToString() const { - char string[1024]; - char *last = lastof(string); - char *s = string; - *s = '\0'; + if (this->settings.empty()) return {}; + + std::string result; for (const auto &item : this->settings) { - char no[INT32_DIGITS_WITH_SIGN_AND_TERMINATION]; - seprintf(no, lastof(no), "%d", item.second); - - /* Check if the string would fit in the destination */ - size_t needed_size = strlen(item.first) + 1 + strlen(no); - /* If it doesn't fit, skip the next settings */ - if (s + needed_size > last) break; - - s = strecat(s, item.first, last); - s = strecat(s, "=", last); - s = strecat(s, no, last); - s = strecat(s, ",", last); + fmt::format_to(std::back_inserter(result), "{}={},", item.first, item.second); } - /* Remove the last ',', but only if at least one setting was saved. */ - if (s != string) s[-1] = '\0'; - - return string; + /* Remove the last ','. */ + result.resize(result.size() - 1); + return result; } std::optional ScriptConfig::GetTextfile(TextfileType type, CompanyID slot) const diff --git a/src/script/script_config.hpp b/src/script/script_config.hpp index 342d5ad362..c1034c3b9a 100644 --- a/src/script/script_config.hpp +++ b/src/script/script_config.hpp @@ -57,7 +57,7 @@ typedef std::list ScriptConfigItemList; ///< List of ScriptCon class ScriptConfig { protected: /** List with name=>value pairs of all script-specific settings */ - typedef std::map SettingValueList; + typedef std::map SettingValueList; public: ScriptConfig() : diff --git a/src/script/script_scanner.cpp b/src/script/script_scanner.cpp index fc1e734444..8dd88d3ff6 100644 --- a/src/script/script_scanner.cpp +++ b/src/script/script_scanner.cpp @@ -84,12 +84,8 @@ void ScriptScanner::RescanDir() void ScriptScanner::Reset() { for (const auto &item : this->info_list) { - free(item.first); delete item.second; } - for (const auto &item : this->info_single_list) { - free(item.first); - } this->info_list.clear(); this->info_single_list.clear(); @@ -128,15 +124,16 @@ void ScriptScanner::RegisterScript(ScriptInfo *info) return; } - this->info_list[stredup(script_name)] = info; + this->info_list[script_name] = info; if (!info->IsDeveloperOnly() || _settings_client.gui.ai_developer_tools) { /* Add the script to the 'unique' script list, where only the highest version * of the script is registered. */ - if (this->info_single_list.find(script_original_name) == this->info_single_list.end()) { - this->info_single_list[stredup(script_original_name)] = info; - } else if (this->info_single_list[script_original_name]->GetVersion() < info->GetVersion()) { + auto it = this->info_single_list.find(script_original_name); + if (it == this->info_single_list.end()) { this->info_single_list[script_original_name] = info; + } else if (it->second->GetVersion() < info->GetVersion()) { + it->second = info; } } } diff --git a/src/script/script_scanner.hpp b/src/script/script_scanner.hpp index 6d1cbf5b10..707eade0cd 100644 --- a/src/script/script_scanner.hpp +++ b/src/script/script_scanner.hpp @@ -12,9 +12,9 @@ #include #include "../fileio_func.h" -#include "../core/string_compare_type.hpp" +#include "../string_func.h" -typedef std::map ScriptInfoList; ///< Type for the list of scripts. +typedef std::map ScriptInfoList; ///< Type for the list of scripts. /** Scanner to help finding scripts. */ class ScriptScanner : public FileScanner {