diff options
author | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2022-01-15 17:21:11 -0500 |
---|---|---|
committer | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2022-01-15 17:21:11 -0500 |
commit | 4cffd6c2c092b18940f2dd1041e418f60573a87e (patch) | |
tree | e4d07afd879337f3dbe66f6cc89d458fb748c52e | |
parent | 8ebb9ce8d4c554b077e1e6286531c101d64c019d (diff) | |
download | SMAPI-4cffd6c2c092b18940f2dd1041e418f60573a87e.tar.gz SMAPI-4cffd6c2c092b18940f2dd1041e418f60573a87e.tar.bz2 SMAPI-4cffd6c2c092b18940f2dd1041e418f60573a87e.zip |
add save recovery for missing custom farm type
-rw-r--r-- | docs/release-notes.md | 3 | ||||
-rw-r--r-- | src/SMAPI.Mods.ErrorHandler/Patches/SaveGamePatcher.cs | 30 |
2 files changed, 30 insertions, 3 deletions
diff --git a/docs/release-notes.md b/docs/release-notes.md index 06d75b15..aea4dbab 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -3,7 +3,8 @@ # Release notes ## Upcoming release * For players: - * Added auto-fix for custom maps which don't have a required tilesheet. + * Added automatic fix for custom maps which don't have a required tilesheet. + * Added automatic save recovery when the custom farm type isn't available anymore. * Added the new game build number to the SMAPI console + log. * Fixed extra newlines shown in the console in non-developer mode. * Fixed macOS launch issue when using some terminals (thanks to bruce2409!). diff --git a/src/SMAPI.Mods.ErrorHandler/Patches/SaveGamePatcher.cs b/src/SMAPI.Mods.ErrorHandler/Patches/SaveGamePatcher.cs index 2a43cb10..0a7ed212 100644 --- a/src/SMAPI.Mods.ErrorHandler/Patches/SaveGamePatcher.cs +++ b/src/SMAPI.Mods.ErrorHandler/Patches/SaveGamePatcher.cs @@ -4,11 +4,11 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; using HarmonyLib; using Microsoft.Xna.Framework.Content; +using StardewModdingAPI.Internal; using StardewModdingAPI.Internal.Patching; using StardewValley; using StardewValley.Buildings; using StardewValley.Locations; -using SObject = StardewValley.Object; namespace StardewModdingAPI.Mods.ErrorHandler.Patches { @@ -47,6 +47,11 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches original: this.RequireMethod<SaveGame>(nameof(SaveGame.loadDataToLocations)), prefix: this.GetHarmonyMethod(nameof(SaveGamePatcher.Before_LoadDataToLocations)) ); + + harmony.Patch( + original: this.RequireMethod<SaveGame>(nameof(SaveGame.LoadFarmType)), + finalizer: this.GetHarmonyMethod(nameof(SaveGamePatcher.Finalize_LoadFarmType)) + ); } @@ -58,14 +63,35 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches /// <returns>Returns whether to execute the original method.</returns> private static bool Before_LoadDataToLocations(List<GameLocation> gamelocations) { + // missing locations/NPCs IDictionary<string, string> npcs = Game1.content.Load<Dictionary<string, string>>("Data\\NPCDispositions"); - if (SaveGamePatcher.RemoveBrokenContent(gamelocations, npcs)) SaveGamePatcher.OnContentRemoved(); return true; } + /// <summary>The method to call after <see cref="SaveGame.LoadFarmType"/> throws an exception.</summary> + /// <param name="__exception">The exception thrown by the wrapped method, if any.</param> + /// <returns>Returns the exception to throw, if any.</returns> + private static Exception Finalize_LoadFarmType(Exception __exception) + { + // missing custom farm type + if (__exception?.Message?.Contains("not a valid farm type") == true && !int.TryParse(SaveGame.loaded.whichFarm, out _)) + { + SaveGamePatcher.Monitor.Log(__exception.GetLogSummary(), LogLevel.Error); + SaveGamePatcher.Monitor.Log($"Removed invalid custom farm type '{SaveGame.loaded.whichFarm}' to avoid a crash when loading save '{Constants.SaveFolderName}'. (Did you remove a custom farm type mod?)", LogLevel.Warn); + + SaveGame.loaded.whichFarm = Farm.default_layout.ToString(); + SaveGame.LoadFarmType(); + SaveGamePatcher.OnContentRemoved(); + + __exception = null; + } + + return __exception; + } + /// <summary>Remove content which no longer exists in the game data.</summary> /// <param name="locations">The current game locations.</param> /// <param name="npcs">The NPC data.</param> |