Exemplo n.º 1
0
        /// <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 PatchProcessor Unpatch(HarmonyPatchType type, string harmonyID)
        {
            foreach (var original in originals)
            {
                var patchInfo = original.ToPatchInfo();

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

                original.GetMethodPatcher().Apply();
            }

            return(this);
        }
Exemplo n.º 2
0
 public void Remove(Harmony harmony, HarmonyPatchType patchType = HarmonyPatchType.All)
 {
     harmony.Unpatch(
         original: Original,
         type: patchType,
         harmonyID: harmony.Id
         );
 }
Exemplo n.º 3
0
        /// <summary>Unpatches a method</summary>
        /// <param name="original">The original method</param>
        /// <param name="type">The patch type</param>
        /// <param name="harmonyID">The optional Harmony ID to restrict unpatching to a specific instance</param>
        ///
        public void Unpatch(MethodBase original, HarmonyPatchType type, string harmonyID = null)
        {
            var processor = new PatchProcessor(this, new List <MethodBase> {
                original
            });

            processor.Unpatch(type, harmonyID);
        }
Exemplo n.º 4
0
 public PatchTemplate(HarmonyPatchType type, MethodInfo original, string patch = null, HarmonyMethod method = null)
 {
     this.type     = type;
     this.original = original;
     this.patch    = patch ?? method.methodName;
     this.method   = method ?? new HarmonyMethod(
         methodType: typeof(HarmonyPatches),
         methodName: patch);
 }
Exemplo n.º 5
0
 protected Patch(HarmonyPatchType type,
                 Reflect.Method patchMethod,
                 Reflect.Method targetMethod,
                 int priority)
 {
     _type         = type;
     _patchMethod  = patchMethod;
     _targetMethod = targetMethod;
     _priority     = priority;
 }
Exemplo n.º 6
0
 public void Remove(Harmony harmony, HarmonyPatchType patchType = HarmonyPatchType.All)
 {
     foreach (var originalMethod in Original)
     {
         harmony.Unpatch(
             original: originalMethod,
             type: patchType,
             harmonyID: harmony.Id
             );
     }
 }
Exemplo n.º 7
0
        /// <summary>
        /// Checks to see if a patch with the specified method name (the method used in the
        /// patch class) and type is defined.
        /// </summary>
        /// <param name="instance">The Harmony instance to query for patches. Unused.</param>
        /// <param name="target">The target method to search for patches.</param>
        /// <param name="type">The patch type to look up.</param>
        /// <param name="name">The patch method name to look up (name as declared by patch owner).</param>
        /// <returns>true if such a patch was found, or false otherwise</returns>
        public static bool HasPatchWithMethodName(Harmony instance, MethodBase target,
                                                  HarmonyPatchType type, string name)
        {
            bool found = false;

            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException(nameof(name));
            }
            var patches = Harmony.GetPatchInfo(target);

            if (patches != null)
            {
                ICollection <Patch> patchList;
                switch (type)
                {
                case HarmonyPatchType.Prefix:
                    patchList = patches.Prefixes;
                    break;

                case HarmonyPatchType.Postfix:
                    patchList = patches.Postfixes;
                    break;

                case HarmonyPatchType.Transpiler:
                    patchList = patches.Transpilers;
                    break;

                case HarmonyPatchType.All:
                default:
                    // All
                    if (patches.Transpilers != null)
                    {
                        found = HasPatchWithMethodName(patches.Transpilers, name);
                    }
                    if (patches.Prefixes != null)
                    {
                        found = found || HasPatchWithMethodName(patches.Prefixes, name);
                    }
                    patchList = patches.Postfixes;
                    break;
                }
                if (patchList != null)
                {
                    found = found || HasPatchWithMethodName(patchList, name);
                }
            }
            return(found);
        }
Exemplo n.º 8
0
        public static bool PatchProcessor_Unpatch2_Prefix(HarmonyPatchType type, string harmonyID, object ___instance, List <MethodBase> ___originals)
        {
            var harmony = CreateHarmony(___instance);

            foreach (var method in ___originals)
            {
#if DEBUG
                UnityEngine.Debug.Log($"Unpatching patch ({type}) from method {method.FullDescription()} (HarmonyId: {harmony.Id})");
#endif
                harmony.Unpatch(method, type, harmonyID);
            }

            return(false);
        }
Exemplo n.º 9
0
        private static void ApplyPatch(MethodInfo target, HarmonyPatchType patchType, MethodInfo patch)
        {
            var harmonyMethod = new HarmonyMethod(patch);

            switch (patchType)
            {
            case HarmonyPatchType.Prefix:
                NVHarmonyPatcher.NVHarmony.Patch(target, harmonyMethod);

                break;

            case HarmonyPatchType.Postfix:
                NVHarmonyPatcher.NVHarmony.Patch(target, postfix: harmonyMethod);

                break;

            case HarmonyPatchType.Transpiler:
                NVHarmonyPatcher.NVHarmony.Patch(target, transpiler: harmonyMethod);

                break;
            }
        }
Exemplo n.º 10
0
        public static void ApplyHarmonyPatches(string id)
        {
            Harmony harmony = new(id : id);

            foreach (Patch patch in Patches)
            {
                Log.D($"Applying Harmony patch {patch.TargetType}{PatchDelimiter}{patch.PatchMethod}",
                      CustomCommunityCentre.ModEntry.Config.DebugMode);

                // Generate patch method
                string           harmonyTypeName = patch.PatchMethod.Split(PatchDelimiter).Last();
                HarmonyPatchType harmonyType     = (HarmonyPatchType)Enum.Parse(
                    enumType: typeof(HarmonyPatchType),
                    value: harmonyTypeName);
                HarmonyMethod harmonyMethod = new(
                    methodType : patch.PatchType,
                    methodName : patch.PatchMethod);

                // Get original method
                System.Reflection.MethodBase original = (patch.TargetMethod == ConstructorName)
                                        ? (System.Reflection.MethodBase)AccessTools.Constructor(
                    type: patch.TargetType,
                    parameters: patch.TargetParams)
                                        : AccessTools.Method(
                    type: patch.TargetType,
                    name: patch.TargetMethod,
                    parameters: patch.TargetParams);

                // Apply patch to original
                harmony.Patch(
                    original: original,
                    prefix: harmonyType == HarmonyPatchType.Prefix ? harmonyMethod : null,
                    postfix: harmonyType == HarmonyPatchType.Postfix ? harmonyMethod : null,
                    transpiler: harmonyType == HarmonyPatchType.Transpiler ? harmonyMethod : null,
                    finalizer: harmonyType == HarmonyPatchType.Finalizer ? harmonyMethod : null);
            }
        }
Exemplo n.º 11
0
        public void Apply()
        {
            if (Applied)
            {
                return;
            }
            foreach (PatchMethodInfo patchMethodInfo in this.GetPatchMethodsInfo())
            {
                MethodInfo       patchMethod      = patchMethodInfo.PatchMethod;
                MethodInfo       patchedMethod    = patchMethodInfo.PatchedMethod;
                HarmonyPatchType harmonyPatchType = patchMethodInfo.HarmonyPatchType;
                HarmonyMethod    harmonyMethod    = new HarmonyMethod(patchMethod);
                switch (harmonyPatchType)
                {
                case HarmonyPatchType.Prefix:
                    _harmony.Patch(patchedMethod, prefix: harmonyMethod);
                    break;

                case HarmonyPatchType.Postfix:
                    _harmony.Patch(patchedMethod, postfix: harmonyMethod);
                    break;

                case HarmonyPatchType.Transpiler:
                    _harmony.Patch(patchedMethod, transpiler: harmonyMethod);
                    break;

                case HarmonyPatchType.Finalizer:
                    _harmony.Patch(patchedMethod, finalizer: harmonyMethod);
                    break;

                default:
                    throw new NotSupportedException($"{harmonyPatchType} action is not supported when manually patching");
                }
            }
            Applied = true;
        }
Exemplo n.º 12
0
 public void Remove(HarmonyInstance harmony, HarmonyPatchType patchType = HarmonyPatchType.All)
 {
     harmony.Unpatch(Original, patchType, harmony.Id);
 }
Exemplo n.º 13
0
 public static void Unpatch(this MethodInfo method, HarmonyPatchType patchType = HarmonyPatchType.All, string id = null)
 {
     Harmony.Unpatch(method, patchType, id);
 }
 public HarmonyPatch(MethodInfo patch, HarmonyPatchType type, string id, int index, int priority = -1)
 {
     this.patch = patch; this.type = type; this.id = id; this.index = index; this.priority = priority;
 }
Exemplo n.º 15
0
        /// <summary>Unpatches a method by patching it with zero patches. Fully unpatching is not supported. Be careful, unpatching is global</summary>
        /// <param name="original">The original method/constructor</param>
        /// <param name="type">The <see cref="HarmonyPatchType"/></param>
        /// <param name="harmonyID">The optional Harmony ID to restrict unpatching to a specific Harmony instance</param>
        ///
        public void Unpatch(MethodBase original, HarmonyPatchType type, string harmonyID = null)
        {
            var processor = CreateProcessor(original);

            _ = processor.Unpatch(type, harmonyID);
        }
 public PatchMethodInfo(MethodInfo patchedMethod, HarmonyPatchType harmonyPatchType, MethodInfo patchMethod)
 {
     PatchedMethod    = patchedMethod;
     HarmonyPatchType = harmonyPatchType;
     PatchMethod      = patchMethod;
 }
Exemplo n.º 17
0
 public void Unpatch(MethodBase original, HarmonyPatchType type, string harmonyId = null) =>
 _harmonyInstance.Unpatch(original, type, harmonyId);