Пример #1
0
        internal static void ReversePatch(MethodInfo standin, MethodBase original, string instanceID, MethodInfo transpiler)
        {
            var emptyFixes  = new List <MethodInfo>();
            var transpilers = new List <MethodInfo>();

            if (transpiler != null)
            {
                transpilers.Add(transpiler);
            }

            var replacement = MethodPatcher.CreatePatchedMethod(standin, original, instanceID, emptyFixes, emptyFixes, transpilers, emptyFixes);

            if (replacement == null)
            {
                throw new MissingMethodException("Cannot create dynamic replacement for " + standin.FullDescription());
            }

            var errorString = Memory.DetourMethod(standin, replacement);

            if (errorString != null)
            {
                throw new FormatException("Method " + standin.FullDescription() + " cannot be patched. Reason: " + errorString);
            }

            PatchTools.RememberObject(standin, replacement);
        }
Пример #2
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 DynamicMethod 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 replacement = MethodPatcher.CreatePatchedMethod(original, null, instanceID, sortedPrefixes, sortedPostfixes, sortedTranspilers, sortedFinalizers);

            if (replacement == null)
            {
                throw new MissingMethodException("Cannot create dynamic replacement for " + original.FullDescription());
            }

            var errorString = Memory.DetourMethod(original, replacement);

            if (errorString != null)
            {
                throw new FormatException("Method " + original.FullDescription() + " cannot be patched. Reason: " + errorString);
            }

            PatchTools.RememberObject(original, replacement);             // no gc for new value + release old value to gc

            return(replacement);
        }
Пример #3
0
        internal static void DetourMethodAndPersist(MethodBase original, MethodBase replacement)
        {
            var errorString = DetourMethod(original, replacement);

            if (errorString is object)
            {
                throw new FormatException($"Method {original.FullDescription()} cannot be patched. Reason: {errorString}");
            }
            PatchTools.RememberObject(original, replacement);
        }
Пример #4
0
        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);
        }
Пример #5
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 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);
        }