diff options
author | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2021-05-01 17:39:34 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2021-05-01 17:39:34 -0400 |
commit | 28c5cb79d4ca671881c54f473a9cfb6235298099 (patch) | |
tree | c59d1a3c36f6afe4a3416ce4cd92d097fccff7e6 /src | |
parent | 99f70f963459912ce66f5a586eb4fc36e561b69d (diff) | |
download | SMAPI-28c5cb79d4ca671881c54f473a9cfb6235298099.tar.gz SMAPI-28c5cb79d4ca671881c54f473a9cfb6235298099.tar.bz2 SMAPI-28c5cb79d4ca671881c54f473a9cfb6235298099.zip |
add error-handling for seasonal tilesheet crash
Diffstat (limited to 'src')
-rw-r--r-- | src/SMAPI.Mods.ErrorHandler/Patches/GameLocationPatches.cs | 59 | ||||
-rw-r--r-- | src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj | 1 |
2 files changed, 56 insertions, 4 deletions
diff --git a/src/SMAPI.Mods.ErrorHandler/Patches/GameLocationPatches.cs b/src/SMAPI.Mods.ErrorHandler/Patches/GameLocationPatches.cs index 1edf2d6a..7a48133e 100644 --- a/src/SMAPI.Mods.ErrorHandler/Patches/GameLocationPatches.cs +++ b/src/SMAPI.Mods.ErrorHandler/Patches/GameLocationPatches.cs @@ -8,10 +8,11 @@ using Harmony; #endif using StardewModdingAPI.Framework.Patching; using StardewValley; +using xTile; namespace StardewModdingAPI.Mods.ErrorHandler.Patches { - /// <summary>A Harmony patch for <see cref="GameLocation.checkEventPrecondition"/> which intercepts invalid preconditions and logs an error instead of crashing.</summary> + /// <summary>Harmony patches for <see cref="GameLocation.checkEventPrecondition"/> and <see cref="GameLocation.updateSeasonalTileSheets"/> which intercept errors instead of crashing.</summary> /// <remarks>Patch methods must be static for Harmony to work correctly. See the Harmony documentation before renaming patch arguments.</remarks> [SuppressMessage("ReSharper", "InconsistentNaming", Justification = "Argument names are defined by Harmony and methods are named for clarity.")] [SuppressMessage("ReSharper", "IdentifierTypo", Justification = "Argument names are defined by Harmony and methods are named for clarity.")] @@ -39,17 +40,25 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches public void Apply(Harmony harmony) { harmony.Patch( - original: AccessTools.Method(typeof(GameLocation), "checkEventPrecondition"), + original: AccessTools.Method(typeof(GameLocation), nameof(GameLocation.checkEventPrecondition)), finalizer: new HarmonyMethod(this.GetType(), nameof(EventErrorPatch.Finalize_GameLocation_CheckEventPrecondition)) ); +harmony.Patch( + original: AccessTools.Method(typeof(GameLocation), nameof(GameLocation.updateSeasonalTileSheets)), + finalizer: new HarmonyMethod(this.GetType(), nameof(EventErrorPatch.Before_GameLocation_UpdateSeasonalTileSheets)) + ); } #else public void Apply(HarmonyInstance harmony) { harmony.Patch( - original: AccessTools.Method(typeof(GameLocation), "checkEventPrecondition"), + original: AccessTools.Method(typeof(GameLocation), nameof(GameLocation.checkEventPrecondition)), prefix: new HarmonyMethod(this.GetType(), nameof(GameLocationPatches.Before_GameLocation_CheckEventPrecondition)) ); + harmony.Patch( + original: AccessTools.Method(typeof(GameLocation), nameof(GameLocation.updateSeasonalTileSheets)), + prefix: new HarmonyMethod(this.GetType(), nameof(GameLocationPatches.Before_GameLocation_UpdateSeasonalTileSheets)) + ); } #endif @@ -74,7 +83,7 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches return null; } #else - /// <summary>The method to call instead of GameLocation.checkEventPrecondition.</summary> + /// <summary>The method to call instead of <see cref="GameLocation.checkEventPrecondition"/>.</summary> /// <param name="__instance">The instance being patched.</param> /// <param name="__result">The return value of the original method.</param> /// <param name="precondition">The precondition to be parsed.</param> @@ -103,5 +112,47 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches } } #endif + +#if HARMONY_2 + /// <summary>The method to call instead of <see cref="GameLocation.updateSeasonalTileSheets"/>.</summary> + /// <param name="__instance">The instance being patched.</param> + /// <param name="map">The map whose tilesheets to update.</param> + /// <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 Before_GameLocation_UpdateSeasonalTileSheets(GameLocation __instance, Map map, Exception __exception) + { + if (__exception != null) + GameLocationPatches.MonitorForGame.Log($"Failed updating seasonal tilesheets for location '{__instance.NameOrUniqueName}': \n{__exception}", LogLevel.Error); + + return null; + } +#else + /// <summary>The method to call instead of <see cref="GameLocation.updateSeasonalTileSheets"/>.</summary> + /// <param name="__instance">The instance being patched.</param> + /// <param name="map">The map whose tilesheets to update.</param> + /// <param name="__originalMethod">The method being wrapped.</param> + /// <returns>Returns whether to execute the original method.</returns> + private static bool Before_GameLocation_UpdateSeasonalTileSheets(GameLocation __instance, Map map, MethodInfo __originalMethod) + { + const string key = nameof(GameLocationPatches.Before_GameLocation_UpdateSeasonalTileSheets); + if (!PatchHelper.StartIntercept(key)) + return true; + + try + { + __originalMethod.Invoke(__instance, new object[] { map }); + return false; + } + catch (TargetInvocationException ex) + { + GameLocationPatches.MonitorForGame.Log($"Failed updating seasonal tilesheets for location '{__instance.NameOrUniqueName}'. Technical details:\n{ex.InnerException}", LogLevel.Error); + return false; + } + finally + { + PatchHelper.StopIntercept(key); + } + } +#endif } } diff --git a/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj b/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj index 56daa710..006a09ca 100644 --- a/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj +++ b/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj @@ -15,6 +15,7 @@ <ItemGroup> <Reference Include="$(GameExecutableName)" HintPath="$(GamePath)\$(GameExecutableName).exe" Private="False" /> + <Reference Include="xTile" HintPath="$(GamePath)\xTile.dll" Private="False" /> </ItemGroup> <!-- Windows only --> |