Migrate patches to Harmony2.0

This commit is contained in:
ZaneYork 2020-05-29 14:48:33 +08:00
parent c67506cd69
commit 14e6521e7c
6 changed files with 31 additions and 108 deletions

View File

@ -1,34 +0,0 @@
using System;
using System.Collections.Generic;
namespace StardewModdingAPI.Framework.Patching
{
/// <summary>Provides generic methods for implementing Harmony patches.</summary>
internal class PatchHelper
{
/*********
** Fields
*********/
/// <summary>The interception keys currently being intercepted.</summary>
private static readonly HashSet<string> InterceptingKeys = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
/*********
** Public methods
*********/
/// <summary>Track a method that will be intercepted.</summary>
/// <param name="key">The intercept key.</param>
/// <returns>Returns false if the method was already marked for interception, else true.</returns>
public static bool StartIntercept(string key)
{
return PatchHelper.InterceptingKeys.Add(key);
}
/// <summary>Track a method as no longer being intercepted.</summary>
/// <param name="key">The intercept key.</param>
public static void StopIntercept(string key)
{
PatchHelper.InterceptingKeys.Remove(key);
}
}
}

View File

@ -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
/// <summary>The method to call instead of <see cref="StardewValley.Game1.OnAppPause"/>.</summary>
/// <remarks>This method must be static for Harmony to work correctly. See the Harmony documentation before renaming arguments.</remarks>
[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;
}
}

View File

@ -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
/// <summary>The method to call instead of <see cref="StardewValley.Object.getDescription"/>.</summary>
/// <remarks>This method must be static for Harmony to work correctly. See the Harmony documentation before renaming arguments.</remarks>
[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;
}
}
}

View File

@ -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
/// <summary>The method to call instead of <see cref="StardewValley.Menus.SaveGameMenu.update"/>.</summary>
/// <remarks>This method must be static for Harmony to work correctly. See the Harmony documentation before renaming arguments.</remarks>
[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;
}
}
}

View File

@ -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
/// <summary>The method to call instead of <see cref="System.Threading.ThreadHelper.ThreadStart_Context"/>.</summary>
/// <param name="state">The thread context.</param>
/// <returns>Returns whether to execute the original method.</returns>
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;
}
}
}

View File

@ -332,7 +332,6 @@
<Compile Include="Framework\Networking\RemoteContextModModel.cs" />
<Compile Include="Framework\Patching\GamePatcher.cs" />
<Compile Include="Framework\Patching\IHarmonyPatch.cs" />
<Compile Include="Framework\Patching\PatchHelper.cs" />
<Compile Include="Framework\PerformanceMonitoring\AlertContext.cs" />
<Compile Include="Framework\PerformanceMonitoring\AlertEntry.cs" />
<Compile Include="Framework\PerformanceMonitoring\PeakEntry.cs" />