summaryrefslogtreecommitdiff
path: root/src/StardewModdingAPI/Program.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/StardewModdingAPI/Program.cs')
-rw-r--r--src/StardewModdingAPI/Program.cs138
1 files changed, 67 insertions, 71 deletions
diff --git a/src/StardewModdingAPI/Program.cs b/src/StardewModdingAPI/Program.cs
index ca45eba5..ab3d8f5c 100644
--- a/src/StardewModdingAPI/Program.cs
+++ b/src/StardewModdingAPI/Program.cs
@@ -85,7 +85,7 @@ namespace StardewModdingAPI
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-GB");
// add info header
- Program.Monitor.Log($"Launching SMAPI {Constants.Version} with Stardew Valley {Game1.version} on {Environment.OSVersion}", LogLevel.Info);
+ Program.Monitor.Log($"SMAPI {Constants.Version} with Stardew Valley {Game1.version} on {Environment.OSVersion}", LogLevel.Info);
// load user settings
{
@@ -120,7 +120,7 @@ namespace StardewModdingAPI
}
// initialise
- Program.Monitor.Log("Initialising...");
+ Program.Monitor.Log("Loading SMAPI...");
Console.Title = Constants.ConsoleTitle;
Program.VerifyPath(Program.ModPath);
Program.VerifyPath(Constants.LogDir);
@@ -171,31 +171,28 @@ namespace StardewModdingAPI
/// <summary>Hook into Stardew Valley and launch the game.</summary>
private static void StartGame()
{
- // load the game assembly (ignore security)
- Program.Monitor.Log("Preparing game...");
- Program.StardewAssembly = Assembly.UnsafeLoadFrom(Program.GameExecutablePath);
- Program.StardewProgramType = Program.StardewAssembly.GetType("StardewValley.Program", true);
- Program.StardewGameInfo = Program.StardewProgramType.GetField("gamePtr");
-
- // change the game's version
- Game1.version += $"-Z_MODDED | SMAPI {Constants.Version}";
-
- // add error interceptors
-#if SMAPI_FOR_WINDOWS
- Application.ThreadException += (sender, e) => Program.Monitor.Log($"Critical thread exception: {e.Exception}", LogLevel.Error);
- Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
-#endif
- AppDomain.CurrentDomain.UnhandledException += (sender, e) => Program.Monitor.Log($"Critical app domain exception: {e.ExceptionObject}", LogLevel.Error);
-
- // initialise game
try
{
- Program.Monitor.Log("Patching game...");
- Program.gamePtr = new SGame(Program.Monitor);
+ // load the game assembly
+ Program.Monitor.Log("Loading game...");
+ Program.StardewAssembly = Assembly.UnsafeLoadFrom(Program.GameExecutablePath);
+ Program.StardewProgramType = Program.StardewAssembly.GetType("StardewValley.Program", true);
+ Program.StardewGameInfo = Program.StardewProgramType.GetField("gamePtr");
+ Game1.version += $"-Z_MODDED | SMAPI {Constants.Version}";
+
+ // add error interceptors
+#if SMAPI_FOR_WINDOWS
+ Application.ThreadException += (sender, e) => Program.Monitor.Log($"Critical thread exception: {e.Exception}", LogLevel.Error);
+ Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
+#endif
+ AppDomain.CurrentDomain.UnhandledException += (sender, e) => Program.Monitor.Log($"Critical app domain exception: {e.ExceptionObject}", LogLevel.Error);
- // hook events
+ // initialise game instance
+ Program.gamePtr = new SGame(Program.Monitor) { IsMouseVisible = false };
Program.gamePtr.Exiting += (sender, e) => Program.ready = false;
Program.gamePtr.Window.ClientSizeChanged += GraphicsEvents.InvokeResize;
+ Program.gamePtr.Window.Title = $"Stardew Valley - Version {Game1.version}";
+ Program.StardewGameInfo.SetValue(Program.StardewProgramType, Program.gamePtr);
// patch graphics
Game1.graphics.GraphicsProfile = GraphicsProfile.HiDef;
@@ -203,60 +200,50 @@ namespace StardewModdingAPI
// load mods
Program.LoadMods();
- // initialise
- Program.Monitor.Log("Tweaking game...");
- Program.StardewGameInfo.SetValue(Program.StardewProgramType, Program.gamePtr);
- Program.gamePtr.IsMouseVisible = false;
- Program.gamePtr.Window.Title = $"Stardew Valley - Version {Game1.version}";
+ // initialise console after game launches
+ new Thread(() =>
+ {
+ // wait for the game to load up
+ while (!Program.ready) Thread.Sleep(1000);
+
+ // register help command
+ Command.RegisterCommand("help", "Lists all commands | 'help <cmd>' returns command description").CommandFired += Program.help_CommandFired;
+
+ // raise game loaded event
+ GameEvents.InvokeGameLoaded();
+
+ // listen for command line input
+ Program.Monitor.Log("Starting console...");
+ Program.Monitor.Log("Type 'help' for help, or 'help <cmd>' for a command's usage", LogLevel.Info);
+ Thread consoleInputThread = new Thread(Program.ConsoleInputLoop);
+ consoleInputThread.Start();
+ while (Program.ready)
+ Thread.Sleep(1000 / 10); // Check if the game is still running 10 times a second
+
+ // abort the console thread, we're closing
+ if (consoleInputThread.ThreadState == ThreadState.Running)
+ consoleInputThread.Abort();
+ Program.PressAnyKeyToExit();
+ }).Start();
+
+ // start game loop
+ Program.Monitor.Log("Starting game...");
+ try
+ {
+ Program.ready = true;
+ Program.gamePtr.Run();
+ }
+ finally
+ {
+ Program.ready = false;
+ }
}
catch (Exception ex)
{
- Program.Monitor.Log($"Game failed to initialise: {ex}", LogLevel.Error);
+ Program.Monitor.Log($"SMAPI encountered a fatal error:\n{ex}", LogLevel.Error);
+ Program.PressAnyKeyToExit();
return;
}
-
- // initialise after game launches
- new Thread(() =>
- {
- // wait for the game to load up
- while (!Program.ready) Thread.Sleep(1000);
-
- // register help command
- Command.RegisterCommand("help", "Lists all commands | 'help <cmd>' returns command description").CommandFired += Program.help_CommandFired;
-
- // raise game loaded event
- GameEvents.InvokeGameLoaded();
-
- // listen for command line input
- Program.Monitor.Log("Starting console...");
- Program.Monitor.Log("Type 'help' for help, or 'help <cmd>' for a command's usage", LogLevel.Info);
- Thread consoleInputThread = new Thread(Program.ConsoleInputLoop);
- consoleInputThread.Start();
- while (Program.ready)
- Thread.Sleep(1000 / 10); // Check if the game is still running 10 times a second
-
- // abort the console thread, we're closing
- if (consoleInputThread.ThreadState == ThreadState.Running)
- consoleInputThread.Abort();
-
- Program.Monitor.Log("Game has ended. Press any key to continue...", LogLevel.Info);
- Console.ReadKey();
- Thread.Sleep(100);
- Environment.Exit(0);
- }).Start();
-
- // start game loop
- Program.Monitor.Log("Starting Stardew Valley...");
- try
- {
- Program.ready = true;
- Program.gamePtr.Run();
- }
- catch (Exception ex)
- {
- Program.ready = false;
- Program.Monitor.Log($"Game failed to start: {ex}", LogLevel.Error);
- }
}
/// <summary>Create a directory path if it doesn't exist.</summary>
@@ -434,5 +421,14 @@ namespace StardewModdingAPI
else
Program.Monitor.Log("Commands: " + string.Join(", ", Command.RegisteredCommands.Select(x => x.CommandName)), LogLevel.Info);
}
+
+ /// <summary>Show a 'press any key to exit' message, and exit when they press a key.</summary>
+ private static void PressAnyKeyToExit()
+ {
+ Program.Monitor.Log("Game has ended. Press any key to exit.", LogLevel.Info);
+ Console.ReadKey();
+ Thread.Sleep(100);
+ Environment.Exit(0);
+ }
}
}