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; }
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; }
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()); }
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()); }