Please disclose if your mod was created primarily using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of CraftingFilter v0.9.1
CraftingFilter.dll
Decompiled 2 years agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyVersion("1.0.0.0")] public class AedenthornUtils { public static bool IgnoreKeyPresses(bool extra = false) { int result; if (!extra) { if (!((Object)(object)ZNetScene.instance == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null) && !Minimap.IsOpen() && !Console.IsVisible() && !TextInput.IsVisible() && !ZNet.instance.InPasswordDialog()) { Chat instance = Chat.instance; if (instance == null || !instance.HasFocus()) { result = (Menu.IsVisible() ? 1 : 0); goto IL_005f; } } result = 1; goto IL_005f; } int result2; if (!((Object)(object)ZNetScene.instance == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null) && !Minimap.IsOpen() && !Console.IsVisible() && !TextInput.IsVisible() && !ZNet.instance.InPasswordDialog()) { Chat instance2 = Chat.instance; if ((instance2 == null || !instance2.HasFocus()) && !StoreGui.IsVisible() && !InventoryGui.IsVisible() && !Menu.IsVisible()) { TextViewer instance3 = TextViewer.instance; result2 = ((instance3 != null && instance3.IsVisible()) ? 1 : 0); goto IL_00d9; } } result2 = 1; goto IL_00d9; IL_005f: return (byte)result != 0; IL_00d9: return (byte)result2 != 0; } public static bool CheckKeyDown(string value) { try { return Input.GetKeyDown(value.ToLower()); } catch { return false; } } public static bool CheckKeyHeld(string value, bool req = true) { try { return Input.GetKey(value.ToLower()); } catch { return !req; } } } namespace CraftingFilter; [BepInPlugin("aedenthorn.CraftingFilter", "Crafting Filter", "0.9.0")] public class BepInExPlugin : BaseUnityPlugin { [HarmonyPatch(typeof(InventoryGui), "UpdateRecipeList")] private static class UpdateRecipeList_Patch { private static void Prefix(ref List<Recipe> recipes) { if (modEnabled.Value && Object.op_Implicit((Object)(object)Player.m_localPlayer.GetCurrentCraftingStation())) { Dbgl("updating recipes"); GetFilteredRecipes(ref recipes); } } } [HarmonyPatch(typeof(InventoryGui), "Hide")] private static class Hide_Patch { private static void Prefix() { if (modEnabled.Value) { ((TMP_Text)((Component)InventoryGui.instance.m_tabCraft).gameObject.GetComponentInChildren<TextMeshProUGUI>()).text = Localization.instance.Localize("$inventory_craftbutton"); lastCategoryIndex = 0; } } } [HarmonyPatch(typeof(InventoryGui), "OnTabCraftPressed")] private static class OnTabCraftPressed_Patch { private static void Prefix() { if (modEnabled.Value) { Dbgl("Tab craft pressed"); tabCraftPressed = 2; } } } [HarmonyPatch(typeof(InventoryGui), "Awake")] private static class InventoryGui_Awake_Patch { private static void Postfix(InventoryGui __instance) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Expected O, but got Unknown if (!modEnabled.Value) { return; } dropDownList.Clear(); for (int i = 0; i < categoryNames.Count; i++) { int idx = i; GameObject val = Object.Instantiate<GameObject>(((Component)__instance.m_tabCraft).gameObject); ((Object)val).name = categoryNames[i]; val.transform.SetParent(((Component)__instance.m_tabCraft).gameObject.transform.parent.parent); ((Selectable)val.GetComponent<Button>()).interactable = true; val.GetComponent<Button>().onClick = new ButtonClickedEvent(); ((UnityEvent)val.GetComponent<Button>().onClick).AddListener((UnityAction)delegate { SwitchFilter(idx); }); val.SetActive(false); dropDownList.Add(val); } } } [HarmonyPatch(typeof(Terminal), "InputText")] private static class InputText_Patch { private static bool Prefix(Terminal __instance) { if (!modEnabled.Value) { return true; } string text = ((TMP_InputField)__instance.m_input).text; if (text.ToLower().Equals(typeof(BepInExPlugin).Namespace.ToLower() + " reset")) { ((BaseUnityPlugin)context).Config.Reload(); ((BaseUnityPlugin)context).Config.Save(); __instance.AddString(text); __instance.AddString(((BaseUnityPlugin)context).Info.Metadata.Name + " config reloaded"); return false; } return true; } } public static ConfigEntry<bool> modEnabled; public static ConfigEntry<bool> isDebug; public static ConfigEntry<int> nexusID; public static ConfigEntry<bool> useScrollWheel; public static ConfigEntry<bool> showMenu; public static ConfigEntry<string> scrollModKey; public static ConfigEntry<string> prevHotKey; public static ConfigEntry<string> nextHotKey; public static ConfigEntry<string> categoryFile; private static BepInExPlugin context; private static Dictionary<string, List<ItemType>> categoryDict = new Dictionary<string, List<ItemType>>(); private static List<string> categoryNames = new List<string>(); private static List<GameObject> dropDownList = new List<GameObject>(); private static int lastCategoryIndex = 0; private Vector3 lastMousePos; private static bool isShowing = false; private static string assetPath; private static int tabCraftPressed = 0; public static void Dbgl(string str = "", bool pref = true) { if (isDebug.Value) { Debug.Log((object)((pref ? (typeof(BepInExPlugin).Namespace + " ") : "") + str)); } } private void Awake() { context = this; modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable this mod"); isDebug = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "IsDebug", true, "Enable debug logs"); nexusID = ((BaseUnityPlugin)this).Config.Bind<int>("General", "NexusID", 1219, "Nexus mod ID for updates"); nexusID.Value = 1219; useScrollWheel = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "ScrollWheel", true, "Use scroll wheel to switch filter"); showMenu = ((BaseUnityPlugin)this).Config.Bind<bool>("Settings", "ShowMenu", true, "Show filter menu on hover"); scrollModKey = ((BaseUnityPlugin)this).Config.Bind<string>("Settings", "ScrollModKey", "", "Modifer key to allow scroll wheel change. Use https://docs.unity3d.com/Manual/class-InputManager.html"); categoryFile = ((BaseUnityPlugin)this).Config.Bind<string>("Settings", "CategoryFile", "categories.json", "Category file name"); prevHotKey = ((BaseUnityPlugin)this).Config.Bind<string>("Settings", "HotKeyPrev", "", "Hotkey to switch to previous filter. Use https://docs.unity3d.com/Manual/class-InputManager.html"); nextHotKey = ((BaseUnityPlugin)this).Config.Bind<string>("Settings", "HotKeyNext", "", "Hotkey to switch to next filter. Use https://docs.unity3d.com/Manual/class-InputManager.html"); assetPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), typeof(BepInExPlugin).Namespace); LoadCategories(); Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null); } private void LoadCategories() { //IL_0172: Unknown result type (might be due to invalid IL or missing references) if (!Directory.Exists(assetPath)) { Dbgl("Creating mod folder"); Directory.CreateDirectory(assetPath); } string path = Path.Combine(assetPath, categoryFile.Value); CategoryData categoryData; if (!File.Exists(path)) { Dbgl("Creating category file"); categoryData = new CategoryData(); File.WriteAllText(path, JsonUtility.ToJson((object)categoryData)); } else { categoryData = JsonUtility.FromJson<CategoryData>(File.ReadAllText(path)); } Dbgl("Loaded " + categoryData.categories.Count + " categories"); categoryDict.Clear(); categoryNames.Clear(); foreach (string category in categoryData.categories) { if (!category.Contains(":")) { continue; } string[] array = category.Split(new char[1] { ':' }); string[] array2 = array[1].Split(new char[1] { ',' }); categoryNames.Add(array[0]); categoryDict[array[0]] = new List<ItemType>(); string[] array3 = array2; foreach (string value in array3) { if (Enum.TryParse<ItemType>(value, out ItemType result)) { categoryDict[array[0]].Add(result); } } } categoryNames.Sort(delegate(string a, string b) { if (categoryDict[a].Contains((ItemType)0)) { return -1; } return categoryDict[b].Contains((ItemType)0) ? 1 : a.CompareTo(b); }); } private void Update() { //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Expected O, but got Unknown //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) if (!modEnabled.Value || !Object.op_Implicit((Object)(object)Player.m_localPlayer) || !InventoryGui.IsVisible() || (!Object.op_Implicit((Object)(object)Player.m_localPlayer.GetCurrentCraftingStation()) && !Player.m_localPlayer.NoCostCheat())) { lastCategoryIndex = 0; UpdateDropDown(show: false); return; } if (!InventoryGui.instance.InCraftTab()) { UpdateDropDown(show: false); return; } bool flag = false; Vector3 mousePosition = Input.mousePosition; if (lastMousePos == Vector3.zero) { lastMousePos = mousePosition; } PointerEventData val = new PointerEventData(EventSystem.current) { position = Vector2.op_Implicit(lastMousePos) }; List<RaycastResult> list = new List<RaycastResult>(); EventSystem.current.RaycastAll(val, list); foreach (RaycastResult item in list) { RaycastResult current = item; if (((RaycastResult)(ref current)).gameObject.layer != LayerMask.NameToLayer("UI")) { continue; } if (((Object)((RaycastResult)(ref current)).gameObject).name == "Craft") { flag = true; if (tabCraftPressed == 0) { if (useScrollWheel.Value && AedenthornUtils.CheckKeyHeld(scrollModKey.Value, req: false) && Input.mouseScrollDelta.y != 0f) { SwitchFilter(Input.mouseScrollDelta.y < 0f); } if (showMenu.Value) { UpdateDropDown(show: true); } } } else if (dropDownList.Contains(((RaycastResult)(ref current)).gameObject)) { flag = true; } } if (!flag) { if (tabCraftPressed > 0) { tabCraftPressed--; } UpdateDropDown(show: false); } if (AedenthornUtils.CheckKeyDown(prevHotKey.Value)) { SwitchFilter(next: false); } else if (AedenthornUtils.CheckKeyDown(nextHotKey.Value)) { SwitchFilter(next: true); } lastMousePos = Input.mousePosition; } private static void SwitchFilter(int idx) { lastCategoryIndex = idx; UpdateDropDown(show: false); SwitchFilter(); } private static void SwitchFilter(bool next) { if (next) { lastCategoryIndex++; lastCategoryIndex %= categoryNames.Count; } else { lastCategoryIndex--; if (lastCategoryIndex < 0) { lastCategoryIndex = categoryNames.Count - 1; } } List<Recipe> list = new List<Recipe>(); Player.m_localPlayer.GetAvailableRecipes(ref list); int num = 0; while (!categoryDict[categoryNames[lastCategoryIndex]].Contains((ItemType)0) && list.FindAll((Recipe r) => categoryDict[categoryNames[lastCategoryIndex]].Contains(r.m_item.m_itemData.m_shared.m_itemType)).Count == 0 && num < categoryNames.Count) { num++; if (next) { lastCategoryIndex++; lastCategoryIndex %= categoryNames.Count; continue; } lastCategoryIndex--; if (lastCategoryIndex < 0) { lastCategoryIndex = categoryNames.Count - 1; } } SwitchFilter(); } private static void SwitchFilter() { List<Recipe> list = new List<Recipe>(); Player.m_localPlayer.GetAvailableRecipes(ref list); Dbgl($"Switching to filter {categoryNames[lastCategoryIndex]} {list.Count} total recipes "); Traverse val = Traverse.Create((object)InventoryGui.instance); val.Method("UpdateRecipeList", new object[1] { list }).GetValue(); val.Method("SetRecipe", new object[2] { 0, true }).GetValue(); ((Component)InventoryGui.instance.m_tabCraft).gameObject.GetComponentInChildren<TMP_Text>().text = Localization.instance.Localize("$inventory_craftbutton") + (categoryDict[categoryNames[lastCategoryIndex]].Contains((ItemType)0) ? "" : ("\n" + categoryNames[lastCategoryIndex])); } private static void GetFilteredRecipes(ref List<Recipe> recipes) { if (InventoryGui.instance.InCraftTab() && !categoryDict[categoryNames[lastCategoryIndex]].Contains((ItemType)0)) { recipes = recipes.FindAll((Recipe r) => categoryDict[categoryNames[lastCategoryIndex]].Contains(r.m_item.m_itemData.m_shared.m_itemType)); Dbgl($"using filter {categoryNames[lastCategoryIndex]}, {recipes.Count} filtered recipes"); } } private static void UpdateDropDown(bool show) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) if (show == isShowing) { return; } if (show) { List<Recipe> list = new List<Recipe>(); Player.m_localPlayer.GetAvailableRecipes(ref list); float scaleFactor = GameObject.Find("LoadingGUI").GetComponent<CanvasScaler>().scaleFactor; Vector2 val = Vector2.op_Implicit(((Transform)((Component)((Component)InventoryGui.instance.m_tabCraft).gameObject.transform).GetComponent<RectTransform>()).position); Rect rect = ((Component)((Component)InventoryGui.instance.m_tabCraft).gameObject.transform).GetComponent<RectTransform>().rect; float num = ((Rect)(ref rect)).height * scaleFactor; int num2 = 0; int i; for (i = 0; i < categoryNames.Count; i++) { int count = list.FindAll((Recipe r) => categoryDict[categoryNames[i]].Contains(r.m_item.m_itemData.m_shared.m_itemType)).Count; dropDownList[i].SetActive(count > 0 || categoryDict[categoryNames[i]].Contains((ItemType)0)); if (count > 0 || categoryDict[categoryNames[i]].Contains((ItemType)0)) { ((Transform)dropDownList[i].GetComponent<RectTransform>()).position = Vector2.op_Implicit(val - new Vector2(0f, num * (float)(num2++ + 1))); dropDownList[i].GetComponentInChildren<TMP_Text>().text = categoryNames[i] + ((count == 0) ? "" : $" ({count})"); } } } else { for (int j = 0; j < categoryNames.Count; j++) { dropDownList[j].SetActive(false); } } isShowing = show; } } public class CategoryData { public List<string> categories = new List<string>(); public CategoryData() { string[] names = Enum.GetNames(typeof(ItemType)); foreach (string text in names) { categories.Add(text + ":" + text); } } }