Decompiled source of EasyKey v1.0.0

EasyKey.dll

Decompiled 9 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using AskaShared.Game;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using Fusion;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using SSSGame;
using SSSGame.Controllers;
using SSSGame.UI;
using SandSailorStudio.Attributes;
using SandSailorStudio.Inventory;
using SandSailorStudio.Localization;
using SandSailorStudio.UI;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Utilities;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("EasyKey")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0")]
[assembly: AssemblyInformationalVersion("0.1.0+11cf36d98a0d1e7ad9d879e4f0d3f5280812f82c")]
[assembly: AssemblyProduct("EasyKey")]
[assembly: AssemblyTitle("EasyKey")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.0.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 AskaEasyKey
{
	[HarmonyPatch]
	public static class AutoMove
	{
		private const float PressThreshold = 0.5f;

		private const float InputPresentThreshold = 0.2f;

		private const float DominanceRatio = 1.2f;

		private const float NearMissWindows = 3f;

		private static int _driveId;

		private static bool _haveDrive;

		private static bool _failed;

		private static bool _sawPostfix;

		private static bool _sawRealInput;

		private static bool _tapping;

		private static Vector2 _tapPeak;

		private static float _tapPressTime;

		private static Vector2 _pendingTap;

		private static float _pendingPressTime;

		private static bool _engaged;

		private static bool _engagedSwimming;

		private static Vector2 _forced;

		private static int _frames;

		internal static void OnLocalPlayerSpawned()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			Disengage();
			_tapping = false;
			_pendingTap = Vector2.zero;
			_haveDrive = false;
			if (EasyKeyConfig.AutoMoveOn)
			{
				Character localCharacter = LocalPlayerTool.LocalCharacter;
				PlayerDrive val = (((Object)(object)localCharacter == (Object)null) ? null : ((Component)localCharacter).GetComponentInChildren<PlayerDrive>());
				if ((Object)(object)val == (Object)null)
				{
					Plugin.Log.LogError((object)"AutoMove: the local character has no PlayerDrive, so double-tap to auto-move is off for this session.");
					return;
				}
				_driveId = ((Object)val).GetInstanceID();
				_haveDrive = true;
				_failed = false;
				_sawPostfix = false;
				_sawRealInput = false;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerDrive), "ReadInput")]
		public static void AfterReadInput(PlayerDrive __instance)
		{
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Expected O, but got Unknown
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Expected O, but got Unknown
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			if (!EasyKeyConfig.AutoMoveOn || _failed || !_haveDrive || (Object)(object)__instance == (Object)null || ((Object)__instance).GetInstanceID() != _driveId)
			{
				return;
			}
			bool flag = default(bool);
			if (!_sawPostfix)
			{
				_sawPostfix = true;
				ManualLogSource log = Plugin.Log;
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(89, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("AutoMove: the ReadInput postfix is running on the local drive, instance ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(_driveId);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(". Tap window ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(EasyKeyConfig.AutoMoveTapWindowMs.Value);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ms.");
				}
				log.LogInfo(val);
			}
			try
			{
				Vector2 direction = __instance._direction;
				float magnitude = ((Vector2)(ref direction)).magnitude;
				if (_engaged && magnitude >= 0.2f)
				{
					ManualLogSource log2 = Plugin.Log;
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(89, 4, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("AutoMove off: movement input ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Format(direction));
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" magnitude ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(magnitude, "F2");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" after ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(_frames);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" frames of ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Name(_forced));
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(". That press is passed through.");
					}
					log2.LogInfo(val);
					Disengage();
				}
				if (_engaged)
				{
					string text = CancelReason(__instance);
					if (text != null)
					{
						ManualLogSource log3 = Plugin.Log;
						BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(33, 3, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral("AutoMove off: ");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" after ");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(_frames);
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" frames of ");
							((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Name(_forced));
							((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".");
						}
						log3.LogInfo(val);
						Disengage();
					}
				}
				TrackTap(__instance, direction, magnitude);
				if (_engaged)
				{
					__instance._direction = _forced;
					_frames++;
				}
			}
			catch (Exception ex)
			{
				_failed = true;
				Disengage();
				ManualLogSource log4 = Plugin.Log;
				BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(76, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("AutoMove: the ReadInput postfix threw ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.GetType().Name);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(". Auto-move is off for this session.");
				}
				log4.LogError(val2);
			}
		}

		private static string CancelReason(PlayerDrive drive)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Invalid comparison between Unknown and I4
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			if (Cursor.visible || (int)Cursor.lockState != 1)
			{
				return "a UI has focus, so the cursor is free";
			}
			PlayerInteractionAgent playerInteractionAgent = drive._playerInteractionAgent;
			if ((Object)(object)playerInteractionAgent != (Object)null && (int)playerInteractionAgent.State != 0)
			{
				return $"an interaction is {playerInteractionAgent.State}";
			}
			CharacterMovement characterMovement = drive._characterMovement;
			if (!((Object)(object)characterMovement != (Object)null) || !characterMovement.IsSwimming)
			{
				_engagedSwimming = false;
			}
			else if (!_engagedSwimming)
			{
				return "swimming started after the walk did";
			}
			return null;
		}

		private static void TrackTap(PlayerDrive drive, Vector2 input, float magnitude)
		{
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: 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_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			if (!_tapping)
			{
				if (magnitude < 0.5f)
				{
					return;
				}
				if (!_sawRealInput)
				{
					_sawRealInput = true;
					ManualLogSource log = Plugin.Log;
					bool flag = default(bool);
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(99, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("AutoMove: real movement input reaches the ReadInput postfix, first reading ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Format(input));
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(". Tap detection is live.");
					}
					log.LogInfo(val);
				}
				_tapping = true;
				_tapPeak = input;
				_tapPressTime = Time.realtimeSinceStartup;
			}
			else if (magnitude >= 0.2f)
			{
				if (magnitude > ((Vector2)(ref _tapPeak)).magnitude)
				{
					_tapPeak = input;
				}
			}
			else
			{
				_tapping = false;
				CompleteTap(drive, Cardinal(_tapPeak), _tapPressTime);
			}
		}

		private static void CompleteTap(PlayerDrive drive, Vector2 cardinal, float pressTime)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_0068: 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_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Expected O, but got Unknown
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Expected O, but got Unknown
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			int value = EasyKeyConfig.AutoMoveTapWindowMs.Value;
			float num = (pressTime - _pendingPressTime) * 1000f;
			bool flag = _pendingTap != Vector2.zero;
			bool flag2 = flag && num <= (float)value * 3f;
			bool flag3 = default(bool);
			if (Plugin.DebugLogging)
			{
				ManualLogSource log = Plugin.Log;
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(55, 3, ref flag3);
				if (flag3)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("AutoMove: tap peak ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Format(_tapPeak));
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" reads ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Name(cardinal));
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(num, "F0");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ms after the previous tap.");
				}
				log.LogInfo(val);
			}
			if (cardinal == Vector2.zero)
			{
				if (flag2)
				{
					ManualLogSource log2 = Plugin.Log;
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(102, 3, ref flag3);
					if (flag3)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("AutoMove: tap peak ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Format(_tapPeak));
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is diagonal and names no single direction, so the ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Name(_pendingTap));
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" tap ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(num, "F0");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ms before it is discarded.");
					}
					log2.LogInfo(val);
				}
				_pendingTap = Vector2.zero;
				return;
			}
			if (flag && _pendingTap == cardinal)
			{
				if (num <= (float)value)
				{
					Engage(drive, cardinal, num, value);
					return;
				}
				if (flag2)
				{
					ManualLogSource log3 = Plugin.Log;
					BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(86, 3, ref flag3);
					if (flag3)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("AutoMove: second ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Name(cardinal));
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" tap arrived ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(num, "F0");
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ms after the first and the window is ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(value);
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ms. No auto-move.");
					}
					log3.LogInfo(val);
				}
			}
			_pendingTap = cardinal;
			_pendingPressTime = pressTime;
		}

		private static void Engage(PlayerDrive drive, Vector2 cardinal, float gapMs, int window)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			_pendingTap = Vector2.zero;
			_engaged = true;
			_forced = cardinal;
			_frames = 0;
			CharacterMovement characterMovement = drive._characterMovement;
			_engagedSwimming = (Object)(object)characterMovement != (Object)null && characterMovement.IsSwimming;
			ManualLogSource log = Plugin.Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(77, 5, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("AutoMove on: ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Name(cardinal));
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Format(cardinal));
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", two taps ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(gapMs, "F0");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ms apart inside a ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(window);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ms window. Swimming at engage: ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(_engagedSwimming);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".");
			}
			log.LogInfo(val);
		}

		private static void Disengage()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			_engaged = false;
			_engagedSwimming = false;
			_forced = Vector2.zero;
			_frames = 0;
		}

		private static Vector2 Cardinal(Vector2 v)
		{
			//IL_0000: 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_0022: 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)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: 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)
			float num = Mathf.Abs(v.x);
			float num2 = Mathf.Abs(v.y);
			if (num > num2 * 1.2f)
			{
				return new Vector2(Mathf.Sign(v.x), 0f);
			}
			if (num2 > num * 1.2f)
			{
				return new Vector2(0f, Mathf.Sign(v.y));
			}
			return Vector2.zero;
		}

		private static string Name(Vector2 cardinal)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			if (cardinal == Vector2.zero)
			{
				return "no direction";
			}
			if (cardinal.y > 0f)
			{
				return "forward";
			}
			if (cardinal.y < 0f)
			{
				return "back";
			}
			if (!(cardinal.x > 0f))
			{
				return "left";
			}
			return "right";
		}

		private static string Format(Vector2 v)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			return $"({v.x:F2}, {v.y:F2})";
		}
	}
	[HarmonyPatch(typeof(Character))]
	public static class CharacterSpawnPatch
	{
		private const string ToolObjectName = "EasyKey_Tool";

		[HarmonyPostfix]
		[HarmonyPatch("Spawned")]
		public static void Spawned(Character __instance)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			LocalPlayerTool.AttachOnSpawn(__instance, Plugin.Log, "EasyKey_Tool", Vector3.zero, typeof(EasyKeyTool));
		}
	}
	[HarmonyPatch]
	public static class DropAllStacks
	{
		public sealed class DropState
		{
			internal int InfoId { get; }

			internal string ItemName { get; }

			internal BaseContainerPanel Source { get; }

			internal IntPtr Clicked { get; }

			internal DropState(int infoId, string itemName, BaseContainerPanel source, IntPtr clicked)
			{
				InfoId = infoId;
				ItemName = itemName;
				Source = source;
				Clicked = clicked;
			}
		}

		private static bool _dropping;

		[HarmonyPrefix]
		[HarmonyPatch(typeof(ItemThumbnailPanel), "CommandDropItem")]
		public static void BeforeCommandDropItem(ItemThumbnailPanel __instance, out DropState __state)
		{
			__state = null;
			if (!EasyKeyConfig.DropAllModifierOn || _dropping || !MeansAllStacks() || (Object)(object)__instance == (Object)null)
			{
				return;
			}
			BaseContainerPanel parent = __instance.parent;
			if ((Object)(object)parent == (Object)null)
			{
				return;
			}
			Item item = __instance.Item;
			if (item != null)
			{
				ItemInfo info = item.info;
				if (!((Object)(object)info == (Object)null))
				{
					__state = new DropState(info.id, ((Object)info).name, parent, PointerOf((Il2CppObjectBase)(object)__instance));
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ItemThumbnailPanel), "CommandDropItem")]
		public static void AfterCommandDropItem(DropState __state)
		{
			if (__state != null)
			{
				DropRemainingStacks(__state);
			}
		}

		private static bool MeansAllStacks()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return Input.GetKey(EasyKeyConfig.DropAllModifier.Value);
		}

		private static void DropRemainingStacks(DropState state)
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			List<ItemThumbnailPanel> list = SnapshotMatchingPanels(state);
			int num = 1;
			int num2 = 0;
			_dropping = true;
			try
			{
				foreach (ItemThumbnailPanel item in list)
				{
					if (!StillEligible(item, state))
					{
						num2++;
						continue;
					}
					item.CommandDropItem();
					num++;
				}
			}
			finally
			{
				_dropping = false;
			}
			ManualLogSource log = Plugin.Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(50, 4, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("DropAll: ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" stacks of ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(state.ItemName);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" dropped. candidates=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(list.Count);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" skipped=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num2);
			}
			log.LogInfo(val);
		}

		private static List<ItemThumbnailPanel> SnapshotMatchingPanels(DropState state)
		{
			List<ItemThumbnailPanel> list = new List<ItemThumbnailPanel>();
			foreach (ItemThumbnailPanel componentsInChild in ((Component)state.Source).GetComponentsInChildren<ItemThumbnailPanel>())
			{
				if (!((Object)(object)componentsInChild == (Object)null) && !(PointerOf((Il2CppObjectBase)(object)componentsInChild) == state.Clicked) && Matches(componentsInChild, state))
				{
					list.Add(componentsInChild);
				}
			}
			return list;
		}

		private static bool StillEligible(ItemThumbnailPanel panel, DropState state)
		{
			if ((Object)(object)panel == (Object)null || PointerOf((Il2CppObjectBase)(object)panel.parent) != PointerOf((Il2CppObjectBase)(object)state.Source))
			{
				return false;
			}
			if (!Matches(panel, state))
			{
				return false;
			}
			Item item = panel.Item;
			if (item != null)
			{
				return item.Container != null;
			}
			return false;
		}

		private static bool Matches(ItemThumbnailPanel panel, DropState state)
		{
			Item item = panel.Item;
			if (item == null)
			{
				return false;
			}
			ItemInfo info = item.info;
			if ((Object)(object)info != (Object)null)
			{
				return info.id == state.InfoId;
			}
			return false;
		}

		private static IntPtr PointerOf(Il2CppObjectBase obj)
		{
			if (obj != null)
			{
				return obj.Pointer;
			}
			return IntPtr.Zero;
		}
	}
	internal static class EasyKeyConfig
	{
		private const string Section = "Easy Key";

		private static readonly HashSet<ConfigEntryBase> ReloadOnly = new HashSet<ConfigEntryBase>();

		private static bool _loadComplete;

		internal static ConfigEntry<bool> Enabled { get; private set; }

		internal static ConfigEntry<bool> MoveAllModifierEnabled { get; private set; }

		internal static ConfigEntry<bool> DropAllModifierEnabled { get; private set; }

		internal static ConfigEntry<bool> InstantMultiPickupEnabled { get; private set; }

		internal static ConfigEntry<bool> TapGatherEnabled { get; private set; }

		internal static ConfigEntry<bool> TapHarvestEnabled { get; private set; }

		internal static ConfigEntry<bool> TapBuildEnabled { get; private set; }

		internal static ConfigEntry<bool> TapDrinkEnabled { get; private set; }

		internal static ConfigEntry<bool> TapFireEnabled { get; private set; }

		internal static ConfigEntry<bool> AutoWorkshopsEnabled { get; private set; }

		internal static ConfigEntry<bool> AutoRotateEnabled { get; private set; }

		internal static ConfigEntry<bool> AutoQuenchEnabled { get; private set; }

		internal static ConfigEntry<bool> TapToolSwapEnabled { get; private set; }

		internal static ConfigEntry<bool> AutoMoveEnabled { get; private set; }

		internal static ConfigEntry<bool> HoldPromptStripEnabled { get; private set; }

		internal static ConfigEntry<KeyCode> MoveAllModifier { get; private set; }

		internal static ConfigEntry<bool> MoveAllOnModifier { get; private set; }

		internal static ConfigEntry<KeyCode> DropAllModifier { get; private set; }

		internal static ConfigEntry<int> AutoMoveTapWindowMs { get; private set; }

		internal static bool MasterEnabled { get; private set; }

		internal static bool MoveAllModifierOn { get; private set; }

		internal static bool DropAllModifierOn { get; private set; }

		internal static bool InstantMultiPickupOn { get; private set; }

		internal static bool TapGatherOn { get; private set; }

		internal static bool TapHarvestOn { get; private set; }

		internal static bool TapBuildOn { get; private set; }

		internal static bool TapDrinkOn { get; private set; }

		internal static bool TapFireOn { get; private set; }

		internal static bool AutoWorkshopsOn { get; private set; }

		internal static bool AutoRotateOn { get; private set; }

		internal static bool AutoQuenchOn { get; private set; }

		internal static bool TapToolSwapOn { get; private set; }

		internal static bool AutoMoveOn { get; private set; }

		internal static bool HoldPromptStripOn { get; private set; }

		internal static void Init(ConfigFile file)
		{
			Enabled = BindReload(file, "Enabled", defaultValue: true, "Master on/off switch for this mod.");
			MoveAllModifierEnabled = BindReload(file, "MoveAllModifierEnabled", defaultValue: true, "Let MoveAllModifier plus a right click on an item move every stack of that item's type at once.");
			DropAllModifierEnabled = BindReload(file, "DropAllModifierEnabled", defaultValue: true, "Let DropAllModifier plus the game's drop key on an item drop every stack of that item's type at once.");
			InstantMultiPickupEnabled = BindReload(file, "InstantMultiPickupEnabled", defaultValue: true, "Put pick-up-everything-nearby on E as a single press, and retire the single-item pickup.");
			TapGatherEnabled = BindReload(file, "TapGatherEnabled", defaultValue: true, "Gather on one press: the first press starts gathering and it continues with the key released, the second press stops it.");
			TapHarvestEnabled = BindReload(file, "TapHarvestEnabled", defaultValue: true, "Chop and mine on one press: the first press starts the action and it continues with the key released, the second press stops it.");
			TapBuildEnabled = BindReload(file, "TapBuildEnabled", defaultValue: true, "Build and repair at a station on one press: the first press starts hammering and it continues with the key released, the second press stops it.");
			TapDrinkEnabled = BindReload(file, "TapDrinkEnabled", defaultValue: true, "Drink from a well or water source on one press: the first press starts drinking and it continues with the key released, the second press stops it, and it stops by itself when thirst is quenched.");
			TapFireEnabled = BindReload(file, "TapFireEnabled", defaultValue: true, "Light or put out a fire on one press: the first press starts it and it continues with the key released, the second press stops it, and it ends by itself when the fire catches or goes out.");
			AutoWorkshopsEnabled = BindReload(file, "AutoWorkshopsEnabled", defaultValue: true, "Automate the hold work at workshops. At the anvil and the woodworking bench, one press starts the work and it continues with the key released, and a second press stops it.");
			AutoRotateEnabled = BindReload(file, "AutoRotateEnabled", defaultValue: true, "Wherever a worked piece must be turned to reach every side, such as the anvil and the woodworking bench, turn it to the next side by itself as each side is finished, using the game's own turn rule, so you never press the rotate key.");
			AutoQuenchEnabled = BindReload(file, "AutoQuenchEnabled", defaultValue: true, "At the anvil and woodworking bench, quench the piece by itself once every side is finished, so you never press the quench key.");
			TapToolSwapEnabled = BindReload(file, "TapToolSwapEnabled", defaultValue: true, "When a tap needs a different tool, keep the action alive until the tool is in hand so one tap still starts it.");
			AutoMoveEnabled = BindReload(file, "AutoMoveEnabled", defaultValue: true, "Double-tap a movement key to walk in that direction until any movement key is pressed or the context changes.");
			HoldPromptStripEnabled = BindReload(file, "HoldPromptStripEnabled", defaultValue: true, "Remove the stray 'Hold' word from the prompt of interactions this mod turns into one tap (harvest, gather, build, fire, anvil). The key and label stay; real holds keep their word.");
			MoveAllModifier = file.Bind<KeyCode>("Easy Key", "MoveAllModifier", (KeyCode)306, "The modifier held to move every stack of a type. LeftControl also crouches and is a menu click modifier in the game; both firing is harmless.");
			MoveAllOnModifier = file.Bind<bool>("Easy Key", "MoveAllOnModifier", true, "True puts move-all on the modified click and one stack on the plain click. False swaps the two.");
			DropAllModifier = file.Bind<KeyCode>("Easy Key", "DropAllModifier", (KeyCode)306, "The modifier held while pressing the game's drop key to drop every stack of a type. Held drops all; the plain drop key still drops one. LeftControl also crouches and is a menu click modifier in the game; both firing is harmless.");
			AutoMoveTapWindowMs = file.Bind<int>("Easy Key", "AutoMoveTapWindowMs", 300, "How long, in milliseconds, the second tap of a movement key has to arrive to count as a double-tap.");
			file.SettingChanged += OnSettingChanged;
			MasterEnabled = Enabled.Value;
			MoveAllModifierOn = MasterEnabled && MoveAllModifierEnabled.Value;
			DropAllModifierOn = MasterEnabled && DropAllModifierEnabled.Value;
			InstantMultiPickupOn = MasterEnabled && InstantMultiPickupEnabled.Value;
			TapGatherOn = MasterEnabled && TapGatherEnabled.Value;
			TapHarvestOn = MasterEnabled && TapHarvestEnabled.Value;
			TapBuildOn = MasterEnabled && TapBuildEnabled.Value;
			TapDrinkOn = MasterEnabled && TapDrinkEnabled.Value;
			TapFireOn = MasterEnabled && TapFireEnabled.Value;
			AutoWorkshopsOn = MasterEnabled && AutoWorkshopsEnabled.Value;
			AutoRotateOn = MasterEnabled && AutoRotateEnabled.Value;
			AutoQuenchOn = MasterEnabled && AutoQuenchEnabled.Value;
			TapToolSwapOn = MasterEnabled && TapToolSwapEnabled.Value;
			AutoMoveOn = MasterEnabled && AutoMoveEnabled.Value;
			HoldPromptStripOn = MasterEnabled && HoldPromptStripEnabled.Value;
		}

		internal static void MarkLoadComplete()
		{
			_loadComplete = true;
		}

		private static ConfigEntry<T> BindReload<T>(ConfigFile file, string key, T defaultValue, string description)
		{
			ConfigEntry<T> val = file.Bind<T>("Easy Key", key, defaultValue, description + " Applies on the next launch: a change made while the game is running is ignored.");
			ReloadOnly.Add((ConfigEntryBase)(object)val);
			return val;
		}

		private static void OnSettingChanged(object sender, SettingChangedEventArgs args)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			if (_loadComplete && ReloadOnly.Contains(args.ChangedSetting))
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(91, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(args.ChangedSetting.Definition.Key);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" was changed while the game is running. Easy Key ignores it; it applies on the next launch.");
				}
				log.LogError(val);
			}
		}
	}
	public class EasyKeyTool : MonoBehaviour
	{
		private void Start()
		{
			MoveAllStacks.WarnOnModifierOverlap();
			AutoMove.OnLocalPlayerSpawned();
		}

		private void Update()
		{
			TapToWork.Tick();
		}
	}
	[HarmonyPatch]
	public static class HoldPromptStrip
	{
		private static string _word;

		private static bool _wordResolved;

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerHarvestInteractionSession), "RefreshWidgetData")]
		public static void HarvestRefresh(PlayerHarvestInteractionSession __instance, IInteractionWidgetProvider interactWidget)
		{
			Strip((Il2CppObjectBase)(object)__instance, interactWidget);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerHarvestInteractionSession), "SetupWidget")]
		public static void HarvestSetup(PlayerHarvestInteractionSession __instance, IInteractionWidgetProvider interactWidget)
		{
			Strip((Il2CppObjectBase)(object)__instance, interactWidget);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerGatherInteractionSession), "RefreshWidgetData")]
		public static void GatherRefresh(PlayerGatherInteractionSession __instance, IInteractionWidgetProvider interactWidget)
		{
			Strip((Il2CppObjectBase)(object)__instance, interactWidget);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerGatherInteractionSession), "SetupWidget")]
		public static void GatherSetup(PlayerGatherInteractionSession __instance, IInteractionWidgetProvider interactWidget)
		{
			Strip((Il2CppObjectBase)(object)__instance, interactWidget);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerBuildInteractionSession), "RefreshWidgetData")]
		public static void BuildRefresh(PlayerBuildInteractionSession __instance, IInteractionWidgetProvider interactWidget)
		{
			Strip((Il2CppObjectBase)(object)__instance, interactWidget);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerBuildInteractionSession), "SetupWidget")]
		public static void BuildSetup(PlayerBuildInteractionSession __instance, IInteractionWidgetProvider interactWidget)
		{
			Strip((Il2CppObjectBase)(object)__instance, interactWidget);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerFireInteractionSession), "RefreshWidgetData")]
		public static void FireRefresh(PlayerFireInteractionSession __instance, IInteractionWidgetProvider interactWidget)
		{
			Strip((Il2CppObjectBase)(object)__instance, interactWidget);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerFireInteractionSession), "SetupWidget")]
		public static void FireSetup(PlayerFireInteractionSession __instance, IInteractionWidgetProvider interactWidget)
		{
			Strip((Il2CppObjectBase)(object)__instance, interactWidget);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerAnvilInteractionSession), "RefreshWidgetData")]
		public static void AnvilRefresh(PlayerAnvilInteractionSession __instance, IInteractionWidgetProvider interactWidget)
		{
			Strip((Il2CppObjectBase)(object)__instance, interactWidget);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerAnvilInteractionSession), "SetupWidget")]
		public static void AnvilSetup(PlayerAnvilInteractionSession __instance, IInteractionWidgetProvider interactWidget)
		{
			Strip((Il2CppObjectBase)(object)__instance, interactWidget);
		}

		private static void Strip(Il2CppObjectBase session, IInteractionWidgetProvider provider)
		{
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Expected O, but got Unknown
			if (!EasyKeyConfig.HoldPromptStripOn)
			{
				return;
			}
			try
			{
				IInteractionWidgetUser val = ((session == null) ? null : session.TryCast<IInteractionWidgetUser>());
				InteractWidget val2 = ((provider == null) ? null : ((Il2CppObjectBase)provider).TryCast<InteractWidget>());
				if (val == null || (Object)(object)val2 == (Object)null)
				{
					return;
				}
				Dictionary<IInteractionWidgetUser, Dictionary<int, ValueTuple<InteractSlot, InteractSlot>>> interactions = val2._interactions;
				if (interactions == null || !interactions.ContainsKey(val))
				{
					return;
				}
				Dictionary<int, ValueTuple<InteractSlot, InteractSlot>> val3 = interactions[val];
				if (val3 != null)
				{
					Enumerator<int, ValueTuple<InteractSlot, InteractSlot>> enumerator = val3.GetEnumerator();
					while (enumerator.MoveNext())
					{
						ValueTuple<InteractSlot, InteractSlot> value = enumerator.Current.Value;
						StripSlot(value.Item1);
						StripSlot(value.Item2);
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(19, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("HoldPromptStrip: ");
					((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(ex.GetType().Name);
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(": ");
					((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(ex.Message);
				}
				log.LogWarning(val4);
			}
		}

		private static void StripSlot(InteractSlot slot)
		{
			if ((Object)(object)slot == (Object)null || !slot._requiresHold)
			{
				return;
			}
			TMP_Text keyText = slot.keyText;
			if ((Object)(object)keyText == (Object)null)
			{
				return;
			}
			string text = keyText.text;
			if (string.IsNullOrEmpty(text))
			{
				return;
			}
			string text2 = HoldWord();
			if (!string.IsNullOrEmpty(text2) && text.IndexOf(text2, StringComparison.Ordinal) >= 0)
			{
				string text3 = Regex.Replace(text.Replace(text2, ""), "\\s+", " ").Trim();
				if (text3 != text)
				{
					keyText.text = text3;
				}
			}
		}

		private static string HoldWord()
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			if (_wordResolved)
			{
				return _word;
			}
			_wordResolved = true;
			try
			{
				LocalizationManager instance = LocalizationManager.Instance;
				if ((Object)(object)instance != (Object)null)
				{
					string text = instance.Loc("misc.ui_hold_format", false);
					if (!string.IsNullOrEmpty(text))
					{
						_word = text.Replace("{0}", "").Trim();
					}
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(43, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("HoldPromptStrip: hold word lookup threw: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.GetType().Name);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
				}
				log.LogWarning(val);
			}
			if (string.IsNullOrEmpty(_word))
			{
				_word = "Hold";
			}
			return _word;
		}
	}
	[HarmonyPatch]
	public static class MoveAllStacks
	{
		public sealed class ClickState
		{
			internal int InfoId { get; }

			internal string ItemName { get; }

			internal BaseContainerPanel Source { get; }

			internal Item ClickedItem { get; }

			internal IntPtr ClickedContainer { get; }

			internal int ClickedCount { get; }

			internal ClickState(int infoId, string itemName, BaseContainerPanel source, Item clickedItem)
			{
				InfoId = infoId;
				ItemName = itemName;
				Source = source;
				ClickedItem = clickedItem;
				ClickedContainer = PointerOf((Il2CppObjectBase)(object)clickedItem.Container);
				ClickedCount = clickedItem.count;
			}
		}

		private static bool _moving;

		private static bool _overlapChecked;

		[HarmonyPrefix]
		[HarmonyPatch(typeof(ItemThumbnailPanel), "OnCustomAction1")]
		public static void BeforeCustomAction1(ItemThumbnailPanel __instance, out ClickState __state)
		{
			__state = null;
			if (!EasyKeyConfig.MoveAllModifierOn || _moving || !MeansAllStacks() || (Object)(object)__instance == (Object)null)
			{
				return;
			}
			BaseContainerPanel parent = __instance.parent;
			if ((Object)(object)parent == (Object)null)
			{
				return;
			}
			Item item = __instance.Item;
			if (item != null)
			{
				ItemInfo info = item.info;
				if (!((Object)(object)info == (Object)null))
				{
					__state = new ClickState(info.id, ((Object)info).name, parent, item);
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ItemThumbnailPanel), "OnCustomAction1")]
		public static void AfterCustomAction1(ItemThumbnailPanel __instance, ClickState __state)
		{
			if (__state != null)
			{
				MoveRemainingStacks(__instance, __state);
			}
		}

		private static bool MeansAllStacks()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return Input.GetKey(EasyKeyConfig.MoveAllModifier.Value) == EasyKeyConfig.MoveAllOnModifier.Value;
		}

		private static void MoveRemainingStacks(ItemThumbnailPanel clicked, ClickState state)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f8: Expected O, but got Unknown
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Expected O, but got Unknown
			bool flag = default(bool);
			if (!Moved(state.ClickedItem, state.ClickedContainer, state.ClickedCount))
			{
				ManualLogSource log = Plugin.Log;
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(209, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("MoveAll: 0 stacks of ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(state.ItemName);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" moved. The clicked stack did not move in this call, so no stack followed it. The game calls OnCustomAction1 twice per click and only one call moves; a full destination reads the same way.");
				}
				log.LogInfo(val);
				return;
			}
			StorageMenu val2 = ResolveMenu(state.Source);
			if ((Object)(object)val2 == (Object)null)
			{
				ManualLogSource log2 = Plugin.Log;
				BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(100, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("MoveAll: 1 stack of ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(state.ItemName);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" moved. No StorageMenu owns this panel, so the remaining stacks were left alone.");
				}
				log2.LogWarning(val3);
				return;
			}
			List<ItemThumbnailPanel> list = SnapshotMatchingPanels(clicked, state);
			int num = 1;
			int num2 = 0;
			bool flag2 = false;
			_moving = true;
			try
			{
				foreach (ItemThumbnailPanel item2 in list)
				{
					if (!StillEligible(item2, state, out var item))
					{
						num2++;
						continue;
					}
					IntPtr beforeContainer = PointerOf((Il2CppObjectBase)(object)item.Container);
					int count = item.count;
					val2.SwitchContainer(item2);
					if (!Moved(item, beforeContainer, count))
					{
						flag2 = true;
						break;
					}
					num++;
				}
			}
			finally
			{
				_moving = false;
			}
			string text = $" candidates={list.Count} skipped={num2}";
			if (flag2)
			{
				ManualLogSource log3 = Plugin.Log;
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(80, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("MoveAll: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" stacks of ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(state.ItemName);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" moved. The game refused the next one, so the rest stay put.");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
				}
				log3.LogInfo(val);
			}
			else
			{
				ManualLogSource log4 = Plugin.Log;
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(27, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("MoveAll: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" stacks of ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(state.ItemName);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" moved.");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text);
				}
				log4.LogInfo(val);
			}
		}

		private static List<ItemThumbnailPanel> SnapshotMatchingPanels(ItemThumbnailPanel clicked, ClickState state)
		{
			List<ItemThumbnailPanel> list = new List<ItemThumbnailPanel>();
			foreach (ItemThumbnailPanel componentsInChild in ((Component)state.Source).GetComponentsInChildren<ItemThumbnailPanel>())
			{
				if (!((Object)(object)componentsInChild == (Object)null) && !(PointerOf((Il2CppObjectBase)(object)componentsInChild) == PointerOf((Il2CppObjectBase)(object)clicked)) && Matches(componentsInChild, state))
				{
					list.Add(componentsInChild);
				}
			}
			return list;
		}

		private static bool StillEligible(ItemThumbnailPanel panel, ClickState state, out Item item)
		{
			item = null;
			if ((Object)(object)panel == (Object)null || PointerOf((Il2CppObjectBase)(object)panel.parent) != PointerOf((Il2CppObjectBase)(object)state.Source))
			{
				return false;
			}
			if (!Matches(panel, state))
			{
				return false;
			}
			item = panel.Item;
			return item.Container != null;
		}

		private static bool Matches(ItemThumbnailPanel panel, ClickState state)
		{
			Item item = panel.Item;
			if (item == null)
			{
				return false;
			}
			ItemInfo info = item.info;
			if ((Object)(object)info != (Object)null)
			{
				return info.id == state.InfoId;
			}
			return false;
		}

		private static bool Moved(Item item, IntPtr beforeContainer, int beforeCount)
		{
			if (item == null)
			{
				return true;
			}
			if (PointerOf((Il2CppObjectBase)(object)item.Container) != beforeContainer)
			{
				return true;
			}
			return item.count < beforeCount;
		}

		private static StorageMenu ResolveMenu(BaseContainerPanel source)
		{
			StorageMenu componentInParent = ((Component)source).GetComponentInParent<StorageMenu>();
			if ((Object)(object)componentInParent != (Object)null)
			{
				return componentInParent;
			}
			Menu val = (((Object)(object)MenuManager.Instance == (Object)null) ? null : MenuManager.Instance.PeekMenuStack);
			componentInParent = (((Object)(object)val == (Object)null) ? null : ((Il2CppObjectBase)val).TryCast<StorageMenu>());
			if ((Object)(object)componentInParent != (Object)null)
			{
				Plugin.Log.LogInfo((object)"MoveAll: the panel has no StorageMenu above it; the top of the menu stack answered instead.");
			}
			return componentInParent;
		}

		private static IntPtr PointerOf(Il2CppObjectBase obj)
		{
			if (obj != null)
			{
				return obj.Pointer;
			}
			return IntPtr.Zero;
		}

		internal static void WarnOnModifierOverlap()
		{
			//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_0020: 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)
			//IL_003e: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Expected O, but got Unknown
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Expected O, but got Unknown
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Expected O, but got Unknown
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: 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)
			if (_overlapChecked || !EasyKeyConfig.MoveAllModifierOn)
			{
				return;
			}
			_overlapChecked = true;
			KeyCode value = EasyKeyConfig.MoveAllModifier.Value;
			bool flag = default(bool);
			BepInExWarningLogInterpolatedStringHandler val;
			if (!TryControlPath(value, out var path))
			{
				ManualLogSource log = Plugin.Log;
				val = new BepInExWarningLogInterpolatedStringHandler(176, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("MoveAll: ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<KeyCode>(value);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" has no Input System control path, so its overlap with the game's own bindings was not checked. The modifier itself still works; it is read from the keyboard directly.");
				}
				log.LogWarning(val);
				return;
			}
			Controls controls = InputManager.controls;
			InputActionAsset val2 = ((controls != null) ? controls.asset : null);
			if ((Object)(object)val2 == (Object)null)
			{
				ManualLogSource log2 = Plugin.Log;
				BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(82, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("MoveAll: InputManager.controls.asset is null, so the overlap for ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<KeyCode>(value);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" was not checked.");
				}
				log2.LogError(val3);
				return;
			}
			List<string> list = ActionsBoundTo(val2, path);
			if (list.Count == 0)
			{
				ManualLogSource log3 = Plugin.Log;
				BepInExInfoLogInterpolatedStringHandler val4 = new BepInExInfoLogInterpolatedStringHandler(53, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("MoveAll: the modifier ");
					((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<KeyCode>(value);
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" (");
					((BepInExLogInterpolatedStringHandler)val4).AppendFormatted<string>(path);
					((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(") is bound to no game action.");
				}
				log3.LogInfo(val4);
				return;
			}
			ManualLogSource log4 = Plugin.Log;
			val = new BepInExWarningLogInterpolatedStringHandler(162, 3, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("MoveAll: the modifier ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<KeyCode>(value);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(path);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(") is also bound to ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(string.Join(", ", list));
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(". Both the game and Easy Key read it and both fire; that overlap is accepted. Change MoveAllModifier if it bothers you.");
			}
			log4.LogWarning(val);
		}

		private static List<string> ActionsBoundTo(InputActionAsset asset, string path)
		{
			List<string> list = new List<string>();
			ReadOnlyArray<InputActionMap> actionMaps = asset.actionMaps;
			for (int i = 0; i < actionMaps.Count; i++)
			{
				InputActionMap val = actionMaps[i];
				ReadOnlyArray<InputAction> actions = val.actions;
				for (int j = 0; j < actions.Count; j++)
				{
					InputAction val2 = actions[j];
					ReadOnlyArray<InputBinding> bindings = val2.bindings;
					for (int k = 0; k < bindings.Count; k++)
					{
						if (!(bindings[k].effectivePath != path))
						{
							list.Add(val.name + "/" + val2.name);
							break;
						}
					}
				}
			}
			return list;
		}

		private unsafe static bool TryControlPath(KeyCode key, out string path)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Invalid comparison between Unknown and I4
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Expected I4, but got Unknown
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			path = null;
			string text = ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString();
			if (text.StartsWith("Alpha", StringComparison.Ordinal))
			{
				text = "Digit" + text.Substring(5);
			}
			else if (text.StartsWith("Keypad", StringComparison.Ordinal))
			{
				text = "Numpad" + text.Substring(6);
			}
			if ((int)key != 13)
			{
				switch (key - 305)
				{
				case 1:
					text = "LeftCtrl";
					break;
				case 0:
					text = "RightCtrl";
					break;
				case 5:
					text = "LeftMeta";
					break;
				case 4:
					text = "RightMeta";
					break;
				}
			}
			else
			{
				text = "Enter";
			}
			if (!Enum.TryParse<Key>(text, ignoreCase: false, out Key result) || (int)result == 0)
			{
				return false;
			}
			path = "<Keyboard>/" + char.ToLowerInvariant(text[0]) + text.Substring(1);
			return true;
		}
	}
	[HarmonyPatch]
	public static class PickupSlots
	{
		private const int LoggedInstances = 3;

		private static int _proxiesPromoted;

		private static int _pickupsRetired;

		private static PlayerMultiInteractionConfig _holdConfig;

		private static bool _holdInputOriginal;

		private static bool _holdInputCleared;

		[HarmonyPostfix]
		[HarmonyPatch(typeof(MultiInteractionProxy), "Start")]
		public static void AfterProxyStart(MultiInteractionProxy __instance)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			if (!EasyKeyConfig.InstantMultiPickupOn || (Object)(object)__instance == (Object)null)
			{
				return;
			}
			((Interaction)__instance).order = (InteractionOrder)0;
			_proxiesPromoted++;
			if (_proxiesPromoted <= 3)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(53, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("PickupSlots: MultiInteractionProxy order=PRIMARY (#");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(_proxiesPromoted);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(").");
				}
				log.LogInfo(val);
			}
			ClearHoldInputOnce();
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Interaction), "OnEnable")]
		public static void AfterInteractionOnEnable(Interaction __instance)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			if (!EasyKeyConfig.InstantMultiPickupOn || (Object)(object)__instance == (Object)null || (Object)(object)((Il2CppObjectBase)__instance).TryCast<PickupInteraction>() == (Object)null || (int)__instance.order != 0 || (Object)(object)((Component)__instance).GetComponent<MultiInteractionProxy>() == (Object)null)
			{
				return;
			}
			__instance.order = (InteractionOrder)8;
			_pickupsRetired++;
			if (_pickupsRetired <= 3)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(48, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("PickupSlots: PickupInteraction order=IGNORE (#");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(_pickupsRetired);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(").");
				}
				log.LogInfo(val);
			}
		}

		private static void ClearHoldInputOnce()
		{
			if (_holdInputCleared)
			{
				return;
			}
			foreach (Object item in (Il2CppArrayBase<Object>)(object)Resources.FindObjectsOfTypeAll(Il2CppType.Of<PlayerMultiInteractionConfig>()))
			{
				PlayerMultiInteractionConfig val = ((Il2CppObjectBase)item).TryCast<PlayerMultiInteractionConfig>();
				if (!((Object)(object)val == (Object)null))
				{
					_holdConfig = val;
					_holdInputOriginal = val._usesHoldInput;
					val._usesHoldInput = false;
					_holdInputCleared = true;
					Plugin.Log.LogInfo((object)($"PickupSlots: PlayerMultiInteractionConfig._usesHoldInput {_holdInputOriginal} to False. " + "The multi-pickup prompt is a press."));
					break;
				}
			}
		}

		internal static void RestoreHoldInput()
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			if (!_holdInputCleared)
			{
				return;
			}
			_holdInputCleared = false;
			if ((Object)(object)_holdConfig == (Object)null)
			{
				Plugin.Log.LogWarning((object)"PickupSlots: the multi-interaction configuration is gone, so _usesHoldInput was not restored. It is not persisted, so the next launch reads the shipped value.");
				_holdConfig = null;
				return;
			}
			_holdConfig._usesHoldInput = _holdInputOriginal;
			ManualLogSource log = Plugin.Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(70, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("PickupSlots: PlayerMultiInteractionConfig._usesHoldInput restored to ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(_holdInputOriginal);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".");
			}
			log.LogInfo(val);
			_holdConfig = null;
		}
	}
	[BepInPlugin("mugsy33.easykey", "Easy Key", "0.1.0")]
	public class Plugin : BasePlugin
	{
		public const string PluginGuid = "mugsy33.easykey";

		public const string PluginName = "Easy Key";

		public const string PluginVersion = "0.1.0";

		internal static ManualLogSource Log;

		internal static readonly bool DebugLogging;

		public override void Load()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_030d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0313: Expected O, but got Unknown
			//IL_0341: Unknown result type (might be due to invalid IL or missing references)
			//IL_0347: Expected O, but got Unknown
			Log = ((BasePlugin)this).Log;
			EasyKeyConfig.Init(((BasePlugin)this).Config);
			ManualLogSource log = Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(264, 16, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("Easy Key");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": resolved switches - MasterEnabled=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(EasyKeyConfig.MasterEnabled);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", ");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("MoveAllModifierOn=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(EasyKeyConfig.MoveAllModifierOn);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", ");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("DropAllModifierOn=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(EasyKeyConfig.DropAllModifierOn);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", ");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("InstantMultiPickupOn=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(EasyKeyConfig.InstantMultiPickupOn);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", ");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TapGatherOn=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(EasyKeyConfig.TapGatherOn);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", TapHarvestOn=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(EasyKeyConfig.TapHarvestOn);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", ");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TapBuildOn=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(EasyKeyConfig.TapBuildOn);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", TapDrinkOn=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(EasyKeyConfig.TapDrinkOn);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", ");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TapFireOn=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(EasyKeyConfig.TapFireOn);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", AutoWorkshopsOn=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(EasyKeyConfig.AutoWorkshopsOn);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", ");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("AutoRotateOn=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(EasyKeyConfig.AutoRotateOn);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", AutoQuenchOn=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(EasyKeyConfig.AutoQuenchOn);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", ");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TapToolSwapOn=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(EasyKeyConfig.TapToolSwapOn);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", ");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("AutoMoveOn=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(EasyKeyConfig.AutoMoveOn);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", ");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("HoldPromptStripOn=");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(EasyKeyConfig.HoldPromptStripOn);
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".");
			}
			log.LogInfo(val);
			ClassInjector.RegisterTypeInIl2Cpp<EasyKeyTool>();
			if (EasyKeyConfig.MasterEnabled)
			{
				Harmony.CreateAndPatchAll(typeof(CharacterSpawnPatch), (string)null);
				Harmony.CreateAndPatchAll(typeof(PickupSlots), (string)null);
				Harmony.CreateAndPatchAll(typeof(MoveAllStacks), (string)null);
				Harmony.CreateAndPatchAll(typeof(DropAllStacks), (string)null);
				Harmony.CreateAndPatchAll(typeof(TapToWorkHarvest), (string)null);
				Harmony.CreateAndPatchAll(typeof(TapToWorkGather), (string)null);
				Harmony.CreateAndPatchAll(typeof(TapToWorkBuild), (string)null);
				Harmony.CreateAndPatchAll(typeof(TapToWorkAnvil), (string)null);
				Harmony.CreateAndPatchAll(typeof(AnvilHoldInput), (string)null);
				Harmony.CreateAndPatchAll(typeof(TapToWorkDrink), (string)null);
				Harmony.CreateAndPatchAll(typeof(TapToWorkFire), (string)null);
				Harmony.CreateAndPatchAll(typeof(TapToWorkMatchTarget), (string)null);
				Harmony.CreateAndPatchAll(typeof(AutoMove), (string)null);
				Harmony.CreateAndPatchAll(typeof(HoldPromptStrip), (string)null);
			}
			else
			{
				ManualLogSource log2 = Log;
				val = new BepInExInfoLogInterpolatedStringHandler(74, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("Easy Key");
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": Enabled=false. No patch is installed and nothing in the game is changed.");
				}
				log2.LogInfo(val);
			}
			EasyKeyConfig.MarkLoadComplete();
			ManualLogSource log3 = Log;
			val = new BepInExInfoLogInterpolatedStringHandler(10, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("Easy Key");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" v");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("0.1.0");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" loaded.");
			}
			log3.LogInfo(val);
		}

		public override bool Unload()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			ManualLogSource log = Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(15, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("Easy Key");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": Unload fired.");
			}
			log.LogInfo(val);
			PickupSlots.RestoreHoldInput();
			return ((BasePlugin)this).Unload();
		}
	}
	internal static class TapToWork
	{
		private const float BridgeSeconds = 0.75f;

		private const int SwapHoldMilliseconds = 600;

		private const int SwapStartFrames = 3;

		private const float TapMilliseconds = 150f;

		private const int MaxActionLines = 8;

		private static InteractionSession _session;

		private static IntPtr _sessionPointer;

		private static string _kind;

		private static bool _armed;

		private static bool _stopRequested;

		private static bool _bridging;

		private static float _bridgeUntil;

		private static int _bridgeFrames;

		private static bool _promoteArmed;

		private static int _promoteArmedFrame = -1;

		private static bool _matchTargetAccepted;

		private static IntPtr _promotedPointer;

		private static bool _inPromotion;

		private static float _pressStart;

		private static bool _actionRunning;

		private static int _actionTransitions;

		private static bool _watchLost;

		private static bool _swapPending;

		private static EquipmentItem _resolvedTool;

		private static int _equipLandedFrame = -1;

		private static string _swapHandName;

		private static string _swapResolvedName;

		private static CallbackContext _storedAbortContext;

		private static bool _hasStoredAbort;

		private static bool _replayingAbort;

		private const float DrinkFullNormalized = 0.99f;

		private static bool _waterWatchLost;

		private static int _autoRotateLastInput = 1;

		private static bool _anvilHoldActive;

		private static IntPtr _anvilHoldActionPointer;

		internal static void ArmPromotion(object session)
		{
			InteractionSession val = (InteractionSession)((session is InteractionSession) ? session : null);
			bool started = default(bool);
			if (val != null && !(_armed && ((Il2CppObjectBase)val).Pointer == _sessionPointer && TryActionStarted((Il2CppObjectBase)(object)val, out started) && started))
			{
				_promoteArmed = true;
				_promoteArmedFrame = Time.frameCount;
				_matchTargetAccepted = false;
			}
		}

		internal static void NoteMatchTargetResult(bool result)
		{
			if (_promoteArmed)
			{
				_promoteArmed = false;
				if (Time.frameCount == _promoteArmedFrame)
				{
					_matchTargetAccepted = result;
				}
			}
		}

		internal static void Started(object session)
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Expected O, but got Unknown
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Expected O, but got Unknown
			InteractionSession val = (InteractionSession)((session is InteractionSession) ? session : null);
			if (val == null)
			{
				return;
			}
			_pressStart = Time.realtimeSinceStartup;
			bool flag = default(bool);
			if (_armed && ((Il2CppObjectBase)val).Pointer == _sessionPointer)
			{
				if (TryActionStarted((Il2CppObjectBase)(object)val, out var started) && started)
				{
					StopRequested(session);
					return;
				}
				ManualLogSource log = Plugin.Log;
				BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(117, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TapToWork: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(_kind);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" re-armed on the same session, the game had ended the previous action, so this press is a fresh first tap.");
				}
				log.LogInfo(val2);
			}
			else if (_armed)
			{
				ManualLogSource log2 = Plugin.Log;
				BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(143, 4, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TapToWork: a ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(Kind((Il2CppObjectBase)(object)val));
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" session took over from the armed ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(_kind);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" one, incoming interaction instance ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(InteractionIdentity(val));
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", ");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("armed interaction instance ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(InteractionIdentity(_session));
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", so the old toggle is cleared.");
				}
				log2.LogInfo(val2);
			}
			if (((Il2CppObjectBase)val).Pointer != _sessionPointer)
			{
				_autoRotateLastInput = 1;
			}
			_session = val;
			_sessionPointer = ((Il2CppObjectBase)val).Pointer;
			_kind = Kind((Il2CppObjectBase)(object)val);
			_armed = true;
			_stopRequested = false;
			_actionRunning = false;
			_actionTransitions = 0;
			_watchLost = false;
			_promotedPointer = IntPtr.Zero;
			ClearSwapState();
			if (Engage())
			{
				_bridging = true;
				_bridgeUntil = Time.time + 0.75f;
				_bridgeFrames = 0;
				ManualLogSource log3 = Plugin.Log;
				BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(53, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TapToWork: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(_kind);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" first tap, engaged interaction instance ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(InteractionIdentity(val));
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(".");
				}
				log3.LogInfo(val2);
				Promote(val);
				if (EasyKeyConfig.TapToolSwapOn)
				{
					EvaluateSwapHold((Il2CppObjectBase)(object)val);
				}
			}
		}

		private static void EvaluateSwapHold(Il2CppObjectBase session)
		{
			InteractionSession session2 = session.TryCast<InteractionSession>();
			EquipmentItem val;
			try
			{
				val = ResolvedEquipment(session);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)($"TapToWork: reading _equippedEquipment for the swap hold threw {ex.GetType().Name}: {ex.Message}. " + "No swap hold is armed for this tap."));
				return;
			}
			if (val != null)
			{
				bool flag = SafeIsEquipped(val);
				bool readable;
				bool flag2 = SwapToolInHandByEquipPoint(session2, val, out readable);
				if (readable ? (!flag2) : (!flag))
				{
					_swapPending = true;
					_resolvedTool = val;
					_equipLandedFrame = -1;
					_hasStoredAbort = false;
					_swapResolvedName = ItemNameOf(val);
					_swapHandName = HandItemName(session2);
					Plugin.Log.LogInfo((object)($"TapToWork: {_kind} swap hold armed, resolved tool {_swapResolvedName} is not in hand (!IsEquipped()={!flag}, equip-point[0] mismatch={(readable ? (!flag2).ToString() : "unreadable")}). " + "The abort is swallowed and the game's own completion refused until the tool is equipped."));
				}
			}
		}

		private static EquipmentItem ResolvedEquipment(Il2CppObjectBase session)
		{
			PlayerHarvestInteractionSession val = session.TryCast<PlayerHarvestInteractionSession>();
			if (val != null)
			{
				return val._equippedEquipment;
			}
			PlayerBuildInteractionSession val2 = session.TryCast<PlayerBuildInteractionSession>();
			if (val2 != null)
			{
				return val2._equippedEquipment;
			}
			PlayerAnvilInteractionSession val3 = session.TryCast<PlayerAnvilInteractionSession>();
			if (val3 != null)
			{
				return val3._equippedEquipment;
			}
			return null;
		}

		private static bool SafeIsEquipped(EquipmentItem item)
		{
			try
			{
				return item.IsEquipped();
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)($"TapToWork: IsEquipped() for the swap hold threw {ex.GetType().Name}: {ex.Message}. " + "The item is read as in hand, so no swap hold is armed on this test."));
				return true;
			}
		}

		private static bool SwapToolInHandByEquipPoint(InteractionSession session, EquipmentItem resolved, out bool readable)
		{
			readable = false;
			try
			{
				PlayerInteractionAgent val = ((session.Agent == null) ? null : ((Il2CppObjectBase)session.Agent).TryCast<PlayerInteractionAgent>());
				if ((Object)(object)val == (Object)null)
				{
					return false;
				}
				EquipmentManager equipmentManager = val.GetEquipmentManager();
				if ((Object)(object)equipmentManager == (Object)null)
				{
					return false;
				}
				List<EquipPoint> equipPoints = equipmentManager.equipPoints;
				if (equipPoints == null || equipPoints.Count == 0)
				{
					return false;
				}
				EquipmentItem item = equipPoints[0]._item;
				readable = true;
				return item != null && ((Il2CppObjectBase)item).Pointer == ((Il2CppObjectBase)resolved).Pointer;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)($"TapToWork: reading equip point [0] for the swap hold threw {ex.GetType().Name}: {ex.Message}. " + "The IsEquipped() test decides this tap instead."));
				readable = false;
				return false;
			}
		}

		private static string HandItemName(InteractionSession session)
		{
			try
			{
				if (session == null)
				{
					return "unknown, no session";
				}
				PlayerInteractionAgent val = ((session.Agent == null) ? null : ((Il2CppObjectBase)session.Agent).TryCast<PlayerInteractionAgent>());
				if ((Object)(object)val == (Object)null)
				{
					return "unknown, no PlayerInteractionAgent";
				}
				EquipmentManager equipmentManager = val.GetEquipmentManager();
				if ((Object)(object)equipmentManager == (Object)null)
				{
					return "unknown, no EquipmentManager";
				}
				List<EquipPoint> equipPoints = equipmentManager.equipPoints;
				if (equipPoints == null || equipPoints.Count == 0)
				{
					return "unknown, no equip points";
				}
				EquipmentItem item = equipPoints[0]._item;
				return (item == null) ? "an empty hand" : ItemNameOf(item);
			}
			catch (Exception ex)
			{
				return "unknown (" + ex.GetType().Name + ")";
			}
		}

		private static string ItemNameOf(EquipmentItem item)
		{
			try
			{
				if (item == null)
				{
					return "nothing";
				}
				ItemInfo info = ((Item)item).info;
				return ((Object)(object)info == (Object)null) ? "an item with no ItemInfo" : ((Object)info).name;
			}
			catch (Exception ex)
			{
				return "unknown (" + ex.GetType().Name + ")";
			}
		}

		internal static void CaptureAbortContext(object session, CallbackContext obj)
		{
			InteractionSession val = (InteractionSession)((session is InteractionSession) ? session : null);
			if (val != null && _armed && !(((Il2CppObjectBase)val).Pointer != _sessionPointer))
			{
				_storedAbortContext = obj;
				_hasStoredAbort = true;
			}
		}

		internal static void AutoRotateBillet(AnvilInteraction anvil)
		{
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Expected O, but got Unknown
			//IL_0012: 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_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: 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)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Expected O, but got Unknown
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			if (!EasyKeyConfig.AutoRotateOn || !ArmedAnvilMatches(anvil))
			{
				return;
			}
			bool flag = default(bool);
			try
			{
				DieRotationAxis allowedRotationAxis = anvil.allowedRotationAxis;
				if ((int)allowedRotationAxis == 0 || !anvil.HasHotIron || anvil.IsConsolidated || anvil._rotationRoutine != null)
				{
					return;
				}
				Transform dieHandleTransform = anvil.dieHandleTransform;
				if ((Object)(object)dieHandleTransform == (Object)null)
				{
					return;
				}
				Item hotItem = anvil._hotItem;
				if (hotItem == null)
				{
					return;
				}
				int num = CurrentDieFaceId(dieHandleTransform);
				float num2 = default(float);
				if (!hotItem.TryGetPropertyValue(ref num, ref num2) || !(num2 > 0f))
				{
					DieRotationAxis val = ChooseRotationAxis(allowedRotationAxis, _autoRotateLastInput = ((_autoRotateLastInput <= 0) ? 1 : (-1)));
					anvil.RotateBillet(ref val);
					ManualLogSource log = Plugin.Log;
					BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(90, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TapToWork: auto-rotated the billet on the finishing hit (axis ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<DieRotationAxis>(val);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("), the game's own turn rule.");
					}
					log.LogInfo(val2);
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log2 = Plugin.Log;
				BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(66, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("TapToWork: auto-rotate threw ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(ex.GetType().Name);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(": ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(ex.Message);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(". The rotate is left to the player.");
				}
				log2.LogWarning(val3);
			}
		}

		private static bool ArmedAnvilMatches(AnvilInteraction anvil)
		{
			if ((Object)(object)anvil == (Object)null || !_armed || _session == null)
			{
				return false;
			}
			Interaction interaction = _session.Interaction;
			if (interaction != null)
			{
				return ((Il2CppObjectBase)interaction).Pointer == ((Il2CppObjectBase)anvil).Pointer;
			}
			return false;
		}

		private static DieRotationAxis ChooseRotationAxis(DieRotationAxis allowed, int rotateInput)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: 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_0008: Invalid comparison between Unknown and I4
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (allowed - 1 <= 1 || (int)allowed == 4)
			{
				return allowed;
			}
			if (rotateInput > 0)
			{
				return (DieRotationAxis)1;
			}
			return (DieRotationAxis)4;
		}

		private static int CurrentDieFaceId(Transform die)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: 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_0023: 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)
			float num = Vector3.Dot(die.up, Vector3.up);
			float num2 = Vector3.Dot(die.right, Vector3.up);
			float num3 = Vector3.Dot(die.forward, Vector3.up);
			float num4 = Math.Abs(num);
			float num5 = Math.Abs(num2);
			float num6 = Math.Abs(num3);
			if (num4 > num5 && num4 > num6)
			{
				return 1024 + ((num <= 0f) ? 1 : 0);
			}
			if (num5 > num4 && num5 > num6)
			{
				return 1026 + ((num2 <= 0f) ? 1 : 0);
			}
			return 1028 + ((num3 <= 0f) ? 1 : 0);
		}

		internal static void AutoQuenchOrStop(AnvilInteraction anvil)
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Expected O, but got Unknown
			if (!ArmedAnvilMatches(anvil))
			{
				return;
			}
			try
			{
				if (anvil.IsConsolidated)
				{
					if (EasyKeyConfig.AutoQuenchOn && (Object)(object)anvil.troughInteraction != (Object)null)
					{
						anvil.SendToQuenching(_session.Agent);
						Plugin.Log.LogInfo((object)"TapToWork: auto-quenched the finished piece, which ends the session.");
					}
					else
					{
						_anvilHoldActive = false;
						((Interaction)anvil).Finish(_session.Agent, (InteractionSessionState)8);
						Plugin.Log.LogInfo((object)"TapToWork: piece complete, stopped the work; quench it manually.");
					}
					Clear();
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(60, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TapToWork: auto-quench or stop threw ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.GetType().Name);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(". Left to the player.");
				}
				log.LogWarning(val);
			}
		}

		internal static void EvaluateAnvilHold(PlayerAnvilInteractionSession anvil)
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Expected O, but got Unknown
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Invalid comparison between Unknown and I4
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			_anvilHoldActive = false;
			_anvilHoldActionPointer = IntPtr.Zero;
			if (anvil == null || !_armed || ((Il2CppObjectBase)anvil).Pointer != _sessionPointer)
			{
				return;
			}
			try
			{
				AnvilInteraction interaction = anvil.Interaction;
				if (interaction != null && (int)((Interaction)interaction).mode == 1)
				{
					InputAction action = InputManager.GetAction(((Interaction)interaction).order);
					if (action != null)
					{
						_anvilHoldActionPointer = ((Il2CppObjectBase)action).Pointer;
						_anvilHoldActive = true;
						Plugin.Log.LogInfo((object)"TapToWork: anvil ACTION-mode work (the woodworking cut) - holding its input so it keeps working with the key released.");
					}
				}
			}
			catch (Exception ex)
			{
				_anvilHoldActive = false;
				_anvilHoldActionPointer = IntPtr.Zero;
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(110, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TapToWork: evaluating the anvil held-input spoof threw ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.GetType().Name);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(". The work is left on the vanilla key-held behaviour.");
				}
				log.LogWarning(val);
			}
		}

		internal static bool ShouldHoldAnvilCut(InputAction action)
		{
			if (!_anvilHoldActive)
			{
				return false;
			}
			if (action == null || ((Il2CppObjectBase)action).Pointer != _anvilHoldActionPointer)
			{
				return false;
			}
			if (!_armed || _stopRequested || _session == null)
			{
				return false;
			}
			bool started;
			return TryActionStarted((Il2CppObjectBase)(object)_session, out started) && started;
		}

		internal static void NoteItemEquipped(object session, EquipmentItem obj)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			InteractionSession val = (InteractionSession)((session is InteractionSession) ? session : null);
			if (val != null && _swapPending && !(((Il2CppObjectBase)val).Pointer != _sessionPointer) && _resolvedTool != null && obj != null && !(((Il2CppObjectBase)obj).Pointer != ((Il2CppObjectBase)_resolvedTool).Pointer))
			{
				_equipLandedFrame = Time.frameCount;
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(135, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TapToWork: harvest swap hold, the resolved tool ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ItemNameOf(obj));
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" was equipped ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(SincePress());
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" after the tap. ");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("The bridge waits up to ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(3);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" frame(s) for the action to start.");
				}
				log.LogInfo(val2);
			}
		}

		private static void Promote(InteractionSession self)
		{
			bool matchTargetAccepted = _matchTargetAccepted;
			_matchTargetAccepted = false;
			if (!matchTargetAccepted)
			{
				Plugin.Log.LogInfo((object)("TapToWork: the " + _kind + " tap is not promoted, because the game did not accept a match target for it. The stock path runs unchanged and this tap needs the key held."));
				return;
			}
			Plugin.Log.LogInfo((object)($"TapToWork: {_kind} promoting, calling the session's own match-target callback with success=true {SincePress()} after the tap, with the key still down, on interaction instance {InteractionIdentity(self)}. Distance to matchTargetPos: {MatchTargetDistance(self)}. Equipped: {EquippedItem((Il2CppObjectBase)(object)self)}. " + "The game's own completion arrives about a quarter second later and is refused."));
			_promotedPointer = ((Il2CppObjectBase)self).Pointer;
			try
			{
				_inPromotion = true;
				if (!CallMatchTargetCallback((Il2CppObjectBase)(object)self))
				{
					_promotedPointer = IntPtr.Zero;
					Plugin.Log.LogWarning((object)("TapToWork: the " + _kind + " session has no match-target callback Easy Key knows, so the tap is left to the game."));
				}
			}
			catch (Exception ex)
			{
				_promotedPointer = IntPtr.Zero;
				Plugin.Log.LogError((object)($"TapToWork: the {_kind} match-target callback threw {ex.GetType().Name}: {ex.Message}. " + "Nothing is retried, and the game's own completion is left to run."));
			}
			finally
			{
				_inPromotion = false;
			}
		}

		private static void Repromote()
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			if (_session == null || _promotedPointer == IntPtr.Zero)
			{
				return;
			}
			try
			{
				_inPromotion = true;
				CallMatchTargetCallback((Il2CppObjectBase)(object)_session);
			}
			catch (Exception ex)
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(87, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TapToWork: re-promoting the ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(_kind);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" session on a bridge frame threw ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.GetType().Name);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(". The bridge carries on.");
				}
				log.LogWarning(val);
			}
			finally
			{
				_inPromotion = false;
			}
		}

		private static bool CallMatchTargetCallback(Il2CppObjectBase session)
		{
			PlayerHarvestInteractionSession val = session.TryCast<PlayerHarvestInteractionSession>();
			if (val != null)
			{
				val._OnMatchTarget(true);
				return true;
			}
			PlayerGatherInteractionSession val2 = session.TryCast<PlayerGatherInteractionSession>();
			if (val2 != null)
			{
				val2.OnEnd(true);
				return true;
			}
			PlayerBuildInteractionSession val3 = session.TryCast<PlayerBuildInteractionSession>();
			if (val3 != null)
			{
				val3._OnMatchTarget(true);
				return true;
			}
			PlayerFireInteractionSession val4 = session.TryCast<PlayerFireInteractionSession>();
			if (val4 != null)
			{
				val4._OnMatchTargetEnd(true);
				return true;
			}
			PlayerAnvilInteractionSession val5 = session.TryCast<PlayerAnvilInteractionSession>();
			if (val5 != null)
			{
				val5._OnMatchTarget(true);
				return true;
			}
			return false;
		}

		internal static bool ShouldRunMatchTargetCallback(object session)
		{
			InteractionSession val = (InteractionSession)((session is InteractionSession) ? session : null);
			if (val == null)
			{
				return true;
			}
			if (_inPromotion)
			{
				return true;
			}
			if (_promotedPointer == IntPtr.Zero || ((Il2CppObjectBase)val).Pointer != _promotedPointer)
			{
				return true;
			}
			if (!TryActionStarted((Il2CppObjectBase)(object)val, out var started) || !started)
			{
				if (_swapPending)
				{
					Plugin.Log.LogInfo((object)($"TapToWork: {_kind} swap hold: {_swapHandName} to {_swapResolvedName}, completion refused {SincePress()} " + "after the tap, so the game's own key-up poll cannot end the session before the tool is equipped."));
					return false;
				}
				Plugin.Log.LogInfo((object)($"TapToWork: the game's own {_kind} match-target completion is PASSED THROUGH {SincePress()} after the tap. " + "Easy Key promoted this session and no action has started, so the game's own completion is the only thing left that can start one and Easy Key lets it run."));
				return true;
			}
			Plugin.Log.LogInfo((object)($"TapToWork: the game's own {_kind} match-target completion is REFUSED {SincePress()} after the tap. " + "Easy Key already promoted this session and the action is running, so the game is not allowed to start it a second time."));
			return false;
		}

		internal static bool ShouldSwallowCancel(object session)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Expected O, but got Unknown
			InteractionSession val = (InteractionSession)((session is InteractionSession) ? session : null);
			if (val == null)
			{
				return false;
			}
			if (_replayingAbort)
			{
				return false;
			}
			if (!_armed || ((Il2CppObjectBase)val).Pointer != _sessionPointer)
			{
				return false;
			}
			if (_stopRequested)
			{
				return false;
			}
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val2;
			if (!TryActionStarted((Il2CppObjectBase)(object)val, out var started) || !started)
			{
				if (_swapPending)
				{
					ManualLogSource log = Plugin.Log;
					val2 = new BepInExInfoLogInterpolatedStringHandler(105, 4, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TapToWork: ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(_kind);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" swap hold: ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(_swapHandName);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" to ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(_swapResolvedName);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", cancel swallowed after ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(PressDescription());
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(". The session stays alive until the tool is equipped.");
					}
					log.LogInfo(val2);
					return true;
				}
				Plugin.Log.LogInfo((object)($"TapToWork: {_kind} cancel NOT SWALLOWED after {PressDescription()}, because no action had " + "started for the armed session. This tap falls back to the vanilla hold: the release reaches the game, which ends the session itself, and the toggle is cleared so the next tap is a fresh first tap."));
				return false;
			}
			ManualLogSource log2 = Plugin.Log;
			val2 = new BepInExInfoLogInterpolatedStringHandler(72, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TapToWork: ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(_kind);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" cancel SWALLOWED after ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(PressDescription());
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", the action runs on with the key up.");
			}
			log2.LogInfo(val2);
			return true;
		}

		internal static void StopRequested(object session)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			InteractionSession val = (InteractionSession)((session is InteractionSession) ? session : null);
			if (val != null && _armed && !(((Il2CppObjectBase)val).Pointer != _sessionPointer) && !_stopRequested)
			{
				_stopRequested = true;
				_bridging = false;
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(71, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TapToWork: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(_kind);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" second tap, stop requested. The next cancel passes through.");
				}
				log.LogInfo(val2);
			}
		}

		internal static void Ended(object session)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			InteractionSession val = (InteractionSession)((session is InteractionSession) ? session : null);
			if (val != null && _armed && !(((Il2CppObjectBase)val).Pointer != _sessionPointer))
			{
				ManualLogSource log = Plugin.Log;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(64, 3, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TapToWork: ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(_kind);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" cancel PASSED THROUGH after ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(PressDescription());
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(_stopRequested ? " and a stop request" : "");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", the toggle is cleared.");
				}
				log.LogInfo(val2);
				Clear();
			}
		}

		internal static void Tick()
		{
			if (EasyKeyConfig.MasterEnabled)
			{
				if (_bridging)
				{
					TickBridge();
				}
				TickDrinkStop();
				WatchAction();
			}
		}

		private static void TickDrinkStop()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Invalid comparison between Unknown and I4
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Expected O, but got Unknown
			if (!_armed || _stopRequested || _waterWatchLost || _session == null)
			{
				return;
			}
			PlayerGatherInteractionSession val;
			bool flag = default(bool);
			try
			{
				val = ((Il2CppObjectBase)_session).TryCast<PlayerGatherInteractionSession>();
				if (val == null || (int)val._gatherMode != 1)
				{
					return;
				}
			}
			catch (Exception ex)
			{
				_waterWatchLost = true;
				ManualLogSource log = Plugin.Log;
				BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(165, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TapToWork: reading the drink session's gather mode for the thirst-full auto-stop threw ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.GetType().Name);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(". The auto-stop is off for this session; a second tap still stops the drink.");
				}
				log.LogWarning(val2);
				return;
			}
			if (TryActionStarted((Il2CppObjectBase)(object)_session, out var started) && started && WaterFull(out var reading))
			{
				ManualLogSource log2 = Plugin.Log;
				BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpo