mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-26 22:10:21 +00:00
c617aa206d
Re-dump safari slots for HGSS; the repackaged narc accidentally shuffled files so the wrong water tables were output. Add error log output on reporting exception fail first to always dump an error log file. Don't trust the popup/form. Permit TID/OT duplication for in-game trades/N's pokemon. https://projectpokemon.org/home/forums/topic/57375-pkhex-new-update-legality-errors-contribution-page/?do=findComment&comment=287395
162 lines
6 KiB
C#
162 lines
6 KiB
C#
using System;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
using PKHeX.Core;
|
|
|
|
#if !DEBUG
|
|
using System.Reflection;
|
|
using System.IO;
|
|
using System.Threading;
|
|
#endif
|
|
|
|
namespace PKHeX.WinForms;
|
|
|
|
internal static class Program
|
|
{
|
|
/// <summary>
|
|
/// The main entry point for the application.
|
|
/// </summary>
|
|
[STAThread]
|
|
private static void Main()
|
|
{
|
|
#if !DEBUG
|
|
// Add the event handler for handling UI thread exceptions to the event.
|
|
Application.ThreadException += UIThreadException;
|
|
|
|
// Set the unhandled exception mode to force all Windows Forms errors to go through our handler.
|
|
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
|
|
|
|
// Add the event handler for handling non-UI thread exceptions to the event.
|
|
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
|
#endif
|
|
// Run the application
|
|
Application.EnableVisualStyles();
|
|
Application.SetCompatibleTextRenderingDefault(false);
|
|
var splash = new SplashScreen();
|
|
new Task(() => splash.ShowDialog()).Start();
|
|
new Task(() => EncounterEvent.RefreshMGDB(WinForms.Main.MGDatabasePath)).Start();
|
|
var main = new Main();
|
|
splash.Invoke(splash.ForceClose);
|
|
Application.Run(main);
|
|
}
|
|
|
|
// Pipelines build can sometimes tack on text to the version code. Strip it out.
|
|
public static readonly Version CurrentVersion = Version.Parse(GetSaneVersionTag(Application.ProductVersion));
|
|
|
|
private static ReadOnlySpan<char> GetSaneVersionTag(ReadOnlySpan<char> productVersion)
|
|
{
|
|
// Take only 0-9 and '.', stop on first char not in that set.
|
|
for (int i = 0; i < productVersion.Length; i++)
|
|
{
|
|
char c = productVersion[i];
|
|
if (c == '.')
|
|
continue;
|
|
if (char.IsNumber(c))
|
|
continue;
|
|
return productVersion[..i];
|
|
}
|
|
return productVersion;
|
|
}
|
|
|
|
#if !DEBUG
|
|
private static void Error(string msg) => MessageBox.Show(msg, "PKHeX Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
|
|
|
|
// Handle the UI exceptions by showing a dialog box, and asking the user if they wish to abort execution.
|
|
private static void UIThreadException(object sender, ThreadExceptionEventArgs t)
|
|
{
|
|
DialogResult result = DialogResult.Cancel;
|
|
try
|
|
{
|
|
result = ErrorWindow.ShowErrorDialog("An unhandled exception has occurred.\nYou can continue running PKHeX, but please report this error.", t.Exception, true);
|
|
}
|
|
catch (Exception reportingException)
|
|
{
|
|
HandleReportingException(t.Exception, reportingException);
|
|
}
|
|
|
|
// Exits the program when the user clicks Abort.
|
|
if (result == DialogResult.Abort)
|
|
Application.Exit();
|
|
}
|
|
|
|
// Handle the UI exceptions by showing a dialog box, and asking the user if they wish to abort execution.
|
|
// NOTE: This exception cannot be kept from terminating the application - it can only
|
|
// log the event, and inform the user about it.
|
|
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
|
|
{
|
|
var ex = e.ExceptionObject as Exception;
|
|
try
|
|
{
|
|
if (IsOldPkhexCorePresent(ex))
|
|
{
|
|
Error("You have upgraded PKHeX incorrectly. Please delete PKHeX.Core.dll.");
|
|
}
|
|
else if (ex != null)
|
|
{
|
|
ErrorWindow.ShowErrorDialog("An unhandled exception has occurred.\nPKHeX must now close.", ex, false);
|
|
}
|
|
else
|
|
{
|
|
Error("A fatal non-UI error has occurred in PKHeX, and the details could not be displayed. Please report this to the author.");
|
|
}
|
|
}
|
|
catch (Exception reportingException)
|
|
{
|
|
HandleReportingException(ex, reportingException);
|
|
}
|
|
}
|
|
|
|
private static void HandleReportingException(Exception? ex, Exception reportingException)
|
|
{
|
|
try
|
|
{
|
|
EmergencyErrorLog(ex, reportingException);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
// We've failed to even save the error details to a file. There's nothing else we can do.
|
|
}
|
|
if (reportingException is FileNotFoundException x && x.FileName?.StartsWith("PKHeX.Core") == true)
|
|
{
|
|
Error("Could not locate PKHeX.Core.dll. Make sure you're running PKHeX together with its code library. Usually caused when all files are not extracted.");
|
|
return;
|
|
}
|
|
try
|
|
{
|
|
Error("A fatal non-UI error has occurred in PKHeX, and there was a problem displaying the details. Please report this to the author.");
|
|
}
|
|
finally
|
|
{
|
|
Application.Exit();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Attempt to log exceptions to a file when there's an error displaying exception details.
|
|
/// </summary>
|
|
/// <param name="originalException"></param>
|
|
/// <param name="errorHandlingException"></param>
|
|
private static bool EmergencyErrorLog(Exception? originalException, Exception errorHandlingException)
|
|
{
|
|
try
|
|
{
|
|
// Not using a string builder because something's very wrong, and we don't want to make things worse
|
|
var message = (originalException?.ToString() ?? "null first exception") + Environment.NewLine + errorHandlingException;
|
|
File.WriteAllText($"PKHeX_Error_Report {DateTime.Now:yyyyMMddHHmmss}.txt", message);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
// We've failed to save the error details twice now. There's nothing else we can do.
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private static bool IsOldPkhexCorePresent(Exception? ex)
|
|
{
|
|
return ex is MissingMethodException or TypeLoadException or TypeInitializationException
|
|
&& File.Exists("PKHeX.Core.dll")
|
|
&& AssemblyName.GetAssemblyName("PKHeX.Core.dll").Version < CurrentVersion;
|
|
}
|
|
#endif
|
|
}
|