Decompiled source of ButtonFix v1.0.0

plugins/ButtonFix/SoDControllerFix.dll

Decompiled 13 hours 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 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 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.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", "Button Fix", "1.0.0")]
	public sealed class Plugin : BasePlugin
	{
		public const string VER = "1.0.0";

		internal static ManualLogSource L;

		internal static ConfigEntry<bool> OnePressPerClick;

		internal static ConfigEntry<bool> LogBlocked;

		internal static ConfigEntry<float> ClickWindow;

		internal static ConfigEntry<bool> SelectUnderCursor;

		public override void Load()
		{
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: 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.");
			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(18, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Button Fix ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("1.0.0");
				((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;

		private static int logged;

		private static Vector3 lastMouse;

		private static float lastMove = -10f;

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

		private void Update()
		{
			Seen();
			if (Plugin.SelectUnderCursor.Value)
			{
				FollowCursor();
			}
		}

		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
	{
		[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);
		}

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