Decompiled source of ControllerFix v1.2.3

plugins/ControllerFix/SoDControllerFix.dll

Decompiled an hour ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using Rewired;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("SoDControllerFix")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0")]
[assembly: AssemblyProduct("SoDControllerFix")]
[assembly: AssemblyTitle("SoDControllerFix")]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 SoDControllerFix
{
	[BepInPlugin("sm3gm.sod.controllerfix", "Controller Fix", "1.2.2")]
	public sealed class Plugin : BasePlugin
	{
		public const string VER = "1.2.2";

		internal static ManualLogSource L;

		internal static ConfigEntry<bool> OnePressPerClick;

		internal static ConfigEntry<bool> LogBlocked;

		internal static ConfigEntry<float> ClickWindow;

		internal static ConfigEntry<bool> SelectUnderCursor;

		internal static ConfigEntry<float> DragThreshold;

		internal static ConfigEntry<bool> PhoneLook;

		internal static ConfigEntry<bool> YClosesCard;

		public override void Load()
		{
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Expected O, but got Unknown
			L = ((BasePlugin)this).Log;
			OnePressPerClick = ((BasePlugin)this).Config.Bind<bool>("Buttons", "OnePressPerClick", true, "Keypads, phone keys and elevator buttons take one press per click. Stops one click typing a digit several times.");
			ClickWindow = ((BasePlugin)this).Config.Bind<float>("Buttons", "ClickWindowSeconds", 0.6f, "How long after a click the game may still press the key (the hand moves to it first).");
			SelectUnderCursor = ((BasePlugin)this).Config.Bind<bool>("Buttons", "SelectUnderCursor", true, "When the cursor moves onto a button, that button becomes the selected one, so a controller click presses what you point at and not a tab elsewhere.");
			DragThreshold = ((BasePlugin)this).Config.Bind<float>("CaseBoard", "DragThreshold", 24f, "How far (in pixels at 1080p) the cursor must move with the button held before a click becomes a drag. A shaky controller or trackpad click then opens the item instead of moving it. The game uses 10. 0 = leave the game's value.");
			PhoneLook = ((BasePlugin)this).Config.Bind<bool>("Phone", "KeepViewOnPhone", true, "On a phone call the view stays put when you switch between controller and keyboard (the game let it go).");
			YClosesCard = ((BasePlugin)this).Config.Bind<bool>("CaseBoard", "YClosesTopCard", true, "On the case board with a controller, Y closes the card you opened last, one per press (B closes the whole board). Over a pin, Y opens its menu as usual.");
			LogBlocked = ((BasePlugin)this).Config.Bind<bool>("Debug", "LogBlocked", false, "Write a line to the log for every repeated press that was stopped.");
			((BasePlugin)this).AddComponent<InputWatch>();
			new Harmony("sm3gm.sod.controllerfix").PatchAll(typeof(Presses));
			ManualLogSource l = L;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(22, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Controller Fix ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("1.2.2");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" loaded");
			}
			l.LogInfo(val);
		}
	}
	public class InputWatch : MonoBehaviour
	{
		internal static int LastDownFrame = -10;

		internal static float LastDownTime = -10f;

		internal static bool Used = true;

		internal static float AutoUntil = -10f;

		private static string lastKey = "";

		private static float lastKeyTime = -10f;

		private static int lastKeyFrame = -1;

		internal static float CursorUntil = -10f;

		internal static float PadCursorUntil = -10f;

		private static int yButton = -2;

		private static int secondary = -2;

		private static int lastCardFrame = -1;

		private static int cardErr;

		private static int cardLogs;

		private static float nextDrag;

		private static int lastMode = -1;

		private static int relock;

		private static bool lockedThisCall;

		private static int logged;

		private static Vector3 lastMouse;

		private static float lastMove = -10f;

		public InputWatch(IntPtr ptr)
			: base(ptr)
		{
		}

		private void Update()
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			Seen();
			try
			{
				Drag();
			}
			catch
			{
			}
			try
			{
				Phone();
			}
			catch
			{
			}
			try
			{
				KeepCursor();
			}
			catch
			{
			}
			try
			{
				CloseCard();
			}
			catch (Exception ex)
			{
				if (cardErr++ < 3)
				{
					ManualLogSource l = Plugin.L;
					bool flag = default(bool);
					BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(7, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[CARD] ");
						((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
					}
					l.LogWarning(val);
				}
			}
			if (Plugin.SelectUnderCursor.Value && !OnBoard())
			{
				FollowCursor();
			}
		}

		private static void KeepCursor()
		{
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			if (Time.unscaledTime <= PadCursorUntil && OnBoard())
			{
				VirtualCursorController instance = VirtualCursorController.Instance;
				if ((Object)(object)instance != (Object)null && !instance.isActive)
				{
					instance.TryActivateVirtualCursor((StartingMousePosition)0, (RectTransform)null);
				}
			}
			else if (!(Time.unscaledTime > CursorUntil) && OnBoard())
			{
				InputController instance2 = InputController.Instance;
				if ((Object)(object)instance2 != (Object)null && !instance2.cursorVisible)
				{
					instance2.SetCursorVisible(true);
				}
				if (!Cursor.visible)
				{
					Cursor.visible = true;
				}
				if ((int)Cursor.lockState != 0)
				{
					Cursor.lockState = (CursorLockMode)0;
				}
				try
				{
					InterfaceController.Instance.UpdateCursorSprite();
				}
				catch
				{
				}
			}
		}

		private static void CloseCard()
		{
			//IL_03c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ca: Expected O, but got Unknown
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Expected O, but got Unknown
			//IL_049e: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a5: Expected O, but got Unknown
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Expected O, but got Unknown
			if (!Plugin.YClosesCard.Value || !OnBoard())
			{
				return;
			}
			InputController instance = InputController.Instance;
			if ((Object)(object)instance == (Object)null || instance.mouseInputMode)
			{
				return;
			}
			Joystick val = null;
			ControllerHelper controllers = ReInput.controllers;
			int num = 0;
			while (controllers != null && num < 8 && val == null)
			{
				val = controllers.GetJoystick(num);
				num++;
			}
			if (val == null)
			{
				return;
			}
			bool flag = default(bool);
			if (yButton == -2)
			{
				yButton = -1;
				StringBuilder stringBuilder = new StringBuilder();
				for (int i = 0; i < ((Controller)val).buttonCount; i++)
				{
					string text = "";
					try
					{
						text = ((Element)((Controller)val).Buttons[i]).elementIdentifier.name;
					}
					catch
					{
					}
					stringBuilder.Append(i).Append('=').Append(text)
						.Append(' ');
					string text2 = text.Replace(" ", "").ToLowerInvariant();
					if (yButton < 0)
					{
						switch (text2)
						{
						case "y":
						case "ybutton":
						case "buttony":
						case "triangle":
							yButton = i;
							break;
						}
					}
				}
				if (yButton < 0 && ((Controller)val).buttonCount > 3)
				{
					yButton = 3;
				}
				if (Plugin.LogBlocked.Value)
				{
					ManualLogSource l = Plugin.L;
					BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(28, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[CARD] pad buttons: ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<StringBuilder>(stringBuilder);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("-> Y is ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(yButton);
					}
					l.LogInfo(val2);
				}
			}
			bool flag2 = yButton >= 0 && ((Controller)val).GetButtonDown(yButton);
			try
			{
				if (secondary == -2)
				{
					secondary = ReInput.mapping.GetActionId("Secondary");
					if (Plugin.LogBlocked.Value)
					{
						ManualLogSource l2 = Plugin.L;
						BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(27, 1, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[CARD] Secondary action is ");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(secondary);
						}
						l2.LogInfo(val2);
					}
				}
				if (!flag2 && secondary >= 0 && ReInput.players.GetPlayer(0).GetButtonDown(secondary))
				{
					flag2 = true;
				}
			}
			catch
			{
			}
			if (!flag2 || Time.frameCount == lastCardFrame)
			{
				return;
			}
			lastCardFrame = Time.frameCount;
			InterfaceController instance2 = InterfaceController.Instance;
			bool flag3 = false;
			StringBuilder stringBuilder2 = new StringBuilder();
			List<MonoBehaviour> currentMouseOverElement = instance2.currentMouseOverElement;
			int num2 = 0;
			while (currentMouseOverElement != null && num2 < currentMouseOverElement.Count)
			{
				MonoBehaviour val3 = currentMouseOverElement[num2];
				if (!((Object)(object)val3 == (Object)null))
				{
					stringBuilder2.Append(((Object)val3).name).Append(' ');
					if ((Object)(object)((Component)val3).GetComponentInParent<InfoWindow>() == (Object)null && (Object)(object)((Component)val3).GetComponentInParent<PinnedItemController>() != (Object)null)
					{
						flag3 = true;
					}
				}
				num2++;
			}
			InfoWindow val4 = null;
			List<InfoWindow> activeWindows = instance2.activeWindows;
			int num3 = ((activeWindows != null) ? (activeWindows.Count - 1) : (-1));
			while (num3 >= 0 && (Object)(object)val4 == (Object)null)
			{
				InfoWindow val5 = activeWindows[num3];
				if ((Object)(object)val5 != (Object)null && ((Component)val5).gameObject.activeInHierarchy && !val5.forceDisableClose)
				{
					val4 = val5;
				}
				num3--;
			}
			if (Plugin.LogBlocked.Value && cardLogs++ < 30)
			{
				StringBuilder stringBuilder3 = new StringBuilder();
				try
				{
					Player player = ReInput.players.GetPlayer(0);
					for (int j = 0; j < 300; j++)
					{
						InputAction action = ReInput.mapping.GetAction(j);
						if (action != null && player.GetButtonDown(j))
						{
							stringBuilder3.Append(action.name).Append(' ');
						}
					}
				}
				catch
				{
				}
				ManualLogSource l3 = Plugin.L;
				BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(61, 5, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[CARD] Y on the board: actions [");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<StringBuilder>(stringBuilder3);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("] over [");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<StringBuilder>(stringBuilder2);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("] open cards ");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(activeWindows?.Count ?? 0);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", top '");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((Object)(object)val4 != (Object)null) ? ((Object)val4).name : "-");
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(flag3 ? ", over a pin: left to the game" : "");
				}
				l3.LogInfo(val2);
			}
			if (flag3 || (Object)(object)val4 == (Object)null)
			{
				return;
			}
			val4.CloseWindow(true);
			if (Plugin.LogBlocked.Value)
			{
				ManualLogSource l4 = Plugin.L;
				BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(16, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[CARD] closed '");
					((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((Object)val4).name);
					((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'");
				}
				l4.LogInfo(val2);
			}
		}

		private static bool OnBoard()
		{
			try
			{
				InterfaceController instance = InterfaceController.Instance;
				return (Object)(object)instance != (Object)null && instance.desktopMode;
			}
			catch
			{
				return false;
			}
		}

		private static void Drag()
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			if (Time.unscaledTime < nextDrag || Plugin.DragThreshold.Value <= 0f)
			{
				return;
			}
			nextDrag = Time.unscaledTime + 1f;
			EventSystem current = EventSystem.current;
			if ((Object)(object)current == (Object)null)
			{
				return;
			}
			int num = Mathf.RoundToInt(Plugin.DragThreshold.Value * (float)Screen.height / 1080f);
			if (current.pixelDragThreshold == num)
			{
				return;
			}
			if (Plugin.LogBlocked.Value)
			{
				ManualLogSource l = Plugin.L;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(25, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[FIX] drag threshold ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(current.pixelDragThreshold);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" -> ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num);
				}
				l.LogInfo(val);
			}
			current.pixelDragThreshold = num;
		}

		private static void Phone()
		{
			if (!Plugin.PhoneLook.Value)
			{
				return;
			}
			InputController instance = InputController.Instance;
			Player instance2 = Player.Instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)instance2 == (Object)null)
			{
				return;
			}
			int num = (instance.mouseInputMode ? 1 : 0);
			if (lastMode != -1 && num != lastMode && instance2.phoneInteractable != null)
			{
				relock = 10;
				lockedThisCall = true;
			}
			lastMode = num;
			if (lockedThisCall && instance2.phoneInteractable == null)
			{
				lockedThisCall = false;
				relock = 0;
				instance2.EnablePlayerMouseLook(true, false);
				if (Plugin.LogBlocked.Value)
				{
					Plugin.L.LogInfo((object)"[FIX] call over, view given back");
				}
			}
			else
			{
				if (relock <= 0)
				{
					return;
				}
				relock--;
				if (instance2.phoneInteractable == null)
				{
					relock = 0;
					return;
				}
				instance2.EnablePlayerMouseLook(false, false);
				if (relock == 0 && Plugin.LogBlocked.Value)
				{
					Plugin.L.LogInfo((object)"[FIX] kept the view still on the phone after an input switch");
				}
			}
		}

		private static void FollowCursor()
		{
			//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_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_0016: 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_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Expected O, but got Unknown
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Vector3 val = Vector2.op_Implicit(CursorPos());
				Vector3 val2 = val - lastMouse;
				if (((Vector3)(ref val2)).sqrMagnitude > 1f)
				{
					lastMouse = val;
					lastMove = Time.unscaledTime;
				}
				if (Time.unscaledTime - lastMove > 2f)
				{
					return;
				}
				EventSystem current = EventSystem.current;
				GameObject val3 = (((Object)(object)current != (Object)null) ? current.currentSelectedGameObject : null);
				if ((Object)(object)val3 == (Object)null || (Object)(object)val3.GetComponent<TMP_InputField>() != (Object)null || (Object)(object)val3.GetComponent<InputField>() != (Object)null || (Object)(object)val3.GetComponentInParent<TMP_Dropdown>() != (Object)null || (Object)(object)val3.GetComponentInParent<Dropdown>() != (Object)null || (Object)(object)val3.GetComponent<Scrollbar>() != (Object)null || ((Object)val3).name.StartsWith("Item "))
				{
					return;
				}
				RectTransform component = val3.GetComponent<RectTransform>();
				if ((Object)(object)component == (Object)null)
				{
					return;
				}
				Canvas componentInParent = val3.GetComponentInParent<Canvas>();
				Camera val4 = (((Object)(object)componentInParent != (Object)null && (int)componentInParent.renderMode != 0) ? componentInParent.worldCamera : null);
				if (RectTransformUtility.RectangleContainsScreenPoint(component, CursorPos(), val4))
				{
					return;
				}
				current.SetSelectedGameObject((GameObject)null);
				if (Plugin.LogBlocked.Value && logged++ < 300)
				{
					ManualLogSource l = Plugin.L;
					bool flag = default(bool);
					BepInExInfoLogInterpolatedStringHandler val5 = new BepInExInfoLogInterpolatedStringHandler(53, 2, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[FIX] dropped selection '");
						((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(((Object)val3).name);
						((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("' (not under the cursor at ");
						((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<Vector2>(CursorPos());
						((BepInExLogInterpolatedStringHandler)val5).AppendLiteral(")");
					}
					l.LogInfo(val5);
				}
			}
			catch
			{
			}
		}

		private static Vector2 CursorPos()
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				VirtualCursorController instance = VirtualCursorController.Instance;
				if ((Object)(object)instance != (Object)null && instance.isActive && (Object)(object)instance.mouse != (Object)null)
				{
					return instance.mouse.screenPosition;
				}
			}
			catch
			{
			}
			Vector3 mousePosition = Input.mousePosition;
			return new Vector2(mousePosition.x, mousePosition.y);
		}

		internal static void Seen()
		{
			if (Input.anyKeyDown && LastDownFrame != Time.frameCount)
			{
				LastDownFrame = Time.frameCount;
				LastDownTime = Time.unscaledTime;
				Used = false;
			}
		}

		internal static bool Allow(string what, int n)
		{
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Expected O, but got Unknown
			if (!Plugin.OnePressPerClick.Value)
			{
				return true;
			}
			if (Time.unscaledTime < AutoUntil)
			{
				return true;
			}
			Seen();
			if (!Used && Time.unscaledTime - LastDownTime <= Plugin.ClickWindow.Value)
			{
				Used = true;
				lastKey = what + n;
				lastKeyTime = Time.unscaledTime;
				lastKeyFrame = Time.frameCount;
				return true;
			}
			bool flag = Time.frameCount == lastKeyFrame;
			if (what + n != lastKey || Time.unscaledTime - lastKeyTime > 1f || (flag && what != "elevator"))
			{
				lastKey = what + n;
				lastKeyTime = Time.unscaledTime;
				lastKeyFrame = Time.frameCount;
				return true;
			}
			if (Plugin.LogBlocked.Value)
			{
				ManualLogSource l = Plugin.L;
				bool flag2 = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(60, 3, ref flag2);
				if (flag2)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[FIX] stopped a repeated ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(what);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" press of ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(n);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (last click ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(Time.frameCount - LastDownFrame);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" frames ago)");
				}
				l.LogInfo(val);
			}
			return false;
		}
	}
	[HarmonyPatch]
	internal static class Presses
	{
		private static float lastFloorTime = -10f;

		private static int lastFloorFrameDown = -1;

		private static int lastFloor = int.MinValue;

		private static float sliderAt = float.NaN;

		private static FloorZoomController? zoom;

		[HarmonyPatch(typeof(KeypadController), "OnInputCode")]
		[HarmonyPrefix]
		private static void SavedCode(List<int> code)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			int num = code?.Count ?? 4;
			InputWatch.AutoUntil = Time.unscaledTime + 1.5f + (float)num * 0.6f;
			if (Plugin.LogBlocked.Value)
			{
				ManualLogSource l = Plugin.L;
				bool flag = default(bool);
				BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(66, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[FIX] game is entering a saved code (");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" digits), presses let through");
				}
				l.LogInfo(val);
			}
		}

		[HarmonyPatch(typeof(KeypadController), "PressNumberButton")]
		[HarmonyPrefix]
		private static bool Keypad(KeypadController __instance, int newInt)
		{
			return InputWatch.Allow(__instance.isTelephone ? "phone" : "keypad", newInt);
		}

		private static Slider? FloorSlider()
		{
			try
			{
				if ((Object)(object)zoom == (Object)null)
				{
					zoom = Object.FindObjectOfType<FloorZoomController>();
				}
				FloorZoomController? obj = zoom;
				object result;
				if (obj == null)
				{
					result = null;
				}
				else
				{
					SliderController floorSlider = obj.floorSlider;
					result = ((floorSlider != null) ? floorSlider.slider : null);
				}
				return (Slider?)result;
			}
			catch
			{
				return null;
			}
		}

		[HarmonyPatch(typeof(MapController), "SetFloorLayer")]
		[HarmonyPrefix]
		private static bool MapFloor(int newFloor, bool forceLoad)
		{
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Expected O, but got Unknown
			if (!Plugin.OnePressPerClick.Value || forceLoad)
			{
				return true;
			}
			InputWatch.Seen();
			bool num = InputWatch.LastDownFrame == lastFloorFrameDown;
			int num2 = newFloor - lastFloor;
			if (num && (num2 == 1 || num2 == -1) && Time.unscaledTime - lastFloorTime < 0.5f)
			{
				Slider val = FloorSlider();
				bool flag = false;
				if ((Object)(object)val != (Object)null && !float.IsNaN(sliderAt) && Mathf.Abs(val.value - sliderAt) > 0.01f)
				{
					val.SetValueWithoutNotify(sliderAt);
					flag = true;
					try
					{
						zoom.floorSlider.UpdateDisplayValue();
					}
					catch
					{
					}
				}
				if (Plugin.LogBlocked.Value)
				{
					ManualLogSource l = Plugin.L;
					bool flag2 = default(bool);
					BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(43, 2, ref flag2);
					if (flag2)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[FIX] stopped a repeated map floor step to ");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(newFloor);
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(flag ? $", slider put back to {sliderAt}" : "");
					}
					l.LogInfo(val2);
				}
				return false;
			}
			lastFloorTime = Time.unscaledTime;
			lastFloorFrameDown = InputWatch.LastDownFrame;
			lastFloor = newFloor;
			return true;
		}

		[HarmonyPatch(typeof(MapController), "SetFloorLayer")]
		[HarmonyPostfix]
		private static void MapFloorDone()
		{
			Slider val = FloorSlider();
			if ((Object)(object)val != (Object)null)
			{
				sliderAt = val.value;
			}
		}

		[HarmonyPatch(typeof(InputController), "SetMouseInputMode")]
		[HarmonyPostfix]
		private static void InputSwitched(InputController __instance, bool val)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			try
			{
				InterfaceController instance = InterfaceController.Instance;
				if ((Object)(object)instance == (Object)null || !instance.desktopMode)
				{
					return;
				}
				if (!val)
				{
					InputWatch.CursorUntil = -10f;
					InputWatch.PadCursorUntil = Time.unscaledTime + 1f;
					VirtualCursorController instance2 = VirtualCursorController.Instance;
					if ((Object)(object)instance2 != (Object)null && !instance2.isActive)
					{
						instance2.TryActivateVirtualCursor((StartingMousePosition)0, (RectTransform)null);
					}
					if (Plugin.LogBlocked.Value)
					{
						ManualLogSource l = Plugin.L;
						bool flag = default(bool);
						BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(66, 1, ref flag);
						if (flag)
						{
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[FIX] controller cursor switched on again on the case board (was ");
							((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((Object)(object)instance2 != (Object)null && instance2.isActive) ? "on" : "off");
							((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(")");
						}
						l.LogInfo(val2);
					}
					return;
				}
				InputWatch.PadCursorUntil = -10f;
				InputWatch.CursorUntil = Time.unscaledTime + 1f;
				if (!__instance.cursorVisible)
				{
					__instance.SetCursorVisible(true);
					__instance.SetCursorLock(false);
					if (Plugin.LogBlocked.Value)
					{
						Plugin.L.LogInfo((object)"[FIX] mouse cursor shown again on the case board after switching to mouse");
					}
				}
			}
			catch
			{
			}
		}

		[HarmonyPatch(typeof(ElevatorControlsController), "PressNumberButton")]
		[HarmonyPrefix]
		private static bool Elevator(int newInt)
		{
			return InputWatch.Allow("elevator", newInt);
		}
	}
}