From 14e6521e7c229a939da4ccbdfd5897b3be4419a4 Mon Sep 17 00:00:00 2001 From: ZaneYork Date: Fri, 29 May 2020 14:48:33 +0800 Subject: [PATCH] Migrate patches to Harmony2.0 --- src/SMAPI/Framework/Patching/PatchHelper.cs | 34 ------------------- src/SMAPI/Patches/OnAppPausePatch.cs | 21 +++--------- src/SMAPI/Patches/SaveBackupPatch.cs | 37 +++++++++------------ src/SMAPI/Patches/SaveGamePatch.cs | 22 +++--------- src/SMAPI/Patches/ThreadSilenceExitPatch.cs | 24 +++---------- src/SMAPI/SMAPI.csproj | 1 - 6 files changed, 31 insertions(+), 108 deletions(-) delete mode 100644 src/SMAPI/Framework/Patching/PatchHelper.cs diff --git a/src/SMAPI/Framework/Patching/PatchHelper.cs b/src/SMAPI/Framework/Patching/PatchHelper.cs deleted file mode 100644 index 4cb436f0..00000000 --- a/src/SMAPI/Framework/Patching/PatchHelper.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace StardewModdingAPI.Framework.Patching -{ - /// Provides generic methods for implementing Harmony patches. - internal class PatchHelper - { - /********* - ** Fields - *********/ - /// The interception keys currently being intercepted. - private static readonly HashSet InterceptingKeys = new HashSet(StringComparer.OrdinalIgnoreCase); - - - /********* - ** Public methods - *********/ - /// Track a method that will be intercepted. - /// The intercept key. - /// Returns false if the method was already marked for interception, else true. - public static bool StartIntercept(string key) - { - return PatchHelper.InterceptingKeys.Add(key); - } - - /// Track a method as no longer being intercepted. - /// The intercept key. - public static void StopIntercept(string key) - { - PatchHelper.InterceptingKeys.Remove(key); - } - } -} diff --git a/src/SMAPI/Patches/OnAppPausePatch.cs b/src/SMAPI/Patches/OnAppPausePatch.cs index b40ce3a1..9ae331b0 100644 --- a/src/SMAPI/Patches/OnAppPausePatch.cs +++ b/src/SMAPI/Patches/OnAppPausePatch.cs @@ -35,7 +35,7 @@ namespace StardewModdingAPI.Patches public void Apply(Harmony harmony) { harmony.Patch(AccessTools.Method(typeof(Game1), nameof(Game1.OnAppPause)), - new HarmonyMethod(AccessTools.Method(this.GetType(), nameof(OnAppPausePatch.Game_OnAppPausePrefix)))); + finalizer:new HarmonyMethod(AccessTools.Method(this.GetType(), nameof(OnAppPausePatch.Game_OnAppPauseFinalizer)))); } @@ -45,24 +45,13 @@ namespace StardewModdingAPI.Patches /// The method to call instead of . /// This method must be static for Harmony to work correctly. See the Harmony documentation before renaming arguments. [SuppressMessage("ReSharper", "InconsistentNaming", Justification = "Argument names are defined by Harmony.")] - private static bool Game_OnAppPausePrefix(Game1 __instance, MethodInfo __originalMethod) + private static Exception Game_OnAppPauseFinalizer(Exception __exception) { - const string key = nameof(OnAppPausePatch.Game_OnAppPausePrefix); - if (!PatchHelper.StartIntercept(key)) - return true; - try + if (__exception != null) { - __originalMethod.Invoke(__instance, new object[] { }); + OnAppPausePatch.Monitor.Log($"Failed during OnAppPause method :\n{__exception.InnerException ?? __exception}", LogLevel.Error); } - catch (Exception ex) - { - OnAppPausePatch.Monitor.Log($"Failed during OnAppPause method :\n{ex.InnerException ?? ex}", LogLevel.Error); - } - finally - { - PatchHelper.StopIntercept(key); - } - return false; + return null; } } diff --git a/src/SMAPI/Patches/SaveBackupPatch.cs b/src/SMAPI/Patches/SaveBackupPatch.cs index bd03107e..b0e16c4b 100644 --- a/src/SMAPI/Patches/SaveBackupPatch.cs +++ b/src/SMAPI/Patches/SaveBackupPatch.cs @@ -45,9 +45,10 @@ namespace StardewModdingAPI.Patches MethodInfo saveWholeBackup = AccessTools.Method(typeof(Game1), nameof(Game1.saveWholeBackup)); MethodInfo prefix = AccessTools.Method(this.GetType(), nameof(SaveBackupPatch.GameSave_Prefix)); + MethodInfo finalizer = AccessTools.Method(this.GetType(), nameof(SaveBackupPatch.GameSave_Finalizer)); - harmony.Patch(makeFullBackup, new HarmonyMethod(prefix)); - harmony.Patch(saveWholeBackup, new HarmonyMethod(prefix)); + harmony.Patch(makeFullBackup, new HarmonyMethod(prefix), finalizer: new HarmonyMethod(finalizer)); + harmony.Patch(saveWholeBackup, new HarmonyMethod(prefix), finalizer: new HarmonyMethod(finalizer)); } @@ -57,28 +58,22 @@ namespace StardewModdingAPI.Patches /// The method to call instead of . /// This method must be static for Harmony to work correctly. See the Harmony documentation before renaming arguments. [SuppressMessage("ReSharper", "InconsistentNaming", Justification = "Argument names are defined by Harmony.")] - private static bool GameSave_Prefix(MethodInfo __originalMethod) + private static bool GameSave_Prefix() { - const string key = nameof(SaveBackupPatch.GameSave_Prefix); - if (!PatchHelper.StartIntercept(key)) - return true; SaveBackupPatch.Events.Saving.RaiseEmpty(); - try - { - __originalMethod.Invoke(null, new object[] { }); - } - catch (Exception ex) - { - SaveBackupPatch.Monitor.Log($"Failed to save the game :\n{ex.InnerException ?? ex}", LogLevel.Error); - Game1.addHUDMessage(new HUDMessage("An error occurs during save the game.Check the error log for details.", HUDMessage.error_type)); - } - finally - { - PatchHelper.StopIntercept(key); - } - SaveBackupPatch.Events.Saved.RaiseEmpty(); - return false; + return true; } + [SuppressMessage("ReSharper", "InconsistentNaming", Justification = "Argument names are defined by Harmony.")] + private static Exception GameSave_Finalizer(Exception __exception) + { + if (__exception != null) + { + SaveBackupPatch.Monitor.Log($"Failed to save the game :\n{__exception.InnerException ?? __exception}", LogLevel.Error); + Game1.addHUDMessage(new HUDMessage("An error occurs during save the game.Check the error log for details.", HUDMessage.error_type)); + } + SaveBackupPatch.Events.Saved.RaiseEmpty(); + return null; + } } } diff --git a/src/SMAPI/Patches/SaveGamePatch.cs b/src/SMAPI/Patches/SaveGamePatch.cs index afd44040..2f335c3a 100644 --- a/src/SMAPI/Patches/SaveGamePatch.cs +++ b/src/SMAPI/Patches/SaveGamePatch.cs @@ -50,7 +50,7 @@ namespace StardewModdingAPI.Patches ); harmony.Patch( original: AccessTools.Method(typeof(SaveGameMenu), "update"), - prefix: new HarmonyMethod(this.GetType(), nameof(SaveGamePatch.SaveGameMenu_UpdatePrefix)) + finalizer: new HarmonyMethod(this.GetType(), nameof(SaveGamePatch.SaveGameMenu_UpdateFinalizer)) ); } @@ -156,26 +156,14 @@ namespace StardewModdingAPI.Patches /// The method to call instead of . /// This method must be static for Harmony to work correctly. See the Harmony documentation before renaming arguments. [SuppressMessage("ReSharper", "InconsistentNaming", Justification = "Argument names are defined by Harmony.")] - private static bool SaveGameMenu_UpdatePrefix(SaveGameMenu __instance, GameTime time, MethodInfo __originalMethod) + private static Exception SaveGameMenu_UpdateFinalizer(SaveGameMenu __instance, Exception __exception) { - const string key = nameof(SaveGamePatch.SaveGameMenu_UpdatePrefix); - if (!PatchHelper.StartIntercept(key)) - return true; - try - { - __originalMethod.Invoke(__instance, new object[] {time}); - } - catch (Exception ex) - { - SaveGamePatch.Monitor.Log($"Failed during SaveGameMenu.update method :\n{ex.InnerException ?? ex}", LogLevel.Error); + if(__exception != null) { + SaveGamePatch.Monitor.Log($"Failed during SaveGameMenu.update method :\n{__exception.InnerException ?? __exception}", LogLevel.Error); __instance.complete(); Game1.addHUDMessage(new HUDMessage("An error occurs during save the game.Check the error log for details.", HUDMessage.error_type)); } - finally - { - PatchHelper.StopIntercept(key); - } - return false; + return null; } } } diff --git a/src/SMAPI/Patches/ThreadSilenceExitPatch.cs b/src/SMAPI/Patches/ThreadSilenceExitPatch.cs index 70315993..4af3f7d1 100644 --- a/src/SMAPI/Patches/ThreadSilenceExitPatch.cs +++ b/src/SMAPI/Patches/ThreadSilenceExitPatch.cs @@ -45,7 +45,7 @@ namespace StardewModdingAPI.Patches { harmony.Patch( original: AccessTools.Method(Type.GetType("System.Threading.ThreadHelper"), "ThreadStart_Context"), - prefix: new HarmonyMethod(this.GetType(), nameof(ThreadSilenceExitPatch.ThreadStart_Finalizer)) + finalizer: new HarmonyMethod(this.GetType(), nameof(ThreadSilenceExitPatch.ThreadStart_Finalizer)) ); } @@ -56,26 +56,12 @@ namespace StardewModdingAPI.Patches /// The method to call instead of . /// The thread context. /// Returns whether to execute the original method. - private static bool ThreadStart_Finalizer(object state) + private static Exception ThreadStart_Finalizer(Exception __exception) { - try - { - object _start = state.GetType().GetField("_start", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetValue(state); - if (_start is ThreadStart) - { - ((ThreadStart)_start)(); - } - else - { - object _startArg = state.GetType().GetField("_startArg", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).GetValue(state); - ((ParameterizedThreadStart)_start)(_startArg); - } + if (__exception != null) { + Monitor.Log($"Thread failed:\n{__exception.InnerException ?? __exception}", LogLevel.Error); } - catch (Exception ex) - { - Monitor.Log($"Thread failed:\n{ex.InnerException ?? ex}", LogLevel.Error); - } - return false; + return null; } } } diff --git a/src/SMAPI/SMAPI.csproj b/src/SMAPI/SMAPI.csproj index c6932876..fd332df1 100644 --- a/src/SMAPI/SMAPI.csproj +++ b/src/SMAPI/SMAPI.csproj @@ -332,7 +332,6 @@ -