From 460991ecf4fbeca2c0f8c39874b39a0885d6f67d Mon Sep 17 00:00:00 2001 From: Loïc Guilloux Date: Sat, 17 Jul 2021 12:48:35 +0200 Subject: Feature: Persistant rotation of numbered auto/netsave after restart (#9397) It was always starting from 0 on openttd restart. Now the most recent auto/netsave number will be used as a base to generate the next filename. --- src/fios.cpp | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) (limited to 'src/fios.cpp') diff --git a/src/fios.cpp b/src/fios.cpp index c59bcfb21..0491c1e51 100644 --- a/src/fios.cpp +++ b/src/fios.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #ifndef _WIN32 # include @@ -745,3 +746,59 @@ void ScanScenarios() { _scanner.Scan(true); } + +/** + * Constructs FiosNumberedSaveName. Initial number is the most recent save, or -1 if not found. + * @param prefix The prefix to use to generate a filename. +*/ +FiosNumberedSaveName::FiosNumberedSaveName(const std::string &prefix) : prefix(prefix), number(-1) +{ + static std::optional _autosave_path; + if (!_autosave_path) _autosave_path = FioFindDirectory(AUTOSAVE_DIR); + + static std::string _prefix; ///< Static as the lambda needs access to it. + + /* Callback for FiosFileScanner. */ + static fios_getlist_callback_proc *proc = [](SaveLoadOperation fop, const std::string &file, const char *ext, char *title, const char *last) { + if (strcasecmp(ext, ".sav") == 0 && StrStartsWith(file, _prefix)) return FIOS_TYPE_FILE; + return FIOS_TYPE_INVALID; + }; + + /* Prefix to check in the callback. */ + _prefix = *_autosave_path + this->prefix; + + /* Get the save list. */ + FileList list; + FiosFileScanner scanner(SLO_SAVE, proc, list); + scanner.Scan(".sav", _autosave_path->c_str(), false); + + /* Find the number for the most recent save, if any. */ + if (list.begin() != list.end()) { + SortingBits order = _savegame_sort_order; + _savegame_sort_order = SORT_BY_DATE | SORT_DESCENDING; + std::sort(list.begin(), list.end()); + _savegame_sort_order = order; + + std::string_view name = list.begin()->title; + std::from_chars(name.data() + this->prefix.size(), name.data() + name.size(), this->number); + } +} + +/** + * Generate a savegame name and number according to _settings_client.gui.max_num_autosaves. + * @return A filename in format ".sav". +*/ +std::string FiosNumberedSaveName::Filename() +{ + if (++this->number >= _settings_client.gui.max_num_autosaves) this->number = 0; + return fmt::format("{}{}.sav", this->prefix, this->number); +} + +/** + * Generate an extension for a savegame name. + * @return An extension in format "-.sav". +*/ +std::string FiosNumberedSaveName::Extension() +{ + return fmt::format("-{}.sav", this->prefix); +} -- cgit v1.2.3-54-g00ecf