Beispiel #1
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) ?? new PatchInfo();

                        patchInfo.AddPrefixes(instance.Id, job.prefixes.ToArray());
                        patchInfo.AddPostfixes(instance.Id, job.postfixes.ToArray());
                        patchInfo.AddTranspilers(instance.Id, job.transpilers.ToArray());
                        patchInfo.AddFinalizers(instance.Id, job.finalizers.ToArray());

                        replacement = PatchFunctions.UpdateWrapper(job.original, patchInfo);
                        HarmonySharedState.UpdatePatchInfo(job.original, replacement, patchInfo);
                    }
                    catch (Exception ex)
                    {
                        exception = ex;
                    }
                }
            }
            RunMethod <HarmonyCleanup>(ref exception, job.original, exception);
            ReportException(exception, job.original);
            job.replacement = replacement;
        }
Beispiel #2
0
        List <MethodInfo> BulkPatch(List <MethodBase> originals, ref MethodBase lastOriginal)
        {
            var jobs = new PatchJobs <MethodInfo>();

            for (var i = 0; i < originals.Count; i++)
            {
                lastOriginal = originals[i];
                var job = jobs.GetJob(lastOriginal);
                foreach (var patchMethod in patchMethods)
                {
                    var note = "You cannot combine TargetMethod, TargetMethods or [HarmonyPatchAll] with individual annotations";
                    var info = patchMethod.info;
                    if (info.methodName is object)
                    {
                        throw new ArgumentException($"{note} [{info.methodName}]");
                    }
                    if (info.methodType.HasValue && info.methodType.Value != MethodType.Normal)
                    {
                        throw new ArgumentException($"{note} [{info.methodType}]");
                    }
                    if (info.argumentTypes is object)
                    {
                        throw new ArgumentException($"{note} [{info.argumentTypes.Description()}]");
                    }

                    job.AddPatch(patchMethod);
                }
            }
            foreach (var job in jobs.GetJobs())
            {
                lastOriginal = job.original;
                ProcessPatchJob(job);
            }
            return(jobs.GetReplacements());
        }
        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;
        }
Beispiel #4
0
        List <MethodInfo> PatchWithAttributes()
        {
            var jobs = new PatchJobs <MethodInfo>();

            foreach (var patchMethod in patchMethods)
            {
                var original = patchMethod.info.GetOriginalMethod();
                if (original == null)
                {
                    throw new ArgumentException($"Undefined target method for patch method {patchMethod.info.method.FullDescription()}");
                }

                var job = jobs.GetJob(original);
                job.AddPatch(patchMethod);
            }
            foreach (var job in jobs.GetJobs())
            {
                ProcessPatchJob(job);
            }
            return(jobs.GetReplacements());
        }
Beispiel #5
0
        List <MethodInfo> BulkPatch()
        {
            var jobs = new PatchJobs <MethodInfo>();

            foreach (var original in bulkOriginals)
            {
                var job = jobs.GetJob(original);
                foreach (var patchMethod in patchMethods)
                {
                    var note = "You cannot combine TargetMethod, TargetMethods or PatchAll with individual annotations";
                    var info = patchMethod.info;
                    if (info.declaringType != null)
                    {
                        throw new ArgumentException($"{note} [{info.declaringType.FullDescription()}]");
                    }
                    if (info.methodName != null)
                    {
                        throw new ArgumentException($"{note} [{info.methodName}]");
                    }
                    if (info.methodType.HasValue && info.methodType.Value != MethodType.Normal)
                    {
                        throw new ArgumentException($"{note} [{info.methodType}]");
                    }
                    if (info.argumentTypes != null)
                    {
                        throw new ArgumentException($"{note} [{info.argumentTypes.Description()}]");
                    }

                    job.AddPatch(patchMethod);
                }
            }
            foreach (var job in jobs.GetJobs())
            {
                ProcessPatchJob(job);
            }
            return(jobs.GetReplacements());
        }