/// <summary>Creates new dynamic 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> /// <param name="instanceID">Harmony ID</param> /// <returns>The newly created dynamic method</returns> /// internal static MethodInfo UpdateWrapper(MethodBase original, PatchInfo patchInfo, string instanceID) { var sortedPrefixes = GetSortedPatchMethods(original, patchInfo.prefixes); var sortedPostfixes = GetSortedPatchMethods(original, patchInfo.postfixes); var sortedTranspilers = GetSortedPatchMethods(original, patchInfo.transpilers); var sortedFinalizers = GetSortedPatchMethods(original, patchInfo.finalizers); var patcher = new MethodPatcher(original, null, instanceID, sortedPrefixes, sortedPostfixes, sortedTranspilers, sortedFinalizers); var replacement = patcher.CreateReplacement(); if (replacement == null) { throw new MissingMethodException($"Cannot create dynamic replacement for {original.FullDescription()}"); } Memory.DetourMethodAndPersist(original, replacement); return(replacement); }
internal static MethodInfo ReversePatch(HarmonyMethod standin, MethodBase original, Harmony instance, MethodInfo postTranspiler) { if (standin == null) { throw new ArgumentNullException(nameof(standin)); } if (standin.method == null) { throw new ArgumentNullException($"{nameof(standin)}.{nameof(standin.method)}"); } var transpilers = new List <MethodInfo>(); if (standin.reversePatchType == HarmonyReversePatchType.Snapshot) { var info = Harmony.GetPatchInfo(original); transpilers.AddRange(GetSortedPatchMethods(original, info.Transpilers.ToArray())); } if (postTranspiler != null) { transpilers.Add(postTranspiler); } var empty = new List <MethodInfo>(); var patcher = new MethodPatcher(standin.method, original, instance.Id, empty, empty, transpilers, empty); var replacement = patcher.CreateReplacement(); 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); }