Implemented emergency save on crash, closes #572
parent
ee9457f156
commit
7e028977bd
|
@ -21,6 +21,8 @@
|
|||
|
||||
#include "common/config.h"
|
||||
|
||||
#include "common/resources/resourcemanager.h"
|
||||
|
||||
#include "app/system.h"
|
||||
|
||||
#include "common/stringutils.h"
|
||||
|
@ -93,6 +95,8 @@ void CSignalHandlers::HandleOtherUncaughtException()
|
|||
|
||||
void CSignalHandlers::ReportError(const std::string& errorMessage)
|
||||
{
|
||||
static bool triedSaving = false;
|
||||
|
||||
std::stringstream msg;
|
||||
msg << "Unhandled exception occured!" << std::endl;
|
||||
msg << "==============================" << std::endl;
|
||||
|
@ -109,21 +113,44 @@ void CSignalHandlers::ReportError(const std::string& errorMessage)
|
|||
msg << "You are running version " << COLOBOT_VERSION_DISPLAY << " from CI build #" << BUILD_NUMBER << std::endl;
|
||||
#endif
|
||||
msg << std::endl;
|
||||
bool canSave = false;
|
||||
CRobotMain* robotMain = nullptr;
|
||||
if (!CRobotMain::IsCreated())
|
||||
{
|
||||
msg << "CRobotMain instance does not seem to exist" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
CRobotMain* robotMain = CRobotMain::GetInstancePointer();
|
||||
robotMain = CRobotMain::GetInstancePointer();
|
||||
msg << "The game was in phase " << PhaseToString(robotMain->GetPhase()) << " (ID=" << robotMain->GetPhase() << ")" << std::endl;
|
||||
msg << "Last started level was: category=" << GetLevelCategoryDir(robotMain->GetLevelCategory()) << " chap=" << robotMain->GetLevelChap() << " rank=" << robotMain->GetLevelRank() << std::endl;
|
||||
canSave = (robotMain->GetPhase() == PHASE_SIMUL);
|
||||
}
|
||||
msg << "==============================" << std::endl;
|
||||
msg << std::endl;
|
||||
msg << "Sorry for inconvenience!";
|
||||
|
||||
std::cerr << std::endl << msg.str() << std::endl;
|
||||
|
||||
m_systemUtils->SystemDialog(SDT_ERROR, "Unhandled exception occured!", msg.str());
|
||||
|
||||
if (canSave && !triedSaving)
|
||||
{
|
||||
msg.str("");
|
||||
msg << "You can try saving the game at the moment of a crash. Keep in mind, the game engine is in" << std::endl;
|
||||
msg << "an unstable state so the saved game may be corrupted or even cause another crash." << std::endl;
|
||||
msg << std::endl;
|
||||
msg << "Do you want to try saving now?";
|
||||
|
||||
SystemDialogResult result = m_systemUtils->SystemDialog(SDT_YES_NO, "Try to save?", msg.str());
|
||||
if (result == SDR_YES)
|
||||
{
|
||||
CResourceManager::CreateDirectory("crashsave");
|
||||
robotMain->IOWriteScene("crashsave/data.sav", "crashsave/cbot.run", "crashsave/screen.png", "Backup at the moment of a crash", true);
|
||||
m_systemUtils->SystemDialog(SDT_INFO, "Try to save?", "Saving finished.\nPlease restart the game now");
|
||||
}
|
||||
triedSaving = true;
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
|
|
@ -471,7 +471,7 @@ void CPlayerProfile::SaveScene(std::string dir, std::string info)
|
|||
CResourceManager::CreateDirectory(dir);
|
||||
}
|
||||
|
||||
CRobotMain::GetInstancePointer()->IOWriteScene(dir + "/data.sav", dir + "/cbot.run", dir + "/screen.png", const_cast<char*>(info.c_str()));
|
||||
CRobotMain::GetInstancePointer()->IOWriteScene(dir + "/data.sav", dir + "/cbot.run", dir + "/screen.png", info.c_str());
|
||||
}
|
||||
|
||||
void CPlayerProfile::LoadScene(std::string dir)
|
||||
|
|
|
@ -481,6 +481,23 @@ void CRobotMain::ChangePhase(Phase phase)
|
|||
pb->SetState(Ui::STATE_SIMPLY);
|
||||
pb->ClearState(Ui::STATE_VISIBLE);
|
||||
|
||||
if (m_phase == PHASE_PLAYER_SELECT)
|
||||
{
|
||||
if (CResourceManager::DirectoryExists("crashsave"))
|
||||
{
|
||||
GetLogger()->Info("Pre-crash save found!\n");
|
||||
m_ui->GetDialog()->StartQuestion("Your game seems to have crashed. Do you want to restore pre-crash state?", false, false, false, [&]() {
|
||||
GetLogger()->Info("Trying to restore pre-crash state...\n");
|
||||
assert(m_playerProfile != nullptr);
|
||||
m_playerProfile->LoadScene("../../crashsave");
|
||||
CResourceManager::RemoveDirectory("../../crashsave");
|
||||
}, [&]() {
|
||||
GetLogger()->Info("Not restoring pre-crash state\n");
|
||||
CResourceManager::RemoveDirectory("../../crashsave");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
m_ui->ChangePhase(m_phase);
|
||||
if (!resetWorld) return;
|
||||
|
||||
|
@ -4486,11 +4503,14 @@ void CRobotMain::IOWriteObject(CLevelParserLine* line, CObject* obj, const std::
|
|||
}
|
||||
|
||||
//! Saves the current game
|
||||
bool CRobotMain::IOWriteScene(std::string filename, std::string filecbot, std::string filescreenshot, char *info)
|
||||
bool CRobotMain::IOWriteScene(std::string filename, std::string filecbot, std::string filescreenshot, const std::string& info, bool emergencySave)
|
||||
{
|
||||
// Render the indicator to show that we are working
|
||||
ShowSaveIndicator(true);
|
||||
m_app->Render(); // update
|
||||
if (!emergencySave)
|
||||
{
|
||||
// Render the indicator to show that we are working
|
||||
ShowSaveIndicator(true);
|
||||
m_app->Render(); // update
|
||||
}
|
||||
|
||||
std::string dirname = filename.substr(0, filename.find_last_of("/"));
|
||||
|
||||
|
@ -4609,21 +4629,24 @@ bool CRobotMain::IOWriteScene(std::string filename, std::string filecbot, std::s
|
|||
CBotClass::SaveStaticState(file);
|
||||
fClose(file);
|
||||
|
||||
ShowSaveIndicator(false); // force hide for screenshot
|
||||
MouseMode oldMouseMode = m_app->GetMouseMode();
|
||||
m_app->SetMouseMode(MOUSE_NONE); // disable the mouse
|
||||
m_displayText->HideText(true); // hide
|
||||
m_engine->SetScreenshotMode(true);
|
||||
if (!emergencySave)
|
||||
{
|
||||
ShowSaveIndicator(false); // force hide for screenshot
|
||||
MouseMode oldMouseMode = m_app->GetMouseMode();
|
||||
m_app->SetMouseMode(MOUSE_NONE); // disable the mouse
|
||||
m_displayText->HideText(true); // hide
|
||||
m_engine->SetScreenshotMode(true);
|
||||
|
||||
m_engine->Render(); // update (but don't show, we're not swapping buffers here!)
|
||||
m_engine->WriteScreenShot(CResourceManager::GetSaveLocation() + "/" + filescreenshot); //TODO: Use PHYSFS?
|
||||
m_shotSaving++;
|
||||
m_engine->Render(); // update (but don't show, we're not swapping buffers here!)
|
||||
m_engine->WriteScreenShot(CResourceManager::GetSaveLocation() + "/" + filescreenshot); //TODO: Use PHYSFS?
|
||||
m_shotSaving++;
|
||||
|
||||
m_engine->SetScreenshotMode(false);
|
||||
m_displayText->HideText(false);
|
||||
m_app->SetMouseMode(oldMouseMode);
|
||||
m_engine->SetScreenshotMode(false);
|
||||
m_displayText->HideText(false);
|
||||
m_app->SetMouseMode(oldMouseMode);
|
||||
|
||||
m_app->ResetTimeAfterLoading();
|
||||
m_app->ResetTimeAfterLoading();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -288,7 +288,7 @@ public:
|
|||
CPlayerProfile* GetPlayerProfile();
|
||||
|
||||
bool IOIsBusy();
|
||||
bool IOWriteScene(std::string filename, std::string filecbot, std::string filescreenshot, char *info);
|
||||
bool IOWriteScene(std::string filename, std::string filecbot, std::string filescreenshot, const std::string& info, bool emergencySave = false);
|
||||
void IOWriteSceneFinished();
|
||||
CObject* IOReadScene(std::string filename, std::string filecbot);
|
||||
void IOWriteObject(CLevelParserLine *line, CObject* obj, const std::string& programDir, int objRank);
|
||||
|
|
Loading…
Reference in New Issue