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 ControllerChords v0.2.0
ControllerChords.dll
Decompiled 11 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using UnityEngine; [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.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("0.0.0.0")] namespace ControllerChords; [BepInPlugin("marc.valheim.controllerchords", "Controller Chords", "0.2.0")] [BepInProcess("valheim.exe")] public sealed class ControllerChordsPlugin : BaseUnityPlugin { private sealed class ChordSlot { public int Index; public ConfigEntry<bool> Enabled; public ConfigEntry<ControllerButton> Modifier; public ConfigEntry<ControllerButton> Button; public ConfigEntry<KeyCode> TargetKey; public ConfigEntry<bool> BlockModifierDefaultAction; public ConfigEntry<int> VirtualPressFrames; public ConfigEntry<bool> HoldMode; } private struct ChordDefaults { public readonly bool Enabled; public readonly ControllerButton Modifier; public readonly ControllerButton Button; public readonly KeyCode TargetKey; public readonly bool BlockModifierDefaultAction; public readonly int VirtualPressFrames; public ChordDefaults(bool enabled, ControllerButton modifier, ControllerButton button, KeyCode targetKey, bool blockModifierDefaultAction, int virtualPressFrames) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) Enabled = enabled; Modifier = modifier; Button = button; TargetKey = targetKey; BlockModifierDefaultAction = blockModifierDefaultAction; VirtualPressFrames = virtualPressFrames; } } public const string PluginGuid = "marc.valheim.controllerchords"; public const string PluginName = "Controller Chords"; public const string PluginVersion = "0.2.0"; private const int SlotCount = 12; private const int MinimumVirtualPressFrames = 1; private const int MaximumVirtualPressFrames = 8; internal static ControllerChordsPlugin Instance; private ConfigEntry<bool> enabledConfig; private ConfigEntry<bool> allowInMenus; private ConfigEntry<bool> logChordEvents; private readonly List<ChordSlot> slots = new List<ChordSlot>(12); private readonly Dictionary<KeyCode, int> virtualKeyFrames = new Dictionary<KeyCode, int>(); private readonly Dictionary<string, int> virtualButtonFrames = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase); private readonly Dictionary<string, int> blockedButtonFrames = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase); private readonly List<KeyCode> keyScratch = new List<KeyCode>(); private readonly List<string> stringScratch = new List<string>(); private readonly HashSet<int> heldChordActive = new HashSet<int>(); private Harmony harmony; private Type zInputType; private Func<string, bool> zGetButton; private Func<string, bool> zGetButtonDown; private PropertyInfo zVirtualKeyboardOpenProperty; private MethodInfo menuIsVisibleMethod; private MethodInfo inventoryGuiIsVisibleMethod; private MethodInfo storeGuiIsVisibleMethod; private MethodInfo textInputIsVisibleMethod; private MethodInfo consoleIsVisibleMethod; private bool zInputReady; private bool patchesInstalled; private int chordsFired; private void Awake() { Instance = this; BindConfig(); if (!enabledConfig.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Controller Chords is disabled by config. No Harmony patches were installed."); return; } ResolveZInput(); ResolveMenuGuards(); InstallPatches(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Controller Chords 0.2.0 loaded. Chord detection uses Valheim ZInput when available."); } private void OnDestroy() { if (harmony != null) { harmony.UnpatchSelf(); harmony = null; } virtualKeyFrames.Clear(); virtualButtonFrames.Clear(); blockedButtonFrames.Clear(); if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } private void Update() { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Invalid comparison between Unknown and I4 if (!enabledConfig.Value || !zInputReady || (!allowInMenus.Value && IsMenuInputContext())) { return; } for (int i = 0; i < slots.Count; i++) { ChordSlot chordSlot = slots[i]; if (chordSlot == null || !chordSlot.Enabled.Value) { continue; } ControllerButton value = chordSlot.Modifier.Value; if (!IsSupportedModifier(value)) { continue; } ControllerButton value2 = chordSlot.Button.Value; if (value2 == ControllerButton.None || value2 == value || (int)chordSlot.TargetKey.Value == 0) { continue; } string text = ToZInputButtonName(value); string text2 = ToZInputButtonName(value2); if (string.IsNullOrEmpty(text) || string.IsNullOrEmpty(text2)) { continue; } bool flag = SafeGetZButton(text); if (chordSlot.HoldMode.Value) { bool flag2 = SafeGetZButton(text2); if (flag && flag2) { HoldChord(chordSlot, text); } else if (heldChordActive.Contains(chordSlot.Index)) { heldChordActive.Remove(chordSlot.Index); if (logChordEvents.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Controller Chords: chord " + chordSlot.Index + " HOLD released.")); } } } else { bool flag3 = SafeGetZButtonDown(text2); if (flag && flag3) { FireChord(chordSlot, text); } } } } private void LateUpdate() { AgeKeyFrames(); AgeStringFrames(virtualButtonFrames); AgeStringFrames(blockedButtonFrames); } private void BindConfig() { //IL_010a: Unknown result type (might be due to invalid IL or missing references) enabledConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master switch. If false at startup, Controller Chords installs no active input patches."); allowInMenus = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AllowInMenus", false, "Allow controller chords while Valheim menus/text input are open."); logChordEvents = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "LogChordEvents", false, "Log each fired chord to BepInEx/LogOutput.log."); for (int i = 1; i <= 12; i++) { ChordDefaults defaults = GetDefaults(i); string text = "Chord " + i.ToString("00"); ChordSlot item = new ChordSlot { Index = i, Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>(text, "Enabled", defaults.Enabled, "Enable this controller chord slot."), Modifier = ((BaseUnityPlugin)this).Config.Bind<ControllerButton>(text, "Modifier", defaults.Modifier, "Held modifier button. Supported modifiers are RB, LB, RT, and LT."), Button = ((BaseUnityPlugin)this).Config.Bind<ControllerButton>(text, "Button", defaults.Button, "Trigger button that fires on button-down while the modifier is held."), TargetKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>(text, "TargetKey", defaults.TargetKey, "Keyboard KeyCode exposed virtually to other mods."), BlockModifierDefaultAction = ((BaseUnityPlugin)this).Config.Bind<bool>(text, "BlockModifierDefaultAction", defaults.BlockModifierDefaultAction, "Temporarily suppress this modifier's ZInput action when the chord fires. Defaults false."), VirtualPressFrames = ((BaseUnityPlugin)this).Config.Bind<int>(text, "VirtualPressFrames", defaults.VirtualPressFrames, "Number of frames the virtual key remains visible to input queries (tap mode only)."), HoldMode = ((BaseUnityPlugin)this).Config.Bind<bool>(text, "HoldMode", false, "When true, the target key is held DOWN for as long as you hold the chord (modifier + trigger), and released when you let go. Use this for press-and-hold mods like climbing. When false (default), the chord sends a brief tap suitable for toggle hotkeys.") }; slots.Add(item); } } private static ChordDefaults GetDefaults(int index) { return index switch { 1 => new ChordDefaults(enabled: true, ControllerButton.RB, ControllerButton.A, (KeyCode)306, blockModifierDefaultAction: false, 2), 2 => new ChordDefaults(enabled: false, ControllerButton.RB, ControllerButton.B, (KeyCode)308, blockModifierDefaultAction: false, 2), 3 => new ChordDefaults(enabled: false, ControllerButton.RB, ControllerButton.X, (KeyCode)103, blockModifierDefaultAction: false, 2), 4 => new ChordDefaults(enabled: false, ControllerButton.RB, ControllerButton.Y, (KeyCode)104, blockModifierDefaultAction: false, 2), 5 => new ChordDefaults(enabled: false, ControllerButton.LB, ControllerButton.A, (KeyCode)106, blockModifierDefaultAction: false, 2), 6 => new ChordDefaults(enabled: false, ControllerButton.LB, ControllerButton.B, (KeyCode)107, blockModifierDefaultAction: false, 2), 7 => new ChordDefaults(enabled: false, ControllerButton.LB, ControllerButton.X, (KeyCode)108, blockModifierDefaultAction: false, 2), 8 => new ChordDefaults(enabled: false, ControllerButton.LB, ControllerButton.Y, (KeyCode)59, blockModifierDefaultAction: false, 2), 9 => new ChordDefaults(enabled: false, ControllerButton.RT, ControllerButton.DPadUp, (KeyCode)287, blockModifierDefaultAction: false, 2), 10 => new ChordDefaults(enabled: false, ControllerButton.RT, ControllerButton.DPadDown, (KeyCode)288, blockModifierDefaultAction: false, 2), 11 => new ChordDefaults(enabled: false, ControllerButton.LT, ControllerButton.DPadLeft, (KeyCode)289, blockModifierDefaultAction: false, 2), _ => new ChordDefaults(enabled: false, ControllerButton.LT, ControllerButton.DPadRight, (KeyCode)290, blockModifierDefaultAction: false, 2), }; } private void ResolveZInput() { zInputType = FindType("ZInput"); if (zInputType == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Controller Chords: ZInput type was not found. Controller chord detection is disabled, but Unity key patches can still load safely."); return; } zGetButton = CreateStringBoolDelegate(zInputType, "GetButton"); zGetButtonDown = CreateStringBoolDelegate(zInputType, "GetButtonDown"); zVirtualKeyboardOpenProperty = zInputType.GetProperty("VirtualKeyboardOpen", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); zInputReady = zGetButton != null && zGetButtonDown != null; if (!zInputReady) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Controller Chords: ZInput.GetButton/GetButtonDown were not found. Controller chord detection is disabled."); } else { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Controller Chords: ZInput button reading resolved OK (GetButton/GetButtonDown bound). Chord detection active."); } } private void ResolveMenuGuards() { menuIsVisibleMethod = FindStaticBoolMethod("Menu", "IsVisible"); inventoryGuiIsVisibleMethod = FindStaticBoolMethod("InventoryGui", "IsVisible"); storeGuiIsVisibleMethod = FindStaticBoolMethod("StoreGui", "IsVisible"); textInputIsVisibleMethod = FindStaticBoolMethod("TextInput", "IsVisible"); consoleIsVisibleMethod = FindStaticBoolMethod("Console", "IsVisible"); } private void InstallPatches() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown harmony = new Harmony("marc.valheim.controllerchords"); TryPatchPostfix(typeof(Input).GetMethod("GetKeyDown", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(KeyCode) }, null), "InputKeyPostfix", "UnityEngine.Input.GetKeyDown(KeyCode)"); TryPatchPostfix(typeof(Input).GetMethod("GetKey", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(KeyCode) }, null), "InputKeyPostfix", "UnityEngine.Input.GetKey(KeyCode)"); if (zInputType != null) { TryPatchPostfix(zInputType.GetMethod("GetKeyDown", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[2] { typeof(KeyCode), typeof(bool) }, null), "ZInputKeyPostfix", "ZInput.GetKeyDown(KeyCode,bool)"); TryPatchPostfix(zInputType.GetMethod("GetKey", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[2] { typeof(KeyCode), typeof(bool) }, null), "ZInputKeyPostfix", "ZInput.GetKey(KeyCode,bool)"); TryPatchPostfix(zInputType.GetMethod("GetButtonDown", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(string) }, null), "ZInputButtonPostfix", "ZInput.GetButtonDown(string)"); TryPatchPostfix(zInputType.GetMethod("GetButton", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(string) }, null), "ZInputButtonPostfix", "ZInput.GetButton(string)"); } } private void TryPatchPostfix(MethodInfo target, string postfixName, string label) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown if (target == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Controller Chords: could not find " + label + "; this compatibility patch is disabled.")); return; } try { MethodInfo method = typeof(ControllerChordsPlugin).GetMethod(postfixName, BindingFlags.Static | BindingFlags.NonPublic); harmony.Patch((MethodBase)target, (HarmonyMethod)null, new HarmonyMethod(method), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); patchesInstalled = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Controller Chords: patched " + label + ".")); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Controller Chords: failed to patch " + label + ": " + ex.Message)); } } private unsafe void HoldChord(ChordSlot slot, string modifierName) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) KeyCode value = slot.TargetKey.Value; SetMaxFrameCount(virtualKeyFrames, value, 2); AddVirtualButtonName(value, 2); if (slot.BlockModifierDefaultAction.Value && !string.IsNullOrEmpty(modifierName)) { SetMaxFrameCount(blockedButtonFrames, modifierName, 2); } if (logChordEvents.Value && !heldChordActive.Contains(slot.Index)) { heldChordActive.Add(slot.Index); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Controller Chords: chord " + slot.Index + " HOLD started " + slot.Modifier.Value.ToString() + "+" + slot.Button.Value.ToString() + " -> " + ((object)(*(KeyCode*)(&value))/*cast due to .constrained prefix*/).ToString() + " (held until released).")); } } private unsafe void FireChord(ChordSlot slot, string modifierName) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) int frames = Mathf.Clamp(slot.VirtualPressFrames.Value, 1, 8); KeyCode value = slot.TargetKey.Value; SetMaxFrameCount(virtualKeyFrames, value, frames); AddVirtualButtonName(value, frames); if (slot.BlockModifierDefaultAction.Value && !string.IsNullOrEmpty(modifierName)) { SetMaxFrameCount(blockedButtonFrames, modifierName, frames); } chordsFired++; if (logChordEvents.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Controller Chords: chord " + slot.Index + " fired " + slot.Modifier.Value.ToString() + "+" + slot.Button.Value.ToString() + " -> " + ((object)(*(KeyCode*)(&value))/*cast due to .constrained prefix*/).ToString() + " for " + frames + " frame(s).")); } } private unsafe void AddVirtualButtonName(KeyCode key, int frames) { string text = ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString(); SetMaxFrameCount(virtualButtonFrames, text, frames); SetMaxFrameCount(virtualButtonFrames, text.ToLowerInvariant(), frames); } private bool IsVirtualKeyActive(KeyCode key) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) int value; return enabledConfig.Value && virtualKeyFrames.TryGetValue(key, out value) && value > 0; } private bool IsVirtualButtonActive(string name) { if (string.IsNullOrEmpty(name) || !enabledConfig.Value) { return false; } int value; return virtualButtonFrames.TryGetValue(name, out value) && value > 0; } private bool IsButtonBlocked(string name) { if (string.IsNullOrEmpty(name) || !enabledConfig.Value) { return false; } int value; return blockedButtonFrames.TryGetValue(name, out value) && value > 0; } private bool SafeGetZButton(string name) { try { return zGetButton != null && zGetButton(name); } catch (Exception ex) { zInputReady = false; ((BaseUnityPlugin)this).Logger.LogWarning((object)("Controller Chords: ZInput.GetButton failed and chord detection was disabled: " + ex.Message)); return false; } } private bool SafeGetZButtonDown(string name) { try { return zGetButtonDown != null && zGetButtonDown(name); } catch (Exception ex) { zInputReady = false; ((BaseUnityPlugin)this).Logger.LogWarning((object)("Controller Chords: ZInput.GetButtonDown failed and chord detection was disabled: " + ex.Message)); return false; } } private bool IsMenuInputContext() { if (TryReadStaticBoolProperty(zVirtualKeyboardOpenProperty)) { return true; } return TryInvokeBool(menuIsVisibleMethod) || TryInvokeBool(inventoryGuiIsVisibleMethod) || TryInvokeBool(storeGuiIsVisibleMethod) || TryInvokeBool(textInputIsVisibleMethod) || TryInvokeBool(consoleIsVisibleMethod); } private static bool TryInvokeBool(MethodInfo method) { if (method == null) { return false; } try { object obj = method.Invoke(null, null); return obj is bool && (bool)obj; } catch { return false; } } private static bool TryReadStaticBoolProperty(PropertyInfo property) { if (property == null) { return false; } try { object value = property.GetValue(null, null); return value is bool && (bool)value; } catch { return false; } } private static Type FindType(string typeName) { Type type = Type.GetType(typeName, throwOnError: false); if (type != null) { return type; } Type type2 = Type.GetType(typeName + ", assembly_utils", throwOnError: false); if (type2 != null) { return type2; } Type type3 = Type.GetType(typeName + ", assembly_valheim", throwOnError: false); if (type3 != null) { return type3; } Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { Type type4 = assemblies[i].GetType(typeName, throwOnError: false); if (type4 != null) { return type4; } } return null; } private static MethodInfo FindStaticBoolMethod(string typeName, string methodName) { Type type = FindType(typeName); if (type == null) { return null; } MethodInfo method = type.GetMethod(methodName, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); return (method != null && method.ReturnType == typeof(bool)) ? method : null; } private Func<string, bool> CreateStringBoolDelegate(Type type, string methodName) { MethodInfo method = type.GetMethod(methodName, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(string) }, null); if (method != null && method.ReturnType == typeof(bool)) { try { return (Func<string, bool>)Delegate.CreateDelegate(typeof(Func<string, bool>), method); } catch { } } MethodInfo instanceMethod = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(string) }, null); if (instanceMethod == null || instanceMethod.ReturnType != typeof(bool)) { return null; } PropertyInfo instanceProperty = type.GetProperty("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo instanceField = ((instanceProperty == null) ? type.GetField("m_instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) : null); if (instanceProperty == null && instanceField == null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Controller Chords: found instance method ZInput." + methodName + " but no static 'instance' accessor; chord detection disabled.")); return null; } return delegate(string name) { object obj2 = ((instanceProperty != null) ? instanceProperty.GetValue(null, null) : instanceField.GetValue(null)); if (obj2 == null) { return false; } object obj3 = instanceMethod.Invoke(obj2, new object[1] { name }); bool flag = default(bool); int num; if (obj3 is bool) { flag = (bool)obj3; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; }; } private void AgeKeyFrames() { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) if (virtualKeyFrames.Count == 0) { return; } keyScratch.Clear(); foreach (KeyValuePair<KeyCode, int> virtualKeyFrame in virtualKeyFrames) { keyScratch.Add(virtualKeyFrame.Key); } for (int i = 0; i < keyScratch.Count; i++) { KeyCode key = keyScratch[i]; int num = virtualKeyFrames[key] - 1; if (num <= 0) { virtualKeyFrames.Remove(key); } else { virtualKeyFrames[key] = num; } } } private void AgeStringFrames(Dictionary<string, int> framesByName) { if (framesByName.Count == 0) { return; } stringScratch.Clear(); foreach (KeyValuePair<string, int> item in framesByName) { stringScratch.Add(item.Key); } for (int i = 0; i < stringScratch.Count; i++) { string key = stringScratch[i]; int num = framesByName[key] - 1; if (num <= 0) { framesByName.Remove(key); } else { framesByName[key] = num; } } } private static void SetMaxFrameCount(Dictionary<KeyCode, int> dictionary, KeyCode key, int frames) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (!dictionary.TryGetValue(key, out var value) || value < frames) { dictionary[key] = frames; } } private static void SetMaxFrameCount(Dictionary<string, int> dictionary, string key, int frames) { if (!string.IsNullOrEmpty(key) && (!dictionary.TryGetValue(key, out var value) || value < frames)) { dictionary[key] = frames; } } private static bool IsSupportedModifier(ControllerButton button) { return button == ControllerButton.RB || button == ControllerButton.LB || button == ControllerButton.RT || button == ControllerButton.LT; } private static string ToZInputButtonName(ControllerButton button) { return button switch { ControllerButton.A => "JoyButtonA", ControllerButton.B => "JoyButtonB", ControllerButton.X => "JoyButtonX", ControllerButton.Y => "JoyButtonY", ControllerButton.DPadLeft => "JoyDPadLeft", ControllerButton.DPadRight => "JoyDPadRight", ControllerButton.DPadUp => "JoyDPadUp", ControllerButton.DPadDown => "JoyDPadDown", ControllerButton.LB => "JoyLBumper", ControllerButton.RB => "JoyRBumper", ControllerButton.LT => "JoyLTrigger", ControllerButton.RT => "JoyRTrigger", ControllerButton.LeftStick => "JoyLStick", ControllerButton.RightStick => "JoyRStick", ControllerButton.Back => "JoyBack", ControllerButton.Start => "JoyStart", _ => string.Empty, }; } private static void InputKeyPostfix(KeyCode __0, ref bool __result) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) ControllerChordsPlugin instance = Instance; if (!__result && !((Object)(object)instance == (Object)null) && instance.patchesInstalled && instance.IsVirtualKeyActive(__0)) { __result = true; } } private static void ZInputKeyPostfix(KeyCode __0, ref bool __result) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) ControllerChordsPlugin instance = Instance; if (!__result && !((Object)(object)instance == (Object)null) && instance.patchesInstalled && instance.IsVirtualKeyActive(__0)) { __result = true; } } private static void ZInputButtonPostfix(string __0, ref bool __result) { ControllerChordsPlugin instance = Instance; if (!((Object)(object)instance == (Object)null) && instance.patchesInstalled) { if (instance.IsButtonBlocked(__0)) { __result = false; } else if (!__result && instance.IsVirtualButtonActive(__0)) { __result = true; } } } } public enum ControllerButton { None, A, B, X, Y, DPadLeft, DPadRight, DPadUp, DPadDown, LB, RB, LT, RT, LeftStick, RightStick, Back, Start }