do not get stuck on "in game..." page just because of game crash. output a message instead. could still need some tweaking, but a man gotta sleep. and sheep too...
--- a/QTfrontend/game.cpp Sun Jun 15 00:02:25 2014 +0200
+++ b/QTfrontend/game.cpp Sun Jun 15 04:33:54 2014 +0200
@@ -248,7 +248,12 @@
case 'E':
{
int size = msg.size();
- emit ErrorMessage(QString("Last two engine messages:\n") + QString().append(msg.mid(2)).left(size - 4));
+ emit ErrorMessage(
+ QString("A Fatal ERROR occured! - The game engine had to stop.")
+ + "\n\n " + tr("We are very sorry for the inconvenience :(")
+ + "\n\n" + tr("If this keeps happening, please click the '%1' button in the main menu!")
+ .arg("Feedback") + "\n\n"
+ "Last two engine messages:\n" + QString().append(msg.mid(2)).left(size - 4));
return;
}
case 'i':
--- a/QTfrontend/hwform.cpp Sun Jun 15 00:02:25 2014 +0200
+++ b/QTfrontend/hwform.cpp Sun Jun 15 04:33:54 2014 +0200
@@ -1675,7 +1675,7 @@
connect(game, SIGNAL(CampStateChanged(int)), this, SLOT(UpdateCampaignPageProgress(int)));
connect(game, SIGNAL(GameStateChanged(GameState)), this, SLOT(GameStateChanged(GameState)));
connect(game, SIGNAL(GameStats(char, const QString &)), ui.pageGameStats, SLOT(GameStats(char, const QString &)));
- connect(game, SIGNAL(ErrorMessage(const QString &)), this, SLOT(ShowErrorMessage(const QString &)), Qt::QueuedConnection);
+ connect(game, SIGNAL(ErrorMessage(const QString &)), this, SLOT(ShowFatalErrorMessage(const QString &)), Qt::QueuedConnection);
connect(game, SIGNAL(HaveRecord(RecordType, const QByteArray &)), this, SLOT(GetRecord(RecordType, const QByteArray &)));
m_lastDemo = QByteArray();
}
@@ -2094,9 +2094,9 @@
}
}
-void HWForm::ShowErrorMessage(const QString & msg)
+void HWForm::ShowFatalErrorMessage(const QString & msg)
{
- MessageDialog::ShowErrorMessage(msg, this);
+ MessageDialog::ShowFatalMessage(msg, this);
}
void HWForm::showFeedbackDialog()
--- a/QTfrontend/hwform.h Sun Jun 15 00:02:25 2014 +0200
+++ b/QTfrontend/hwform.h Sun Jun 15 04:33:54 2014 +0200
@@ -120,7 +120,7 @@
void StartMPGame();
void GameStateChanged(GameState gameState);
void ForcedDisconnect(const QString & reason);
- void ShowErrorMessage(const QString &);
+ void ShowFatalErrorMessage(const QString &);
void GetRecord(RecordType type, const QByteArray & record);
void CreateNetGame();
void UpdateWeapons();
--- a/QTfrontend/net/tcpBase.cpp Sun Jun 15 00:02:25 2014 +0200
+++ b/QTfrontend/net/tcpBase.cpp Sun Jun 15 04:33:54 2014 +0200
@@ -172,7 +172,10 @@
thread->start();
#else
process = new QProcess(this);
- connect(process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(StartProcessError(QProcess::ProcessError)));
+ connect(process, SIGNAL(error(QProcess::ProcessError)),
+ this, SLOT(StartProcessError(QProcess::ProcessError)));
+ connect(process, SIGNAL(finished(int, QProcess::ExitStatus)),
+ this, SLOT(onEngineDeath(int, QProcess::ExitStatus)));
QStringList arguments = getArguments();
#ifdef QT_DEBUG
@@ -198,7 +201,9 @@
#endif
emit isReadyNow();
}
+
IPCSocket->deleteLater();
+ IPCSocket = NULL;
deleteLater();
}
@@ -217,6 +222,37 @@
ClientDisconnect();
}
+void TCPBase::onEngineDeath(int exitCode, QProcess::ExitStatus exitStatus)
+{
+ Q_UNUSED(exitStatus);
+
+ ClientDisconnect();
+
+ // show error message if there was an error that was not an engine's
+ // fatal error - because that one already sent a info via IPC
+ if ((exitCode != 0) && (exitCode != 2))
+ {
+ // inform user that something bad happened
+ MessageDialog::ShowFatalMessage(
+ tr("The game engine died unexpectedly!")
+ + QString("\n(exit code %1)").arg(exitCode)
+ + "\n\n " + tr("We are very sorry for the inconvenience :(") + "\n\n" +
+ tr("If this keeps happening, please click the '%1' button in the main menu!")
+ .arg("Feedback"));
+
+ }
+
+ // cleanup up
+ if (IPCSocket)
+ {
+ IPCSocket->close();
+ IPCSocket->deleteLater();
+ }
+
+ // plot suicide
+ deleteLater();
+}
+
void TCPBase::tcpServerReady()
{
disconnect(srvsList.first(), SIGNAL(isReadyNow()), this, SLOT(tcpServerReady()));
--- a/QTfrontend/net/tcpBase.h Sun Jun 15 00:02:25 2014 +0200
+++ b/QTfrontend/net/tcpBase.h Sun Jun 15 04:33:54 2014 +0200
@@ -88,6 +88,7 @@
void ClientDisconnect();
void ClientRead();
void StartProcessError(QProcess::ProcessError error);
+ void onEngineDeath(int exitCode, QProcess::ExitStatus exitStatus);
void tcpServerReady();
};
--- a/QTfrontend/util/MessageDialog.cpp Sun Jun 15 00:02:25 2014 +0200
+++ b/QTfrontend/util/MessageDialog.cpp Sun Jun 15 04:33:54 2014 +0200
@@ -47,26 +47,26 @@
int MessageDialog::ShowMessage(const QString & title, const QString & msg, QMessageBox::Icon icon, QWidget * parent)
{
- QMessageBox msgMsg(parent ? parent : HWApplication::activeWindow());
+ // if no parent try to use active window
+ parent = parent ? parent : HWApplication::activeWindow();
+
+ // didn't work? make child of hwform (e.g. for style and because modal)
+ if (!parent)
+ {
+ try
+ {
+ HWApplication * app = dynamic_cast<HWApplication*>(HWApplication::instance());
+ if (app->form)
+ parent = app->form;
+ }
+ catch (...) { /* nothing */ }
+ }
+
+ QMessageBox msgMsg(parent);
msgMsg.setWindowTitle(title != NULL ? title : "Hedgewars");
msgMsg.setText(msg);
msgMsg.setIcon(icon);
msgMsg.setWindowModality(Qt::WindowModal);
- if (!parent)
- {
- try
- {
- /* workaround to make sure style is correct
- * I'd rather assign the stylesheet to qApp directly (in main.cpp),
- * but the current Stylesheet will ruin the look (e.g. map selection) :(
- */
- HWApplication * app = dynamic_cast<HWApplication*>(HWApplication::instance());
- if (app->form)
- msgMsg.setStyleSheet(app->form->styleSheet());
- }
- catch (...) { /* nothing */ }
- }
-
return msgMsg.exec();
}
--- a/hedgewars/uConsts.pas Sun Jun 15 00:02:25 2014 +0200
+++ b/hedgewars/uConsts.pas Sun Jun 15 04:33:54 2014 +0200
@@ -26,15 +26,16 @@
{$INCLUDE "config.inc"}
const
- HaltNoError = 0;
- HaltUsageError = 1;
- HaltFatalError = 2;
- HaltStartupError = 3;
+ HaltNoError = 0;
+ HaltUsageError = 1;
+ HaltFatalError = 2;
+ HaltStartupError = 3;
+ HaltFatalErrorNoIPC = 4;
// for automatic tests
- HaltTestSuccess = 0;
- HaltTestFailed = 10;
- HaltTestLuaError = 11;
+ HaltTestSuccess = 0;
+ HaltTestFailed = 10;
+ HaltTestLuaError = 11;
sfMax = 1000;
--- a/hedgewars/uIO.pas Sun Jun 15 00:02:25 2014 +0200
+++ b/hedgewars/uIO.pas Sun Jun 15 04:33:54 2014 +0200
@@ -416,7 +416,11 @@
SendIPC('E' + s);
// TODO: should we try to clean more stuff here?
SDL_Quit;
- halt(HaltFatalError);
+
+ if IPCSock <> nil then
+ halt(HaltFatalError)
+ else
+ halt(HaltFatalErrorNoIPC);
end;
procedure doPut(putX, putY: LongInt; fromAI: boolean);