Please disclose if any significant portion of your mod was created 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 KeybindLib v1.0.6
KeybindLib.dll
Decompiled a week agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using KeybindLib.Classes; using TMPro; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("KeybindLib")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("KeybindLib")] [assembly: AssemblyCopyright("Copyright © 2024")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("a435cffd-1c69-437a-9daa-52fd5a9b02e6")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace KeybindLib { [BepInPlugin("bulletbot.keybindlib", "KeybindLib", "1.0.6")] internal class Plugin : BaseUnityPlugin { private const string modGUID = "bulletbot.keybindlib"; private const string modName = "KeybindLib"; private const string modVer = "1.0.6"; internal static Plugin instance; internal ManualLogSource logger; private readonly Harmony harmony = new Harmony("bulletbot.keybindlib"); private bool hasPatched; internal List<Keybind> registeredKeybinds; private void Awake() { instance = this; logger = Logger.CreateLogSource("KeybindLib"); registeredKeybinds = new List<Keybind>(); logger.LogMessage((object)"KeybindLib has started."); SceneManager.activeSceneChanged += delegate { if (!hasPatched) { harmony.PatchAll(); logger.LogMessage((object)($"{registeredKeybinds.Count((Keybind x) => !x.registeredAsToggle)} keybind(s) and " + $"{registeredKeybinds.Count((Keybind x) => x.registeredAsToggle)} toggle(s) has been initialized.")); hasPatched = true; } }; } } } namespace KeybindLib.Patches { [HarmonyPatch(typeof(MenuManager))] internal class MenuManagerPatch { private static readonly float _headerOffset = 30f; private static readonly float _categoryOffset = 26.5f; private static readonly float _categoryHeaderOffset = 6.5f; private static readonly float _buttonOffset = 42f; private static readonly float _buttonHeaderOffset = 15f; private static readonly float _buttonCategoryOffset = 11.5f; private static readonly float _buttonBoolSettingOffset = 27.25f; private static readonly float _buttonBoolSettingHeaderOffset = 12.5f; private static readonly float _buttonBoolSettingCategoryOffset = 9f; private static readonly float _boolSettingOffset = 32.25f; private static readonly float _boolSettingHeaderOffset = 15.25f; private static readonly float _boolSettingCategoryOffset = 20.25f; [HarmonyPatch("Start")] [HarmonyPrefix] private static void Start(ref List<MenuPages> ___menuPages) { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Expected O, but got Unknown //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Unknown result type (might be due to invalid IL or missing references) //IL_0366: Unknown result type (might be due to invalid IL or missing references) //IL_036f: Unknown result type (might be due to invalid IL or missing references) //IL_0376: Unknown result type (might be due to invalid IL or missing references) //IL_067d: Unknown result type (might be due to invalid IL or missing references) //IL_0682: Unknown result type (might be due to invalid IL or missing references) //IL_06cc: Unknown result type (might be due to invalid IL or missing references) //IL_06d5: Unknown result type (might be due to invalid IL or missing references) //IL_06dc: Unknown result type (might be due to invalid IL or missing references) //IL_046f: Unknown result type (might be due to invalid IL or missing references) //IL_0474: Unknown result type (might be due to invalid IL or missing references) //IL_048f: Unknown result type (might be due to invalid IL or missing references) //IL_0498: Unknown result type (might be due to invalid IL or missing references) //IL_049f: Unknown result type (might be due to invalid IL or missing references) //IL_0526: Unknown result type (might be due to invalid IL or missing references) //IL_052b: Unknown result type (might be due to invalid IL or missing references) //IL_0575: Unknown result type (might be due to invalid IL or missing references) //IL_057e: Unknown result type (might be due to invalid IL or missing references) //IL_0585: Unknown result type (might be due to invalid IL or missing references) if (Plugin.instance.registeredKeybinds.Count <= 0) { return; } MenuPages val = ((IEnumerable<MenuPages>)___menuPages).FirstOrDefault((Func<MenuPages, bool>)((MenuPages x) => (int)x.menuPageIndex == 6)); Transform child = val.menuPage.transform.GetChild(3); MenuScrollBox component = ((Component)child).GetComponent<MenuScrollBox>(); Transform child2 = child.GetChild(1).GetChild(0); GameObject gameObject = ((Component)child2.Find("Header Player Expressions")).gameObject; Vector3 localPosition = gameObject.transform.localPosition; GameObject gameObject2 = ((Component)child2.Find("Header Grabbing")).gameObject; Vector3 localPosition2 = gameObject2.transform.localPosition; GameObject gameObject3 = ((Component)child2.Find("Big Button Map")).gameObject; Vector3 localPosition3 = gameObject3.transform.localPosition; GameObject gameObject4 = ((Component)child2.Find("Bool Setting - ")).gameObject; Vector3 localPosition4 = gameObject4.transform.localPosition; GameObject val2 = null; foreach (Transform item in child2) { Transform val3 = item; if (((Object)val3).name == "Bool Setting - ") { val2 = ((Component)val3).gameObject; } } Vector3 localPosition5 = val2.transform.localPosition; List<string> currentHeaders = new List<string>(); List<(string, string)> currentCategories = new List<(string, string)>(); Plugin.instance.registeredKeybinds.Sort(delegate(Keybind a, Keybind b) { int num2 = a.modOrderIndex.CompareTo(b.modOrderIndex); if (num2 != 0) { return num2; } bool flag3 = !string.IsNullOrEmpty(a.category); bool flag4 = !string.IsNullOrEmpty(b.category); if (flag3 != flag4) { return flag3.CompareTo(flag4); } bool registeredAsToggle = a.registeredAsToggle; bool registeredAsToggle2 = b.registeredAsToggle; return (registeredAsToggle != registeredAsToggle2) ? registeredAsToggle2.CompareTo(registeredAsToggle) : a.registerIndex.CompareTo(b.registerIndex); }); float num = child2.GetChild(child2.childCount - 1).localPosition.y; List<Keybind> registeredKeybinds = Plugin.instance.registeredKeybinds; for (int i = 0; i < registeredKeybinds.Count; i++) { Keybind keybind2 = registeredKeybinds[i]; bool flag = RequiresHeader(keybind2); if (flag) { num -= _headerOffset; GameObject val4 = Object.Instantiate<GameObject>(gameObject); LocalizationChangedEvent[] componentsInChildren = val4.GetComponentsInChildren<LocalizationChangedEvent>(); foreach (LocalizationChangedEvent val5 in componentsInChildren) { Object.Destroy((Object)(object)val5); } ((Object)val4).name = "Header " + keybind2.modGuid; ((TMP_Text)val4.GetComponentInChildren<TextMeshProUGUI>()).text = keybind2.modGuid; val4.transform.SetParent(child2); val4.transform.localPosition = new Vector3(localPosition.x, num, localPosition.z); currentHeaders.Add(keybind2.modGuid); } bool flag2 = RequiresCategory(keybind2); if (flag2) { num -= _categoryOffset; if (flag) { num -= _categoryHeaderOffset; } GameObject val6 = Object.Instantiate<GameObject>(gameObject2); LocalizationChangedEvent[] componentsInChildren2 = val6.GetComponentsInChildren<LocalizationChangedEvent>(); foreach (LocalizationChangedEvent val7 in componentsInChildren2) { Object.Destroy((Object)(object)val7); } ((Object)val6).name = "Category " + keybind2.modGuid + " " + keybind2.category; ((TMP_Text)val6.GetComponentInChildren<TextMeshProUGUI>()).text = keybind2.category; val6.transform.SetParent(child2); val6.transform.localPosition = new Vector3(localPosition2.x, num, localPosition2.z); currentCategories.Add((keybind2.modGuid, keybind2.category)); flag2 = true; } if (keybind2.inputAction != null) { num -= _buttonOffset; if (flag) { num -= _buttonHeaderOffset; } if (flag2) { num -= _buttonCategoryOffset; } GameObject val8 = Object.Instantiate<GameObject>(gameObject3); LocalizationChangedEvent[] componentsInChildren3 = val8.GetComponentsInChildren<LocalizationChangedEvent>(); foreach (LocalizationChangedEvent val9 in componentsInChildren3) { Object.Destroy((Object)(object)val9); } string name = keybind2.inputAction.name; ((Object)val8).name = "Big Button " + keybind2.modGuid + " " + name; val8.GetComponent<MenuBigButton>().buttonTitle = name; ((TMP_Text)val8.GetComponentInChildren<TextMeshProUGUI>()).text = name; val8.GetComponent<MenuKeybind>().inputKey = keybind2.inputKey; val8.transform.SetParent(child2); val8.transform.localPosition = new Vector3(localPosition3.x, num, localPosition3.z); if (keybind2.toggle != null) { num -= _buttonBoolSettingOffset; GameObject val10 = Object.Instantiate<GameObject>(gameObject4); LocalizationChangedEvent[] componentsInChildren4 = val10.GetComponentsInChildren<LocalizationChangedEvent>(); foreach (LocalizationChangedEvent val11 in componentsInChildren4) { Object.Destroy((Object)(object)val11); } ((Object)val10).name = "Button Toggle " + keybind2.modGuid + " " + name; val10.GetComponent<MenuKeybindToggle>().inputKey = keybind2.inputKey; MenuTwoOptions component2 = val10.GetComponent<MenuTwoOptions>(); component2.option2Text = keybind2.toggle.falseText; component2.option1Text = keybind2.toggle.trueText; val10.transform.SetParent(child2); val10.transform.localPosition = new Vector3(localPosition4.x, num, localPosition4.z); } if (i + 1 < registeredKeybinds.Count) { Keybind keybind3 = registeredKeybinds[i + 1]; if (RequiresHeader(keybind3)) { num -= _buttonBoolSettingHeaderOffset; } if (RequiresCategory(keybind3)) { num -= _buttonBoolSettingCategoryOffset; } } } else { num -= _boolSettingOffset; if (flag) { num -= _boolSettingHeaderOffset; } if (flag2) { num -= _boolSettingCategoryOffset; } GameObject val12 = Object.Instantiate<GameObject>(val2); LocalizationChangedEvent[] componentsInChildren5 = val12.GetComponentsInChildren<LocalizationChangedEvent>(); foreach (LocalizationChangedEvent val13 in componentsInChildren5) { Object.Destroy((Object)(object)val13); } ((Object)val12).name = "Toggle " + keybind2.modGuid + " " + keybind2.category; val12.GetComponent<MenuKeybindToggle>().inputKey = keybind2.inputKey; MenuTwoOptions component3 = val12.GetComponent<MenuTwoOptions>(); component3.option2Text = keybind2.toggle.falseText; component3.option1Text = keybind2.toggle.trueText; val12.transform.SetParent(child2); val12.transform.localPosition = new Vector3(localPosition5.x, num, localPosition5.z); } component.heightPadding += 4f; } bool RequiresCategory(Keybind keybind) { return !string.IsNullOrEmpty(keybind.category) && !currentCategories.Contains((keybind.modGuid, keybind.category)); } bool RequiresHeader(Keybind keybind) { return !currentHeaders.Contains(keybind.modGuid); } } } [HarmonyPatch(typeof(InputManager))] internal class InputManagerPatch { [HarmonyPatch("Start")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> StartTranspiler(IEnumerable<CodeInstruction> instructions) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Expected O, but got Unknown //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null); val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Ldstr, (object)"DefaultKeyBindings.es3", (string)null) }); val.Insert((CodeInstruction[])(object)new CodeInstruction[3] { new CodeInstruction(OpCodes.Ldarg_0, (object)null), new CodeInstruction(OpCodes.Ldflda, (object)AccessTools.Field(typeof(InputManager), "tagDictionary")), new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(InputManagerPatch), "Start", (Type[])null, (Type[])null)) }); return val.InstructionEnumeration(); } private static void Start(ref Dictionary<string, InputKey> tagDictionary) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) foreach (Keybind registeredKeybind in Plugin.instance.registeredKeybinds) { if (!string.IsNullOrEmpty(registeredKeybind.tag)) { tagDictionary.Add(registeredKeybind.tag, registeredKeybind.inputKey); } } } [HarmonyPatch("InitializeInputs")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> InitializeInputsTranspiler(IEnumerable<CodeInstruction> instructions) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Expected O, but got Unknown //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Expected O, but got Unknown //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Expected O, but got Unknown //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Expected O, but got Unknown CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null); int num = -1; while (true) { val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Callvirt, (object)AccessTools.Method(typeof(Dictionary<InputKey, InputAction>), "set_Item", (Type[])null, (Type[])null), (string)null) }); if (!val.IsValid) { break; } num = val.Pos; val.Advance(1); } if (num != -1) { val.Start(); val.Advance(num + 1); val.Insert((CodeInstruction[])(object)new CodeInstruction[5] { new CodeInstruction(OpCodes.Ldarg_0, (object)null), new CodeInstruction(OpCodes.Ldflda, (object)AccessTools.Field(typeof(InputManager), "inputActions")), new CodeInstruction(OpCodes.Ldarg_0, (object)null), new CodeInstruction(OpCodes.Ldflda, (object)AccessTools.Field(typeof(InputManager), "inputToggle")), new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(InputManagerPatch), "InitializeInputs", (Type[])null, (Type[])null)) }); } return val.InstructionEnumeration(); } private static void InitializeInputs(ref Dictionary<InputKey, InputAction> inputActions, ref Dictionary<InputKey, bool> inputToggle) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) foreach (Keybind registeredKeybind in Plugin.instance.registeredKeybinds) { if (registeredKeybind.inputAction != null) { inputActions[registeredKeybind.inputKey] = registeredKeybind.inputAction; } if (registeredKeybind.toggle != null) { inputToggle.Add(registeredKeybind.inputKey, registeredKeybind.toggle.defaultValue); } } } } } namespace KeybindLib.Classes { public class Keybind { public class Toggle { public bool defaultValue; public string falseText = "hold"; public string trueText = "toggle"; } internal bool registeredAsToggle; internal int modOrderIndex; internal int registerIndex; public string modGuid { get; internal set; } public string category { get; internal set; } public string tag { get; internal set; } public Toggle toggle { get; internal set; } public InputKey inputKey { get; internal set; } public InputAction inputAction { get; internal set; } } public static class Keybinds { internal static readonly Dictionary<string, int> _modOrder = new Dictionary<string, int>(); internal static int _nextRegisterIndex = 0; internal static int _nextModOrderIndex = 0; private static BepInPlugin GetPluginByCallingAssembly(Assembly assembly) { return SafeTypes().Select((Func<Type, BepInPlugin>)delegate(Type t) { try { return ((MemberInfo)t).GetCustomAttribute<BepInPlugin>(); } catch { return null; } }).FirstOrDefault((Func<BepInPlugin, bool>)((BepInPlugin attr) => attr != null)); IEnumerable<Type> SafeTypes() { try { return assembly.GetTypes(); } catch (ReflectionTypeLoadException ex) { return ex.Types.Where((Type t) => t != null); } catch { try { return assembly.GetExportedTypes(); } catch { return Enumerable.Empty<Type>(); } } } } public static Keybind Bind(string name, string binding) { return Register(GetPluginByCallingAssembly(Assembly.GetCallingAssembly()), null, name, binding); } public static Keybind Bind(string category, string name, string binding) { return Register(GetPluginByCallingAssembly(Assembly.GetCallingAssembly()), category, name, binding); } public static Keybind Toggle(Keybind.Toggle toggle) { return Register(GetPluginByCallingAssembly(Assembly.GetCallingAssembly()), null, null, null, toggle, isToggle: true); } public static Keybind Toggle(string category, Keybind.Toggle toggle) { return Register(GetPluginByCallingAssembly(Assembly.GetCallingAssembly()), category, null, null, toggle, isToggle: true); } public static Keybind Toggle(Keybind keybind, Keybind.Toggle toggle) { BepInPlugin val = (from x in Assembly.GetCallingAssembly().GetTypes() select ((MemberInfo)x).GetCustomAttribute<BepInPlugin>()).FirstOrDefault(); if (val == null) { Plugin.instance.logger.LogMessage((object)"Failed to apply toggle because the calling mod could not be identified."); return null; } if (keybind == null) { Plugin.instance.logger.LogMessage((object)"Failed to apply toggle because the provided keybind was null."); return null; } bool registeredAsToggle = keybind.registeredAsToggle; string modGuid = keybind.modGuid; string category = keybind.category; string text = ((keybind.inputAction != null) ? keybind.inputAction.name : null); bool flag = keybind.toggle != null; if (modGuid == val.GUID && Plugin.instance.registeredKeybinds.Contains(keybind)) { Plugin.instance.logger.LogMessage((object)(((toggle == null) ? "Removed" : (flag ? "Replaced" : "Attached")) + " toggle" + ((!registeredAsToggle) ? (((toggle == null) ? " from" : " to") + " keybind" + ((!string.IsNullOrEmpty(text)) ? (" \"" + text + "\"") : "")) : "") + ((!string.IsNullOrEmpty(category)) ? (" in category \"" + category + "\"") : "") + " for mod \"" + modGuid + "\".")); keybind.toggle = toggle; return keybind; } Plugin.instance.logger.LogMessage((object)("Failed to " + ((toggle == null) ? "remove" : (flag ? "replace" : "attach")) + " toggle" + ((!registeredAsToggle) ? (((toggle == null) ? " from" : " to") + " keybind" + ((!string.IsNullOrEmpty(text)) ? (" \"" + text + "\"") : "")) : "") + ((!string.IsNullOrEmpty(keybind.category)) ? (" in category \"" + category + "\"") : "") + " for mod \"" + modGuid + "\".")); return null; } internal static Keybind Register(BepInPlugin plugin, string category = null, string name = null, string binding = null, Keybind.Toggle toggle = null, bool isToggle = false) { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Expected I4, but got Unknown //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Expected O, but got Unknown if (plugin == null) { Plugin.instance.logger.LogMessage((object)("Failed to register a " + (isToggle ? "toggle" : "keybind") + " because the calling mod could not be identified.")); return null; } string modGuid = plugin.GUID; InputKey inputKey = ComputeInputKey(); bool flag = !isToggle && (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(binding) || Plugin.instance.registeredKeybinds.Any((Keybind x) => x.modGuid == modGuid && SameCategory(x) && !x.registeredAsToggle && x.inputKey == inputKey)); bool flag2 = isToggle && (toggle == null || Plugin.instance.registeredKeybinds.Any((Keybind x) => x.modGuid == modGuid && SameCategory(x) && x.registeredAsToggle && x.inputKey == inputKey)); if (flag || flag2) { Plugin.instance.logger.LogMessage((object)("Failed to register " + (isToggle ? "toggle" : ("keybind" + ((!string.IsNullOrEmpty(name)) ? (" \"" + name + "\"") : ""))) + ((!string.IsNullOrEmpty(category)) ? (" in category \"" + category + "\"") : "") + " for mod \"" + modGuid + "\".")); return null; } Keybind keybind = new Keybind { modGuid = modGuid, category = category, inputKey = inputKey }; if (isToggle) { keybind.toggle = toggle; } else { keybind.tag = $"[{(int)inputKey}]"; keybind.inputAction = new InputAction(name, (InputActionType)0, binding, (string)null, (string)null, (string)null); } keybind.registeredAsToggle = isToggle; if (!_modOrder.TryGetValue(modGuid, out var value)) { value = _nextModOrderIndex++; _modOrder[modGuid] = value; } keybind.modOrderIndex = value; keybind.registerIndex = _nextRegisterIndex++; Plugin.instance.registeredKeybinds.Add(keybind); Plugin.instance.logger.LogMessage((object)("Registered " + (isToggle ? "toggle" : ("keybind \"" + name + "\"")) + ((!string.IsNullOrEmpty(category)) ? (" in category \"" + category + "\"") : "") + " for mod \"" + modGuid + "\".")); return keybind; InputKey ComputeInputKey() { //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(category)) { category = string.Empty; } if (string.IsNullOrEmpty(name)) { name = string.Empty; } string text = modGuid + "|" + category + "|" + name; uint num = 2166136261u; for (int i = 0; i < text.Length; i++) { num ^= text[i]; num *= 16777619; } num &= 0x3FFFFFFFu; num |= 0x40000000u; return (InputKey)num; } bool SameCategory(Keybind x) { return (string.IsNullOrEmpty(x.category) && string.IsNullOrEmpty(category)) || (!string.IsNullOrEmpty(x.category) && !string.IsNullOrEmpty(category) && x.category.Equals(category, StringComparison.OrdinalIgnoreCase)); } } } }