/// <summary>Unpatches patches of a given type and/or Harmony ID</summary> /// <param name="type">The <see cref="HarmonyPatchType"/> patch type</param> /// <param name="harmonyID">Harmony ID or <c>*</c> for any</param> /// <returns>A <see cref="PatchProcessor"/> for chaining calls</returns> /// public PatchProcessor Unpatch(HarmonyPatchType type, string harmonyID) { lock (locker) { var patchInfo = HarmonySharedState.GetPatchInfo(original); if (patchInfo == null) { patchInfo = new PatchInfo(); } if (type == HarmonyPatchType.All || type == HarmonyPatchType.Prefix) { PatchFunctions.RemovePrefix(patchInfo, harmonyID); } if (type == HarmonyPatchType.All || type == HarmonyPatchType.Postfix) { PatchFunctions.RemovePostfix(patchInfo, harmonyID); } if (type == HarmonyPatchType.All || type == HarmonyPatchType.Transpiler) { PatchFunctions.RemoveTranspiler(patchInfo, harmonyID); } if (type == HarmonyPatchType.All || type == HarmonyPatchType.Finalizer) { PatchFunctions.RemoveFinalizer(patchInfo, harmonyID); } _ = PatchFunctions.UpdateWrapper(original, patchInfo); HarmonySharedState.UpdatePatchInfo(original, patchInfo); return(this); } }
/// <summary>Unpatches patches of a given type and/or Harmony ID</summary> /// <param name="type">The <see cref="HarmonyPatchType"/> patch type</param> /// <param name="harmonyID">Harmony ID or <c>*</c> for any</param> /// <returns>A <see cref="PatchProcessor"/> for chaining calls</returns> /// public PatchProcessor Unpatch(HarmonyPatchType type, string harmonyID) { lock (locker) { var patchInfo = original.ToPatchInfo(); if (type == HarmonyPatchType.All || type == HarmonyPatchType.Prefix) { patchInfo.RemovePrefix(harmonyID); } if (type == HarmonyPatchType.All || type == HarmonyPatchType.Postfix) { patchInfo.RemovePostfix(harmonyID); } if (type == HarmonyPatchType.All || type == HarmonyPatchType.Transpiler) { patchInfo.RemoveTranspiler(harmonyID); } if (type == HarmonyPatchType.All || type == HarmonyPatchType.Finalizer) { patchInfo.RemoveFinalizer(harmonyID); } if (type == HarmonyPatchType.All || type == HarmonyPatchType.ILManipulator) { patchInfo.RemoveILManipulator(harmonyID); } var replacement = PatchFunctions.UpdateWrapper(original, patchInfo); PatchManager.AddReplacementOriginal(original, replacement); return(this); } }
/// <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); } }
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; }
/// <summary>Applies all registered patches</summary> /// <returns>The generated replacement method</returns> /// public MethodInfo Patch() { if (original is null) { throw new NullReferenceException($"Null method for {instance.Id}"); } if (original.IsDeclaredMember() is false) { Logger.Log(Logger.LogChannel.Warn, () => $"{instance.Id}: You should only patch implemented methods/constructors to avoid issues. Patch the declared method {original.GetDeclaredMember().FullDescription()} instead of {original.FullDescription()}."); } lock (locker) { var patchInfo = original.ToPatchInfo(); patchInfo.AddPrefixes(instance.Id, prefix); patchInfo.AddPostfixes(instance.Id, postfix); patchInfo.AddTranspilers(instance.Id, transpiler); patchInfo.AddFinalizers(instance.Id, finalizer); patchInfo.AddILManipulators(instance.Id, ilmanipulator); var replacement = PatchFunctions.UpdateWrapper(original, patchInfo); PatchManager.AddReplacementOriginal(original, replacement); return(replacement); } }
/// <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); } }
/// <summary>Unpatches patches of a given type and/or Harmony ID</summary> /// <param name="type">The patch type</param> /// <param name="harmonyID">Harmony ID or (*) for any</param> /// public void Unpatch(HarmonyPatchType type, string harmonyID) { lock (locker) { foreach (var original in originals) { var patchInfo = HarmonySharedState.GetPatchInfo(original); if (patchInfo == null) { patchInfo = new PatchInfo(); } if (type == HarmonyPatchType.All || type == HarmonyPatchType.Prefix) { PatchFunctions.RemovePrefix(patchInfo, harmonyID); } if (type == HarmonyPatchType.All || type == HarmonyPatchType.Postfix) { PatchFunctions.RemovePostfix(patchInfo, harmonyID); } if (type == HarmonyPatchType.All || type == HarmonyPatchType.Transpiler) { PatchFunctions.RemoveTranspiler(patchInfo, harmonyID); } if (type == HarmonyPatchType.All || type == HarmonyPatchType.Finalizer) { PatchFunctions.RemoveFinalizer(patchInfo, harmonyID); } PatchFunctions.UpdateWrapper(original, patchInfo, instance.Id); HarmonySharedState.UpdatePatchInfo(original, patchInfo); } } }
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; }
/// <summary>Unpatches a specific patch</summary> /// <param name="patch">The method of the patch</param> /// <returns>A <see cref="PatchProcessor"/> for chaining calls</returns> /// public PatchProcessor Unpatch(MethodInfo patch) { lock (locker) { var patchInfo = original.ToPatchInfo(); patchInfo.RemovePatch(patch); var replacement = PatchFunctions.UpdateWrapper(original, patchInfo); PatchManager.AddReplacementOriginal(original, replacement); return(this); } }
/// <summary>Unpatches a specific patch</summary> /// <param name="patch">The method of the patch</param> /// <returns>A <see cref="PatchProcessor"/> for chaining calls</returns> /// public PatchProcessor Unpatch(MethodInfo patch) { lock (locker) { var patchInfo = HarmonySharedState.GetPatchInfo(original); if (patchInfo == null) { patchInfo = new PatchInfo(); } PatchFunctions.RemovePatch(patchInfo, patch); _ = PatchFunctions.UpdateWrapper(original, patchInfo); HarmonySharedState.UpdatePatchInfo(original, patchInfo); return(this); } }
/// <summary>Unpatches the given patch</summary> /// <param name="patch">The patch</param> /// public void Unpatch(MethodInfo patch) { lock (locker) { foreach (var original in originals) { var patchInfo = HarmonySharedState.GetPatchInfo(original); if (patchInfo == null) { patchInfo = new PatchInfo(); } PatchFunctions.RemovePatch(patchInfo, patch); PatchFunctions.UpdateWrapper(original, patchInfo, instance.Id); HarmonySharedState.UpdatePatchInfo(original, patchInfo); } } }