/// <summary>Creates new replacement method with the latest patches and detours the original method</summary> /// <param name="original">The original method</param> /// <param name="patchInfo">Information describing the patches</param> /// <returns>The newly created replacement method</returns> /// internal static MethodInfo UpdateWrapper(MethodBase original, PatchInfo patchInfo) { var debug = patchInfo.Debugging || Harmony.DEBUG; var sortedPrefixes = GetSortedPatchMethods(original, patchInfo.prefixes, debug); var sortedPostfixes = GetSortedPatchMethods(original, patchInfo.postfixes, debug); var sortedTranspilers = GetSortedPatchMethods(original, patchInfo.transpilers, debug); var sortedFinalizers = GetSortedPatchMethods(original, patchInfo.finalizers, debug); var patcher = new MethodPatcher(original, null, sortedPrefixes, sortedPostfixes, sortedTranspilers, sortedFinalizers, debug); var replacement = patcher.CreateReplacement(out var finalInstructions); if (replacement == null) { throw new MissingMethodException($"Cannot create replacement for {original.FullDescription()}"); } try { Memory.DetourMethodAndPersist(original, replacement); } catch (Exception ex) { throw HarmonyException.Create(ex, finalInstructions); } return(replacement); }
internal static MethodInfo ReversePatch(HarmonyMethod standin, MethodBase original, MethodInfo postTranspiler) { if (standin == null) { throw new ArgumentNullException(nameof(standin)); } if (standin.method == null) { throw new ArgumentNullException($"{nameof(standin)}.{nameof(standin.method)}"); } var debug = (standin.debug ?? false) || Harmony.DEBUG; var transpilers = new List <MethodInfo>(); if (standin.reversePatchType == HarmonyReversePatchType.Snapshot) { var info = Harmony.GetPatchInfo(original); transpilers.AddRange(GetSortedPatchMethods(original, info.Transpilers.ToArray(), debug)); } if (postTranspiler != null) { transpilers.Add(postTranspiler); } var empty = new List <MethodInfo>(); var patcher = new MethodPatcher(standin.method, original, empty, empty, transpilers, empty, debug); var replacement = patcher.CreateReplacement(out var finalInstructions); if (replacement == null) { throw new MissingMethodException($"Cannot create replacement for {standin.method.FullDescription()}"); } try { var errorString = Memory.DetourMethod(standin.method, replacement); if (errorString != null) { throw new FormatException($"Method {standin.method.FullDescription()} cannot be patched. Reason: {errorString}"); } } catch (Exception ex) { throw HarmonyException.Create(ex, finalInstructions); } PatchTools.RememberObject(standin.method, replacement); return(replacement); }
/// <summary>Creates new replacement method with the latest patches and detours the original method</summary> /// <param name="original">The original method</param> /// <param name="patchInfo">Information describing the patches</param> /// <returns>The newly created replacement method</returns> /// internal static MethodInfo UpdateWrapper(MethodBase original, PatchInfo patchInfo) { var patcher = original.GetMethodPatcher(); var dmd = patcher.PrepareOriginal(); if (dmd != null) { var ctx = new ILContext(dmd.Definition); HarmonyManipulator.Manipulate(original, patchInfo, ctx); } try { return(patcher.DetourTo(dmd?.Generate()) as MethodInfo); } catch (Exception ex) { throw HarmonyException.Create(ex, dmd?.Definition?.Body); } }