Decompiled source of Card Hotkeys v1.0.0

BepInEx/plugins/CardHotkeys/CardHotkeys.dll

Decompiled 5 days ago
using 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.Versioning;
using BattleMatch;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("CardHotkeys")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("CardHotkeys")]
[assembly: AssemblyTitle("CardHotkeys")]
[assembly: AssemblyVersion("1.0.0.0")]
[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 CardHotkeys
{
	public static class NumberKeys
	{
		public static int GetNumber(Key key, out bool numpad)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Invalid comparison between Unknown and I4
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Invalid comparison between Unknown and I4
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Invalid comparison between Unknown and I4
			//IL_0016: 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)
			//IL_001b: Expected I4, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Invalid comparison between Unknown and I4
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Invalid comparison between Unknown and I4
			//IL_0025: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected I4, but got Unknown
			numpad = (int)key >= 84 && (int)key <= 93;
			if (numpad)
			{
				return key - 84;
			}
			if ((int)key >= 41 && (int)key <= 49)
			{
				return key - 41 + 1;
			}
			if ((int)key != 50)
			{
				return -1;
			}
			return 0;
		}
	}
	[HarmonyPatch(typeof(InputController), "DoKeyBinding")]
	internal static class NumberInputPatch
	{
		private static bool Prefix(CallbackContext _context)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.ActiveInCombat)
			{
				InputControl control = ((CallbackContext)(ref _context)).control;
				KeyControl val = (KeyControl)(object)((control is KeyControl) ? control : null);
				if (val != null)
				{
					bool numpad;
					int number = NumberKeys.GetNumber(val.keyCode, out numpad);
					if (number < 0)
					{
						return true;
					}
					return Plugin.Instance.HandleNumber(_context, number, numpad);
				}
			}
			return true;
		}
	}
	public static class NumericGateIl
	{
		public static IEnumerable<CodeInstruction> ReplaceSettingRead(IEnumerable<CodeInstruction> instructions, bool hints)
		{
			List<CodeInstruction> list = instructions.ToList();
			MethodInfo methodInfo = AccessTools.PropertyGetter(typeof(GameManager), "ConfigKeyboardShortcuts");
			MethodInfo operand = AccessTools.Method(typeof(Plugin), hints ? "NumberHintsEnabled" : "NumberShortcutsEnabled", (Type[])null, (Type[])null);
			int num = 0;
			foreach (CodeInstruction item in list)
			{
				if (CodeInstructionExtensions.Calls(item, methodInfo))
				{
					item.opcode = OpCodes.Call;
					item.operand = operand;
					num++;
				}
			}
			if (num != 1)
			{
				throw new InvalidOperationException("Expected one keyboard setting read, found " + num + ". Game version may be incompatible.");
			}
			return list;
		}
	}
	[HarmonyPatch(typeof(BattleKeyboard), "KeyboardNum")]
	internal static class NumericPermissionPatch
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			return NumericGateIl.ReplaceSettingRead(instructions, hints: false);
		}
	}
	[HarmonyPatch(typeof(BattleKeyboard), "ShowCombatKeyboardByConfig")]
	internal static class CombatHintsPatch
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			return NumericGateIl.ReplaceSettingRead(instructions, hints: true);
		}
	}
	[HarmonyPatch(typeof(CardItem), "ShowKeyNum")]
	internal static class CardHintsPatch
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			return NumericGateIl.ReplaceSettingRead(instructions, hints: true);
		}
	}
	[BepInPlugin("cheyenne.acrosstheobelisk.cardhotkeys", "Card Hotkeys", "1.0.0")]
	[BepInProcess("AcrossTheObelisk.exe")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string Id = "cheyenne.acrosstheobelisk.cardhotkeys";

		public const string Version = "1.0.0";

		internal static Plugin Instance;

		private Harmony harmony;

		private bool operational;

		private int lastHandledFrame = int.MinValue;

		private ConfigEntry<bool> enableMod;

		private ConfigEntry<bool> includeNumpad;

		private ConfigEntry<bool> tenthCard;

		private ConfigEntry<bool> showHints;

		private ConfigEntry<bool> ignoreModifiers;

		internal static bool ActiveInCombat
		{
			get
			{
				if ((Object)(object)Instance != (Object)null && Instance.operational && Instance.enableMod.Value && (Object)(object)MatchManager.Instance != (Object)null)
				{
					return ((Behaviour)MatchManager.Instance).isActiveAndEnabled;
				}
				return false;
			}
		}

		private void Awake()
		{
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			Instance = this;
			enableMod = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable number hotkeys during combat, independently of the game's Keyboard Shortcuts setting.");
			includeNumpad = ((BaseUnityPlugin)this).Config.Bind<bool>("Controls", "IncludeNumpad", true, "Also accept numpad 1-9 (and numpad 0 if enabled below).");
			tenthCard = ((BaseUnityPlugin)this).Config.Bind<bool>("Controls", "EnableTenthCard", true, "Use 0 for the tenth card. Also allows 0 in the game's card and energy selectors.");
			ignoreModifiers = ((BaseUnityPlugin)this).Config.Bind<bool>("Controls", "IgnoreModifiedKeys", true, "Ignore number keys held with Shift, Ctrl, Alt, or Windows/Command.");
			showHints = ((BaseUnityPlugin)this).Config.Bind<bool>("Display", "ShowNumberHints", true, "Show the game's number labels even when its Keyboard Shortcuts setting is off.");
			harmony = new Harmony("cheyenne.acrosstheobelisk.cardhotkeys");
			try
			{
				harmony.PatchAll(typeof(Plugin).Assembly);
				operational = true;
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Card Hotkeys 1.0.0 loaded. 1-9: card, then numbered target; 0: tenth card; Esc: cancel.");
			}
			catch (Exception ex)
			{
				operational = false;
				harmony.UnpatchSelf();
				((BaseUnityPlugin)this).Logger.LogError((object)("Card Hotkeys could not patch this game version and is disabled. " + ex));
			}
		}

		internal bool HandleNumber(CallbackContext context, int number, bool numpad)
		{
			try
			{
				if (!((CallbackContext)(ref context)).performed)
				{
					goto IL_0021;
				}
				InputControl control = ((CallbackContext)(ref context)).control;
				KeyControl val = (KeyControl)(object)((control is KeyControl) ? control : null);
				if (val == null || !((ButtonControl)val).isPressed)
				{
					goto IL_0021;
				}
				if ((numpad && !includeNumpad.Value) || (number == 0 && !tenthCard.Value))
				{
					return false;
				}
				InputDevice device = ((CallbackContext)(ref context)).control.device;
				Keyboard val2 = (Keyboard)(object)((device is Keyboard) ? device : null);
				if (val2 == null || !Application.isFocused || Time.timeScale <= 0f || (ignoreModifiers.Value && (val2.shiftKey.isPressed || val2.ctrlKey.isPressed || val2.altKey.isPressed || ((ButtonControl)val2.leftMetaKey).isPressed || ((ButtonControl)val2.rightMetaKey).isPressed)))
				{
					return false;
				}
				MatchManager instance = MatchManager.Instance;
				if ((Object)(object)instance == (Object)null || instance.MatchIsOver || instance.Keyboard == null || (Object)(object)instance.DeathScreen == (Object)null || (Object)(object)instance.AddcardSelector == (Object)null || (Object)(object)instance.DiscardSelector == (Object)null || (Object)(object)instance.EnergySelector == (Object)null || (Object)(object)instance.DeckCardsWindow == (Object)null || (Object)(object)instance.characterWindow == (Object)null || (Object)(object)instance.console == (Object)null || instance.CardDrag || instance.IsMenuActive() || ((Object)(object)KeyboardManager.Instance != (Object)null && KeyboardManager.Instance.IsActive()) || ((Object)(object)MadnessManager.Instance != (Object)null && MadnessManager.Instance.IsActive()) || ((Object)(object)SandboxManager.Instance != (Object)null && SandboxManager.Instance.IsActive()) || ((Object)(object)PerkTree.Instance != (Object)null && PerkTree.Instance.IsActive()) || TextFieldSelected())
				{
					return false;
				}
				if (lastHandledFrame == Time.frameCount)
				{
					return false;
				}
				lastHandledFrame = Time.frameCount;
				instance.Keyboard.KeyboardNum(number);
				goto end_IL_0000;
				IL_0021:
				return false;
				end_IL_0000:;
			}
			catch (Exception ex)
			{
				operational = false;
				((BaseUnityPlugin)this).Logger.LogError((object)("Card Hotkeys encountered an error and has disabled itself for this session. " + ex));
			}
			return false;
		}

		private static bool TextFieldSelected()
		{
			GameObject val = (((Object)(object)EventSystem.current != (Object)null) ? EventSystem.current.currentSelectedGameObject : null);
			if ((Object)(object)val != (Object)null)
			{
				if (!((Object)(object)val.GetComponentInParent<TMP_InputField>() != (Object)null))
				{
					return (Object)(object)val.GetComponentInParent<InputField>() != (Object)null;
				}
				return true;
			}
			return false;
		}

		public static bool NumberShortcutsEnabled(GameManager game)
		{
			if (!ActiveInCombat)
			{
				return game.ConfigKeyboardShortcuts;
			}
			return true;
		}

		public static bool NumberHintsEnabled(GameManager game)
		{
			if (!ActiveInCombat || !Instance.showHints.Value)
			{
				return game.ConfigKeyboardShortcuts;
			}
			return true;
		}

		private void OnDestroy()
		{
			operational = false;
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}
	}
}