public static void ProfileMods(List <string> modNames)
        {
            var profilerCfg = Settings.Get().cfgDef;
            var settings    = Settings.Get();

            HashSet <string> patches = new HashSet <string>();

            // hugs tick
            var hugsTicks = GetHugsLibTicks();

            if (hugsTicks != null)
            {
                patches.UnionWith(hugsTicks);
            }


            var modsDir = LoadedModManager.RunningModsListForReading.Select(x => new { modContentPack = x, dirName = Path.GetFileName(x.RootDir) }).ToList();

            foreach (var modName in modNames)
            {
                var mod = modsDir.FirstOrDefault(x => x.dirName.StartsWith(modName))?.modContentPack;
                if (mod == null)
                {
                    Log.Error($"Can't find mod with name: {modName}");
                    continue;
                }

                foreach (var d in mod.AllDefs)
                {
                    // ThinkTree childs
                    if (d is ThinkTreeDef thinkDef)
                    {
                        foreach (var child in thinkDef.thinkRoot.ChildrenRecursive)
                        {
                            patches.AddDefMethodsAdvanced((child as ThinkNode_JobGiver)?.GetType(), settings.allowCoreAsm);
                        }
                    }
                    // DesignationCategory childs
                    if (d is DesignationCategoryDef designationCategoryDef)
                    {
                        foreach (var child in designationCategoryDef.specialDesignatorClasses)
                        {
                            patches.AddDefMethodsAdvanced(child, settings.allowCoreAsm);
                        }
                    }
                    // Auto class getter
                    var workers = GetWorkerClasses(d, profilerCfg.workerFields, profilerCfg.workerGetters);
                    foreach (var worker in workers)
                    {
                        patches.AddDefMethodsAdvanced(worker, settings.allowCoreAsm);
                    }
                }
            }
            ProfileMethods(patches.ToArray());
        }
        private void DrawCustomProfiler(Listing_Extended lister, Settings settings)
        {
            lister.LabelColored("Profile Custom(Methods,Classes,Namespaces)", TitleLabelColor);
            Rect buttonRect1 = lister.GetRect(Text.LineHeight),
                 buttonRect2 = buttonRect1;

            buttonRect2.width = buttonRect1.width /= 2;
            buttonRect2.x     = buttonRect1.xMax;

            if (Widgets.ButtonText(buttonRect1, "Profile all dlls"))
            {
                PatchHandler.Initialize();
                var methods     = new HashSet <string>();
                var modDllNames = Utils.GetAllModsDll();
                //File.WriteAllLines("dsdsd", modDllNames.ToArray());
                foreach (var modDllName in modDllNames)
                {
                    //Log.Warning($"[dll] {modDllName}");
                    foreach (var @class in Utils.GetClassesFromDll(modDllName))
                    {
                        methods.AddDefMethodsAdvanced(@class, settings.allowCoreAsm, !settings.allowInheritedMethods);
                    }
                }
                Profiler.Logger.LogOperation("DllProfiling", () => Patcher.ProfileMethods(methods.ToArray()));
            }

            //if (!settings.profileCustom.IsNullOrEmptyOrEqual(Settings.CustomExampleStr))
            {
                lister.CheckboxLabeled("Allow Core assembly", ref settings.allowCoreAsm);
                lister.CheckboxLabeled("Allow class inherited methods", ref settings.allowInheritedMethods);
                if (Widgets.ButtonText(buttonRect2, $"Profile custom methods"))
                {
                    PatchHandler.Initialize();
                    var methods = new HashSet <string>();
                    var list    = settings.profileCustom.Split(new[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
                    foreach (var s in list)
                    {
                        // it's method
                        if (s.Contains(":"))
                        {
                            methods.Add(s);
                        }
                        else if (s.EndsWith(".dll"))
                        {
                            string dllName = s.Replace(".dll", "");
                            foreach (var @class in Utils.GetClassesFromDll(dllName))
                            {
                                methods.AddDefMethodsAdvanced(@class, settings.allowCoreAsm, !settings.allowInheritedMethods);
                            }
                        }
                        else
                        {
                            Type type = AccessTools.TypeByName(s);
                            // it's class
                            if (type?.IsClass ?? false)
                            {
                                methods.AddDefMethodsAdvanced(type, settings.allowCoreAsm, !settings.allowInheritedMethods);
                            }
                            else // parse namespace
                            {
                                var classes = Utils.GetClassesFromNamespace(s);
                                if (!classes.Any())
                                {
                                    Log.Error($"[HarmonyProfiler] Found 0 results for namespace:'{s}'");
                                }
                                foreach (var @class in classes)
                                {
                                    methods.AddDefMethodsAdvanced(@class, settings.allowCoreAsm, !settings.allowInheritedMethods);
                                }
                            }
                        }
                    }

                    Profiler.Logger.LogOperation("CustomProfiling", () => Patcher.ProfileMethods(methods.ToArray()));
                }
            }

            settings.profileCustom = lister.TextAreaFocusControl("CustomProfilerField", settings.profileCustom, 5, ref customScrollPos);
            lister.Gap(20f);
        }