Decompiled source of NathansQol KeyBindings v0.2.2

NathansQol.KeyBindings.dll

Decompiled 6 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.DualShock;
using UnityEngine.InputSystem.Layouts;
using UnityEngine.UI;
using Valheim.SettingsGui;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_guiutils")]
[assembly: IgnoresAccessChecksTo("assembly_utils")]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("NateBuzz")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Public API of the NathansQol_KeyBindings mod for Valheim: lets mods list their hotkeys in the Key Bindings tab of the game settings.")]
[assembly: AssemblyFileVersion("0.2.2.0")]
[assembly: AssemblyInformationalVersion("0.2.2+56e9e83bf8f8eae3fe1e338d2b74ef4717eb2ed6")]
[assembly: AssemblyProduct("NathansQol.KeyBindings")]
[assembly: AssemblyTitle("NathansQol.KeyBindings")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://gitlab.com/nathans-norse-niceties/keybindings-mod.git")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.2.2.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace NathansQol.KeyBindings
{
	public enum GamepadButton
	{
		None,
		DPadUp,
		DPadDown,
		DPadLeft,
		DPadRight,
		ButtonSouth,
		ButtonEast,
		ButtonWest,
		ButtonNorth,
		LeftShoulder,
		RightShoulder,
		LeftTrigger,
		RightTrigger,
		LeftStickButton,
		RightStickButton,
		Start,
		Select
	}
	public sealed class KeyBinding
	{
		private readonly KeySource _source;

		private readonly string _configKey;

		private GamepadButton[] _gamepad;

		private ConfigEntry<string> _gamepadEntry;

		private string _gamepadText;

		private GamepadButton[] _gamepadParsed;

		public string Label { get; }

		public string ModName { get; }

		public string ModGuid { get; }

		public GamepadButton Gamepad
		{
			get
			{
				if (GamepadButtons.Count <= 0)
				{
					return GamepadButton.None;
				}
				return GamepadButtons[0];
			}
		}

		public IReadOnlyList<GamepadButton> GamepadButtons
		{
			get
			{
				if (_gamepadEntry == null)
				{
					return _gamepad;
				}
				string value = _gamepadEntry.Value;
				if ((object)value != _gamepadText && value != _gamepadText)
				{
					_gamepadText = value;
					_gamepadParsed = ChordText.Parse(value);
				}
				return _gamepadParsed;
			}
		}

		public GamepadButton DefaultGamepad
		{
			get
			{
				if (DefaultGamepadButtons.Length == 0)
				{
					return GamepadButton.None;
				}
				return DefaultGamepadButtons[0];
			}
		}

		public GamepadButton[] DefaultGamepadButtons { get; }

		internal KeySource Source => _source;

		public event Action Changed;

		internal KeyBinding(string modGuid, string modName, string label, KeySource source, GamepadButton[] defaultGamepad)
		{
			ModGuid = modGuid;
			ModName = modName;
			Label = label;
			DefaultGamepadButtons = defaultGamepad;
			_source = source;
			_gamepad = defaultGamepad;
			_configKey = Registry.ConfigKey(modGuid, source.Id);
		}

		public bool IsDown()
		{
			if (!_source.IsDown())
			{
				return GamepadInput.IsDown(GamepadButtons);
			}
			return true;
		}

		public bool IsPressed()
		{
			if (!_source.IsPressed())
			{
				return GamepadInput.IsPressed(GamepadButtons);
			}
			return true;
		}

		public bool IsUp()
		{
			if (!_source.IsUp())
			{
				return GamepadInput.IsUp(GamepadButtons);
			}
			return true;
		}

		internal void SetGamepad(GamepadButton button)
		{
			SetGamepadChord((button == GamepadButton.None) ? ChordText.None : new GamepadButton[1] { button });
		}

		internal void SetGamepadChord(IReadOnlyList<GamepadButton> buttons)
		{
			GamepadButton[] array = buttons.Where((GamepadButton b) => b != GamepadButton.None).Distinct().Take(3)
				.ToArray();
			if (_gamepadEntry != null)
			{
				_gamepadEntry.Value = ChordText.Format(array);
			}
			else
			{
				_gamepad = array;
			}
		}

		internal void BindConfig(ConfigFile file)
		{
			if (_gamepadEntry == null)
			{
				_gamepadEntry = file.Bind<string>("Controller", _configKey, ChordText.Format(_gamepad), "Controller button (or buttons held together, joined by +) for '" + Label + "' of " + ModName + ". Change it in the Key Bindings tab of the game settings.");
			}
		}

		internal void NotifyChanged()
		{
			this.Changed?.Invoke();
		}
	}
	public static class KeyBindings
	{
		public const int ApiVersion = 2;

		public static KeyBinding Register(PluginInfo plugin, ConfigEntry<KeyboardShortcut> shortcut, string label, GamepadButton defaultGamepad = GamepadButton.None)
		{
			if (plugin == null)
			{
				throw new ArgumentNullException("plugin");
			}
			return Register(plugin.Metadata.GUID, plugin.Metadata.Name, shortcut, label, defaultGamepad);
		}

		public static KeyBinding Register(PluginInfo plugin, ConfigEntry<KeyCode> key, string label, GamepadButton defaultGamepad = GamepadButton.None)
		{
			if (plugin == null)
			{
				throw new ArgumentNullException("plugin");
			}
			return Register(plugin.Metadata.GUID, plugin.Metadata.Name, key, label, defaultGamepad);
		}

		public static KeyBinding Register(string modGuid, string modName, ConfigEntry<KeyboardShortcut> shortcut, string label, GamepadButton defaultGamepad = GamepadButton.None)
		{
			if (shortcut == null)
			{
				throw new ArgumentNullException("shortcut");
			}
			return Registry.Add(modGuid, modName, new ShortcutSource(shortcut), label, Single(defaultGamepad));
		}

		public static KeyBinding Register(string modGuid, string modName, ConfigEntry<KeyCode> key, string label, GamepadButton defaultGamepad = GamepadButton.None)
		{
			if (key == null)
			{
				throw new ArgumentNullException("key");
			}
			return Registry.Add(modGuid, modName, new KeyCodeSource(key), label, Single(defaultGamepad));
		}

		public static KeyBinding Register(PluginInfo plugin, ConfigEntry<KeyboardShortcut> shortcut, string label, string defaultGamepad)
		{
			if (plugin == null)
			{
				throw new ArgumentNullException("plugin");
			}
			if (shortcut == null)
			{
				throw new ArgumentNullException("shortcut");
			}
			return Registry.Add(plugin.Metadata.GUID, plugin.Metadata.Name, new ShortcutSource(shortcut), label, ChordText.Parse(defaultGamepad));
		}

		public static KeyBinding Register(PluginInfo plugin, ConfigEntry<KeyCode> key, string label, string defaultGamepad)
		{
			if (plugin == null)
			{
				throw new ArgumentNullException("plugin");
			}
			if (key == null)
			{
				throw new ArgumentNullException("key");
			}
			return Registry.Add(plugin.Metadata.GUID, plugin.Metadata.Name, new KeyCodeSource(key), label, ChordText.Parse(defaultGamepad));
		}

		private static GamepadButton[] Single(GamepadButton button)
		{
			if (button != GamepadButton.None)
			{
				return new GamepadButton[1] { button };
			}
			return ChordText.None;
		}
	}
	internal static class ChordText
	{
		public static readonly GamepadButton[] None = new GamepadButton[0];

		public static string Format(IReadOnlyList<GamepadButton> chord)
		{
			if (chord != null && chord.Count != 0)
			{
				return string.Join("+", chord.Select((GamepadButton b) => b.ToString()));
			}
			return "None";
		}

		public static GamepadButton[] Parse(string text)
		{
			if (string.IsNullOrWhiteSpace(text))
			{
				return None;
			}
			List<GamepadButton> list = new List<GamepadButton>();
			string[] array = text.Split('+', ',');
			for (int i = 0; i < array.Length; i++)
			{
				if (Enum.TryParse<GamepadButton>(array[i].Trim(), ignoreCase: true, out var result) && result != GamepadButton.None && !list.Contains(result))
				{
					list.Add(result);
				}
			}
			return list.Take(3).ToArray();
		}
	}
	internal static class GamepadInput
	{
		internal enum Family
		{
			Xbox,
			PlayStation,
			Nintendo
		}

		public static readonly GamepadButton[] Bindable = ((GamepadButton[])Enum.GetValues(typeof(GamepadButton))).Where((GamepadButton b) => b != GamepadButton.None).ToArray();

		public const int MaxChord = 3;

		public static bool IsDown(GamepadButton button)
		{
			ButtonControl val = Control(button);
			if (val != null)
			{
				return val.wasPressedThisFrame;
			}
			return false;
		}

		public static bool IsPressed(GamepadButton button)
		{
			ButtonControl val = Control(button);
			if (val != null)
			{
				return val.isPressed;
			}
			return false;
		}

		public static bool IsUp(GamepadButton button)
		{
			ButtonControl val = Control(button);
			if (val != null)
			{
				return val.wasReleasedThisFrame;
			}
			return false;
		}

		public static bool IsDown(IReadOnlyList<GamepadButton> chord)
		{
			if (!IsPressed(chord))
			{
				return false;
			}
			foreach (GamepadButton item in chord)
			{
				if (IsDown(item))
				{
					return true;
				}
			}
			return false;
		}

		public static bool IsPressed(IReadOnlyList<GamepadButton> chord)
		{
			if (chord == null || chord.Count == 0)
			{
				return false;
			}
			foreach (GamepadButton item in chord)
			{
				if (!IsPressed(item))
				{
					return false;
				}
			}
			return true;
		}

		public static bool IsUp(IReadOnlyList<GamepadButton> chord)
		{
			if (chord == null || chord.Count == 0)
			{
				return false;
			}
			bool result = false;
			foreach (GamepadButton item in chord)
			{
				if (IsUp(item))
				{
					result = true;
				}
				else if (!IsPressed(item))
				{
					return false;
				}
			}
			return result;
		}

		public static List<GamepadButton> HeldNow()
		{
			return Bindable.Where(IsPressed).Take(3).ToList();
		}

		public static string Name(IReadOnlyList<GamepadButton> chord)
		{
			if (chord != null && chord.Count != 0)
			{
				return string.Join(" + ", chord.Select(Name));
			}
			return "-";
		}

		public static GamepadButton PressedThisFrame()
		{
			GamepadButton[] bindable = Bindable;
			foreach (GamepadButton gamepadButton in bindable)
			{
				if (IsDown(gamepadButton))
				{
					return gamepadButton;
				}
			}
			return GamepadButton.None;
		}

		public static string Name(GamepadButton button)
		{
			if (button == GamepadButton.None)
			{
				return "-";
			}
			Family num = CurrentFamily();
			bool flag = num == Family.PlayStation;
			bool flag2 = num == Family.Nintendo;
			switch (button)
			{
			case GamepadButton.DPadUp:
				return "D-pad Up";
			case GamepadButton.DPadDown:
				return "D-pad Down";
			case GamepadButton.DPadLeft:
				return "D-pad Left";
			case GamepadButton.DPadRight:
				return "D-pad Right";
			case GamepadButton.ButtonSouth:
				if (!flag)
				{
					if (!flag2)
					{
						return "A";
					}
					return "B";
				}
				return "Cross";
			case GamepadButton.ButtonEast:
				if (!flag)
				{
					if (!flag2)
					{
						return "B";
					}
					return "A";
				}
				return "Circle";
			case GamepadButton.ButtonWest:
				if (!flag)
				{
					if (!flag2)
					{
						return "X";
					}
					return "Y";
				}
				return "Square";
			case GamepadButton.ButtonNorth:
				if (!flag)
				{
					if (!flag2)
					{
						return "Y";
					}
					return "X";
				}
				return "Triangle";
			case GamepadButton.LeftShoulder:
				if (!flag)
				{
					if (!flag2)
					{
						return "LB";
					}
					return "L";
				}
				return "L1";
			case GamepadButton.RightShoulder:
				if (!flag)
				{
					if (!flag2)
					{
						return "RB";
					}
					return "R";
				}
				return "R1";
			case GamepadButton.LeftTrigger:
				if (!flag)
				{
					if (!flag2)
					{
						return "LT";
					}
					return "ZL";
				}
				return "L2";
			case GamepadButton.RightTrigger:
				if (!flag)
				{
					if (!flag2)
					{
						return "RT";
					}
					return "ZR";
				}
				return "R2";
			case GamepadButton.LeftStickButton:
				if (!flag)
				{
					return "Left Stick";
				}
				return "L3";
			case GamepadButton.RightStickButton:
				if (!flag)
				{
					return "Right Stick";
				}
				return "R3";
			case GamepadButton.Start:
				if (!flag)
				{
					if (!flag2)
					{
						return "Menu";
					}
					return "+";
				}
				return "Options";
			case GamepadButton.Select:
				if (!flag)
				{
					if (!flag2)
					{
						return "View";
					}
					return "-";
				}
				return "Share";
			default:
				return button.ToString();
			}
		}

		private static Family CurrentFamily()
		{
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			switch (KeyBindingsPlugin.ControllerLayout?.Value)
			{
			case "Xbox":
				return Family.Xbox;
			case "PlayStation":
				return Family.PlayStation;
			case "Nintendo":
				return Family.Nintendo;
			default:
			{
				try
				{
					switch (GameGamepadType())
					{
					case "DualShock":
					case "DualSense":
						return Family.PlayStation;
					case "SwitchPro":
					case "JoyCon":
					case "JoyCon2Mouse":
						return Family.Nintendo;
					}
				}
				catch (Exception)
				{
				}
				Gamepad current = Gamepad.current;
				if (current == null)
				{
					return Family.Xbox;
				}
				if (current is DualShockGamepad)
				{
					return Family.PlayStation;
				}
				string name = ((object)current).GetType().Name;
				InputDeviceDescription description = ((InputDevice)current).description;
				return FamilyFromName(name + " " + ((InputDeviceDescription)(ref description)).product);
			}
			}
		}

		internal static Family FamilyFromName(string name)
		{
			string text = (name ?? "").ToLowerInvariant();
			if (text.Contains("xbox") || text.Contains("xinput"))
			{
				return Family.Xbox;
			}
			if (text.Contains("dualshock") || text.Contains("dualsense") || text.Contains("playstation") || text.Contains("ps3") || text.Contains("ps4") || text.Contains("ps5") || text.Contains("wireless controller") || text.Contains("sony"))
			{
				return Family.PlayStation;
			}
			if (text.Contains("switch") || text.Contains("pro controller") || text.Contains("joy-con") || text.Contains("joycon") || text.Contains("nintendo"))
			{
				return Family.Nintendo;
			}
			return Family.Xbox;
		}

		public static string Describe()
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			string text;
			try
			{
				text = GameGamepadType() ?? "none";
			}
			catch (Exception)
			{
				text = "unavailable";
			}
			Gamepad current = Gamepad.current;
			string text2 = text;
			object obj2;
			if (current != null)
			{
				string[] obj = new string[5]
				{
					((object)current).GetType().Name,
					" / ",
					null,
					null,
					null
				};
				InputDeviceDescription description = ((InputDevice)current).description;
				obj[2] = ((InputDeviceDescription)(ref description)).product;
				obj[3] = " / ";
				description = ((InputDevice)current).description;
				obj[4] = ((InputDeviceDescription)(ref description)).interfaceName;
				obj2 = string.Concat(obj);
			}
			else
			{
				obj2 = "no gamepad";
			}
			return "game: " + text2 + "; Unity: " + (string?)obj2;
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		private static string GameGamepadType()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			ZInput instance = ZInput.instance;
			if (instance == null)
			{
				return null;
			}
			PlatformGamepadDefinition definition = instance.m_definition;
			if (definition == null)
			{
				return null;
			}
			return ((object)definition.GetConnectedGamepadType()/*cast due to .constrained prefix*/).ToString();
		}

		private static ButtonControl Control(GamepadButton button)
		{
			Gamepad current = Gamepad.current;
			if (current == null)
			{
				return null;
			}
			return (ButtonControl)(button switch
			{
				GamepadButton.DPadUp => current.dpad.up, 
				GamepadButton.DPadDown => current.dpad.down, 
				GamepadButton.DPadLeft => current.dpad.left, 
				GamepadButton.DPadRight => current.dpad.right, 
				GamepadButton.ButtonSouth => current.buttonSouth, 
				GamepadButton.ButtonEast => current.buttonEast, 
				GamepadButton.ButtonWest => current.buttonWest, 
				GamepadButton.ButtonNorth => current.buttonNorth, 
				GamepadButton.LeftShoulder => current.leftShoulder, 
				GamepadButton.RightShoulder => current.rightShoulder, 
				GamepadButton.LeftTrigger => current.leftTrigger, 
				GamepadButton.RightTrigger => current.rightTrigger, 
				GamepadButton.LeftStickButton => current.leftStickButton, 
				GamepadButton.RightStickButton => current.rightStickButton, 
				GamepadButton.Start => current.startButton, 
				GamepadButton.Select => current.selectButton, 
				_ => null, 
			});
		}
	}
	internal static class KeyNames
	{
		public const string Unbound = "-";

		public static string Format(KeyboardShortcut shortcut)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			if ((int)((KeyboardShortcut)(ref shortcut)).MainKey == 0)
			{
				return "-";
			}
			IEnumerable<string> values = ((KeyboardShortcut)(ref shortcut)).Modifiers.Select(Friendly).Concat(new string[1] { Friendly(((KeyboardShortcut)(ref shortcut)).MainKey) });
			return string.Join(" + ", values);
		}

		public unsafe static string Friendly(KeyCode key)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected I4, but got Unknown
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected I4, but got Unknown
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Invalid comparison between Unknown and I4
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected I4, but got Unknown
			if ((int)key <= 96)
			{
				if ((int)key == 13)
				{
					return "Enter";
				}
				if ((int)key == 96)
				{
					return "`";
				}
			}
			else
			{
				switch (key - 273)
				{
				case 0:
					return "Up";
				case 1:
					return "Down";
				case 3:
					return "Left";
				case 2:
					return "Right";
				}
				switch (key - 303)
				{
				case 3:
					return "Ctrl";
				case 2:
					return "Right Ctrl";
				case 1:
					return "Shift";
				case 0:
					return "Right Shift";
				case 5:
					return "Alt";
				case 4:
					return "Right Alt";
				}
				switch (key - 323)
				{
				case 0:
					return "Left Mouse";
				case 1:
					return "Right Mouse";
				case 2:
					return "Middle Mouse";
				case 3:
					return "Mouse 4";
				case 4:
					return "Mouse 5";
				case 5:
					return "Mouse 6";
				case 6:
					return "Mouse 7";
				}
			}
			string text = ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString();
			if (text.StartsWith("Alpha"))
			{
				return text.Substring("Alpha".Length);
			}
			if (text.StartsWith("Keypad"))
			{
				return "Num " + text.Substring("Keypad".Length);
			}
			return Regex.Replace(text, "(?<=[a-z0-9])(?=[A-Z])", " ");
		}
	}
	internal abstract class KeySource
	{
		public abstract string Id { get; }

		public abstract object Entry { get; }

		public abstract bool AllowsModifiers { get; }

		public abstract bool IsDown();

		public abstract bool IsPressed();

		public abstract bool IsUp();

		public abstract string Display();

		public abstract string ConflictKey();

		public abstract void Set(KeyCode key, IReadOnlyList<KeyCode> modifiers);

		public abstract void ResetToDefault();

		public abstract object Snapshot();

		public abstract void Restore(object snapshot);
	}
	internal sealed class ShortcutSource : KeySource
	{
		private readonly ConfigEntry<KeyboardShortcut> _entry;

		public override string Id => ((ConfigEntryBase)_entry).Definition.Section + "." + ((ConfigEntryBase)_entry).Definition.Key;

		public override object Entry => _entry;

		public override bool AllowsModifiers => true;

		public ShortcutSource(ConfigEntry<KeyboardShortcut> entry)
		{
			_entry = entry;
		}

		public override bool IsDown()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut value = _entry.Value;
			return ((KeyboardShortcut)(ref value)).IsDown();
		}

		public override bool IsPressed()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut value = _entry.Value;
			return ((KeyboardShortcut)(ref value)).IsPressed();
		}

		public override bool IsUp()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut value = _entry.Value;
			return ((KeyboardShortcut)(ref value)).IsUp();
		}

		public override string Display()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return KeyNames.Format(_entry.Value);
		}

		public unsafe override string ConflictKey()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut value = _entry.Value;
			if ((int)((KeyboardShortcut)(ref value)).MainKey == 0)
			{
				return "";
			}
			return string.Join("+", (from m in ((KeyboardShortcut)(ref value)).Modifiers
				select ((object)(*(KeyCode*)(&m))/*cast due to .constrained prefix*/).ToString() into m
				orderby m
				select m).Concat(new string[1] { ((object)((KeyboardShortcut)(ref value)).MainKey/*cast due to .constrained prefix*/).ToString() }));
		}

		public override void Set(KeyCode key, IReadOnlyList<KeyCode> modifiers)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			_entry.Value = new KeyboardShortcut(key, modifiers.ToArray());
		}

		public override void ResetToDefault()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			_entry.Value = (KeyboardShortcut)((ConfigEntryBase)_entry).DefaultValue;
		}

		public override object Snapshot()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return _entry.Value;
		}

		public override void Restore(object snapshot)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			_entry.Value = (KeyboardShortcut)snapshot;
		}
	}
	internal sealed class KeyCodeSource : KeySource
	{
		private readonly ConfigEntry<KeyCode> _entry;

		public override string Id => ((ConfigEntryBase)_entry).Definition.Section + "." + ((ConfigEntryBase)_entry).Definition.Key;

		public override object Entry => _entry;

		public override bool AllowsModifiers => false;

		public KeyCodeSource(ConfigEntry<KeyCode> entry)
		{
			_entry = entry;
		}

		public override bool IsDown()
		{
			//IL_0006: 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)
			if ((int)_entry.Value != 0)
			{
				return Input.GetKeyDown(_entry.Value);
			}
			return false;
		}

		public override bool IsPressed()
		{
			//IL_0006: 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)
			if ((int)_entry.Value != 0)
			{
				return Input.GetKey(_entry.Value);
			}
			return false;
		}

		public override bool IsUp()
		{
			//IL_0006: 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)
			if ((int)_entry.Value != 0)
			{
				return Input.GetKeyUp(_entry.Value);
			}
			return false;
		}

		public override string Display()
		{
			//IL_0006: 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)
			if ((int)_entry.Value != 0)
			{
				return KeyNames.Friendly(_entry.Value);
			}
			return "-";
		}

		public override string ConflictKey()
		{
			//IL_0006: 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_0018: Unknown result type (might be due to invalid IL or missing references)
			if ((int)_entry.Value != 0)
			{
				return ((object)_entry.Value/*cast due to .constrained prefix*/).ToString();
			}
			return "";
		}

		public override void Set(KeyCode key, IReadOnlyList<KeyCode> modifiers)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			_entry.Value = key;
		}

		public override void ResetToDefault()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			_entry.Value = (KeyCode)((ConfigEntryBase)_entry).DefaultValue;
		}

		public override object Snapshot()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return _entry.Value;
		}

		public override void Restore(object snapshot)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			_entry.Value = (KeyCode)snapshot;
		}
	}
	internal sealed class ModSection
	{
		public string Guid { get; }

		public string Name { get; }

		public List<KeyBinding> Bindings { get; } = new List<KeyBinding>();

		public ModSection(string guid, string name)
		{
			Guid = guid;
			Name = (string.IsNullOrWhiteSpace(name) ? guid : name);
		}
	}
	internal static class Registry
	{
		private static readonly object Gate = new object();

		private static readonly Dictionary<string, ModSection> Sections = new Dictionary<string, ModSection>();

		private static readonly List<KeyBinding> Pending = new List<KeyBinding>();

		public static ConfigFile Config { get; private set; }

		public static bool HasAny
		{
			get
			{
				lock (Gate)
				{
					return Sections.Values.Any((ModSection s) => s.Bindings.Count > 0);
				}
			}
		}

		public static void Initialize(ConfigFile config)
		{
			lock (Gate)
			{
				Config = config;
				foreach (KeyBinding item in Pending)
				{
					item.BindConfig(config);
				}
				Pending.Clear();
			}
		}

		public static KeyBinding Add(string modGuid, string modName, KeySource source, string label, GamepadButton[] defaultGamepad)
		{
			if (string.IsNullOrWhiteSpace(modGuid))
			{
				throw new ArgumentException("modGuid is required", "modGuid");
			}
			if (string.IsNullOrWhiteSpace(label))
			{
				throw new ArgumentException("label is required", "label");
			}
			lock (Gate)
			{
				if (!Sections.TryGetValue(modGuid, out var value))
				{
					value = (Sections[modGuid] = new ModSection(modGuid, modName));
				}
				KeyBinding keyBinding = value.Bindings.FirstOrDefault((KeyBinding b) => b.Source.Entry == source.Entry);
				if (keyBinding != null)
				{
					return keyBinding;
				}
				KeyBinding keyBinding2 = new KeyBinding(modGuid, value.Name, label, source, defaultGamepad);
				value.Bindings.Add(keyBinding2);
				if (Config != null)
				{
					keyBinding2.BindConfig(Config);
				}
				else
				{
					Pending.Add(keyBinding2);
				}
				return keyBinding2;
			}
		}

		public static List<ModSection> Snapshot()
		{
			lock (Gate)
			{
				return Sections.Values.Where((ModSection s) => s.Bindings.Count > 0).OrderBy<ModSection, string>((ModSection s) => s.Name, StringComparer.OrdinalIgnoreCase).ToList();
			}
		}

		public static string ConfigKey(string modGuid, string id)
		{
			string text = modGuid + "." + id;
			char[] array = new char[7] { '=', '\n', '\t', '"', '\'', '[', ']' };
			foreach (char oldChar in array)
			{
				text = text.Replace(oldChar, '_');
			}
			return text;
		}
	}
	[BepInPlugin("nathan.qol.keybindings", "Nathans Key Bindings", "0.2.2")]
	public class KeyBindingsPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "nathan.qol.keybindings";

		public const string PluginName = "Nathans Key Bindings";

		public const string PluginVersion = "0.2.2";

		internal static ManualLogSource Log;

		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<string> ControllerLayout;

		private void Awake()
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Shows the Key Bindings tab in the game settings. Mods can still register their keys when it is off.");
			ControllerLayout = ((BaseUnityPlugin)this).Config.Bind<string>("General", "ControllerLayout", "Auto", new ConfigDescription("Button names shown for the controller. Auto uses the controller type the game detects; set it by hand if Steam Input makes your controller look like an Xbox controller.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[4] { "Auto", "Xbox", "PlayStation", "Nintendo" }), Array.Empty<object>()));
			Registry.Initialize(((BaseUnityPlugin)this).Config);
			new Harmony("nathan.qol.keybindings").PatchAll();
			Log.LogInfo((object)string.Format("{0} {1} loaded (API version {2})", "Nathans Key Bindings", "0.2.2", 2));
		}
	}
	internal sealed class KeyBindingsTab : MonoBehaviour, ISettingsTab
	{
		private enum CaptureKind
		{
			None,
			Keyboard,
			Gamepad
		}

		private sealed class Row
		{
			public KeyBinding Binding;

			public TMP_Text Label;

			public TMP_Text KeyboardText;

			public TMP_Text GamepadText;
		}

		private sealed class Original
		{
			public object Key;

			public GamepadButton[] Gamepad;
		}

		private sealed class RightClickRelay : MonoBehaviour, IPointerClickHandler, IEventSystemHandler
		{
			public Action Action;

			public void OnPointerClick(PointerEventData eventData)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Invalid comparison between Unknown and I4
				if ((int)eventData.button == 1)
				{
					Action?.Invoke();
				}
			}
		}

		private const float KeyColumnWidth = 230f;

		private const float RowHeight = 38f;

		private static readonly Color Gold = new Color(1f, 0.72f, 0.23f);

		private static readonly Color Conflict = new Color(1f, 0.38f, 0.32f);

		private static readonly KeyCode[] Modifiers;

		private static readonly KeyCode[] CaptureKeys;

		private readonly List<Row> _rows = new List<Row>();

		private readonly Dictionary<KeyBinding, Original> _originals = new Dictionary<KeyBinding, Original>();

		private Button _buttonTemplate;

		private TMP_Text _textTemplate;

		private Color _buttonTextColor = Color.white;

		private RectTransform _content;

		private GameObject _overlay;

		private TMP_Text _overlayText;

		private GameObject _firstButton;

		private CaptureKind _capture;

		private KeyBinding _target;

		private float _ignoreInputUntil;

		private KeyCode _pendingModifier;

		private readonly List<GamepadButton> _capturedPad = new List<GamepadButton>();

		private readonly List<GamepadButton> _ignoredPad = new List<GamepadButton>();

		public event Action<string, int> SharedSettingChanged;

		public void Configure(Button buttonTemplate, TMP_Text textTemplate)
		{
			//IL_0021: 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)
			_buttonTemplate = buttonTemplate;
			_textTemplate = textTemplate;
			TMP_Text componentInChildren = ((Component)buttonTemplate).GetComponentInChildren<TMP_Text>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				_buttonTextColor = ((Graphic)componentInChildren).color;
			}
		}

		public void Initialize()
		{
			KeyBindingsPlugin.Log.LogInfo((object)("Controller: " + GamepadInput.Describe()));
			BuildPage();
			RefreshAll();
			foreach (Row row in _rows)
			{
				_originals[row.Binding] = new Original
				{
					Key = row.Binding.Source.Snapshot(),
					Gamepad = row.Binding.GamepadButtons.ToArray()
				};
			}
		}

		public void OnTabOpen(Button backButton, Button okButton)
		{
			if ((Object)(object)_firstButton != (Object)null && (Object)(object)EventSystem.current != (Object)null && ZInput.IsGamepadActive())
			{
				EventSystem.current.SetSelectedGameObject(_firstButton);
			}
		}

		public void OnBack()
		{
			foreach (KeyValuePair<KeyBinding, Original> original in _originals)
			{
				original.Key.Source.Restore(original.Value.Key);
				original.Key.SetGamepadChord(original.Value.Gamepad);
			}
		}

		public void OnOkAsync(OkActionCompletedHandler okActionCompletedCallback)
		{
			if (okActionCompletedCallback != null)
			{
				okActionCompletedCallback.Invoke();
			}
		}

		public void OnSharedSettingChanged(string setting, int value)
		{
		}

		public void Terminate()
		{
			if (_capture != CaptureKind.None)
			{
				_capture = CaptureKind.None;
				if ((Object)(object)Settings.instance != (Object)null)
				{
					Settings.instance.BlockNavigation(false);
				}
			}
		}

		private void BuildPage()
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Expected O, but got Unknown
			RectTransform val = NewRect("Scroll", ((Component)this).transform, typeof(ScrollRect));
			Stretch(val);
			RectTransform val2 = NewRect("Viewport", (Transform)(object)val, typeof(RectMask2D), typeof(Image));
			Stretch(val2);
			((Graphic)((Component)val2).GetComponent<Image>()).color = new Color(0f, 0f, 0f, 0f);
			_content = NewRect("Content", (Transform)(object)val2, typeof(VerticalLayoutGroup), typeof(ContentSizeFitter));
			_content.anchorMin = new Vector2(0f, 1f);
			_content.anchorMax = new Vector2(1f, 1f);
			_content.pivot = new Vector2(0.5f, 1f);
			_content.anchoredPosition = Vector2.zero;
			_content.sizeDelta = Vector2.zero;
			VerticalLayoutGroup component = ((Component)_content).GetComponent<VerticalLayoutGroup>();
			((LayoutGroup)component).padding = new RectOffset(24, 24, 12, 12);
			((HorizontalOrVerticalLayoutGroup)component).spacing = 6f;
			((LayoutGroup)component).childAlignment = (TextAnchor)0;
			((HorizontalOrVerticalLayoutGroup)component).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)component).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)component).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)component).childForceExpandHeight = false;
			((Component)_content).GetComponent<ContentSizeFitter>().verticalFit = (FitMode)2;
			ScrollRect component2 = ((Component)val).GetComponent<ScrollRect>();
			component2.viewport = val2;
			component2.content = _content;
			component2.horizontal = false;
			component2.vertical = true;
			component2.movementType = (MovementType)2;
			component2.scrollSensitivity = 40f;
			component2.inertia = false;
			((Component)val).gameObject.AddComponent<ScrollRectEnsureVisible>();
			AddColumnTitles();
			foreach (ModSection item in Registry.Snapshot())
			{
				AddSectionHeader(item);
				foreach (KeyBinding binding in item.Bindings)
				{
					AddRow(binding);
				}
			}
			BuildOverlay();
		}

		private void AddColumnTitles()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			RectTransform parent = NewRow("Columns");
			AddLayout(((Component)AddText((Transform)(object)parent, "Action", (TextAlignmentOptions)4097, Gold)).gameObject, 1f, 260f);
			AddLayout(((Component)AddText((Transform)(object)parent, "Keyboard / Mouse", (TextAlignmentOptions)4098, Gold)).gameObject, -1f, 230f, 230f);
			AddLayout(((Component)AddText((Transform)(object)parent, "Controller", (TextAlignmentOptions)4098, Gold)).gameObject, -1f, 230f, 230f);
		}

		private void AddSectionHeader(ModSection section)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Expected O, but got Unknown
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = NewRow(section.Name);
			((Component)val).GetComponent<LayoutElement>().minHeight = 52f;
			((Component)val).GetComponent<LayoutElement>().preferredHeight = 52f;
			((LayoutGroup)((Component)val).GetComponent<HorizontalLayoutGroup>()).padding = new RectOffset(0, 0, 12, 0);
			TMP_Text obj = AddText((Transform)(object)val, section.Name, (TextAlignmentOptions)4097, Gold);
			obj.fontSize *= 1.25f;
			AddLayout(((Component)obj).gameObject, 1f, 260f);
			((Object)AddButton((Transform)(object)val, "Reset to default", 230f, 32f, delegate
			{
				ResetSection(section);
			}, null)).name = "Reset";
		}

		private void AddRow(KeyBinding binding)
		{
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			RectTransform parent = NewRow(binding.Label);
			TMP_Text val = AddText((Transform)(object)parent, binding.Label, (TextAlignmentOptions)4097, ((Graphic)_textTemplate).color);
			AddLayout(((Component)val).gameObject, 1f, 260f);
			GameObject val2 = AddButton((Transform)(object)parent, "", 230f, 34f, delegate
			{
				BeginCapture(binding, CaptureKind.Keyboard);
			}, null);
			GameObject val3 = AddButton((Transform)(object)parent, "", 230f, 34f, delegate
			{
				BeginCapture(binding, CaptureKind.Gamepad);
			}, delegate
			{
				ClearGamepad(binding);
			});
			if ((Object)(object)_firstButton == (Object)null)
			{
				_firstButton = val2;
			}
			_rows.Add(new Row
			{
				Binding = binding,
				Label = val,
				KeyboardText = val2.GetComponentInChildren<TMP_Text>(true),
				GamepadText = val3.GetComponentInChildren<TMP_Text>(true)
			});
		}

		private RectTransform NewRow(string name)
		{
			RectTransform obj = NewRect(name, (Transform)(object)_content, typeof(HorizontalLayoutGroup), typeof(LayoutElement));
			HorizontalLayoutGroup component = ((Component)obj).GetComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)component).spacing = 12f;
			((LayoutGroup)component).childAlignment = (TextAnchor)3;
			((HorizontalOrVerticalLayoutGroup)component).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)component).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)component).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)component).childForceExpandHeight = true;
			LayoutElement component2 = ((Component)obj).GetComponent<LayoutElement>();
			component2.minHeight = 38f;
			component2.preferredHeight = 38f;
			return obj;
		}

		private TMP_Text AddText(Transform parent, string text, TextAlignmentOptions alignment, Color color)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = Object.Instantiate<GameObject>(((Component)_textTemplate).gameObject, parent);
			((Object)obj).name = "Text";
			obj.SetActive(true);
			TMP_Text component = obj.GetComponent<TMP_Text>();
			component.text = text;
			component.alignment = alignment;
			((Graphic)component).color = color;
			((Graphic)component).raycastTarget = false;
			component.textWrappingMode = (TextWrappingModes)0;
			component.overflowMode = (TextOverflowModes)1;
			return component;
		}

		private GameObject AddButton(Transform parent, string text, float width, float height, Action onClick, Action onRightClick)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			GameObject val = Object.Instantiate<GameObject>(((Component)_buttonTemplate).gameObject, parent);
			((Object)val).name = "Button";
			val.SetActive(true);
			Button component = val.GetComponent<Button>();
			Navigation navigation = default(Navigation);
			((Navigation)(ref navigation)).mode = (Mode)3;
			((Selectable)component).navigation = navigation;
			component.onClick = new ButtonClickedEvent();
			((UnityEvent)component.onClick).AddListener((UnityAction)delegate
			{
				onClick();
			});
			AddLayout(val, -1f, width, width, height, height);
			TMP_Text componentInChildren = val.GetComponentInChildren<TMP_Text>(true);
			if ((Object)(object)componentInChildren != (Object)null)
			{
				componentInChildren.text = text;
				componentInChildren.enableAutoSizing = true;
				componentInChildren.fontSizeMin = 12f;
				componentInChildren.fontSizeMax = componentInChildren.fontSize;
			}
			if (onRightClick != null)
			{
				val.AddComponent<RightClickRelay>().Action = onRightClick;
			}
			return val;
		}

		private static LayoutElement AddLayout(GameObject go, float flexibleWidth = -1f, float minWidth = -1f, float preferredWidth = -1f, float minHeight = -1f, float preferredHeight = -1f)
		{
			LayoutElement obj = go.GetComponent<LayoutElement>() ?? go.AddComponent<LayoutElement>();
			obj.flexibleWidth = flexibleWidth;
			obj.minWidth = minWidth;
			obj.preferredWidth = preferredWidth;
			obj.minHeight = minHeight;
			obj.preferredHeight = preferredHeight;
			return obj;
		}

		private static RectTransform NewRect(string name, Transform parent, params Type[] components)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			RectTransform val = (RectTransform)new GameObject(name, new Type[1] { typeof(RectTransform) }.Concat(components).ToArray()).transform;
			((Transform)val).SetParent(parent, false);
			return val;
		}

		private static void Stretch(RectTransform rect)
		{
			//IL_0001: 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_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			rect.anchorMin = Vector2.zero;
			rect.anchorMax = Vector2.one;
			rect.offsetMin = Vector2.zero;
			rect.offsetMax = Vector2.zero;
		}

		private void BuildOverlay()
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = NewRect("CaptureOverlay", ((Component)this).transform, typeof(Image));
			Stretch(val);
			((Graphic)((Component)val).GetComponent<Image>()).color = new Color(0f, 0f, 0f, 0.85f);
			_overlay = ((Component)val).gameObject;
			_overlayText = AddText((Transform)(object)val, "", (TextAlignmentOptions)514, Color.white);
			RectTransform val2 = (RectTransform)_overlayText.transform;
			val2.anchorMin = new Vector2(0.1f, 0.3f);
			val2.anchorMax = new Vector2(0.9f, 0.7f);
			val2.offsetMin = Vector2.zero;
			val2.offsetMax = Vector2.zero;
			_overlayText.textWrappingMode = (TextWrappingModes)1;
			_overlayText.overflowMode = (TextOverflowModes)0;
			TMP_Text overlayText = _overlayText;
			overlayText.fontSize *= 1.3f;
			_overlay.SetActive(false);
		}

		private void RefreshAll()
		{
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0245: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<string, int> dictionary = (from r in _rows
				select r.Binding.Source.ConflictKey() into k
				where k.Length > 0
				group k by k).ToDictionary((IGrouping<string, string> g) => g.Key, (IGrouping<string, string> g) => g.Count());
			Dictionary<string, int> dictionary2 = (from r in _rows
				select ChordText.Format(r.Binding.GamepadButtons) into c
				where c != "None"
				group c by c).ToDictionary((IGrouping<string, string> g) => g.Key, (IGrouping<string, string> g) => g.Count());
			foreach (Row row in _rows)
			{
				string text = row.Binding.Source.ConflictKey();
				bool flag = text.Length > 0 && dictionary[text] > 1;
				row.KeyboardText.text = row.Binding.Source.Display();
				((Graphic)row.KeyboardText).color = (flag ? Conflict : _buttonTextColor);
				string text2 = ChordText.Format(row.Binding.GamepadButtons);
				bool flag2 = text2 != "None" && dictionary2[text2] > 1;
				row.GamepadText.text = GamepadInput.Name(row.Binding.GamepadButtons);
				((Graphic)row.GamepadText).color = (flag2 ? Conflict : _buttonTextColor);
				((Graphic)row.Label).color = ((flag || flag2) ? Conflict : ((Graphic)_textTemplate).color);
			}
		}

		private void ResetSection(ModSection section)
		{
			foreach (KeyBinding binding in section.Bindings)
			{
				binding.Source.ResetToDefault();
				binding.SetGamepadChord(binding.DefaultGamepadButtons);
				binding.NotifyChanged();
			}
			RefreshAll();
		}

		private void ClearGamepad(KeyBinding binding)
		{
			binding.SetGamepad(GamepadButton.None);
			binding.NotifyChanged();
			RefreshAll();
		}

		private void BeginCapture(KeyBinding binding, CaptureKind kind)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			if (_capture == CaptureKind.None)
			{
				_capture = kind;
				_target = binding;
				_pendingModifier = (KeyCode)0;
				_capturedPad.Clear();
				_ignoredPad.Clear();
				_ignoredPad.AddRange(GamepadInput.HeldNow());
				_ignoreInputUntil = Time.unscaledTime + 0.25f;
				string text = ((kind == CaptureKind.Keyboard) ? "Press the new key or mouse button for" : "Press the new controller button for");
				string text2 = ((kind == CaptureKind.Keyboard) ? "Hold Ctrl, Shift or Alt first for a combination (also with the left mouse button).  Esc: cancel" : ((Gamepad.current == null) ? "No controller found.  Esc: cancel" : "Hold up to three buttons together, then let go.  Esc: cancel   (right-click a controller button to clear it)"));
				_overlayText.text = text + "\n<color=#FFB83B>" + binding.Label + "</color>\n\n<size=70%>" + text2 + "</size>";
				_overlay.SetActive(true);
				if ((Object)(object)Settings.instance != (Object)null)
				{
					Settings.instance.BlockNavigation(true);
				}
			}
		}

		private void Update()
		{
			if (_capture != CaptureKind.None && !(Time.unscaledTime < _ignoreInputUntil))
			{
				if (Input.GetKeyDown((KeyCode)27))
				{
					EndCapture();
				}
				else if (_capture == CaptureKind.Keyboard)
				{
					PollKeyboard();
				}
				else
				{
					PollGamepad();
				}
			}
		}

		private void PollKeyboard()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: 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_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			KeyCode[] captureKeys = CaptureKeys;
			foreach (KeyCode val in captureKeys)
			{
				if (Input.GetKeyDown(val))
				{
					Apply(val, HeldModifiers());
					return;
				}
			}
			if (Input.GetKeyDown((KeyCode)323) && _target.Source.AllowsModifiers && HeldModifiers().Length != 0)
			{
				Apply((KeyCode)323, HeldModifiers());
				return;
			}
			captureKeys = Modifiers;
			foreach (KeyCode val2 in captureKeys)
			{
				if (Input.GetKeyDown(val2))
				{
					_pendingModifier = val2;
				}
			}
			if ((int)_pendingModifier != 0 && Input.GetKeyUp(_pendingModifier))
			{
				Apply(_pendingModifier, Array.Empty<KeyCode>());
			}
		}

		private void PollGamepad()
		{
			List<GamepadButton> held = GamepadInput.HeldNow();
			_ignoredPad.RemoveAll((GamepadButton b) => !held.Contains(b));
			foreach (GamepadButton item in held)
			{
				if (!_ignoredPad.Contains(item) && !_capturedPad.Contains(item) && _capturedPad.Count < 3)
				{
					_capturedPad.Add(item);
				}
			}
			if (_capturedPad.Count != 0)
			{
				if (held.Count > _ignoredPad.Count)
				{
					ShowCaptured();
					return;
				}
				_target.SetGamepadChord(_capturedPad.ToArray());
				Finish();
			}
		}

		private void ShowCaptured()
		{
			_overlayText.text = "Press the new controller button for\n<color=#FFB83B>" + _target.Label + "</color>\n\n<size=130%>" + GamepadInput.Name(_capturedPad) + "</size>\n\n<size=70%>Let go of all buttons to confirm.  Esc: cancel</size>";
		}

		private static KeyCode[] HeldModifiers()
		{
			return ((IEnumerable<KeyCode>)Modifiers).Where((Func<KeyCode, bool>)Input.GetKey).ToArray();
		}

		private void Apply(KeyCode key, IReadOnlyList<KeyCode> modifiers)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			KeySource source = _target.Source;
			IReadOnlyList<KeyCode> modifiers2;
			if (!_target.Source.AllowsModifiers)
			{
				IReadOnlyList<KeyCode> readOnlyList = Array.Empty<KeyCode>();
				modifiers2 = readOnlyList;
			}
			else
			{
				modifiers2 = modifiers;
			}
			source.Set(key, modifiers2);
			Finish();
		}

		private void Finish()
		{
			_target.NotifyChanged();
			RefreshAll();
			EndCapture();
		}

		private void EndCapture()
		{
			_capture = CaptureKind.None;
			_overlay.SetActive(false);
			if (((Behaviour)this).isActiveAndEnabled)
			{
				((MonoBehaviour)this).StartCoroutine(UnblockNavigation());
			}
			else if ((Object)(object)Settings.instance != (Object)null)
			{
				Settings.instance.BlockNavigation(false);
			}
		}

		private IEnumerator UnblockNavigation()
		{
			yield return null;
			if (_capture == CaptureKind.None && (Object)(object)Settings.instance != (Object)null)
			{
				Settings.instance.BlockNavigation(false);
			}
		}

		static KeyBindingsTab()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			KeyCode[] array = new KeyCode[6];
			RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			Modifiers = (KeyCode[])(object)array;
			CaptureKeys = (from k in ((KeyCode[])Enum.GetValues(typeof(KeyCode))).Distinct()
				where (int)k != 0 && (int)k != 27 && (int)k != 323
				where (int)k < 330 || (int)k > 509
				where !Modifiers.Contains(k)
				where (int)k != 310 && (int)k != 309 && (int)k != 311 && (int)k != 312
				select k).ToArray();
		}
	}
	[HarmonyPatch(typeof(Settings), "InitializeTabs")]
	internal static class InitializeTabsPatch
	{
		private static bool _dumped;

		private static void Prefix(Settings __instance)
		{
			try
			{
				Install(__instance);
			}
			catch (Exception arg)
			{
				KeyBindingsPlugin.Log.LogError((object)$"Could not add the Key Bindings tab: {arg}");
			}
		}

		private static void Install(Settings settings)
		{
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Expected O, but got Unknown
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Expected O, but got Unknown
			//IL_0250: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Expected O, but got Unknown
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Expected O, but got Unknown
			//IL_0370: Unknown result type (might be due to invalid IL or missing references)
			//IL_0375: Unknown result type (might be due to invalid IL or missing references)
			//IL_037d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0385: Unknown result type (might be due to invalid IL or missing references)
			//IL_038c: Unknown result type (might be due to invalid IL or missing references)
			//IL_038d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0397: Expected O, but got Unknown
			//IL_039c: Expected O, but got Unknown
			//IL_033b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0342: Unknown result type (might be due to invalid IL or missing references)
			//IL_0347: Unknown result type (might be due to invalid IL or missing references)
			//IL_035b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0360: Unknown result type (might be due to invalid IL or missing references)
			if (!KeyBindingsPlugin.Enabled.Value || !Registry.HasAny)
			{
				return;
			}
			TabHandler componentInChildren = ((Component)settings).GetComponentInChildren<TabHandler>();
			KeyboardMouseSettings componentInChildren2 = ((Component)settings).GetComponentInChildren<KeyboardMouseSettings>(true);
			if ((Object)(object)componentInChildren == (Object)null || (Object)(object)componentInChildren2 == (Object)null)
			{
				KeyBindingsPlugin.Log.LogWarning((object)"The settings screen looks different than expected, no Key Bindings tab added");
				return;
			}
			Tab val = ((IEnumerable<Tab>)componentInChildren.m_tabs).LastOrDefault((Func<Tab, bool>)((Tab t) => (Object)(object)t.m_button != (Object)null && (Object)(object)t.m_page != (Object)null));
			if (val == null)
			{
				KeyBindingsPlugin.Log.LogWarning((object)"No existing settings tab found to copy, no Key Bindings tab added");
				return;
			}
			RectTransform val2 = ((componentInChildren2.m_keys.Count > 0) ? componentInChildren2.m_keys[0].m_keyTransform : null);
			Button val3 = (((Object)(object)val2 != (Object)null) ? ((Component)val2).GetComponentInChildren<Button>(true) : null);
			if ((Object)(object)val3 == (Object)null || (Object)(object)componentInChildren2.m_mouseSensitivityText == (Object)null)
			{
				KeyBindingsPlugin.Log.LogWarning((object)"Could not find the key button style of the game, no Key Bindings tab added");
				return;
			}
			if (!_dumped)
			{
				_dumped = true;
				KeyBindingsPlugin.Log.LogInfo((object)("Settings tab bar:\n" + UiDump.Describe(((Component)val.m_button).transform.parent, 2)));
				KeyBindingsPlugin.Log.LogInfo((object)("Settings page (template):\n" + UiDump.Describe((Transform)(object)val.m_page, 2)));
				KeyBindingsPlugin.Log.LogInfo((object)("Key button (template):\n" + UiDump.Describe(((Component)val3).transform, 3)));
			}
			GameObject val4 = new GameObject("NathansKeyBindingsPage", new Type[1] { typeof(RectTransform) });
			RectTransform val5 = (RectTransform)val4.transform;
			((Transform)val5).SetParent(((Transform)val.m_page).parent, false);
			val5.anchorMin = val.m_page.anchorMin;
			val5.anchorMax = val.m_page.anchorMax;
			val5.pivot = val.m_page.pivot;
			val5.anchoredPosition = val.m_page.anchoredPosition;
			val5.sizeDelta = val.m_page.sizeDelta;
			val4.SetActive(false);
			val4.AddComponent<KeyBindingsTab>().Configure(val3, componentInChildren2.m_mouseSensitivityText);
			GameObject obj = Object.Instantiate<GameObject>(((Component)val.m_button).gameObject, ((Component)val.m_button).transform.parent);
			((Object)obj).name = "NathansKeyBindingsTab";
			Button component = obj.GetComponent<Button>();
			component.onClick = new ButtonClickedEvent();
			RectTransform val6 = (RectTransform)obj.transform;
			RectTransform val7 = (RectTransform)((Component)val.m_button).transform;
			TMP_Text[] componentsInChildren = obj.GetComponentsInChildren<TMP_Text>(true);
			foreach (TMP_Text val8 in componentsInChildren)
			{
				if (!IsInside(val8.transform, "KeyHint", (Transform)(object)val6))
				{
					val8.text = "Key Bindings";
				}
			}
			Transform val9 = ((Transform)val7).Find("KeyHint");
			Transform val10 = ((Transform)val6).Find("KeyHint");
			if ((Object)(object)val9 != (Object)null && (Object)(object)val10 != (Object)null)
			{
				((Component)val9).gameObject.SetActive(false);
				GameObject[] tabKeyHints = settings.m_tabKeyHints;
				for (int num2 = 0; num2 < tabKeyHints.Length; num2++)
				{
					if ((Object)(object)tabKeyHints[num2] == (Object)(object)((Component)val9).gameObject)
					{
						tabKeyHints[num2] = ((Component)val10).gameObject;
					}
				}
			}
			if ((Object)(object)((Component)((Transform)val6).parent).GetComponent<LayoutGroup>() == (Object)null)
			{
				Vector2 anchoredPosition = val7.anchoredPosition;
				Rect rect = val7.rect;
				val6.anchoredPosition = anchoredPosition + new Vector2(((Rect)(ref rect)).width + 8f, 0f);
			}
			componentInChildren.m_tabs.Add(new Tab
			{
				m_button = component,
				m_page = val5,
				m_default = false,
				m_onClick = new UnityEvent()
			});
		}

		private static bool IsInside(Transform child, string ancestorName, Transform root)
		{
			Transform val = child;
			while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)root)
			{
				if (((Object)val).name == ancestorName)
				{
					return true;
				}
				val = val.parent;
			}
			return false;
		}
	}
	internal static class UiDump
	{
		public static string Describe(Transform root, int maxDepth)
		{
			StringBuilder stringBuilder = new StringBuilder();
			Append(stringBuilder, root, 0, maxDepth);
			return stringBuilder.ToString();
		}

		private static void Append(StringBuilder sb, Transform t, int depth, int maxDepth)
		{
			//IL_0053: 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_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Expected O, but got Unknown
			sb.Append(new string(' ', depth * 2)).Append(((Object)t).name).Append(((Component)t).gameObject.activeSelf ? "" : " (inactive)");
			RectTransform val = (RectTransform)(object)((t is RectTransform) ? t : null);
			if (val != null)
			{
				object[] obj = new object[4] { val.anchorMin, val.anchorMax, val.anchoredPosition, null };
				Rect rect = val.rect;
				obj[3] = ((Rect)(ref rect)).size;
				sb.Append(string.Format("  anchors={0}-{1} pos={2} size={3}", obj));
			}
			sb.Append("  [").Append(string.Join(",", (from c in ((Component)t).GetComponents<Component>()
				where (Object)(object)c != (Object)null
				select ((object)c).GetType().Name).ToArray())).Append("]\n");
			if (depth >= maxDepth)
			{
				return;
			}
			foreach (Transform item in t)
			{
				Transform t2 = item;
				Append(sb, t2, depth + 1, maxDepth);
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}