예제 #1
0
 private static bool HasActivePatches(Harmony.Patches patches)
 {
     return(patches != null &&
            ((patches.Prefixes != null && patches.Prefixes.Count != 0) ||
             (patches.Postfixes != null && patches.Postfixes.Count != 0) ||
             (patches.Transpilers != null && patches.Transpilers.Count != 0)));
 }
예제 #2
0
        public static void UnpatchTarget(PatchPredicate pred)
        {
            var harmony = Bootstrapper.Instance.Harmony;

            var hostiles = new List <KeyValuePair <MethodBase, MethodInfo> >();

            foreach (var target in harmony.GetPatchedMethods())
            {
                //Log.Debug($"found patched method: {target} [{target.Attributes}]");
                Harmony.Patches info = null;

                try {
                    info = harmony.GetPatchInfo(target);
                } catch (InvalidCastException e) {
                    Log.Error($"incompatible Harmony patch detected; this might cause serious conflicts (or visual glitch) in-game\nError: {e}");
                    continue;
                }

                foreach (var p in info.Prefixes)
                {
                    // TODO: if we have prefix patches, remove others
                    // Log.Warn($"found patch: {p} (ignoring)");
                }

                foreach (var p in info.Postfixes)
                {
                    if (pred.Invoke(p))
                    {
                        {
                            var msg = $"found target patch: {p.GetMethod(target)} [by {p.owner}]";
                            if (p.owner == Mod.ModInfo.COMIdentifier)
                            {
                                Log.Debug(msg);
                            }
                            else
                            {
                                Log.Warn(msg);
                            }
                        }
                        //Log.Warn($"Unknown Harmony patcher from owner \"{p.owner}\" found! This will lead to undesired behavior; please report.");
                        hostiles.Add(new KeyValuePair <MethodBase, MethodInfo>(target, p.GetMethod(target)));
                    }
                }
            }

            foreach (var kv in hostiles)
            {
                Log.Warn($"unpatching: {kv.Value} for {kv.Key}");
                harmony.Unpatch(kv.Key, kv.Value);
            }
        }
예제 #3
0
        /// <summary>
        /// Returns all patched methods by NPC Adventures mod.
        /// </summary>
        /// <returns>Enumerable patched methods</returns>
        public IEnumerable <PatchedMethod> GetPatchedMethods()
        {
            var methods = this.harmony
                          .GetPatchedMethods()
                          .ToArray();

            foreach (var method in methods)
            {
                Harmony.Patches info = this.harmony.GetPatchInfo(method);

                if (info != null && info.Owners.Contains(this.harmony.Id))
                {
                    yield return(new PatchedMethod(method, info));
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Checks the merged harmonyMethod info whether the original method is already patched with the given patch type.
        /// </summary>
        private static bool IsPatchedWithType(HarmonyMethod harmonyMethod, Type withType)
        {
            MethodInfo originalMethod = AccessTools.Method(harmonyMethod.originalType, harmonyMethod.methodName, harmonyMethod.parameter);

            Harmony.Patches patches = PatchProcessor.IsPatched(originalMethod);
            if (patches == null)
            {
                return(false);
            }

            bool DeclaredInType(Patch p) => p.patch.DeclaringType == withType;

            if (patches.Prefixes.Any(DeclaredInType) || patches.Postfixes.Any(DeclaredInType) || patches.Transpilers.Any(DeclaredInType))
            {
                return(true);
            }

            return(false);
        }
예제 #5
0
        public static Patches GetPatchInfo(MethodBase method)
        {
            var     obj = locker;
            Patches result;

            lock (obj)
            {
                var patchInfo = HarmonySharedState.GetPatchInfo(method);
                if (patchInfo == null)
                {
                    result = null;
                }
                else
                {
                    result = new Patches(patchInfo.prefixes, patchInfo.postfixes, patchInfo.transpilers, patchInfo.finalizers);
                }
            }

            return(result);
        }
예제 #6
0
 public PatchedMethod(MethodBase method, Harmony.Patches patchInfo)
 {
     this.Method    = method;
     this.PatchInfo = patchInfo;
 }