示例#1
0
        /// <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);
        }
示例#2
0
        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);
        }