From 7f67b567f91d899c1fcb6a6aafa743c25bd29e1d Mon Sep 17 00:00:00 2001 From: ScottNZ Date: Sun, 18 Aug 2013 02:12:39 +1200 Subject: [PATCH] Add Fatal Error dialog --- OpenRA.Game/GameRules/Settings.cs | 3 + OpenRA.Game/OpenRA.Game.csproj | 1 + OpenRA.Game/Support/FatalErrorDialog.cs | 105 ++++++++++++++++++ OpenRA.Game/Support/Program.cs | 9 +- .../Widgets/Logic/CncSettingsLogic.cs | 4 + .../Widgets/Logic/SettingsMenuLogic.cs | 4 + mods/cnc/chrome/settings.yaml | 7 ++ mods/ra/chrome/settings.yaml | 8 +- 8 files changed, 137 insertions(+), 4 deletions(-) create mode 100644 OpenRA.Game/Support/FatalErrorDialog.cs diff --git a/OpenRA.Game/GameRules/Settings.cs b/OpenRA.Game/GameRules/Settings.cs index bd4b6c15d1..89ee438400 100644 --- a/OpenRA.Game/GameRules/Settings.cs +++ b/OpenRA.Game/GameRules/Settings.cs @@ -78,6 +78,9 @@ namespace OpenRA.GameRules public int Samples = 25; public bool IgnoreVersionMismatch = false; public bool DeveloperMenu = false; + + public bool ShowFatalErrorDialog = true; + public string FatalErrorDialogFaq = "http://github.com/OpenRA/OpenRA/wiki/FAQ"; } public class GraphicSettings diff --git a/OpenRA.Game/OpenRA.Game.csproj b/OpenRA.Game/OpenRA.Game.csproj index e15a4185e7..57d52ea8a0 100644 --- a/OpenRA.Game/OpenRA.Game.csproj +++ b/OpenRA.Game/OpenRA.Game.csproj @@ -155,6 +155,7 @@ + diff --git a/OpenRA.Game/Support/FatalErrorDialog.cs b/OpenRA.Game/Support/FatalErrorDialog.cs new file mode 100644 index 0000000000..da08c990d5 --- /dev/null +++ b/OpenRA.Game/Support/FatalErrorDialog.cs @@ -0,0 +1,105 @@ +#region Copyright & License Information +/* + * Copyright 2007-2013 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using System; +using System.Diagnostics; +using System.Drawing; +using System.Media; +using System.Windows.Forms; + +namespace OpenRA +{ + public static class FatalErrorDialog + { + public static void Show() + { + var form = new Form + { + Size = new Size(315, 140), + Text = "Fatal Error", + MinimizeBox = false, + MaximizeBox = false, + FormBorderStyle = FormBorderStyle.FixedDialog, + StartPosition = FormStartPosition.CenterScreen + }; + + var notice = new Label + { + Location = new Point(10, 10), + AutoSize = true, + Text = "OpenRA has encountered a fatal error and must close.{0}Refer to the crash logs and FAQ for more information.".F(Environment.NewLine), + TextAlign = ContentAlignment.TopCenter + }; + form.Controls.Add(notice); + + var dontShowAgain = new CheckBox + { + Location = new Point(25, 50), + AutoSize = true, + Text = "Don't show this message again", + }; + form.Controls.Add(dontShowAgain); + + var viewLogs = new Button + { + Location = new Point(10, 80), + Size = new Size(75, 23), + Text = "View Logs" + }; + viewLogs.Click += ViewLogsClicked; + form.Controls.Add(viewLogs); + + var viewFaq = new Button + { + Location = new Point(90, 80), + Size = new Size(75, 23), + Text = "View FAQ" + }; + viewFaq.Click += ViewFaqClicked; + form.Controls.Add(viewFaq); + + var quit = new Button + { + Location = new Point(225, 80), + Size = new Size(75, 23), + Text = "Quit" + }; + quit.DialogResult = DialogResult.Cancel; + form.Controls.Add(quit); + + form.FormClosed += (sender, e) => + { + Game.Settings.Debug.ShowFatalErrorDialog = !dontShowAgain.Checked; + Game.Settings.Save(); + }; + + SystemSounds.Exclamation.Play(); + form.ShowDialog(); + } + + static void ViewLogsClicked(object sender, EventArgs e) + { + try + { + Process.Start(Log.LogPath); + } + catch { } + } + + static void ViewFaqClicked(object sender, EventArgs e) + { + try + { + Process.Start(Game.Settings.Debug.FatalErrorDialogFaq); + } + catch { } + } + } +} diff --git a/OpenRA.Game/Support/Program.cs b/OpenRA.Game/Support/Program.cs index 78d065ab9a..d73aa72a8e 100644 --- a/OpenRA.Game/Support/Program.cs +++ b/OpenRA.Game/Support/Program.cs @@ -31,7 +31,7 @@ namespace OpenRA return; } - AppDomain.CurrentDomain.UnhandledException += (_, e) => LogException((Exception)e.ExceptionObject); + AppDomain.CurrentDomain.UnhandledException += (_, e) => FatalError((Exception)e.ExceptionObject); try { @@ -39,16 +39,19 @@ namespace OpenRA } catch (Exception e) { - LogException(e); + FatalError(e); } } - static void LogException(Exception e) + static void FatalError(Exception e) { Log.AddChannel("exception", "exception.log"); var rpt = BuildExceptionReport(e).ToString(); Log.Write("exception", "{0}", rpt); Console.Error.WriteLine(rpt); + + if (Game.Settings.Debug.ShowFatalErrorDialog) + FatalErrorDialog.Show(); } static StringBuilder BuildExceptionReport(Exception e) diff --git a/OpenRA.Mods.Cnc/Widgets/Logic/CncSettingsLogic.cs b/OpenRA.Mods.Cnc/Widgets/Logic/CncSettingsLogic.cs index 96ba7a49f4..dbd2cf87f5 100644 --- a/OpenRA.Mods.Cnc/Widgets/Logic/CncSettingsLogic.cs +++ b/OpenRA.Mods.Cnc/Widgets/Logic/CncSettingsLogic.cs @@ -75,6 +75,10 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic checkunsyncedCheckbox.IsChecked = () => debugSettings.SanityCheckUnsyncedCode; checkunsyncedCheckbox.OnClick = () => debugSettings.SanityCheckUnsyncedCode ^= true; + var showFatalErrorDialog = generalPane.Get("SHOW_FATAL_ERROR_DIALOG_CHECKBOX"); + showFatalErrorDialog.IsChecked = () => Game.Settings.Debug.ShowFatalErrorDialog; + showFatalErrorDialog.OnClick = () => Game.Settings.Debug.ShowFatalErrorDialog ^= true; + // Video var windowModeDropdown = generalPane.Get("MODE_DROPDOWN"); windowModeDropdown.OnMouseDown = _ => SettingsMenuLogic.ShowWindowModeDropdown(windowModeDropdown, graphicsSettings); diff --git a/OpenRA.Mods.RA/Widgets/Logic/SettingsMenuLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/SettingsMenuLogic.cs index bf23d15a6a..7c7bd10f41 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/SettingsMenuLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/SettingsMenuLogic.cs @@ -239,6 +239,10 @@ namespace OpenRA.Mods.RA.Widgets.Logic developerMenuCheckbox.IsChecked = () => Game.Settings.Debug.DeveloperMenu; developerMenuCheckbox.OnClick = () => Game.Settings.Debug.DeveloperMenu ^= true; + var showFatalErrorDialog = debug.Get("SHOW_FATAL_ERROR_DIALOG_CHECKBOX"); + showFatalErrorDialog.IsChecked = () => Game.Settings.Debug.ShowFatalErrorDialog; + showFatalErrorDialog.OnClick = () => Game.Settings.Debug.ShowFatalErrorDialog ^= true; + bg.Get("BUTTON_CLOSE").OnClick = () => { int x, y; diff --git a/mods/cnc/chrome/settings.yaml b/mods/cnc/chrome/settings.yaml index e1a9da1647..586d9db2e2 100644 --- a/mods/cnc/chrome/settings.yaml +++ b/mods/cnc/chrome/settings.yaml @@ -92,6 +92,13 @@ Container@SETTINGS_PANEL: Height:20 Font:Regular Text:Check Sync around Unsynced Code + Checkbox@SHOW_FATAL_ERROR_DIALOG_CHECKBOX: + X:15 + Y:260 + Width:300 + Height:20 + Font:Regular + Text:Show Fatal Error dialog Label@VIDEO_TITLE: Y:20 X:375 diff --git a/mods/ra/chrome/settings.yaml b/mods/ra/chrome/settings.yaml index bb65bed75a..95c0a563e8 100644 --- a/mods/ra/chrome/settings.yaml +++ b/mods/ra/chrome/settings.yaml @@ -389,4 +389,10 @@ Background@SETTINGS_MENU: Y:180 Width:300 Height:20 - Text:Enable Asset Browser (requires restart) \ No newline at end of file + Text:Enable Asset Browser (requires restart) + Checkbox@SHOW_FATAL_ERROR_DIALOG_CHECKBOX: + X:0 + Y:210 + Width:200 + Height:20 + Text:Show Fatal Error dialog \ No newline at end of file