public List <DynamicMethod> Patch() { lock (locker) { var dynamicMethods = new List <DynamicMethod>(); foreach (var original in originals) { if (original == null) { throw new NullReferenceException("original"); } 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); dynamicMethods.Add(PatchFunctions.UpdateWrapper(original, patchInfo, instance.Id)); HarmonySharedState.UpdatePatchInfo(original, patchInfo); RunMethod <HarmonyCleanup>(original); } } return(dynamicMethods); } }
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); } PatchFunctions.UpdateWrapper(original, patchInfo, instance.Id); HarmonySharedState.UpdatePatchInfo(original, patchInfo); } } }
public void Patch() { var obj = locker; lock (obj) { foreach (var methodBase in originals) { if (methodBase == null) { throw new NullReferenceException("original"); } if (RunMethod <HarmonyPrepare, bool>(true, methodBase)) { var patchInfo = HarmonySharedState.GetPatchInfo(methodBase) ?? new PatchInfo(); PatchFunctions.AddPrefix(patchInfo, instance.Id, prefix); PatchFunctions.AddPostfix(patchInfo, instance.Id, postfix); PatchFunctions.AddTranspiler(patchInfo, instance.Id, transpiler); PatchFunctions.UpdateWrapper(methodBase, patchInfo, instance.Id); HarmonySharedState.UpdatePatchInfo(methodBase, patchInfo); RunMethod <HarmonyCleanup>(methodBase); } } } }
/// <summary> /// 执行Patch /// </summary> /// <returns></returns> public PatchInfoData Patch(PatchFlags flags) { PatchInfo patchInfo = null; lock (locker) { #if RECORD_PATCH_STATE patchInfo = HarmonySharedState.GetPatchInfo(original); if (patchInfo == null) { patchInfo = new PatchInfo(); } #endif patchInfo = new PatchInfo(); PatchFunctions.AddPrefix(patchInfo, instance.id, prefix); PatchFunctions.AddPostfix(patchInfo, instance.id, postfix); PatchFunctions.AddTranspiler(patchInfo, instance.id, transpiler); PatchFunctions.UpdateWrapper(original, patchInfo, flags); #if RECORD_PATCH_STATE HarmonySharedState.UpdatePatchInfo(original, patchInfo); #endif } return(patchInfo.patchdata); }
public void Unpatch(HarmonyPatchType type, string harmonyID) { var obj = locker; lock (obj) { foreach (var methodBase in originals) { var patchInfo = HarmonySharedState.GetPatchInfo(methodBase) ?? 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); } PatchFunctions.UpdateWrapper(methodBase, patchInfo, instance.Id); HarmonySharedState.UpdatePatchInfo(methodBase, patchInfo); } } }
public 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); bool isIl2Cpp = UnhollowerSupport.IsGeneratedAssemblyType(original.DeclaringType); if (isIl2Cpp) { if (sortedTranspilers.Count > 0) { throw new NotSupportedException("IL2CPP patches cannot use transpilers (got " + sortedTranspilers.Count + ")"); } if (patchInfo.copiedMethodInfoPointer == IntPtr.Zero) { IntPtr origMethodPtr = UnhollowerSupport.MethodBaseToIl2CppMethodInfoPointer(original); patchInfo.copiedMethodInfoPointer = CopyMethodInfoStruct(origMethodPtr); HarmonySharedState.UpdatePatchInfo(original, patchInfo); } sortedTranspilers.Add(AccessTools.DeclaredMethod(typeof(PatchFunctions), "UnhollowerTranspiler")); } var replacement = MethodPatcher.CreatePatchedMethod(original, instanceID, sortedPrefixes, sortedPostfixes, sortedTranspilers); if (replacement == null) { throw new MissingMethodException("Cannot create dynamic replacement for " + original.FullDescription()); } if (isIl2Cpp) { DynamicMethod il2CppShim = CreateIl2CppShim(replacement, original); InstallIl2CppPatch(patchInfo, il2CppShim); PatchTools.RememberObject(original, new PotatoTuple { First = replacement, Second = il2CppShim }); } else { 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); }
public void Unpatch(MethodInfo patch) { var obj = locker; lock (obj) { foreach (var methodBase in originals) { var patchInfo = HarmonySharedState.GetPatchInfo(methodBase) ?? new PatchInfo(); PatchFunctions.RemovePatch(patchInfo, patch); PatchFunctions.UpdateWrapper(methodBase, patchInfo, instance.Id); HarmonySharedState.UpdatePatchInfo(methodBase, patchInfo); } } }
public void Patch() { 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.AddInfix(patchInfo, instance.Id, infix); PatchFunctions.UpdateWrapper(original, patchInfo); HarmonySharedState.UpdatePatchInfo(original, patchInfo); } }
public List <DynamicMethod> Patch() { lock (locker) { var dynamicMethods = new List <DynamicMethod>(); foreach (var original in originals) { if (original == null) { throw new NullReferenceException("original"); } if ((original.DeclaringType.Assembly.GetCustomAttributes(typeof(HarmonyShield), false).Count() > 0) || (original.DeclaringType.GetCustomAttributes(typeof(HarmonyShield), false).Count() > 0) || (original.GetCustomAttributes(typeof(HarmonyShield), false).Count() > 0)) { continue; } if (MelonDebug.IsEnabled() && UnhollowerSupport.IsGeneratedAssemblyType(original.DeclaringType)) { WarnIfTargetMethodInlined(original); } 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); dynamicMethods.Add(PatchFunctions.UpdateWrapper(original, patchInfo, instance.Id)); HarmonySharedState.UpdatePatchInfo(original, patchInfo); RunMethod <HarmonyCleanup>(original); } } return(dynamicMethods); } }
public void Restore() { lock (locker) { var patchInfo = HarmonySharedState.GetPatchInfo(original); if (patchInfo == null) { return; } PatchFunctions.RemovePrefix(patchInfo, prefix); PatchFunctions.RemovePostfix(patchInfo, postfix); PatchFunctions.RemoveTranspiler(patchInfo, transpiler); PatchFunctions.UpdateWrapper(original, patchInfo); HarmonySharedState.UpdatePatchInfo(original, patchInfo); } }
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); } } }