diff --git a/Harmony/Internal/MethodPatcher.cs b/Harmony/Internal/MethodPatcher.cs index 27ce9396..6e41cb97 100644 --- a/Harmony/Internal/MethodPatcher.cs +++ b/Harmony/Internal/MethodPatcher.cs @@ -1,10 +1,9 @@ +using MonoMod.RuntimeDetour; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Reflection.Emit; -using MonoMod.RuntimeDetour; -using MonoMod.Utils; namespace HarmonyLib { @@ -20,7 +19,7 @@ internal static class MethodPatcher public static string PARAM_INDEX_PREFIX = "__"; public static string INSTANCE_FIELD_PREFIX = "___"; - public static MethodInfo CreatePatchedMethod(MethodBase original, MethodBase source, string harmonyInstanceID, List prefixes, List postfixes, List transpilers, List finalizers) + internal static MethodInfo CreatePatchedMethod(MethodBase original, MethodBase source, string harmonyInstanceID, List prefixes, List postfixes, List transpilers, List finalizers) { try { diff --git a/Harmony/Internal/PatchFunctions.cs b/Harmony/Internal/PatchFunctions.cs index b7a6a947..5dfa77b5 100644 --- a/Harmony/Internal/PatchFunctions.cs +++ b/Harmony/Internal/PatchFunctions.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Reflection; using System.Reflection.Emit; @@ -164,28 +165,24 @@ internal static MethodInfo ReversePatch(HarmonyMethod standin, MethodBase origin if (standin.method == null) throw new ArgumentNullException($"{nameof(standin)}.{nameof(standin.method)}"); - var processor = instance.CreateProcessor(standin.method); + var transpilers = new List(); if (standin.reversePatchType == HarmonyReversePatchType.Snapshot) { var info = Harmony.GetPatchInfo(original); - foreach (var tr in info.Transpilers) - { - var transpiler = new HarmonyMethod(tr.GetMethod(original)) - { - before = tr.before, - after = tr.after, - - priority = tr.priority - }; - _ = processor.AddTranspiler(transpiler); - } + transpilers.AddRange(GetSortedPatchMethods(original, info.Transpilers.ToArray())); } - if (postTranspiler != null) - { - var transpiler = new HarmonyMethod(postTranspiler) { priority = int.MinValue }; - _ = processor.AddTranspiler(transpiler); - } - return processor.Patch(); + if (postTranspiler != null) transpilers.Add(postTranspiler); + + var empty = new List(); + var replacement = MethodPatcher.CreatePatchedMethod(standin.method, original, instance.Id, empty, empty, transpilers, empty); + if (replacement == null) throw new MissingMethodException($"Cannot create dynamic replacement for {standin.method.FullDescription()}"); + + var errorString = Memory.DetourMethod(standin.method, replacement); + if (errorString != null) + throw new FormatException($"Method {standin.method.FullDescription()} cannot be patched. Reason: {errorString}"); + + PatchTools.RememberObject(standin.method, replacement); + return replacement; } } } \ No newline at end of file diff --git a/Harmony/Public/PatchProcessor.cs b/Harmony/Public/PatchProcessor.cs index 2eff583e..d2baca59 100644 --- a/Harmony/Public/PatchProcessor.cs +++ b/Harmony/Public/PatchProcessor.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Reflection; +using System.Reflection.Emit; namespace HarmonyLib { @@ -236,5 +237,17 @@ public static Patches GetPatchInfo(MethodBase method) }); return result; } + + /// Returns the methods unmodified list of CodeInstructions + /// The original method + /// The generator that now contains all local variables and labels contained in the result + /// A list containing all the original CodeInstructions + public static List GetOriginalInstructions(MethodBase original, out ILGenerator generator) + { + var patch = DynamicTools.CreateDynamicMethod(original, $"_Copy{Guid.NewGuid()}"); + generator = patch.GetILGenerator(); + var reader = MethodBodyReader.GetInstructions(generator, original); + return reader.Select(ins => ins.GetCodeInstruction()).ToList(); + } } } \ No newline at end of file diff --git a/HarmonyTests/ReversePatching/AttributeReversePatches.cs b/HarmonyTests/ReversePatching/AttributeReversePatches.cs index dc6d417c..0b69acd1 100644 --- a/HarmonyTests/ReversePatching/AttributeReversePatches.cs +++ b/HarmonyTests/ReversePatching/AttributeReversePatches.cs @@ -7,7 +7,7 @@ namespace HarmonyLibTests [TestFixture] public class AttributeReversePatches { - //[Test] + [Test] public void Test_ReversePatchingWithAttributes() { var test = new Class1Reverse(); diff --git a/HarmonyTests/ReversePatching/ReverseTranspiling.cs b/HarmonyTests/ReversePatching/ReverseTranspiling.cs index ccff16ec..e83bee35 100644 --- a/HarmonyTests/ReversePatching/ReverseTranspiling.cs +++ b/HarmonyTests/ReversePatching/ReverseTranspiling.cs @@ -7,7 +7,7 @@ namespace HarmonyLibTests [TestFixture] public class ReverseTranspiling { - //[Test] + [Test] public void Test_ReverseTranspilerPatching() { var class0 = new Class0Reverse();