summaryrefslogtreecommitdiff
path: root/src/SMAPI/Framework/SCore.cs
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2022-08-20 17:01:59 -0400
committerJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2022-08-20 17:01:59 -0400
commita1bc96d365dc40275f198668d3f4c09bd7a92613 (patch)
tree5a130399bf8031aa70defb71a121b740d7c6cd7a /src/SMAPI/Framework/SCore.cs
parentd51ffe58f7b7450cd4c4a7ee3d8b4da1cf55e7e4 (diff)
parentf3a79219e85c9af18f2f6d8b2aaa794afa08578d (diff)
downloadSMAPI-a1bc96d365dc40275f198668d3f4c09bd7a92613.tar.gz
SMAPI-a1bc96d365dc40275f198668d3f4c09bd7a92613.tar.bz2
SMAPI-a1bc96d365dc40275f198668d3f4c09bd7a92613.zip
Merge branch 'develop' into stable
Diffstat (limited to 'src/SMAPI/Framework/SCore.cs')
-rw-r--r--src/SMAPI/Framework/SCore.cs67
1 files changed, 46 insertions, 21 deletions
diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs
index 46d65f6a..0f86ed6b 100644
--- a/src/SMAPI/Framework/SCore.cs
+++ b/src/SMAPI/Framework/SCore.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
@@ -50,6 +49,7 @@ using StardewModdingAPI.Utilities;
using StardewValley;
using StardewValley.Menus;
using StardewValley.Objects;
+using StardewValley.SDKs;
using xTile.Display;
using LanguageCode = StardewValley.LocalizedContentManager.LanguageCode;
using MiniMonoModHotfix = MonoMod.Utils.MiniMonoModHotfix;
@@ -67,8 +67,11 @@ namespace StardewModdingAPI.Framework
/****
** Low-level components
****/
+ /// <summary>A state which indicates whether SMAPI should exit immediately and any pending initialization should be cancelled.</summary>
+ private ExitState ExitState;
+
/// <summary>Whether the game should exit immediately and any pending initialization should be cancelled.</summary>
- private bool IsExiting;
+ private bool IsExiting => this.ExitState != ExitState.None;
/// <summary>Manages the SMAPI console window and log file.</summary>
private readonly LogManager LogManager;
@@ -297,22 +300,13 @@ namespace StardewModdingAPI.Framework
this.IsGameRunning = true;
StardewValley.Program.releaseBuild = true; // game's debug logic interferes with SMAPI opening the game window
this.Game.Run();
+ this.Dispose(isError: false);
}
catch (Exception ex)
{
this.LogManager.LogFatalLaunchError(ex);
this.LogManager.PressAnyKeyToExit();
- }
- finally
- {
- try
- {
- this.Dispose();
- }
- catch (Exception ex)
- {
- this.Monitor.Log($"The game ended, but SMAPI wasn't able to dispose correctly. Technical details: {ex}", LogLevel.Error);
- }
+ this.Dispose(isError: true);
}
}
@@ -328,6 +322,14 @@ namespace StardewModdingAPI.Framework
[SuppressMessage("ReSharper", "ConditionalAccessQualifierIsNonNullableAccordingToAPIContract", Justification = "May be disposed before SMAPI is fully initialized.")]
public void Dispose()
{
+ this.Dispose(isError: true); // if we got here, SMAPI didn't detect the exit before it happened
+ }
+
+ /// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
+ /// <param name="isError">Whether the process is exiting due to an error or crash.</param>
+ [SuppressMessage("ReSharper", "ConditionalAccessQualifierIsNonNullableAccordingToAPIContract", Justification = "May be disposed before SMAPI is fully initialized.")]
+ public void Dispose(bool isError)
+ {
// skip if already disposed
if (this.IsDisposed)
return;
@@ -349,13 +351,29 @@ namespace StardewModdingAPI.Framework
// dispose core components
this.IsGameRunning = false;
- this.IsExiting = true;
+ if (this.ExitState == ExitState.None || isError)
+ this.ExitState = isError ? ExitState.Crash : ExitState.GameExit;
this.ContentCore?.Dispose();
this.Game?.Dispose();
this.LogManager.Dispose(); // dispose last to allow for any last-second log messages
- // end game (moved from Game1.OnExiting to let us clean up first)
- Process.GetCurrentProcess().Kill();
+ // clean up SDK
+ // This avoids Steam connection errors when it exits unexpectedly. The game avoids this
+ // by killing the entire process, but we can't set the error code if we do that.
+ try
+ {
+ FieldInfo? field = typeof(StardewValley.Program).GetField("_sdk", BindingFlags.NonPublic | BindingFlags.Static);
+ SDKHelper? sdk = field?.GetValue(null) as SDKHelper;
+ sdk?.Shutdown();
+ }
+ catch
+ {
+ // well, at least we tried
+ }
+
+ // end game with error code
+ // This helps the OS decide whether to keep the window open (e.g. Windows may keep it open on error).
+ Environment.Exit(this.ExitState == ExitState.Crash ? 1 : 0);
}
@@ -387,7 +405,14 @@ namespace StardewModdingAPI.Framework
{
string[] looseFiles = new DirectoryInfo(this.ModsPath).GetFiles().Select(p => p.Name).ToArray();
if (looseFiles.Any())
+ {
+ if (looseFiles.Any(name => name.Equals("manifest.json", StringComparison.OrdinalIgnoreCase) || name.EndsWith(".dll", StringComparison.OrdinalIgnoreCase)))
+ {
+ this.Monitor.Log($"Detected mod files directly inside the '{Path.GetFileName(this.ModsPath)}' folder. These will be ignored. Each mod must have its own subfolder instead.", LogLevel.Error);
+ }
+
this.Monitor.Log($" Ignored loose files: {string.Join(", ", looseFiles.OrderBy(p => p, StringComparer.OrdinalIgnoreCase))}");
+ }
}
// load manifests
@@ -1250,7 +1275,7 @@ namespace StardewModdingAPI.Framework
private void OnGameExiting()
{
this.Multiplayer.Disconnect(StardewValley.Multiplayer.DisconnectType.ClosedGame);
- this.Dispose();
+ this.Dispose(isError: false);
}
/// <summary>Raised when a mod network message is received.</summary>
@@ -1670,7 +1695,7 @@ namespace StardewModdingAPI.Framework
source: metadata,
nounPhrase: $"{nameof(IAssetEditor)}",
version: "3.14.0",
- severity: DeprecationLevel.Notice,
+ severity: DeprecationLevel.Info,
logStackTrace: false
);
@@ -1683,7 +1708,7 @@ namespace StardewModdingAPI.Framework
source: metadata,
nounPhrase: $"{nameof(IAssetLoader)}",
version: "3.14.0",
- severity: DeprecationLevel.Notice,
+ severity: DeprecationLevel.Info,
logStackTrace: false
);
@@ -1715,7 +1740,7 @@ namespace StardewModdingAPI.Framework
metadata,
$"using {name} without bundling it",
"3.14.7",
- DeprecationLevel.Notice,
+ DeprecationLevel.Info,
logStackTrace: false
);
}
@@ -2239,7 +2264,7 @@ namespace StardewModdingAPI.Framework
this.Monitor.LogFatal(message);
this.LogManager.WriteCrashLog();
- this.IsExiting = true;
+ this.ExitState = ExitState.Crash;
this.Game.Exit();
}