Changeset - r25832:31ae4f709a39
[Not reviewed]
master
0 6 0
Loïc Guilloux - 3 years ago 2021-07-17 10:48:35
glx22@users.noreply.github.com
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.
6 files changed with 77 insertions and 18 deletions:
0 comments (0 inline, 0 general)
src/fios.cpp
Show inline comments
 
@@ -19,12 +19,13 @@
 
#include "string_func.h"
 
#include "strings_func.h"
 
#include "tar_type.h"
 
#include <sys/stat.h>
 
#include <functional>
 
#include <optional>
 
#include <charconv>
 

	
 
#ifndef _WIN32
 
# include <unistd.h>
 
#endif /* _WIN32 */
 

	
 
#include "table/strings.h"
 
@@ -742,6 +743,62 @@ bool HasScenario(const ContentInfo *ci, 
 
 * Force a (re)scan of the scenarios.
 
 */
 
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<std::string> _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 "<prefix><number>.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 "-<prefix>.sav".
 
*/
 
std::string FiosNumberedSaveName::Extension()
 
{
 
	return fmt::format("-{}.sav", this->prefix);
 
}
src/fios.h
Show inline comments
 
@@ -122,7 +122,19 @@ StringID FiosGetDescText(const char **pa
 
bool FiosDelete(const char *name);
 
std::string FiosMakeHeightmapName(const char *name);
 
std::string FiosMakeSavegameName(const char *name);
 

	
 
FiosType FiosGetSavegameListCallback(SaveLoadOperation fop, const std::string &file, const char *ext, char *title, const char *last);
 

	
 
/**
 
 * A savegame name automatically numbered.
 
 */
 
struct FiosNumberedSaveName {
 
	FiosNumberedSaveName(const std::string &prefix);
 
	std::string Filename();
 
	std::string Extension();
 
private:
 
	std::string prefix;
 
	int number;
 
};
 

	
 
#endif /* FIOS_H */
src/network/network_client.cpp
Show inline comments
 
@@ -129,14 +129,14 @@ struct PacketReader : LoadFilter {
 

	
 
/**
 
 * Create an emergency savegame when the network connection is lost.
 
 */
 
void ClientNetworkEmergencySave()
 
{
 
	static int _netsave_ctr = 0;
 
	DoAutoOrNetsave(_netsave_ctr, true);
 
	static FiosNumberedSaveName _netsave_ctr("netsave");
 
	DoAutoOrNetsave(_netsave_ctr);
 
}
 

	
 

	
 
/**
 
 * Create a new socket for the client side of the game connection.
 
 * @param s The socket to connect with.
src/openttd.cpp
Show inline comments
 
@@ -1390,13 +1390,13 @@ void StateGameLoop()
 
/**
 
 * Create an autosave. The default name is "autosave#.sav". However with
 
 * the setting 'keep_all_autosave' the name defaults to company-name + date
 
 */
 
static void DoAutosave()
 
{
 
	static int _autosave_ctr = 0;
 
	static FiosNumberedSaveName _autosave_ctr("autosave");
 
	DoAutoOrNetsave(_autosave_ctr);
 
}
 

	
 
/**
 
 * Request a new NewGRF scan. This will be executed on the next game-tick.
 
 * This is mostly needed to ensure NewGRF scans (which are blocking) are
src/saveload/saveload.cpp
Show inline comments
 
@@ -3325,32 +3325,21 @@ SaveOrLoadResult SaveOrLoad(const std::s
 

	
 
/**
 
 * Create an autosave or netsave.
 
 * @param counter A reference to the counter variable to be used for rotating the file name.
 
 * @param netsave Indicates if this is a regular autosave or a netsave.
 
 */
 
void DoAutoOrNetsave(int &counter, bool netsave)
 
void DoAutoOrNetsave(FiosNumberedSaveName &counter)
 
{
 
	char buf[MAX_PATH];
 

	
 
	if (_settings_client.gui.keep_all_autosave) {
 
		GenerateDefaultSaveName(buf, lastof(buf));
 
		if (!netsave) {
 
			strecat(buf, ".sav", lastof(buf));
 
		} else {
 
			strecat(buf, "-netsave.sav", lastof(buf));
 
		}
 
		strecat(buf, counter.Extension().c_str(), lastof(buf));
 
	} else {
 
		/* Generate a savegame name and number according to _settings_client.gui.max_num_autosaves. */
 
		if (!netsave) {
 
			seprintf(buf, lastof(buf), "autosave%d.sav", counter);
 
		} else {
 
			seprintf(buf, lastof(buf), "netsave%d.sav", counter);
 
		}
 

	
 
		if (++counter >= _settings_client.gui.max_num_autosaves) counter = 0;
 
		strecpy(buf, counter.Filename().c_str(), lastof(buf));
 
	}
 

	
 
	Debug(sl, 2, "Autosaving to '{}'", buf);
 
	if (SaveOrLoad(buf, SLO_SAVE, DFT_GAME_FILE, AUTOSAVE_DIR) != SL_OK) {
 
		ShowErrorMessage(STR_ERROR_AUTOSAVE_FAILED, INVALID_STRING_ID, WL_ERROR);
 
	}
src/saveload/saveload.h
Show inline comments
 
@@ -8,12 +8,13 @@
 
/** @file saveload.h Functions/types related to saving and loading games. */
 

	
 
#ifndef SAVELOAD_H
 
#define SAVELOAD_H
 

	
 
#include "../fileio_type.h"
 
#include "../fios.h"
 
#include "../strings_type.h"
 
#include "../core/span_type.hpp"
 
#include <optional>
 
#include <string>
 
#include <vector>
 

	
 
@@ -378,13 +379,13 @@ void SetSaveLoadError(StringID str);
 
const char *GetSaveLoadErrorString();
 
SaveOrLoadResult SaveOrLoad(const std::string &filename, SaveLoadOperation fop, DetailedFileType dft, Subdirectory sb, bool threaded = true);
 
void WaitTillSaved();
 
void ProcessAsyncSaveFinish();
 
void DoExitSave();
 

	
 
void DoAutoOrNetsave(int &counter, bool netsave = false);
 
void DoAutoOrNetsave(FiosNumberedSaveName &counter);
 

	
 
SaveOrLoadResult SaveWithFilter(struct SaveFilter *writer, bool threaded);
 
SaveOrLoadResult LoadWithFilter(struct LoadFilter *reader);
 

	
 
typedef void AutolengthProc(void *arg);
 

	
0 comments (0 inline, 0 general)