From 85799eddc275604c5ca7f14922e517f8ce649011 Mon Sep 17 00:00:00 2001 From: Mark Vejvoda Date: Thu, 14 Nov 2013 03:33:15 +0000 Subject: [PATCH] more user friendly handling of loading corrupt saved game files --- .../glest_game/menu/menu_state_load_game.cpp | 90 +++++++++++-------- source/shared_lib/include/xml/xml_parser.h | 6 +- source/shared_lib/sources/xml/xml_parser.cpp | 29 ++++-- .../tests/shared_lib/graphics/font_test.cpp | 2 +- 4 files changed, 78 insertions(+), 49 deletions(-) diff --git a/source/glest_game/menu/menu_state_load_game.cpp b/source/glest_game/menu/menu_state_load_game.cpp index 729c2474..30fc7d97 100644 --- a/source/glest_game/menu/menu_state_load_game.cpp +++ b/source/glest_game/menu/menu_state_load_game.cpp @@ -254,7 +254,11 @@ void MenuStateLoadGame::mouseClick(int x, int y, MouseButton mouseButton){ Game::loadGame(filename,program,false); } catch(const megaglest_runtime_error &ex) { - showMessageBox(ex.what(), lang.getString("Notice"), true); + char szBuf[8096]=""; + snprintf(szBuf,8096,"In [%s::%s Line: %d]\nError [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); + + showMessageBox(ex.what(), lang.getString("Notice"), false); } return; } @@ -283,8 +287,12 @@ void MenuStateLoadGame::mouseClick(int x, int y, MouseButton mouseButton){ } } catch(const megaglest_runtime_error &ex) { + char szBuf[8096]=""; + snprintf(szBuf,8096,"In [%s::%s Line: %d]\nError [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); + cleanupTexture(&previewTexture); - showMessageBox(ex.what(), lang.getString("Notice"), true); + showMessageBox(ex.what(), lang.getString("Notice"), false); } } else { @@ -302,44 +310,54 @@ void MenuStateLoadGame::mouseClick(int x, int y, MouseButton mouseButton){ if(SystemFlags::VERBOSE_MODE_ENABLED) printf("Before load of XML\n"); std::map mapExtraTagReplacementValues; - xmlTree.load(filename, Properties::getTagReplacementValues(&mapExtraTagReplacementValues),true); - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("After load of XML\n"); + try { + xmlTree.load(filename, Properties::getTagReplacementValues(&mapExtraTagReplacementValues),true,false,true); - const XmlNode *rootNode= xmlTree.getRootNode(); - if(rootNode != NULL && rootNode->hasChild("megaglest-saved-game") == true) { - rootNode = rootNode->getChild("megaglest-saved-game"); + if(SystemFlags::VERBOSE_MODE_ENABLED) printf("After load of XML\n"); + + const XmlNode *rootNode= xmlTree.getRootNode(); + if(rootNode != NULL && rootNode->hasChild("megaglest-saved-game") == true) { + rootNode = rootNode->getChild("megaglest-saved-game"); + } + + if(rootNode == NULL) { + char szBuf[8096]=""; + snprintf(szBuf,8096,"Invalid XML saved game file: [%s]",filename.c_str()); + infoTextLabel.setText(szBuf); + return; + } + + const XmlNode *versionNode= rootNode; + string gameVer = versionNode->getAttribute("version")->getValue(); + if(gameVer != glestVersionString && checkVersionComptability(gameVer, glestVersionString) == false) { + char szBuf[8096]=""; + snprintf(szBuf,8096,lang.getString("SavedGameBadVersion").c_str(),gameVer.c_str(),glestVersionString.c_str()); + infoTextLabel.setText(szBuf); + } + else { + XmlNode *gameNode = rootNode->getChild("Game"); + GameSettings newGameSettings; + newGameSettings.loadGame(gameNode); + + char szBuf[8096]=""; + snprintf(szBuf,8096,lang.getString("LoadSavedGameInfo").c_str(), + newGameSettings.getMap().c_str(), + newGameSettings.getTileset().c_str(), + newGameSettings.getTech().c_str(), + newGameSettings.getScenario().c_str(), + newGameSettings.getFactionCount(), + (newGameSettings.getThisFactionIndex() >= 0 && + newGameSettings.getThisFactionIndex() < newGameSettings.getFactionCount() ? + newGameSettings.getFactionTypeName(newGameSettings.getThisFactionIndex()).c_str() : "")); + infoTextLabel.setText(szBuf); + } } - - if(rootNode == NULL) { + catch(const megaglest_runtime_error &ex) { char szBuf[8096]=""; - snprintf(szBuf,8096,"Invalid XML saved game file: [%s]",filename.c_str()); - infoTextLabel.setText(szBuf); - return; - } + snprintf(szBuf,8096,"In [%s::%s Line: %d]\nError [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,ex.what()); + SystemFlags::OutputDebug(SystemFlags::debugError,szBuf); - const XmlNode *versionNode= rootNode; - string gameVer = versionNode->getAttribute("version")->getValue(); - if(gameVer != glestVersionString && checkVersionComptability(gameVer, glestVersionString) == false) { - char szBuf[8096]=""; - snprintf(szBuf,8096,lang.getString("SavedGameBadVersion").c_str(),gameVer.c_str(),glestVersionString.c_str()); - infoTextLabel.setText(szBuf); - } - else { - XmlNode *gameNode = rootNode->getChild("Game"); - GameSettings newGameSettings; - newGameSettings.loadGame(gameNode); - - char szBuf[8096]=""; - snprintf(szBuf,8096,lang.getString("LoadSavedGameInfo").c_str(), - newGameSettings.getMap().c_str(), - newGameSettings.getTileset().c_str(), - newGameSettings.getTech().c_str(), - newGameSettings.getScenario().c_str(), - newGameSettings.getFactionCount(), - (newGameSettings.getThisFactionIndex() >= 0 && - newGameSettings.getThisFactionIndex() < newGameSettings.getFactionCount() ? - newGameSettings.getFactionTypeName(newGameSettings.getThisFactionIndex()).c_str() : "")); - infoTextLabel.setText(szBuf); + showMessageBox(ex.what(), lang.getString("Notice"), false); } } else { diff --git a/source/shared_lib/include/xml/xml_parser.h b/source/shared_lib/include/xml/xml_parser.h index baf3b9dc..04451aec 100644 --- a/source/shared_lib/include/xml/xml_parser.h +++ b/source/shared_lib/include/xml/xml_parser.h @@ -90,7 +90,7 @@ public: static bool isInitialized(); void cleanup(); - XmlNode *load(const string &path, const std::map &mapTagReplacementValues,bool noValidation=false); + XmlNode *load(const string &path, const std::map &mapTagReplacementValues,bool noValidation=false,bool skipStackTrace=false); void save(const string &path, const XmlNode *node); }; @@ -109,7 +109,7 @@ public: static bool isInitialized(); void cleanup(); - XmlNode *load(const string &path, const std::map &mapTagReplacementValues,bool noValidation=false,bool skipStackCheck=false); + XmlNode *load(const string &path, const std::map &mapTagReplacementValues,bool noValidation=false,bool skipStackTrace=false); void save(const string &path, const XmlNode *node); }; @@ -133,7 +133,7 @@ public: ~XmlTree(); void init(const string &name); - void load(const string &path, const std::map &mapTagReplacementValues, bool noValidation=false,bool skipStackCheck=false); + void load(const string &path, const std::map &mapTagReplacementValues, bool noValidation=false,bool skipStackCheck=false,bool skipStackTrace=false); void save(const string &path); XmlNode *getRootNode() const {return rootNode;} diff --git a/source/shared_lib/sources/xml/xml_parser.cpp b/source/shared_lib/sources/xml/xml_parser.cpp index 3f2fd4d8..3e4c3c9b 100644 --- a/source/shared_lib/sources/xml/xml_parser.cpp +++ b/source/shared_lib/sources/xml/xml_parser.cpp @@ -208,7 +208,7 @@ DOMNode *XmlIo::loadDOMNode(const string &path, bool noValidation) { return NULL; } -XmlNode *XmlIo::load(const string &path, const std::map &mapTagReplacementValues,bool noValidation) { +XmlNode *XmlIo::load(const string &path, const std::map &mapTagReplacementValues,bool noValidation,bool skipStackTrace) { //printf("Load file using Xerces engine [%s]\n",path.c_str()); try { @@ -222,10 +222,15 @@ XmlNode *XmlIo::load(const string &path, const std::map &mapTagRe } catch(const DOMException &ex) { char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] Exception while loading: [%s], msg:\n%s",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,path.c_str(),XMLString::transcode(ex.msg)); + if(skipStackTrace == false) { + snprintf(szBuf,8096,"In [%s::%s Line: %d] Exception while loading: [%s], msg:\n%s",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,path.c_str(),XMLString::transcode(ex.msg)); + } + else { + snprintf(szBuf,8096,"Error loading: [%s], msg:\n%s",path.c_str(),XMLString::transcode(ex.msg)); + } SystemFlags::OutputDebug(SystemFlags::debugError,"%s\n",szBuf); - throw megaglest_runtime_error(szBuf); + throw megaglest_runtime_error(szBuf,skipStackTrace); } return NULL; } @@ -320,7 +325,7 @@ XmlIoRapid::~XmlIoRapid() { cleanup(); } -XmlNode *XmlIoRapid::load(const string &path, const std::map &mapTagReplacementValues,bool noValidation,bool skipStackCheck) { +XmlNode *XmlIoRapid::load(const string &path, const std::map &mapTagReplacementValues,bool noValidation,bool skipStackTrace) { bool showPerfStats = SystemFlags::VERBOSE_MODE_ENABLED; Chrono chrono; chrono.start(); @@ -398,10 +403,16 @@ XmlNode *XmlIoRapid::load(const string &path, const std::map &map } catch(const exception &ex) { char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] Exception while loading: [%s], msg:\n%s",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,path.c_str(),ex.what()); + + if(skipStackTrace == false) { + snprintf(szBuf,8096,"In [%s::%s Line: %d] Exception while loading: [%s], msg:\n%s",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,path.c_str(),ex.what()); + } + else { + snprintf(szBuf,8096,"Error loading: [%s], msg:\n%s",path.c_str(),ex.what()); + } SystemFlags::OutputDebug(SystemFlags::debugError,"%s\n",szBuf); - throw megaglest_runtime_error(szBuf); + throw megaglest_runtime_error(szBuf,skipStackTrace); } //if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] took msecs: %ld for file [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis(),path.c_str()); @@ -506,7 +517,7 @@ typedef std::vector LoadStack; //static LoadStack loadStack; static string loadStackCacheName = string(__FILE__) + string("_loadStackCacheName"); -void XmlTree::load(const string &path, const std::map &mapTagReplacementValues, bool noValidation,bool skipStackCheck) { +void XmlTree::load(const string &path, const std::map &mapTagReplacementValues, bool noValidation,bool skipStackCheck,bool skipStackTrace) { if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] about to load [%s] skipStackCheck = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,path.c_str(),skipStackCheck); clearRootNode(); @@ -532,10 +543,10 @@ void XmlTree::load(const string &path, const std::map &mapTagRepl loadPath = path; if(this->engine_type == XML_XERCES_ENGINE) { - this->rootNode= XmlIo::getInstance().load(path, mapTagReplacementValues, noValidation); + this->rootNode= XmlIo::getInstance().load(path, mapTagReplacementValues, noValidation,skipStackTrace); } else { - this->rootNode= XmlIoRapid::getInstance().load(path, mapTagReplacementValues, noValidation,this->skipStackCheck); + this->rootNode= XmlIoRapid::getInstance().load(path, mapTagReplacementValues, noValidation,skipStackTrace); } if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] about to load [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,path.c_str()); diff --git a/source/tests/shared_lib/graphics/font_test.cpp b/source/tests/shared_lib/graphics/font_test.cpp index af767fdc..451facb5 100644 --- a/source/tests/shared_lib/graphics/font_test.cpp +++ b/source/tests/shared_lib/graphics/font_test.cpp @@ -44,7 +44,7 @@ public: string expected = text; #ifdef HAVE_FRIBIDI Font::bidi_cvt(text); - printf("Expected: [%s] result[%s]\n",expected.c_str(),text.c_str()); + //printf("Expected: [%s] result[%s]\n",expected.c_str(),text.c_str()); CPPUNIT_ASSERT_EQUAL( expected,text ); #endif