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