diff --git a/client/NetPacksClient.cpp b/client/NetPacksClient.cpp index 69d2734b7..1655f3809 100644 --- a/client/NetPacksClient.cpp +++ b/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) diff --git a/lib/Connection.cpp b/lib/Connection.cpp index ec6caeb4d..009fcb104 100644 --- a/lib/Connection.cpp +++ b/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(fname.c_str(), std::ios::binary); - if(!(*sfile)) - { - tlog1 << "Error: cannot open to write " << fname << std::endl; - sfile = NULL; - } - else + try { + sfile = make_unique(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); diff --git a/lib/Connection.h b/lib/Connection.h index 615747c56..fe52aa35b 100644 --- a/lib/Connection.h +++ b/lib/Connection.h @@ -1004,11 +1004,12 @@ public: std::string fName; unique_ptr 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); }; diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index ef3cd5795..96aff8518 100644 --- a/server/CGameHandler.cpp +++ b/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(*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(*gs->map) << gs->scenarioOps << *VLC << gs; + } - { - tlog0 << "Serializing server info...\n"; - CSaveFile save(GVCMIDirs.UserPath + "/Games/" + fname + ".vsgm1"); - save << *this; + { + 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) + { + tlog1 << "Failed to save game: " << e.what() << std::endl; } - tlog0 << "Game has been successfully saved!\n"; } void CGameHandler::close()