public Initializer(ModContentPack content) : base(content)
 {
     Instance = this;
     HarmonyMain.Initialize();
     //Settings.Instance = GetSettings<Settings>();
     HarmonyProfilerController.Initialize();
     Log.Message($"HarmonyProfiler :: Initialized");
 }
Beispiel #2
0
        public static string AllHarmonyPatchesDump()
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendLine("===[Harmony Patches]===");

            void dumpPatchesInfo(string type, ReadOnlyCollection <Patch> patches)
            {
                // Sort patches by harmony execute priority
                var patchesSorted = patches.ToList().OrderByDescending(x => x.priority).ThenBy(x => x.index);

                foreach (var p in patchesSorted)
                {
                    var m = p.PatchMethod;
                    sb.AppendLine($" {type}:{m.ReturnType.Name} {m.GetMethodFullString()} [mod:{p.owner}, prior:{p.priority}, idx:{p.index}]");
                    foreach (var b in p.before)
                    {
                        sb.AppendLine($"  before:{b}");
                    }
                    foreach (var a in p.after)
                    {
                        sb.AppendLine($"  after:{a}");
                    }
                }
                //if (patches.Count > 0)
                //    sb.AppendLine();
            }

            var patchesDic = HarmonyMain.GetPatches(null, false);

            foreach (var kv in patchesDic)
            {
                var patch = kv.Value;
                if (patch.Owners.Count >= 1)
                {
                    sb.AppendLine($"{kv.Key.GetMethodFullString()}:(Owners:{patch.Owners.Count}, Prefixes:{patch.Prefixes.Count}, Postfixes:{patch.Postfixes.Count}, Transpilers:{patch.Transpilers.Count})");
                    dumpPatchesInfo("prefix", patch.Prefixes);
                    dumpPatchesInfo("transpiler", patch.Transpilers);
                    dumpPatchesInfo("postfix", patch.Postfixes);
                    sb.AppendLine();
                }
            }

            return(sb.ToString());
        }
Beispiel #3
0
        public static void ResetProfiler()
        {
            if (!CanUnpatch())
            {
                return;
            }

            // Unpatch all
            foreach (var p in HarmonyMain.GetPatches(new[] { DubId }, false))
            {
                DubInst.Unpatch(p.Key, HarmonyPatchType.All, DubId);
            }

            // ApplyPerfomancePatches
            beforeMainTabs_PatchMe.Invoke(null, null);
            foreach (var type in GenTypes.AllTypes.Where(x => x.GetAttr("PerformancePatch") != null))
            {
                MethodInfo methodInfo = AccessTools.Method(type, "PerformancePatch");
                methodInfo?.Invoke(null, null);
            }

            //ResetTabs
            if (dialogAnalyzer_mainTabs.GetValue(null) is IEnumerable list)
            {
                var enumerator = list.GetEnumerator();
                while (enumerator.MoveNext())
                {
                    // clear dictionary
                    var modes = profileTab_Modes.GetValue(enumerator.Current);
                    modes.GetType().GetMethod("Clear").Invoke(modes, null);
                }
            }
            dialogAnalyzer_PatchedEverything.SetValue(null, false);
            analyzer_RequestStop.SetValue(null, true);
            Log.Warning($"Unpatched: {DubId}");
        }
Beispiel #4
0
        public static string CanConflictHarmonyPatchesDump()
        {
            StringBuilder sb = new StringBuilder();

            sb.AppendLine("===[Harmony Patches Can Conflict]===");

            var allPatches = HarmonyMain.GetPatchedMethods(null, false)
                             .GroupBy(x => x.originalMethod)
                             .Select(x => new
            {
                method  = x.Key,
                patches = x                                             // sort patches in execution priority. prefixes->transpilers->postfixes
                          .Where(y => y.patchType != PatchType.Postfix) // can be blocked only transpilers or low priority prefixes
                          .OrderBy(y => y.patchType)
                          .ThenByDescending(y => y.harmonyPatch.priority)
                          .ThenBy(y => y.harmonyPatch.index)
                          .ToList()
            });

            bool HasConflictPatches(List <PatchInfo> sortedByExecuteOrder)
            {
                for (int i = 0; i < sortedByExecuteOrder.Count; i++)
                {
                    var p = sortedByExecuteOrder[i];
                    if (p.patchType == PatchType.Prefix &&
                        p.harmonyPatch.PatchMethod.ReturnType == typeof(System.Boolean) &&
                        i != sortedByExecuteOrder.Count - 1)
                    {
                        // can block another prefixes, transpilers or postfixes
                        return(true);
                    }

                    if (p.patchType > PatchType.Prefix)
                    {
                        // transpilers and postfixes can't be bool patch
                        return(false);
                    }
                }

                return(false);
            }

            foreach (var p in allPatches)
            {
                if (!HasConflictPatches(p.patches))
                {
                    continue;
                }

                int owners = p.patches.Select(x => x.harmonyPatch.owner).Distinct().Count();
                if (owners <= 1)
                {
                    continue;
                }

                int prefixes    = p.patches.Count(x => x.patchType == PatchType.Prefix);
                int transpilers = p.patches.Count(x => x.patchType == PatchType.Transpiler);
                int postfixes   = p.patches.Count(x => x.patchType == PatchType.Postfix);
                sb.AppendLine($"{p.method.GetMethodFullString()}:(Owners: {owners} Prefixes:{prefixes}, Postfixes:{postfixes}, Transpilers:{transpilers})");
                foreach (var patchInfo in p.patches)
                {
                    var harmonyPatch = patchInfo.harmonyPatch;
                    var patchMethod  = harmonyPatch.PatchMethod;
                    sb.AppendLine($" {patchInfo.patchType} => {patchMethod.ReturnType.Name} {patchMethod.GetMethodFullString()} [mod:{harmonyPatch.owner}, prior:{harmonyPatch.priority}, idx:{harmonyPatch.index}]");
                    foreach (var b in harmonyPatch.before)
                    {
                        sb.AppendLine($"  before:{b}");
                    }
                    foreach (var a in harmonyPatch.after)
                    {
                        sb.AppendLine($"  after:{a}");
                    }
                }
                sb.AppendLine();
            }

            return(sb.ToString());
        }