Forráskód Böngészése

#994 should not crash anymore.

Michał W. Urbańczyk 13 éve
szülő
commit
e6ebf42308
4 módosított fájl, 48 hozzáadás és 22 törlés
  1. 9 2
      client/NetPacksClient.cpp
  2. 19 7
      lib/Connection.cpp
  3. 4 4
      lib/Connection.h
  4. 16 9
      server/CGameHandler.cpp

+ 9 - 2
client/NetPacksClient.cpp

@@ -761,8 +761,15 @@ void YourTurn::applyCl( CClient *cl )
 
 void SaveGame::applyCl(CClient *cl)
 {
-	CSaveFile save(GVCMIDirs.UserPath + "/Games/" + fname + ".vcgm1");
-	save << *cl;
+	try
+	{
+		CSaveFile save(GVCMIDirs.UserPath + "/Games/" + fname + ".vcgm1");
+		save << *cl;
+	}
+	catch(std::exception &e)
+	{
+		tlog1 << "Failed to save game:" << e.what() << std::endl;
+	}
 }
 
 void PlayerMessage::applyCl(CClient *cl)

+ 19 - 7
lib/Connection.cpp

@@ -268,17 +268,23 @@ int CSaveFile::write( const void * data, unsigned size )
 void CSaveFile::openNextFile(const std::string &fname)
 {
 	fName = fname;
-	sfile = make_unique<std::ofstream>(fname.c_str(), std::ios::binary);
-	if(!(*sfile))
-	{
-		tlog1 << "Error: cannot open to write " << fname << std::endl;
-		sfile = NULL;
-	}
-	else
+	try
 	{
+		sfile = make_unique<std::ofstream>(fname.c_str(), std::ios::binary);
+		sfile->exceptions(std::ifstream::failbit | std::ifstream::badbit); //we throw a lot anyway
+
+		if(!(*sfile))
+			THROW_FORMAT("Error: cannot open to write %s!", fname);
+
 		sfile->write("VCMI",4); //write magic identifier
 		*this << version; //write format version
 	}
+	catch(...)
+	{
+		tlog1 << "Failed to save to " << fname << std::endl;
+		clear();
+		throw;
+	}
 }
 
 void CSaveFile::reportState(CLogger &out)
@@ -290,6 +296,12 @@ void CSaveFile::reportState(CLogger &out)
 	}
 }
 
+void CSaveFile::clear()
+{
+	fName.clear();
+	sfile = nullptr;
+}
+
 CLoadFile::CLoadFile(const std::string &fname, int minimalVersion /*= version*/)
 {
 	registerTypes(*this);

+ 4 - 4
lib/Connection.h

@@ -1004,11 +1004,12 @@ public:
 	std::string fName;
 	unique_ptr<std::ofstream> sfile;
 
-	CSaveFile(const std::string &fname);
+	CSaveFile(const std::string &fname); //throws!
 	~CSaveFile();
 	int write(const void * data, unsigned size);
 
-	void openNextFile(const std::string &fname);
+	void openNextFile(const std::string &fname); //throws!
+	void clear();
 	void reportState(CLogger &out);
 };
 
@@ -1026,10 +1027,9 @@ public:
 
 	CLoadFile(const std::string &fname, int minimalVersion = version); //throws!
 	~CLoadFile();
-	int read(const void * data, unsigned size);
+	int read(const void * data, unsigned size); //throws!
 
 	void openNextFile(const std::string &fname, int minimalVersion); //throws!
-
 	void clear();
 	void reportState(CLogger &out);
 };

+ 16 - 9
server/CGameHandler.cpp

@@ -2250,19 +2250,26 @@ void CGameHandler::save( const std::string &fname )
 		sendToAllClients(&sg);
 	}
 
+	try
 	{
-		tlog0 << "Serializing game info...\n";
-		CSaveFile save(GVCMIDirs.UserPath + "/Games/" + fname + ".vlgm1");
-		char hlp[8] = "VCMISVG";
-		save << hlp << static_cast<CMapHeader&>(*gs->map) << gs->scenarioOps << *VLC << gs;
-	}
+		{
+			tlog0 << "Serializing game info...\n";
+			CSaveFile save(GVCMIDirs.UserPath + "/Games/" + fname + ".vlgm1");
+			char hlp[8] = "VCMISVG";
+			save << hlp << static_cast<CMapHeader&>(*gs->map) << gs->scenarioOps << *VLC << gs;
+		}
 
+		{
+			tlog0 << "Serializing server info...\n";
+			CSaveFile save(GVCMIDirs.UserPath + "/Games/" + fname + ".vsgm1");
+			save << *this;
+		}
+		tlog0 << "Game has been successfully saved!\n";
+	}
+	catch(std::exception &e)
 	{
-		tlog0 << "Serializing server info...\n";
-		CSaveFile save(GVCMIDirs.UserPath + "/Games/" + fname + ".vsgm1");
-		save << *this;
+		tlog1 << "Failed to save game: " << e.what() << std::endl;
 	}
-	tlog0 << "Game has been successfully saved!\n";
 }
 
 void CGameHandler::close()