Просмотр исходного кода

Merge pull request #6580 from IvanSavenko/before_visit_optional

[1.7.1?] Add option to disable before-visit save in Launcher
Ivan Savenko 1 месяц назад
Родитель
Сommit
d051247e91

+ 5 - 0
config/schemas/settings.json

@@ -40,6 +40,7 @@
 				"autosaveCountLimit",
 				"useSavePrefix",
 				"savePrefix",
+				"saveBeforeVisit",
 				"startTurnAutosave",
 				"enableUiEnhancements",
 				"audioMuteFocus",
@@ -113,6 +114,10 @@
 					"type" : "boolean",
 					"default" : false
 				},
+				"saveBeforeVisit" : {
+					"type" : "boolean",
+					"default" : true
+				},
 				"userRelativePointer" : {
 					"type" : "boolean",
 					"default" : false

+ 9 - 0
launcher/settingsView/csettingsview_moc.cpp

@@ -302,6 +302,8 @@ void CSettingsView::loadToggleButtonSettings()
 
 	setCheckbuttonState(ui->buttonIgnoreMuteSwitch, settings["general"]["ignoreMuteSwitch"].Bool());
 
+	setCheckbuttonState(ui->buttonSaveBeforeVisit, settings["general"]["saveBeforeVisit"].Bool());
+
 	std::string cursorType = settings["video"]["cursor"].String();
 	int cursorTypeIndex = vstd::find_pos(cursorTypesList, cursorType);
 	setCheckbuttonState(ui->buttonCursorType, cursorTypeIndex);
@@ -577,6 +579,13 @@ void CSettingsView::on_spinBoxNetworkPort_valueChanged(int arg1)
 	node->Float() = arg1;
 }
 
+void CSettingsView::on_buttonSaveBeforeVisit_toggled(bool value)
+{
+	Settings node = settings.write["general"]["saveBeforeVisit"];
+	node->Bool() = value;
+	updateCheckbuttonText(ui->buttonSaveBeforeVisit);
+}
+
 void CSettingsView::on_buttonShowIntro_toggled(bool value)
 {
 	Settings node = settings.write["video"]["showIntro"];

+ 1 - 0
launcher/settingsView/csettingsview_moc.h

@@ -48,6 +48,7 @@ private slots:
 	void on_comboBoxAlliedPlayerAI_currentIndexChanged(int index);
 	void on_comboBoxEnemyPlayerAI_currentIndexChanged(int index);
 	void on_spinBoxNetworkPort_valueChanged(int arg1);
+	void on_buttonSaveBeforeVisit_toggled(bool value);
 	void on_buttonShowIntro_toggled(bool value);
 	void on_buttonAllowPortrait_toggled(bool value);
 	void on_buttonAutoCheck_toggled(bool value);

Разница между файлами не показана из-за своего большого размера
+ 505 - 288
launcher/settingsView/csettingsview_moc.ui


+ 16 - 7
lib/serializer/CSaveFile.cpp

@@ -12,23 +12,32 @@
 
 VCMI_LIB_NAMESPACE_BEGIN
 
-CSaveFile::CSaveFile(const boost::filesystem::path &fname)
+CSaveFile::CSaveFile()
 	: serializer(this)
-	, sfile(fname.c_str(), std::ios::out | std::ios::binary)
 {
+	saveData.reserve(128*1024);
+	static const char * SAVE_HEADER = "VCMI";
+
+	write(reinterpret_cast<const std::byte*>(SAVE_HEADER), 4); //write magic identifier
+	serializer & ESerializationVersion::CURRENT; //write format version
+	write(reinterpret_cast<const std::byte*>(SAVEGAME_MAGIC.c_str()), SAVEGAME_MAGIC.length());
+}
+
+void CSaveFile::write(const boost::filesystem::path & fileName)
+{
+	std::ofstream sfile(fileName.c_str(), std::ios::out | std::ios::binary);
+
 	sfile.exceptions(std::ifstream::failbit | std::ifstream::badbit); //we throw a lot anyway
 
 	if(!sfile)
-		throw std::runtime_error("Error: cannot open file '" + fname.string() + "' for writing!");
+		throw std::runtime_error("Error: cannot open file '" + fileName.string() + "' for writing!");
 
-	sfile.write("VCMI", 4); //write magic identifier
-	serializer & ESerializationVersion::CURRENT; //write format version
-	sfile.write(SAVEGAME_MAGIC.c_str(), SAVEGAME_MAGIC.length());
+	sfile.write(reinterpret_cast<const char *>(saveData.data()), saveData.size());
 }
 
 int CSaveFile::write(const std::byte * data, unsigned size)
 {
-	sfile.write(reinterpret_cast<const char *>(data), size);
+	saveData.insert(saveData.end(), data, data + size);
 	return size;
 }
 

+ 9 - 2
lib/serializer/CSaveFile.h

@@ -17,12 +17,12 @@ VCMI_LIB_NAMESPACE_BEGIN
 class DLL_LINKAGE CSaveFile final : public IBinaryWriter
 {
 	BinarySerializer serializer;
-	std::fstream sfile;
+	std::vector<std::byte> saveData;
 
 	int write(const std::byte * data, unsigned size) final;
 
 public:
-	explicit CSaveFile(const boost::filesystem::path & fname); //throws!
+	CSaveFile();
 
 	template<class T>
 	void save(const T & data)
@@ -30,6 +30,13 @@ public:
 		static_assert(is_serializeable<BinarySerializer, T>::value, "This class can't be serialized (possible pointer?)");
 		serializer & data;
 	}
+
+	void write(const boost::filesystem::path & fname);
+
+	const std::vector<std::byte> & currentContent() const
+	{
+		return saveData;
+	}
 };
 
 VCMI_LIB_NAMESPACE_END

+ 7 - 3
server/CGameHandler.cpp

@@ -1001,7 +1001,10 @@ bool CGameHandler::moveHero(ObjectInstanceID hid, int3 dst, EMovementMode moveme
 		return false;
 	};
 
-	if (gameInfo().getPlayerState(h->getOwner())->human && (guardian || objectToVisit) && movementMode == EMovementMode::STANDARD)
+	if (settings["general"]["saveBeforeVisit"].Bool() &&
+		gameInfo().getPlayerState(h->getOwner())->human &&
+	   (guardian || objectToVisit) &&
+	   movementMode == EMovementMode::STANDARD)
 		save("Saves/BeforeVisitSave");
 
 	if (!transit && embarking)
@@ -1621,16 +1624,17 @@ void CGameHandler::save(const std::string & filename)
 
 	try
 	{
-		CSaveFile save(*CResourceHandler::get("local")->getResourceName(savePath));
+		CSaveFile save;
 		gameState().saveGame(save);
 		logGlobal->info("Saving server state");
 		save.save(*this);
-		logGlobal->info("Game has been successfully saved!");
+		save.write(*CResourceHandler::get("local")->getResourceName(savePath));
 	}
 	catch(std::exception &e)
 	{
 		logGlobal->error("Failed to save game: %s", e.what());
 	}
+	logGlobal->info("Game has been successfully saved!");
 }
 
 void CGameHandler::load(const StartInfo &info)

Некоторые файлы не были показаны из-за большого количества измененных файлов