From 948c800a98f00b1bdcfd05ee6228e3423f9eb465 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Fri, 30 Jul 2021 00:54:15 -0400 Subject: migrate to the new Harmony patch pattern used in my mods That improves validation and error-handling. --- src/SMAPI.Mods.ErrorHandler/ModEntry.cs | 4 ++-- .../Patches/DialoguePatcher.cs | 18 +++++++------- .../Patches/DictionaryPatcher.cs | 28 +++++++++------------- .../Patches/EventPatcher.cs | 12 +++++----- .../Patches/GameLocationPatcher.cs | 24 +++++++++---------- .../Patches/IClickableMenuPatcher.cs | 14 +++++------ src/SMAPI.Mods.ErrorHandler/Patches/NpcPatcher.cs | 24 +++++++++---------- .../Patches/ObjectPatcher.cs | 16 ++++++------- .../Patches/SaveGamePatcher.cs | 15 ++++++------ .../Patches/SpriteBatchPatcher.cs | 20 ++++++++-------- .../Patches/UtilityPatcher.cs | 14 +++++------ .../SMAPI.Mods.ErrorHandler.csproj | 1 + 12 files changed, 92 insertions(+), 98 deletions(-) (limited to 'src/SMAPI.Mods.ErrorHandler') diff --git a/src/SMAPI.Mods.ErrorHandler/ModEntry.cs b/src/SMAPI.Mods.ErrorHandler/ModEntry.cs index ac9d1b94..067f6a8d 100644 --- a/src/SMAPI.Mods.ErrorHandler/ModEntry.cs +++ b/src/SMAPI.Mods.ErrorHandler/ModEntry.cs @@ -1,7 +1,7 @@ using System; using System.Reflection; using StardewModdingAPI.Events; -using StardewModdingAPI.Framework.Patching; +using StardewModdingAPI.Internal.Patching; using StardewModdingAPI.Mods.ErrorHandler.Patches; using StardewValley; @@ -28,7 +28,7 @@ namespace StardewModdingAPI.Mods.ErrorHandler IMonitor monitorForGame = this.GetMonitorForGame(); // apply patches - new GamePatcher(this.Monitor).Apply( + HarmonyPatcher.Apply(this.ModManifest.UniqueID, this.Monitor, new DialoguePatcher(monitorForGame, this.Helper.Reflection), new DictionaryPatcher(this.Helper.Reflection), new EventPatcher(monitorForGame), diff --git a/src/SMAPI.Mods.ErrorHandler/Patches/DialoguePatcher.cs b/src/SMAPI.Mods.ErrorHandler/Patches/DialoguePatcher.cs index 7b730ee5..7a3af39c 100644 --- a/src/SMAPI.Mods.ErrorHandler/Patches/DialoguePatcher.cs +++ b/src/SMAPI.Mods.ErrorHandler/Patches/DialoguePatcher.cs @@ -1,17 +1,17 @@ using System; using System.Diagnostics.CodeAnalysis; using HarmonyLib; -using StardewModdingAPI.Framework; -using StardewModdingAPI.Framework.Patching; +using StardewModdingAPI.Internal; +using StardewModdingAPI.Internal.Patching; using StardewValley; namespace StardewModdingAPI.Mods.ErrorHandler.Patches { - /// A Harmony patch for the constructor which intercepts invalid dialogue lines and logs an error instead of crashing. + /// Harmony patches for which intercept invalid dialogue lines and logs an error instead of crashing. /// Patch methods must be static for Harmony to work correctly. See the Harmony documentation before renaming patch arguments. [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.")] - internal class DialoguePatcher : IHarmonyPatch + internal class DialoguePatcher : BasePatcher { /********* ** Fields @@ -36,11 +36,11 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches } /// - public void Apply(Harmony harmony) + public override void Apply(Harmony harmony, IMonitor monitor) { harmony.Patch( - original: AccessTools.Constructor(typeof(Dialogue), new[] { typeof(string), typeof(NPC) }), - finalizer: new HarmonyMethod(this.GetType(), nameof(DialoguePatcher.Finalize_Dialogue_Constructor)) + original: this.RequireConstructor(typeof(string), typeof(NPC)), + finalizer: this.GetHarmonyMethod(nameof(DialoguePatcher.Finalize_Constructor)) ); } @@ -48,13 +48,13 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches /********* ** Private methods *********/ - /// The method to call after the Dialogue constructor. + /// The method to call when the Dialogue constructor throws an exception. /// The instance being patched. /// The dialogue being parsed. /// The NPC for which the dialogue is being parsed. /// The exception thrown by the wrapped method, if any. /// Returns the exception to throw, if any. - private static Exception Finalize_Dialogue_Constructor(Dialogue __instance, string masterDialogue, NPC speaker, Exception __exception) + private static Exception Finalize_Constructor(Dialogue __instance, string masterDialogue, NPC speaker, Exception __exception) { if (__exception != null) { diff --git a/src/SMAPI.Mods.ErrorHandler/Patches/DictionaryPatcher.cs b/src/SMAPI.Mods.ErrorHandler/Patches/DictionaryPatcher.cs index 3c5240b6..6ad64e16 100644 --- a/src/SMAPI.Mods.ErrorHandler/Patches/DictionaryPatcher.cs +++ b/src/SMAPI.Mods.ErrorHandler/Patches/DictionaryPatcher.cs @@ -2,18 +2,18 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using HarmonyLib; -using StardewModdingAPI.Framework.Patching; +using StardewModdingAPI.Internal.Patching; using StardewValley.GameData; using StardewValley.GameData.HomeRenovations; using StardewValley.GameData.Movies; namespace StardewModdingAPI.Mods.ErrorHandler.Patches { - /// A Harmony patch for which adds the accessed key to exceptions. + /// Harmony patches for which add the accessed key to exceptions. /// Patch methods must be static for Harmony to work correctly. See the Harmony documentation before renaming patch arguments. [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.")] - internal class DictionaryPatcher : IHarmonyPatch + internal class DictionaryPatcher : BasePatcher { /********* ** Fields @@ -33,7 +33,7 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches } /// - public void Apply(Harmony harmony) + public override void Apply(Harmony harmony, IMonitor monitor) { Type[] keyTypes = { typeof(int), typeof(string) }; Type[] valueTypes = { typeof(int), typeof(string), typeof(HomeRenovation), typeof(MovieData), typeof(SpecialOrderData) }; @@ -45,8 +45,8 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches Type dictionaryType = typeof(Dictionary<,>).MakeGenericType(keyType, valueType); harmony.Patch( - original: AccessTools.Method(dictionaryType, "get_Item"), - finalizer: new HarmonyMethod(this.GetType(), nameof(DictionaryPatcher.Finalize_GetItem)) + original: AccessTools.Method(dictionaryType, "get_Item") ?? throw new InvalidOperationException($"Can't find method {PatchHelper.GetMethodString(dictionaryType, "get_Item")} to patch."), + finalizer: this.GetHarmonyMethod(nameof(DictionaryPatcher.Finalize_GetItem)) ); } } @@ -63,19 +63,13 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches private static Exception Finalize_GetItem(object key, Exception __exception) { if (__exception is KeyNotFoundException) - AddKeyTo(__exception, key?.ToString()); + { + DictionaryPatcher.Reflection + .GetField(__exception, "_message") + .SetValue($"{__exception.Message}\nkey: '{key}'"); + } return __exception; } - - /// Add the accessed key to an exception message. - /// The exception to modify. - /// The dictionary key. - private static void AddKeyTo(Exception exception, string key) - { - DictionaryPatcher.Reflection - .GetField(exception, "_message") - .SetValue($"{exception.Message}\nkey: '{key}'"); - } } } diff --git a/src/SMAPI.Mods.ErrorHandler/Patches/EventPatcher.cs b/src/SMAPI.Mods.ErrorHandler/Patches/EventPatcher.cs index 9a7b34d8..1b706147 100644 --- a/src/SMAPI.Mods.ErrorHandler/Patches/EventPatcher.cs +++ b/src/SMAPI.Mods.ErrorHandler/Patches/EventPatcher.cs @@ -1,7 +1,7 @@ using System; using System.Diagnostics.CodeAnalysis; using HarmonyLib; -using StardewModdingAPI.Framework.Patching; +using StardewModdingAPI.Internal.Patching; using StardewValley; namespace StardewModdingAPI.Mods.ErrorHandler.Patches @@ -10,7 +10,7 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches /// Patch methods must be static for Harmony to work correctly. See the Harmony documentation before renaming patch arguments. [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.")] - internal class EventPatcher : IHarmonyPatch + internal class EventPatcher : BasePatcher { /********* ** Fields @@ -30,11 +30,11 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches } /// - public void Apply(Harmony harmony) + public override void Apply(Harmony harmony, IMonitor monitor) { harmony.Patch( - original: AccessTools.Method(typeof(Event), nameof(Event.LogErrorAndHalt)), - postfix: new HarmonyMethod(this.GetType(), nameof(EventPatcher.After_Event_LogErrorAndHalt)) + original: this.RequireMethod(nameof(Event.LogErrorAndHalt)), + postfix: this.GetHarmonyMethod(nameof(EventPatcher.After_LogErrorAndHalt)) ); } @@ -44,7 +44,7 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches *********/ /// The method to call after . /// The exception being logged. - private static void After_Event_LogErrorAndHalt(Exception e) + private static void After_LogErrorAndHalt(Exception e) { EventPatcher.MonitorForGame.Log(e.ToString(), LogLevel.Error); } diff --git a/src/SMAPI.Mods.ErrorHandler/Patches/GameLocationPatcher.cs b/src/SMAPI.Mods.ErrorHandler/Patches/GameLocationPatcher.cs index 7427fe48..7df6b0a2 100644 --- a/src/SMAPI.Mods.ErrorHandler/Patches/GameLocationPatcher.cs +++ b/src/SMAPI.Mods.ErrorHandler/Patches/GameLocationPatcher.cs @@ -1,17 +1,17 @@ using System; using System.Diagnostics.CodeAnalysis; using HarmonyLib; -using StardewModdingAPI.Framework.Patching; +using StardewModdingAPI.Internal.Patching; using StardewValley; using xTile; namespace StardewModdingAPI.Mods.ErrorHandler.Patches { - /// Harmony patches for and which intercept errors instead of crashing. + /// Harmony patches for which intercept errors instead of crashing. /// Patch methods must be static for Harmony to work correctly. See the Harmony documentation before renaming patch arguments. [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.")] - internal class GameLocationPatcher : IHarmonyPatch + internal class GameLocationPatcher : BasePatcher { /********* ** Fields @@ -31,15 +31,15 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches } /// - public void Apply(Harmony harmony) + public override void Apply(Harmony harmony, IMonitor monitor) { harmony.Patch( - original: AccessTools.Method(typeof(GameLocation), nameof(GameLocation.checkEventPrecondition)), - finalizer: new HarmonyMethod(this.GetType(), nameof(GameLocationPatcher.Finalize_GameLocation_CheckEventPrecondition)) + original: this.RequireMethod(nameof(GameLocation.checkEventPrecondition)), + finalizer: this.GetHarmonyMethod(nameof(GameLocationPatcher.Finalize_CheckEventPrecondition)) ); harmony.Patch( - original: AccessTools.Method(typeof(GameLocation), nameof(GameLocation.updateSeasonalTileSheets)), - finalizer: new HarmonyMethod(this.GetType(), nameof(GameLocationPatcher.Before_GameLocation_UpdateSeasonalTileSheets)) + original: this.RequireMethod(nameof(GameLocation.updateSeasonalTileSheets)), + finalizer: this.GetHarmonyMethod(nameof(GameLocationPatcher.Finalize_UpdateSeasonalTileSheets)) ); } @@ -47,12 +47,12 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches /********* ** Private methods *********/ - /// The method to call instead of GameLocation.checkEventPrecondition. + /// The method to call when throws an exception. /// The return value of the original method. /// The precondition to be parsed. /// The exception thrown by the wrapped method, if any. /// Returns the exception to throw, if any. - private static Exception Finalize_GameLocation_CheckEventPrecondition(ref int __result, string precondition, Exception __exception) + private static Exception Finalize_CheckEventPrecondition(ref int __result, string precondition, Exception __exception) { if (__exception != null) { @@ -63,12 +63,12 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches return null; } - /// The method to call instead of . + /// The method to call when throws an exception. /// The instance being patched. /// The map whose tilesheets to update. /// The exception thrown by the wrapped method, if any. /// Returns the exception to throw, if any. - private static Exception Before_GameLocation_UpdateSeasonalTileSheets(GameLocation __instance, Map map, Exception __exception) + private static Exception Finalize_UpdateSeasonalTileSheets(GameLocation __instance, Map map, Exception __exception) { if (__exception != null) GameLocationPatcher.MonitorForGame.Log($"Failed updating seasonal tilesheets for location '{__instance.NameOrUniqueName}': \n{__exception}", LogLevel.Error); diff --git a/src/SMAPI.Mods.ErrorHandler/Patches/IClickableMenuPatcher.cs b/src/SMAPI.Mods.ErrorHandler/Patches/IClickableMenuPatcher.cs index d6f9fbf4..b65a695a 100644 --- a/src/SMAPI.Mods.ErrorHandler/Patches/IClickableMenuPatcher.cs +++ b/src/SMAPI.Mods.ErrorHandler/Patches/IClickableMenuPatcher.cs @@ -1,27 +1,27 @@ using System.Diagnostics.CodeAnalysis; using HarmonyLib; -using StardewModdingAPI.Framework.Patching; +using StardewModdingAPI.Internal.Patching; using StardewValley; using StardewValley.Menus; using SObject = StardewValley.Object; namespace StardewModdingAPI.Mods.ErrorHandler.Patches { - /// A Harmony patch for which intercepts crashes due to invalid items. + /// Harmony patches for which intercept crashes due to invalid items. /// Patch methods must be static for Harmony to work correctly. See the Harmony documentation before renaming patch arguments. [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.")] - internal class IClickableMenuPatcher : IHarmonyPatch + internal class IClickableMenuPatcher : BasePatcher { /********* ** Public methods *********/ /// - public void Apply(Harmony harmony) + public override void Apply(Harmony harmony, IMonitor monitor) { harmony.Patch( - original: AccessTools.Method(typeof(IClickableMenu), nameof(IClickableMenu.drawToolTip)), - prefix: new HarmonyMethod(this.GetType(), nameof(IClickableMenuPatcher.Before_IClickableMenu_DrawTooltip)) + original: this.RequireMethod(nameof(IClickableMenu.drawToolTip)), + prefix: this.GetHarmonyMethod(nameof(IClickableMenuPatcher.Before_DrawTooltip)) ); } @@ -32,7 +32,7 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches /// The method to call instead of . /// The item for which to draw a tooltip. /// Returns whether to execute the original method. - private static bool Before_IClickableMenu_DrawTooltip(Item hoveredItem) + private static bool Before_DrawTooltip(Item hoveredItem) { // invalid edible item cause crash when drawing tooltips if (hoveredItem is SObject obj && obj.Edibility != -300 && !Game1.objectInformation.ContainsKey(obj.ParentSheetIndex)) diff --git a/src/SMAPI.Mods.ErrorHandler/Patches/NpcPatcher.cs b/src/SMAPI.Mods.ErrorHandler/Patches/NpcPatcher.cs index 4a07ea1d..275bb5bf 100644 --- a/src/SMAPI.Mods.ErrorHandler/Patches/NpcPatcher.cs +++ b/src/SMAPI.Mods.ErrorHandler/Patches/NpcPatcher.cs @@ -2,17 +2,17 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using HarmonyLib; -using StardewModdingAPI.Framework; -using StardewModdingAPI.Framework.Patching; +using StardewModdingAPI.Internal; +using StardewModdingAPI.Internal.Patching; using StardewValley; namespace StardewModdingAPI.Mods.ErrorHandler.Patches { - /// A Harmony patch for which intercepts crashes due to invalid schedule data. + /// Harmony patches for which intercept crashes due to invalid schedule data. /// Patch methods must be static for Harmony to work correctly. See the Harmony documentation before renaming patch arguments. [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.")] - internal class NpcPatcher : IHarmonyPatch + internal class NpcPatcher : BasePatcher { /********* ** Fields @@ -32,16 +32,16 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches } /// - public void Apply(Harmony harmony) + public override void Apply(Harmony harmony, IMonitor monitor) { harmony.Patch( - original: AccessTools.Property(typeof(NPC), nameof(NPC.CurrentDialogue)).GetMethod, - finalizer: new HarmonyMethod(this.GetType(), nameof(NpcPatcher.Finalize_NPC_CurrentDialogue)) + original: this.RequireMethod($"get_{nameof(NPC.CurrentDialogue)}"), + finalizer: this.GetHarmonyMethod(nameof(NpcPatcher.Finalize_CurrentDialogue)) ); harmony.Patch( - original: AccessTools.Method(typeof(NPC), nameof(NPC.parseMasterSchedule)), - finalizer: new HarmonyMethod(this.GetType(), nameof(NpcPatcher.Finalize_NPC_parseMasterSchedule)) + original: this.RequireMethod(nameof(NPC.parseMasterSchedule)), + finalizer: this.GetHarmonyMethod(nameof(NpcPatcher.Finalize_ParseMasterSchedule)) ); } @@ -49,12 +49,12 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches /********* ** Private methods *********/ - /// The method to call after . + /// The method to call when throws an exception. /// The instance being patched. /// The return value of the original method. /// The exception thrown by the wrapped method, if any. /// Returns the exception to throw, if any. - private static Exception Finalize_NPC_CurrentDialogue(NPC __instance, ref Stack __result, Exception __exception) + private static Exception Finalize_CurrentDialogue(NPC __instance, ref Stack __result, Exception __exception) { if (__exception == null) return null; @@ -71,7 +71,7 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches /// The patched method's return value. /// The exception thrown by the wrapped method, if any. /// Returns the exception to throw, if any. - private static Exception Finalize_NPC_parseMasterSchedule(string rawData, NPC __instance, ref Dictionary __result, Exception __exception) + private static Exception Finalize_ParseMasterSchedule(string rawData, NPC __instance, ref Dictionary __result, Exception __exception) { if (__exception != null) { diff --git a/src/SMAPI.Mods.ErrorHandler/Patches/ObjectPatcher.cs b/src/SMAPI.Mods.ErrorHandler/Patches/ObjectPatcher.cs index c4b25b96..fd4ea35c 100644 --- a/src/SMAPI.Mods.ErrorHandler/Patches/ObjectPatcher.cs +++ b/src/SMAPI.Mods.ErrorHandler/Patches/ObjectPatcher.cs @@ -2,34 +2,34 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using HarmonyLib; -using StardewModdingAPI.Framework.Patching; +using StardewModdingAPI.Internal.Patching; using StardewValley; using SObject = StardewValley.Object; namespace StardewModdingAPI.Mods.ErrorHandler.Patches { - /// A Harmony patch for which intercepts crashes due to the item no longer existing. + /// Harmony patches for which intercept crashes due to invalid items. /// Patch methods must be static for Harmony to work correctly. See the Harmony documentation before renaming patch arguments. [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.")] - internal class ObjectPatcher : IHarmonyPatch + internal class ObjectPatcher : BasePatcher { /********* ** Public methods *********/ /// - public void Apply(Harmony harmony) + public override void Apply(Harmony harmony, IMonitor monitor) { // object.getDescription harmony.Patch( - original: AccessTools.Method(typeof(SObject), nameof(SObject.getDescription)), - prefix: new HarmonyMethod(this.GetType(), nameof(ObjectPatcher.Before_Object_GetDescription)) + original: this.RequireMethod(nameof(SObject.getDescription)), + prefix: this.GetHarmonyMethod(nameof(ObjectPatcher.Before_Object_GetDescription)) ); // object.getDisplayName harmony.Patch( - original: AccessTools.Method(typeof(SObject), "loadDisplayName"), - finalizer: new HarmonyMethod(this.GetType(), nameof(ObjectPatcher.Finalize_Object_loadDisplayName)) + original: this.RequireMethod("loadDisplayName"), + finalizer: this.GetHarmonyMethod(nameof(ObjectPatcher.Finalize_Object_loadDisplayName)) ); } diff --git a/src/SMAPI.Mods.ErrorHandler/Patches/SaveGamePatcher.cs b/src/SMAPI.Mods.ErrorHandler/Patches/SaveGamePatcher.cs index ef165831..8945e4f3 100644 --- a/src/SMAPI.Mods.ErrorHandler/Patches/SaveGamePatcher.cs +++ b/src/SMAPI.Mods.ErrorHandler/Patches/SaveGamePatcher.cs @@ -4,18 +4,18 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; using HarmonyLib; using Microsoft.Xna.Framework.Content; -using StardewModdingAPI.Framework.Patching; +using StardewModdingAPI.Internal.Patching; using StardewValley; using StardewValley.Buildings; using StardewValley.Locations; namespace StardewModdingAPI.Mods.ErrorHandler.Patches { - /// A Harmony patch for which prevents some errors due to broken save data. + /// Harmony patches for which prevent some errors due to broken save data. /// Patch methods must be static for Harmony to work correctly. See the Harmony documentation before renaming patch arguments. [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.")] - internal class SaveGamePatcher : IHarmonyPatch + internal class SaveGamePatcher : BasePatcher { /********* ** Fields @@ -39,13 +39,12 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches SaveGamePatcher.OnContentRemoved = onContentRemoved; } - /// - public void Apply(Harmony harmony) + public override void Apply(Harmony harmony, IMonitor monitor) { harmony.Patch( - original: AccessTools.Method(typeof(SaveGame), nameof(SaveGame.loadDataToLocations)), - prefix: new HarmonyMethod(this.GetType(), nameof(SaveGamePatcher.Before_SaveGame_LoadDataToLocations)) + original: this.RequireMethod(nameof(SaveGame.loadDataToLocations)), + prefix: this.GetHarmonyMethod(nameof(SaveGamePatcher.Before_LoadDataToLocations)) ); } @@ -56,7 +55,7 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches /// The method to call instead of . /// The game locations being loaded. /// Returns whether to execute the original method. - private static bool Before_SaveGame_LoadDataToLocations(List gamelocations) + private static bool Before_LoadDataToLocations(List gamelocations) { bool removedAny = SaveGamePatcher.RemoveBrokenBuildings(gamelocations) diff --git a/src/SMAPI.Mods.ErrorHandler/Patches/SpriteBatchPatcher.cs b/src/SMAPI.Mods.ErrorHandler/Patches/SpriteBatchPatcher.cs index 1099afee..6860a4ec 100644 --- a/src/SMAPI.Mods.ErrorHandler/Patches/SpriteBatchPatcher.cs +++ b/src/SMAPI.Mods.ErrorHandler/Patches/SpriteBatchPatcher.cs @@ -2,27 +2,27 @@ using System; using System.Diagnostics.CodeAnalysis; using HarmonyLib; using Microsoft.Xna.Framework.Graphics; -using StardewModdingAPI.Framework.Patching; +using StardewModdingAPI.Internal.Patching; namespace StardewModdingAPI.Mods.ErrorHandler.Patches { - /// Harmony patch for to validate textures earlier. + /// Harmony patches for which validate textures earlier. /// Patch methods must be static for Harmony to work correctly. See the Harmony documentation before renaming patch arguments. [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.")] - internal class SpriteBatchPatcher : IHarmonyPatch + internal class SpriteBatchPatcher : BasePatcher { /********* ** Public methods *********/ /// - public void Apply(Harmony harmony) + public override void Apply(Harmony harmony, IMonitor monitor) { harmony.Patch( original: Constants.GameFramework == GameFramework.Xna - ? AccessTools.Method(typeof(SpriteBatch), "InternalDraw") - : AccessTools.Method(typeof(SpriteBatch), "CheckValid", new[] { typeof(Texture2D) }), - postfix: new HarmonyMethod(this.GetType(), nameof(SpriteBatchPatcher.After_SpriteBatch_CheckValid)) + ? this.RequireMethod("InternalDraw") + : this.RequireMethod("CheckValid", new[] { typeof(Texture2D) }), + postfix: this.GetHarmonyMethod(nameof(SpriteBatchPatcher.After_CheckValid)) ); } @@ -31,13 +31,13 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches ** Private methods *********/ #if SMAPI_FOR_XNA - /// The method to call instead of . + /// The method to call after . /// The texture to validate. #else - /// The method to call instead of . + /// The method to call after . /// The texture to validate. #endif - private static void After_SpriteBatch_CheckValid(Texture2D texture) + private static void After_CheckValid(Texture2D texture) { if (texture?.IsDisposed == true) throw new ObjectDisposedException("Cannot draw this texture because it's disposed."); diff --git a/src/SMAPI.Mods.ErrorHandler/Patches/UtilityPatcher.cs b/src/SMAPI.Mods.ErrorHandler/Patches/UtilityPatcher.cs index e29e3030..ce85d0c2 100644 --- a/src/SMAPI.Mods.ErrorHandler/Patches/UtilityPatcher.cs +++ b/src/SMAPI.Mods.ErrorHandler/Patches/UtilityPatcher.cs @@ -1,7 +1,7 @@ using System; using System.Diagnostics.CodeAnalysis; using HarmonyLib; -using StardewModdingAPI.Framework.Patching; +using StardewModdingAPI.Internal.Patching; using StardewValley; namespace StardewModdingAPI.Mods.ErrorHandler.Patches @@ -10,17 +10,17 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches /// Patch methods must be static for Harmony to work correctly. See the Harmony documentation before renaming patch arguments. [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.")] - internal class UtilityPatcher : IHarmonyPatch + internal class UtilityPatcher : BasePatcher { /********* ** Public methods *********/ /// - public void Apply(Harmony harmony) + public override void Apply(Harmony harmony, IMonitor monitor) { harmony.Patch( - original: AccessTools.Method(typeof(Utility), nameof(Utility.getItemFromStandardTextDescription)), - finalizer: new HarmonyMethod(this.GetType(), nameof(UtilityPatcher.Finalize_Utility_GetItemFromStandardTextDescription)) + original: this.RequireMethod(nameof(Utility.getItemFromStandardTextDescription)), + finalizer: this.GetHarmonyMethod(nameof(UtilityPatcher.Finalize_GetItemFromStandardTextDescription)) ); } @@ -28,12 +28,12 @@ namespace StardewModdingAPI.Mods.ErrorHandler.Patches /********* ** Private methods *********/ - /// The method to call instead of . + /// The method to call when throws an exception. /// The item text description to parse. /// The delimiter by which to split the text description. /// The exception thrown by the wrapped method, if any. /// Returns the exception to throw, if any. - private static Exception Finalize_Utility_GetItemFromStandardTextDescription(string description, char delimiter, ref Exception __exception) + private static Exception Finalize_GetItemFromStandardTextDescription(string description, char delimiter, ref Exception __exception) { return __exception != null ? new FormatException($"Failed to parse item text description \"{description}\" with delimiter \"{delimiter}\".", __exception) diff --git a/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj b/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj index 531d3699..ffda5f89 100644 --- a/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj +++ b/src/SMAPI.Mods.ErrorHandler/SMAPI.Mods.ErrorHandler.csproj @@ -47,4 +47,5 @@ + -- cgit