示例#1
0
        /// <summary>Applies all registered patches</summary>
        /// <returns>The generated replacement method</returns>
        ///
        public MethodInfo Patch()
        {
            if (original == null)
            {
                throw new NullReferenceException($"Null method for {instance.Id}");
            }

            if (original.IsDeclaredMember() == false)
            {
                var declaredMember = original.GetDeclaredMember();
                throw new ArgumentException($"You can only patch implemented methods/constructors. Path the declared method {declaredMember.FullDescription()} instead.");
            }

            lock (locker)
            {
                var patchInfo = HarmonySharedState.GetPatchInfo(original);
                if (patchInfo == null)
                {
                    patchInfo = new PatchInfo();
                }

                PatchFunctions.AddPrefix(patchInfo, instance.Id, prefix);
                PatchFunctions.AddPostfix(patchInfo, instance.Id, postfix);
                PatchFunctions.AddTranspiler(patchInfo, instance.Id, transpiler);
                PatchFunctions.AddFinalizer(patchInfo, instance.Id, finalizer);
                var replacement = PatchFunctions.UpdateWrapper(original, patchInfo);

                HarmonySharedState.UpdatePatchInfo(original, patchInfo);
                return(replacement);
            }
        }
示例#2
0
        /// <summary>Applies the patch</summary>
        /// <returns>A list of all created dynamic methods</returns>
        ///
        public List <DynamicMethod> Patch()
        {
            lock (locker)
            {
                var dynamicMethods = new List <DynamicMethod>();
                foreach (var original in originals)
                {
                    if (original == null)
                    {
                        throw new NullReferenceException("Null method for " + instance.Id);
                    }

                    var individualPrepareResult = RunMethod <HarmonyPrepare, bool>(true, original);
                    if (individualPrepareResult)
                    {
                        var patchInfo = HarmonySharedState.GetPatchInfo(original);
                        if (patchInfo == null)
                        {
                            patchInfo = new PatchInfo();
                        }

                        PatchFunctions.AddPrefix(patchInfo, instance.Id, prefix);
                        PatchFunctions.AddPostfix(patchInfo, instance.Id, postfix);
                        PatchFunctions.AddTranspiler(patchInfo, instance.Id, transpiler);
                        PatchFunctions.AddFinalizer(patchInfo, instance.Id, finalizer);
                        dynamicMethods.Add(PatchFunctions.UpdateWrapper(original, patchInfo, instance.Id));

                        HarmonySharedState.UpdatePatchInfo(original, patchInfo);

                        RunMethod <HarmonyCleanup>(original);
                    }
                }
                return(dynamicMethods);
            }
        }
示例#3
0
        void ProcessPatchJob(PatchJobs <MethodInfo> .Job job)
        {
            MethodInfo replacement = default;

            var       individualPrepareResult = RunMethod <HarmonyPrepare, bool>(true, false, null, job.original);
            Exception exception = null;

            if (individualPrepareResult)
            {
                lock (PatchProcessor.locker)
                {
                    try
                    {
                        var patchInfo = HarmonySharedState.GetPatchInfo(job.original);
                        if (patchInfo == null)
                        {
                            patchInfo = new PatchInfo();
                        }

                        foreach (var prefix in job.prefixes)
                        {
                            PatchFunctions.AddPrefix(patchInfo, instance.Id, prefix);
                        }
                        foreach (var postfix in job.postfixes)
                        {
                            PatchFunctions.AddPostfix(patchInfo, instance.Id, postfix);
                        }
                        foreach (var transpiler in job.transpilers)
                        {
                            PatchFunctions.AddTranspiler(patchInfo, instance.Id, transpiler);
                        }
                        foreach (var finalizer in job.finalizers)
                        {
                            PatchFunctions.AddFinalizer(patchInfo, instance.Id, finalizer);
                        }

                        replacement = PatchFunctions.UpdateWrapper(job.original, patchInfo);
                        HarmonySharedState.UpdatePatchInfo(job.original, patchInfo);
                    }
                    catch (Exception ex)
                    {
                        exception = ex;
                    }
                }
            }
            RunMethod <HarmonyCleanup>(ref exception, job.original, exception);
            if (exception != null)
            {
                ReportException(exception, job.original);
            }
            job.replacement = replacement;
        }