Quellcode durchsuchen

Merge pull request #2637 from Laserlicht/autosave

Nordsoft91 vor 2 Jahren
Ursprung
Commit
979cf129bc

+ 1 - 0
Global.h

@@ -108,6 +108,7 @@ static_assert(sizeof(bool) == 1, "Bool needs to be 1 byte in size.");
 #include <cassert>
 #include <climits>
 #include <cmath>
+#include <codecvt>
 #include <cstdlib>
 #include <cstdio>
 #include <fstream>

+ 13 - 5
client/CPlayerInterface.cpp

@@ -68,6 +68,7 @@
 #include "../lib/VCMIDirs.h"
 #include "../lib/CStopWatch.h"
 #include "../lib/StartInfo.h"
+#include "../lib/TextOperations.h"
 #include "../lib/CPlayerState.h"
 #include "../lib/GameConstants.h"
 #include "gui/CGuiHandler.h"
@@ -169,7 +170,7 @@ void CPlayerInterface::initGameInterface(std::shared_ptr<Environment> ENV, std::
 void CPlayerInterface::playerStartsTurn(PlayerColor player)
 {
 	EVENT_HANDLER_CALLED_BY_CLIENT;
-	
+
 	makingTurn = false;
 	stillMoveHero.setn(STOP_MOVE);
 
@@ -180,7 +181,7 @@ void CPlayerInterface::playerStartsTurn(PlayerColor player)
 		GH.windows().pushWindow(adventureInt);
 	}
 
-	//close window from another player
+	// close window from another player
 	if(auto w = GH.windows().topWindow<CInfoWindow>())
 		if(w->ID == -1 && player != playerID)
 			w->close();
@@ -212,7 +213,14 @@ void CPlayerInterface::performAutosave()
 			prefix = settings["general"]["savePrefix"].String();
 			if(prefix.empty())
 			{
-				prefix = cb->getMapHeader()->name.substr(0, 5) + "_";
+				std::string name = cb->getMapHeader()->name;
+				int txtlen = TextOperations::getUnicodeCharactersCount(name);
+
+				TextOperations::trimRightUnicode(name, std::max(0, txtlen - 15));
+				std::string forbiddenChars("\\/:?\"<>| ");
+				std::replace_if(name.begin(), name.end(), [&](char c) { return std::string::npos != forbiddenChars.find(c); }, '_' );
+
+				prefix = name + "_" + cb->getStartInfo()->startTimeIso8601 + "/";
 			}
 		}
 
@@ -221,7 +229,7 @@ void CPlayerInterface::performAutosave()
 		int autosaveCountLimit = settings["general"]["autosaveCountLimit"].Integer();
 		if(autosaveCountLimit > 0)
 		{
-			cb->save("Saves/" + prefix + "Autosave_" + std::to_string(autosaveCount));
+			cb->save("Saves/Autosave/" + prefix + std::to_string(autosaveCount));
 			autosaveCount %= autosaveCountLimit;
 		}
 		else
@@ -230,7 +238,7 @@ void CPlayerInterface::performAutosave()
 					+ std::to_string(cb->getDate(Date::WEEK))
 					+ std::to_string(cb->getDate(Date::DAY_OF_WEEK));
 
-			cb->save("Saves/" + prefix + "Autosave_" + stringifiedDate);
+			cb->save("Saves/Autosave/" + prefix + stringifiedDate);
 		}
 	}
 }

+ 1 - 1
config/schemas/settings.json

@@ -117,7 +117,7 @@
 				},
 				"useSavePrefix" : {
 					"type": "boolean",
-					"default": false
+					"default": true
 				},
 				"savePrefix" : {
 					"type": "string",

+ 1 - 0
include/vstd/DateUtils.h

@@ -6,6 +6,7 @@ namespace vstd
 {
 
 	DLL_LINKAGE std::string getFormattedDateTime(std::time_t dt);
+	DLL_LINKAGE std::string getDateTimeISO8601Basic(std::time_t dt);
 
 }
 

+ 5 - 1
lib/StartInfo.h

@@ -9,6 +9,8 @@
  */
 #pragma once
 
+#include "vstd/DateUtils.h"
+
 #include "GameConstants.h"
 #include "TurnTimerInfo.h"
 #include "campaign/CampaignConstants.h"
@@ -81,6 +83,7 @@ struct DLL_LINKAGE StartInfo
 	ui32 seedToBeUsed; //0 if not sure (client requests server to decide, will be send in reply pack)
 	ui32 seedPostInit; //so we know that game is correctly synced at the start; 0 if not known yet
 	ui32 mapfileChecksum; //0 if not relevant
+	std::string startTimeIso8601;
 	TurnTimerInfo turnTimerInfo;
 	std::string mapname; // empty for random map, otherwise name of the map or savegame
 	bool createRandomMap() const { return mapGenOptions != nullptr; }
@@ -104,6 +107,7 @@ struct DLL_LINKAGE StartInfo
 		h & seedToBeUsed;
 		h & seedPostInit;
 		h & mapfileChecksum;
+		h & startTimeIso8601;
 		h & turnTimerInfo;
 		h & mapname;
 		h & mapGenOptions;
@@ -111,7 +115,7 @@ struct DLL_LINKAGE StartInfo
 	}
 
 	StartInfo() : mode(INVALID), difficulty(1), seedToBeUsed(0), seedPostInit(0),
-		mapfileChecksum(0)
+		mapfileChecksum(0), startTimeIso8601(vstd::getDateTimeISO8601Basic(std::time(0)))
 	{
 
 	}

+ 6 - 0
lib/TextOperations.cpp

@@ -193,6 +193,12 @@ void TextOperations::trimRightUnicode(std::string & text, const size_t amount)
 	}
 }
 
+size_t TextOperations::getUnicodeCharactersCount(const std::string & text)
+{
+	std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> conv;
+	return conv.from_bytes(text).size(); 
+}
+
 std::string TextOperations::escapeString(std::string input)
 {
 	boost::replace_all(input, "\\", "\\\\");

+ 3 - 0
lib/TextOperations.h

@@ -46,6 +46,9 @@ namespace TextOperations
 	///delete specified amount of UTF-8 characters from right
 	DLL_LINKAGE void trimRightUnicode(std::string & text, size_t amount = 1);
 
+	/// give back amount of unicode characters
+	size_t DLL_LINKAGE getUnicodeCharactersCount(const std::string & text);
+
 	/// converts number into string using metric system prefixes, e.g. 'k' or 'M' to keep resulting strings within specified size
 	/// Note that resulting string may have more symbols than digits: minus sign and prefix symbol
 	template<typename Arithmetic>

+ 2 - 2
lib/serializer/CSerializer.h

@@ -14,8 +14,8 @@
 
 VCMI_LIB_NAMESPACE_BEGIN
 
-const ui32 SERIALIZATION_VERSION = 825;
-const ui32 MINIMAL_SERIALIZATION_VERSION = 824;
+const ui32 SERIALIZATION_VERSION = 826;
+const ui32 MINIMAL_SERIALIZATION_VERSION = 826;
 const std::string SAVEGAME_MAGIC = "VCMISVG";
 
 class CHero;

+ 8 - 0
lib/vstd/DateUtils.cpp

@@ -22,6 +22,14 @@ namespace vstd
 		return s.str();
 	}
 
+	DLL_LINKAGE std::string getDateTimeISO8601Basic(std::time_t dt)
+	{
+		std::tm tm = *std::localtime(&dt);
+		std::stringstream s;
+		s << std::put_time(&tm, "%Y%m%dT%H%M%S");
+		return s.str();
+	}
+
 }
 
 VCMI_LIB_NAMESPACE_END

+ 2 - 0
server/CVCMIServer.cpp

@@ -307,6 +307,7 @@ bool CVCMIServer::prepareToStartGame()
 	{
 	case StartInfo::CAMPAIGN:
 		logNetwork->info("Preparing to start new campaign");
+		si->startTimeIso8601 = vstd::getDateTimeISO8601Basic(std::time(0));
 		si->campState->setCurrentMap(campaignMap);
 		si->campState->setCurrentMapBonus(campaignBonus);
 		gh->init(si.get(), progressTracking);
@@ -314,6 +315,7 @@ bool CVCMIServer::prepareToStartGame()
 
 	case StartInfo::NEW_GAME:
 		logNetwork->info("Preparing to start new game");
+		si->startTimeIso8601 = vstd::getDateTimeISO8601Basic(std::time(0));
 		gh->init(si.get(), progressTracking);
 		break;