Przeglądaj źródła

possibility to delete unsupported saves

Laserlicht 11 miesięcy temu
rodzic
commit
1f0847660b

+ 1 - 0
Mods/vcmi/config/english.json

@@ -106,6 +106,7 @@
 	"vcmi.lobby.handicap.resource" : "Gives players appropriate resources to start with in addition to the normal starting resources. Negative values are allowed, but are limited to 0 in total (the player never starts with negative resources).",
 	"vcmi.lobby.handicap.income" : "Changes the player's various incomes by the percentage. Is rounded up.",
 	"vcmi.lobby.handicap.growth" : "Changes the growth rate of creatures in the towns owned by the player. Is rounded up.",
+	"vcmi.lobby.deleteUnsupportedSave" : "Unsupported saves found (e.g. from previous versions).\n\nDelete them?",
 		
 	"vcmi.lobby.login.title" : "VCMI Online Lobby",
 	"vcmi.lobby.login.username" : "Username:",

+ 33 - 1
client/lobby/SelectionTab.cpp

@@ -42,9 +42,11 @@
 #include "../../lib/mapping/CMapInfo.h"
 #include "../../lib/mapping/CMapHeader.h"
 #include "../../lib/mapping/MapFormat.h"
+#include "../../lib/networkPacks/PacksForLobby.h"
 #include "../../lib/texts/CGeneralTextHandler.h"
 #include "../../lib/texts/TextOperations.h"
 #include "../../lib/TerrainHandler.h"
+#include "../../lib/UnlockGuard.h"
 
 bool mapSorter::operator()(const std::shared_ptr<ElementInfo> aaa, const std::shared_ptr<ElementInfo> bbb)
 {
@@ -823,6 +825,15 @@ void SelectionTab::parseMaps(const std::unordered_set<ResourcePath> & files)
 
 void SelectionTab::parseSaves(const std::unordered_set<ResourcePath> & files)
 {
+	enum Choice { NONE, REMAIN, DELETE };
+	Choice deleteUnsupported = NONE;
+	auto doDeleteUnsupported = [](std::string file){
+		LobbyDelete ld;
+		ld.type = LobbyDelete::SAVEGAME;
+		ld.name = file;
+		CSH->sendLobbyPack(ld);
+	};
+
 	for(auto & file : files)
 	{
 		try
@@ -863,7 +874,28 @@ void SelectionTab::parseSaves(const std::unordered_set<ResourcePath> & files)
 		}
 		catch(const std::exception & e)
 		{
-			logGlobal->error("Error: Failed to process %s: %s", file.getName(), e.what());
+			// asking for deletion of unsupported saves
+			if(CSH->isHost())
+			{
+				if(deleteUnsupported == DELETE)
+					doDeleteUnsupported(file.getName());
+				else if(deleteUnsupported == NONE)
+				{
+					CInfoWindow::showYesNoDialog(CGI->generaltexth->translate("vcmi.lobby.deleteUnsupportedSave"), std::vector<std::shared_ptr<CComponent>>(), [&deleteUnsupported, doDeleteUnsupported, file](){
+						doDeleteUnsupported(file.getName());
+						deleteUnsupported = DELETE;
+					}, [&deleteUnsupported](){ deleteUnsupported = REMAIN; });
+
+					while(deleteUnsupported == NONE)
+					{
+						auto unlockInterface = vstd::makeUnlockGuard(GH.interfaceMutex);
+						boost::this_thread::sleep_for(boost::chrono::milliseconds(5));
+					}
+				}
+			}
+
+			if(deleteUnsupported != DELETE)
+				logGlobal->error("Error: Failed to process %s: %s", file.getName(), e.what());
 		}
 	}
 }

+ 1 - 0
lib/networkPacks/NetPackVisitor.h

@@ -178,6 +178,7 @@ public:
 	virtual void visitLobbyForceSetPlayer(LobbyForceSetPlayer & pack) {}
 	virtual void visitLobbyShowMessage(LobbyShowMessage & pack) {}
 	virtual void visitLobbyPvPAction(LobbyPvPAction & pack) {}
+	virtual void visitLobbyDelete(LobbyDelete & pack) {}
 	virtual void visitSaveLocalState(SaveLocalState & pack) {}
 };
 

+ 5 - 0
lib/networkPacks/NetPacksLib.cpp

@@ -842,6 +842,11 @@ void LobbyPvPAction::visitTyped(ICPackVisitor & visitor)
 	visitor.visitLobbyPvPAction(*this);
 }
 
+void LobbyDelete::visitTyped(ICPackVisitor & visitor)
+{
+	visitor.visitLobbyDelete(*this);
+}
+
 void SetResources::applyGs(CGameState *gs)
 {
 	assert(player.isValidPlayer());

+ 18 - 0
lib/networkPacks/PacksForLobby.h

@@ -381,4 +381,22 @@ struct DLL_LINKAGE LobbyPvPAction : public CLobbyPackToServer
 	}
 };
 
+struct DLL_LINKAGE LobbyDelete : public CLobbyPackToServer
+{
+	enum EType : ui8 {
+		SAVEGAME, SAVEGAME_FOLDER, RANDOMMAP
+	};
+
+	EType type = SAVEGAME;
+	std::string name;
+
+	void visitTyped(ICPackVisitor & visitor) override;
+
+	template <typename Handler> void serialize(Handler &h)
+	{
+		h & type;
+		h & name;
+	}
+};
+
 VCMI_LIB_NAMESPACE_END

+ 1 - 0
lib/serializer/RegisterTypes.h

@@ -294,6 +294,7 @@ void registerTypes(Serializer &s)
 	s.template registerType<SpellResearch>(241);
 	s.template registerType<SetResearchedSpells>(242);
 	s.template registerType<SaveLocalState>(243);
+	s.template registerType<LobbyDelete>(244);
 }
 
 VCMI_LIB_NAMESPACE_END

+ 2 - 0
server/LobbyNetPackVisitors.h

@@ -39,6 +39,7 @@ public:
 	void visitLobbyChatMessage(LobbyChatMessage & pack) override;
 	void visitLobbyGuiAction(LobbyGuiAction & pack) override;
 	void visitLobbyPvPAction(LobbyPvPAction & pack) override;
+	void visitLobbyDelete(LobbyDelete & pack) override;
 };
 
 class ApplyOnServerAfterAnnounceNetPackVisitor : public VCMI_LIB_WRAP_NAMESPACE(ICPackVisitor)
@@ -96,4 +97,5 @@ public:
 	void visitLobbySetDifficulty(LobbySetDifficulty & pack) override;
 	void visitLobbyForceSetPlayer(LobbyForceSetPlayer & pack) override;
 	void visitLobbyPvPAction(LobbyPvPAction & pack) override;
+	void visitLobbyDelete(LobbyDelete & pack) override;
 };

+ 17 - 1
server/NetPacksLobbyServer.cpp

@@ -22,6 +22,7 @@
 #include "../lib/serializer/Connection.h"
 #include "../lib/mapping/CMapInfo.h"
 #include "../lib/mapping/CMapHeader.h"
+#include "../lib/filesystem/Filesystem.h"
 
 void ClientPermissionsCheckerNetPackVisitor::visitForLobby(CPackForLobby & pack)
 {
@@ -383,7 +384,6 @@ void ApplyOnServerNetPackVisitor::visitLobbyForceSetPlayer(LobbyForceSetPlayer &
 	result = true;
 }
 
-
 void ClientPermissionsCheckerNetPackVisitor::visitLobbyPvPAction(LobbyPvPAction & pack)
 {
 	result = true;
@@ -433,3 +433,19 @@ void ApplyOnServerNetPackVisitor::visitLobbyPvPAction(LobbyPvPAction & pack)
 	}
 	result = true;
 }
+
+
+void ClientPermissionsCheckerNetPackVisitor::visitLobbyDelete(LobbyDelete & pack)
+{
+	result = srv.isClientHost(pack.c->connectionID);
+}
+
+void ApplyOnServerNetPackVisitor::visitLobbyDelete(LobbyDelete & pack)
+{
+	if(pack.type == LobbyDelete::SAVEGAME)
+	{
+		auto res = ResourcePath(pack.name, EResType::SAVEGAME);
+		auto file = boost::filesystem::canonical(*CResourceHandler::get()->getResourceName(res));
+		boost::filesystem::remove(file);
+	}
+}