From 65997c1243a60ae15cc0b832ebcd41d96c3ea06a Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Tue, 1 Oct 2019 21:41:15 -0400 Subject: auto-fix save data when a custom location mod is removed --- src/SMAPI/Patches/LoadErrorPatch.cs | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'src/SMAPI/Patches') diff --git a/src/SMAPI/Patches/LoadErrorPatch.cs b/src/SMAPI/Patches/LoadErrorPatch.cs index 87e8ee14..eedb4164 100644 --- a/src/SMAPI/Patches/LoadErrorPatch.cs +++ b/src/SMAPI/Patches/LoadErrorPatch.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; @@ -20,6 +21,9 @@ namespace StardewModdingAPI.Patches /// Writes messages to the console and log file. private static IMonitor Monitor; + /// A callback invoked when custom content is removed from the save data to avoid a crash. + private static Action OnContentRemoved; + /********* ** Accessors @@ -33,9 +37,11 @@ namespace StardewModdingAPI.Patches *********/ /// Construct an instance. /// Writes messages to the console and log file. - public LoadErrorPatch(IMonitor monitor) + /// A callback invoked when custom content is removed from the save data to avoid a crash. + public LoadErrorPatch(IMonitor monitor, Action onContentRemoved) { LoadErrorPatch.Monitor = monitor; + LoadErrorPatch.OnContentRemoved = onContentRemoved; } @@ -58,6 +64,22 @@ namespace StardewModdingAPI.Patches /// Returns whether to execute the original method. private static bool Before_SaveGame_LoadDataToLocations(List gamelocations) { + bool removedAny = false; + + // remove invalid locations + foreach (GameLocation location in gamelocations.ToArray()) + { + if (location is Cellar) + continue; // missing cellars will be added by the game code + + if (Game1.getLocationFromName(location.name) == null) + { + LoadErrorPatch.Monitor.Log($"Removed invalid location '{location.Name}' to avoid a crash when loading save '{Constants.SaveFolderName}'. (Did you remove a custom location mod?)", LogLevel.Warn); + gamelocations.Remove(location); + removedAny = true; + } + } + // get building interiors var interiors = ( @@ -83,11 +105,15 @@ namespace StardewModdingAPI.Patches { LoadErrorPatch.Monitor.Log($"Removed invalid villager '{npc.Name}' to avoid a crash when loading save '{Constants.SaveFolderName}'. (Did you remove a custom NPC mod?)", LogLevel.Warn); location.characters.Remove(npc); + removedAny = true; } } } } + if (removedAny) + LoadErrorPatch.OnContentRemoved(); + return true; } } -- cgit