diff options
-rw-r--r-- | docs/release-notes.md | 7 | ||||
-rw-r--r-- | src/SMAPI/Program.cs | 31 |
2 files changed, 33 insertions, 5 deletions
diff --git a/docs/release-notes.md b/docs/release-notes.md index 1ac7cf0a..1843b0e6 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -9,13 +9,13 @@ ## Upcoming release * For players: - * Added more aggressive memory optimization which should eliminate many cases of `OutOfMemoryException` crashes. + * Added more aggressive memory optimization which should reduce `OutOfMemoryException` errors with some mods. + * Added more detailed error when `Stardew Valley.exe` exists but can't be loaded. * Fixed error running `install on Windows.bat` in very rare cases. * For mod authors: * Fixed asset propagation for `TileSheets/ChairTiles` not changing existing map seats. * Fixed edge case when playing in non-English where translatable assets loaded via `IAssetLoader` would no longer be applied after returning to the title screen unless manually invalidated from the cache. - * Fixed SMAPI toolkit defaulting the mod type incorrectly if a mod's `manifest.json` has neither `EntryDll` nor `ContentPackFor`. This only affects external tools, since SMAPI itself validates those fields separately. * For the ErrorHandler mod: * Added early detection of disposed textures so the crash stack trace shows the actual code which used them. @@ -26,6 +26,9 @@ * Updated the JSON validator/schema for Content Patcher 1.20. * Fixed mod compatibility list error if a mod has no name. +* For SMAPI developers: + * Fixed SMAPI toolkit defaulting the mod type incorrectly if a mod's `manifest.json` has neither `EntryDll` nor `ContentPackFor`. This only affects external tools, since SMAPI itself validates those fields separately. + ## 3.9.1 Released 25 January 2021 for Stardew Valley 1.5.4 or later. diff --git a/src/SMAPI/Program.cs b/src/SMAPI/Program.cs index 23ee8453..986d2780 100644 --- a/src/SMAPI/Program.cs +++ b/src/SMAPI/Program.cs @@ -73,8 +73,22 @@ namespace StardewModdingAPI /// <remarks>This must be checked *before* any references to <see cref="Constants"/>, and this method should not reference <see cref="Constants"/> itself to avoid errors in Mono or when the game isn't present.</remarks> private static void AssertGamePresent() { - if (Type.GetType($"StardewValley.Game1, {EarlyConstants.GameAssemblyName}", throwOnError: false) == null) - Program.PrintErrorAndExit("Oops! SMAPI can't find the game. Make sure you're running StardewModdingAPI.exe in your game folder. See the readme.txt file for details."); + try + { + _ = Type.GetType($"StardewValley.Game1, {EarlyConstants.GameAssemblyName}", throwOnError: true); + } + catch (Exception ex) + { + // file doesn't exist + if (!File.Exists(Path.Combine(EarlyConstants.ExecutionPath, $"{EarlyConstants.GameAssemblyName}.exe"))) + Program.PrintErrorAndExit("Oops! SMAPI can't find the game. Make sure you're running StardewModdingAPI.exe in your game folder."); + + // can't load file + Program.PrintErrorAndExit( + message: "Oops! SMAPI couldn't load the game executable. The technical details below may have more info.", + technicalMessage: $"Technical details: {ex}" + ); + } } /// <summary>Assert that the game version is within <see cref="Constants.MinimumGameVersion"/> and <see cref="Constants.MaximumGameVersion"/>.</summary> @@ -130,11 +144,22 @@ namespace StardewModdingAPI /// <summary>Write an error directly to the console and exit.</summary> /// <param name="message">The error message to display.</param> - private static void PrintErrorAndExit(string message) + /// <param name="technicalMessage">An additional message to log with technical details.</param> + private static void PrintErrorAndExit(string message, string technicalMessage = null) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(message); Console.ResetColor(); + + if (technicalMessage != null) + { + Console.WriteLine(); + Console.ForegroundColor = ConsoleColor.Gray; + Console.WriteLine(technicalMessage); + Console.ResetColor(); + Console.WriteLine(); + } + Program.PressAnyKeyToExit(showMessage: true); } |