Decompiled source of MouseKeyBindings v1.0.1

MouseKeyBindings.dll

Decompiled 13 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using FastText;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.LowLevel;
using UnityEngine.InputSystem.Utilities;
using _E;
using _m;
using ifapp.Game.Input;
using ifapp.Game.Scenes;
using ifapp.Game.Scenes.Game;
using ifapp.Game.UI.Common;
using ifapp.Game.UI.Settings;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("MouseKeyBindings")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("让六轨操作键位支持 Unity Input System 报告的全部鼠标按钮。")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: AssemblyProduct("MouseKeyBindings")]
[assembly: AssemblyTitle("MouseKeyBindings")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.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 InFalsusMod
{
	[HarmonyPatch(typeof(InputManager), "OnInputSystemEvent")]
	internal static class MouseInputEventPatch
	{
		[HarmonyPrefix]
		private static void Prefix(InputManager __instance, InputEventPtr __0, InputDevice __1)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			MouseInputEvents.Observe(__instance, __0, __1);
		}
	}
	[HarmonyPatch(typeof(InputManager), "Update")]
	internal static class MouseInputUpdatePatch
	{
		[HarmonyPostfix]
		private static void Postfix(InputManager __instance)
		{
			try
			{
				MouseBindingRuntime.Process(__instance);
			}
			catch (Exception exception)
			{
				MouseBindingRuntime.Disable(exception);
			}
		}
	}
	[HarmonyPatch(typeof(KeyPressedIndicator), "_wl")]
	internal static class MouseKeyIndicatorPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(KeyPressedIndicator __instance, Key __0)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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_0018: Unknown result type (might be due to invalid IL or missing references)
			if (!MouseKeyCodec.TryDecode(__0, out var button))
			{
				return true;
			}
			if (__instance._ip == __0)
			{
				return false;
			}
			__instance._ip = __0;
			FastText text = __instance.text;
			if (text != null)
			{
				text.SetTextNonLocalized($"Mouse{button}", (UpdateType)0);
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(LaneKeyBindSettingsContainer), "_gE")]
	internal static class MouseBindingSettingsPatch
	{
		[HarmonyPostfix]
		private static void Postfix(LaneKeyBindSettingsContainer __instance)
		{
			try
			{
				MouseBindingRuntime.RegisterSettings(__instance);
			}
			catch (Exception exception)
			{
				MouseBindingRuntime.Disable(exception);
			}
		}
	}
	[HarmonyPatch(typeof(LaneKeyBindSettingsContainer), "_GE")]
	internal static class MouseBindingRefreshPatch
	{
		[HarmonyPrefix]
		private static bool Prefix(LaneKeyBindSettingsContainer __instance)
		{
			try
			{
				return !MouseBindingRuntime.RefreshBindingView(__instance);
			}
			catch (Exception exception)
			{
				MouseBindingRuntime.Disable(exception);
				return true;
			}
		}
	}
	internal static class MouseBindingRuntime
	{
		private readonly record struct ActiveMousePress(IntPtr Device, GameScene Receiver, Key Key, CurrentKeyboardModifiersState Modifiers)
		{
			[CompilerGenerated]
			public void Deconstruct(out IntPtr Device, out GameScene Receiver, out Key Key, out CurrentKeyboardModifiersState Modifiers)
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Expected I4, but got Unknown
				//IL_001b: 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)
				Device = this.Device;
				Receiver = this.Receiver;
				Key = (Key)(int)this.Key;
				Modifiers = this.Modifiers;
			}
		}

		private static readonly List<MouseTransition> Transitions = new List<MouseTransition>();

		private static readonly Dictionary<int, ActiveMousePress> ActivePresses = new Dictionary<int, ActiveMousePress>();

		private static LaneKeyBindSettingsContainer? settingsContainer;

		private static int waitingLane = -1;

		private static long captureAfterSequence;

		private static bool disabled;

		private static bool gameplayForwardLogged;

		private static bool gameplayReleaseLogged;

		internal static void RegisterSettings(LaneKeyBindSettingsContainer container)
		{
			if (!disabled)
			{
				settingsContainer = container;
				waitingLane = container._Hh;
				captureAfterSequence = MouseInputEvents.CurrentSequence;
				RefreshLabels(container);
				Plugin.Logger.LogDebug((object)"已接管六轨鼠标按键绑定界面。");
			}
		}

		internal static void Process(InputManager manager)
		{
			if (disabled)
			{
				return;
			}
			MouseInputEvents.EnsureDevice(Mouse.current);
			ObserveBindingSlot();
			if (MouseInputEvents.Drain(Transitions) || (ActivePresses.Count > 0 && (Object)(object)GetPlayableGameScene(manager) == (Object)null))
			{
				ReleaseAll(InputState.currentTime);
			}
			foreach (MouseTransition transition in Transitions)
			{
				if (!TryCaptureBinding(transition))
				{
					ForwardToGame(manager, transition);
				}
			}
			ReleasePhysicallyReleasedButtons(InputState.currentTime);
			if ((Object)(object)settingsContainer != (Object)null)
			{
				RefreshLabels(settingsContainer);
			}
		}

		internal static void Disable(Exception exception)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			if (!disabled)
			{
				disabled = true;
				ActivePresses.Clear();
				Transitions.Clear();
				settingsContainer = null;
				ManualLogSource logger = Plugin.Logger;
				bool flag = default(bool);
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(13, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("鼠标轨道绑定运行层已停用:");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(exception);
				}
				logger.LogError(val);
			}
		}

		private static void ObserveBindingSlot()
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			if ((Object)(object)settingsContainer == (Object)null)
			{
				return;
			}
			if (!((Behaviour)settingsContainer).isActiveAndEnabled)
			{
				settingsContainer = null;
				waitingLane = -1;
				captureAfterSequence = MouseInputEvents.CurrentSequence;
				return;
			}
			int hh = settingsContainer._Hh;
			if (hh == waitingLane)
			{
				return;
			}
			waitingLane = hh;
			captureAfterSequence = MouseInputEvents.CurrentSequence;
			if (hh >= 0)
			{
				ManualLogSource logger = Plugin.Logger;
				bool flag = default(bool);
				BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(13, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("轨道 ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(hh + 1);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" 正在等待鼠标按键。");
				}
				logger.LogDebug(val);
			}
		}

		private static bool TryCaptureBinding(MouseTransition transition)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Expected O, but got Unknown
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Expected O, but got Unknown
			if (!transition.Pressed || (Object)(object)settingsContainer == (Object)null || waitingLane < 0 || transition.Sequence <= captureAfterSequence)
			{
				return false;
			}
			int num = waitingLane;
			Key val = MouseKeyCodec.Encode(transition.Button);
			CurrentKeyboardModifiersState val2 = default(CurrentKeyboardModifiersState);
			settingsContainer._iE(val, transition.Time, ref val2);
			Il2CppStructArray<Key> hh = settingsContainer._hh;
			bool num2 = hh != null && num < ((Il2CppArrayBase<Key>)(object)hh).Length && ((Il2CppArrayBase<Key>)(object)hh)[num] == val;
			waitingLane = settingsContainer._Hh;
			captureAfterSequence = MouseInputEvents.CurrentSequence;
			RefreshLabels(settingsContainer);
			bool flag = default(bool);
			if (num2)
			{
				ManualLogSource logger = Plugin.Logger;
				BepInExDebugLogInterpolatedStringHandler val3 = new BepInExDebugLogInterpolatedStringHandler(14, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("轨道 ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(num + 1);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" 已绑定 Mouse");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(transition.Button);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("。");
				}
				logger.LogDebug(val3);
			}
			else
			{
				ManualLogSource logger2 = Plugin.Logger;
				BepInExDebugLogInterpolatedStringHandler val3 = new BepInExDebugLogInterpolatedStringHandler(27, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("Mouse");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(transition.Button);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" 未写入轨道 ");
					((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(num + 1);
					((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(",原版绑定检查已拒绝本次设置。");
				}
				logger2.LogDebug(val3);
			}
			return true;
		}

		private static void ForwardToGame(InputManager manager, MouseTransition transition)
		{
			//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_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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_0060: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Expected O, but got Unknown
			if (!transition.Pressed)
			{
				Release(transition.Button, transition.Time);
			}
			else
			{
				if (ActivePresses.ContainsKey(transition.Button))
				{
					return;
				}
				Key val = MouseKeyCodec.Encode(transition.Button);
				GameScene playableGameScene = GetPlayableGameScene(manager);
				if ((Object)(object)playableGameScene == (Object)null || !IsLaneBinding(val))
				{
					return;
				}
				CurrentKeyboardModifiersState modifiers = transition.Modifiers;
				((InputReceiver)playableGameScene)._OvA(val, transition.Time, ref modifiers);
				ActivePresses.Add(transition.Button, new ActiveMousePress(transition.Device, playableGameScene, val, modifiers));
				if (!gameplayForwardLogged)
				{
					gameplayForwardLogged = true;
					ManualLogSource logger = Plugin.Logger;
					bool flag = default(bool);
					BepInExDebugLogInterpolatedStringHandler val2 = new BepInExDebugLogInterpolatedStringHandler(18, 1, ref flag);
					if (flag)
					{
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Mouse");
						((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(transition.Button);
						((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" 已进入原版六轨按下路径。");
					}
					logger.LogDebug(val2);
				}
			}
		}

		private static GameScene? GetPlayableGameScene(InputManager manager)
		{
			if (!manager.IsAllInputEnabled())
			{
				return null;
			}
			GameScene xn = GameScene._xn;
			if ((Object)(object)xn == (Object)null || !((Behaviour)xn).isActiveAndEnabled)
			{
				return null;
			}
			GamePauseLayer pauseLayer = xn.pauseLayer;
			if ((Object)(object)pauseLayer != (Object)null && pauseLayer._Dz())
			{
				return null;
			}
			Il2CppReferenceArray<InputOwnershipPair> inputAlwaysReceivedStack = manager.inputAlwaysReceivedStack;
			if (inputAlwaysReceivedStack == null)
			{
				return null;
			}
			int num = Math.Min(manager.inputAlwaysReceivedStackCount, ((Il2CppArrayBase<InputOwnershipPair>)(object)inputAlwaysReceivedStack).Length);
			for (int i = 0; i < num; i++)
			{
				InputOwnershipPair obj = ((Il2CppArrayBase<InputOwnershipPair>)(object)inputAlwaysReceivedStack)[i];
				InputReceiver val = ((obj != null) ? obj.Owner : null);
				if ((Object)(object)val != (Object)null && ((Il2CppObjectBase)val).Pointer == ((Il2CppObjectBase)xn).Pointer)
				{
					return xn;
				}
			}
			return null;
		}

		private static bool IsLaneBinding(Key key)
		{
			//IL_001e: 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)
			Il2CppStructArray<Key> jfA = _YD._JfA;
			if (jfA == null)
			{
				return false;
			}
			int num = Math.Min(6, ((Il2CppArrayBase<Key>)(object)jfA).Length);
			for (int i = 0; i < num; i++)
			{
				if (((Il2CppArrayBase<Key>)(object)jfA)[i] == key)
				{
					return true;
				}
			}
			return false;
		}

		private static void ReleasePhysicallyReleasedButtons(double time)
		{
			bool pressed;
			int[] array = (from pair in ActivePresses
				where MouseInputEvents.TryGetCurrentButtonState(pair.Value.Device, pair.Key, out pressed) && !pressed
				select pair.Key).ToArray();
			for (int num = 0; num < array.Length; num++)
			{
				Release(array[num], time);
			}
		}

		private static void Release(int button, double time)
		{
			//IL_0021: 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_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			if (!ActivePresses.Remove(button, out var value) || (Object)(object)value.Receiver == (Object)null)
			{
				return;
			}
			CurrentKeyboardModifiersState modifiers = value.Modifiers;
			((InputReceiver)value.Receiver)._fwA(value.Key, time, ref modifiers);
			if (!gameplayReleaseLogged)
			{
				gameplayReleaseLogged = true;
				ManualLogSource logger = Plugin.Logger;
				bool flag = default(bool);
				BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(18, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Mouse");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(button);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" 已进入原版六轨释放路径。");
				}
				logger.LogDebug(val);
			}
		}

		private static void ReleaseAll(double time)
		{
			int[] array = ActivePresses.Keys.ToArray();
			for (int i = 0; i < array.Length; i++)
			{
				Release(array[i], time);
			}
		}

		internal unsafe static bool RefreshBindingView(LaneKeyBindSettingsContainer container)
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			Il2CppStructArray<Key> hh = container._hh;
			Il2CppReferenceArray<UIButton> laneButtons = container.laneButtons;
			Il2CppReferenceArray<FastText> laneButtonTexts = container.laneButtonTexts;
			if (hh == null || laneButtons == null || laneButtonTexts == null || ((Il2CppArrayBase<UIButton>)(object)laneButtons).Length == 0)
			{
				return false;
			}
			bool flag = false;
			for (int i = 0; i < ((Il2CppArrayBase<Key>)(object)hh).Length; i++)
			{
				flag |= MouseKeyCodec.TryDecode(((Il2CppArrayBase<Key>)(object)hh)[i], out var _);
			}
			if (!flag)
			{
				return false;
			}
			Keyboard current = Keyboard.current;
			int num = ((Il2CppArrayBase<FastText>)(object)laneButtonTexts).Length / ((Il2CppArrayBase<UIButton>)(object)laneButtons).Length;
			for (int j = 0; j < ((Il2CppArrayBase<FastText>)(object)laneButtonTexts).Length / Math.Max(1, num) && j < ((Il2CppArrayBase<Key>)(object)hh).Length; j++)
			{
				Key val = ((Il2CppArrayBase<Key>)(object)hh)[j];
				object obj;
				if (!MouseKeyCodec.TryDecode(val, out var button2))
				{
					if (current == null)
					{
						obj = null;
					}
					else
					{
						KeyControl obj2 = current[val];
						obj = ((obj2 != null) ? ((InputControl)obj2).displayName : null);
					}
					if (obj == null)
					{
						obj = ((object)(*(Key*)(&val))/*cast due to .constrained prefix*/).ToString();
					}
				}
				else
				{
					obj = $"Mouse{button2}";
				}
				string text = (string)obj;
				for (int k = 0; k < num; k++)
				{
					FastText obj3 = ((Il2CppArrayBase<FastText>)(object)laneButtonTexts)[j * num + k];
					if (obj3 != null)
					{
						obj3.SetTextNonLocalized(text, (UpdateType)0);
					}
				}
			}
			Il2CppStructArray<Key> jfA = _YD._JfA;
			bool flag2 = false;
			for (int l = 0; l < ((Il2CppArrayBase<UIButton>)(object)laneButtons).Length && l < ((Il2CppArrayBase<Key>)(object)hh).Length; l++)
			{
				bool flag3 = jfA == null || l >= ((Il2CppArrayBase<Key>)(object)jfA).Length || ((Il2CppArrayBase<Key>)(object)jfA)[l] != ((Il2CppArrayBase<Key>)(object)hh)[l];
				flag2 = flag2 || flag3;
				UIButton obj4 = ((Il2CppArrayBase<UIButton>)(object)laneButtons)[l];
				if (obj4 != null)
				{
					obj4._dSA((_dI)((!flag3) ? 1 : 2));
				}
			}
			UIButton applyButton = container.applyButton;
			if (applyButton != null)
			{
				applyButton._dSA((_dI)(flag2 ? 1 : 0));
			}
			return true;
		}

		private static void RefreshLabels(LaneKeyBindSettingsContainer container)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			Il2CppStructArray<Key> hh = container._hh;
			Il2CppReferenceArray<FastText> laneButtonTexts = container.laneButtonTexts;
			if (hh == null || laneButtonTexts == null || ((Il2CppArrayBase<Key>)(object)hh).Length == 0 || ((Il2CppArrayBase<FastText>)(object)laneButtonTexts).Length % ((Il2CppArrayBase<Key>)(object)hh).Length != 0)
			{
				return;
			}
			int num = ((Il2CppArrayBase<FastText>)(object)laneButtonTexts).Length / ((Il2CppArrayBase<Key>)(object)hh).Length;
			for (int i = 0; i < ((Il2CppArrayBase<Key>)(object)hh).Length; i++)
			{
				if (!MouseKeyCodec.TryDecode(((Il2CppArrayBase<Key>)(object)hh)[i], out var button))
				{
					continue;
				}
				string text = $"Mouse{button}";
				int num2 = i * num;
				for (int j = 0; j < num; j++)
				{
					FastText val = ((Il2CppArrayBase<FastText>)(object)laneButtonTexts)[num2 + j];
					if ((Object)(object)val != (Object)null && !string.Equals(val.GetText(), text, StringComparison.Ordinal))
					{
						val.SetTextNonLocalized(text, (UpdateType)0);
					}
				}
			}
		}
	}
	internal readonly record struct MouseTransition(IntPtr Device, int Button, bool Pressed, double Time, long Sequence, CurrentKeyboardModifiersState Modifiers);
	internal static class MouseInputEvents
	{
		private sealed class MouseDeviceState
		{
			internal int ButtonOffset { get; }

			internal uint StateFormat { get; }

			internal IReadOnlyList<StandardButtonState> StandardButtons { get; }

			internal IReadOnlyList<ExtraButtonState> ExtraButtons { get; }

			internal ushort Buttons { get; set; }

			internal MouseDeviceState(int buttonOffset, uint stateFormat, ushort buttons, IReadOnlyList<StandardButtonState> standardButtons, IReadOnlyList<ExtraButtonState> extraButtons)
			{
				ButtonOffset = buttonOffset;
				StateFormat = stateFormat;
				Buttons = buttons;
				StandardButtons = standardButtons;
				ExtraButtons = extraButtons;
			}
		}

		private sealed class StandardButtonState
		{
			internal ButtonControl Control { get; }

			internal int Number { get; }

			internal StandardButtonState(ButtonControl control, int number)
			{
				Control = control;
				Number = number;
			}
		}

		private readonly record struct ButtonCandidate(ButtonControl Control, ulong StartBit, uint SizeInBits, string Path);

		private sealed class ExtraButtonState
		{
			internal ButtonControl Control { get; }

			internal int Number { get; }

			internal bool Pressed { get; set; }

			internal ExtraButtonState(ButtonControl control, int number, bool pressed)
			{
				Control = control;
				Number = number;
				Pressed = pressed;
			}
		}

		private const uint StateEventCode = 1413567571u;

		private const uint DeltaStateEventCode = 1096043588u;

		private const int RawMouseButtonCount = 16;

		private const int StateEventHeaderSize = 24;

		private const int DeltaStateEventHeaderSize = 28;

		private const int MaximumPendingTransitions = 256;

		private static readonly object Sync = new object();

		private static readonly Dictionary<IntPtr, MouseDeviceState> Devices = new Dictionary<IntPtr, MouseDeviceState>();

		private static readonly Queue<MouseTransition> Pending = new Queue<MouseTransition>();

		private static long lastSequence;

		private static bool resetRequested;

		private static bool disabled;

		internal static long CurrentSequence
		{
			get
			{
				lock (Sync)
				{
					return lastSequence;
				}
			}
		}

		internal static void EnsureDevice(Mouse? mouse)
		{
			if (disabled || mouse == null)
			{
				return;
			}
			try
			{
				lock (Sync)
				{
					GetOrCreateDevice(mouse);
				}
			}
			catch (Exception exception)
			{
				Disable(exception);
			}
		}

		internal unsafe static void Observe(InputManager manager, InputEventPtr eventPtr, InputDevice? device)
		{
			//IL_000a: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: 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_0239: Unknown result type (might be due to invalid IL or missing references)
			if (disabled || device == null || eventPtr.m_EventPtr == IntPtr.Zero)
			{
				return;
			}
			try
			{
				Mouse val = ((Il2CppObjectBase)device).TryCast<Mouse>();
				if (val == null)
				{
					return;
				}
				lock (Sync)
				{
					MouseDeviceState orCreateDevice = GetOrCreateDevice(val);
					byte* eventData = (byte*)(void*)eventPtr.m_EventPtr;
					bool contextRead = false;
					double time = 0.0;
					CurrentKeyboardModifiersState modifiers = default(CurrentKeyboardModifiersState);
					ushort num = 0;
					float num2 = default(float);
					foreach (StandardButtonState standardButton in orCreateDevice.StandardButtons)
					{
						if (InputControlExtensions.ReadValueFromEvent<float>((InputControl<float>)(object)standardButton.Control, eventPtr, ref num2))
						{
							ushort num3 = (ushort)(1 << standardButton.Number);
							num |= num3;
							bool flag = (orCreateDevice.Buttons & num3) != 0;
							float num4 = (flag ? (standardButton.Control.pressPointOrDefault * ButtonControl.s_GlobalDefaultButtonReleaseThreshold) : standardButton.Control.pressPointOrDefault);
							bool flag2 = num2 >= num4;
							if (flag2 != flag)
							{
								orCreateDevice.Buttons = (flag2 ? ((ushort)(orCreateDevice.Buttons | num3)) : ((ushort)(orCreateDevice.Buttons & ~num3)));
								QueueTransition(manager, eventPtr, ((Il2CppObjectBase)val).Pointer, standardButton.Number, flag2, ref contextRead, ref time, ref modifiers);
							}
						}
					}
					if (TryReadButtons(eventData, orCreateDevice, out var buttons))
					{
						ushort num5 = (ushort)(~num);
						ushort num6 = (ushort)((buttons ^ orCreateDevice.Buttons) & num5);
						orCreateDevice.Buttons = (ushort)((orCreateDevice.Buttons & num) | (buttons & num5));
						for (int i = 0; i < 16; i++)
						{
							ushort num7 = (ushort)(1 << i);
							if ((num6 & num7) != 0)
							{
								QueueTransition(manager, eventPtr, ((Il2CppObjectBase)val).Pointer, i, (buttons & num7) != 0, ref contextRead, ref time, ref modifiers);
							}
						}
					}
					float num8 = default(float);
					foreach (ExtraButtonState extraButton in orCreateDevice.ExtraButtons)
					{
						if (InputControlExtensions.ReadValueFromEvent<float>((InputControl<float>)(object)extraButton.Control, eventPtr, ref num8))
						{
							float num9 = (extraButton.Pressed ? (extraButton.Control.pressPointOrDefault * ButtonControl.s_GlobalDefaultButtonReleaseThreshold) : extraButton.Control.pressPointOrDefault);
							bool flag3 = num8 >= num9;
							if (flag3 != extraButton.Pressed)
							{
								extraButton.Pressed = flag3;
								QueueTransition(manager, eventPtr, ((Il2CppObjectBase)val).Pointer, extraButton.Number, flag3, ref contextRead, ref time, ref modifiers);
							}
						}
					}
				}
			}
			catch (Exception exception)
			{
				Disable(exception);
			}
		}

		internal static bool Drain(List<MouseTransition> destination)
		{
			lock (Sync)
			{
				destination.Clear();
				while (Pending.Count > 0)
				{
					destination.Add(Pending.Dequeue());
				}
				bool result = resetRequested;
				resetRequested = false;
				return result;
			}
		}

		private static MouseDeviceState GetOrCreateDevice(Mouse mouse)
		{
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: 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_0115: Unknown result type (might be due to invalid IL or missing references)
			if (Devices.TryGetValue(((Il2CppObjectBase)mouse).Pointer, out MouseDeviceState value))
			{
				return value;
			}
			StandardButtonState[] array = new StandardButtonState[5]
			{
				new StandardButtonState(mouse.leftButton, 0),
				new StandardButtonState(mouse.rightButton, 1),
				new StandardButtonState(mouse.middleButton, 2),
				new StandardButtonState(mouse.forwardButton, 3),
				new StandardButtonState(mouse.backButton, 4)
			};
			ushort num = 0;
			StandardButtonState[] array2 = array;
			foreach (StandardButtonState standardButtonState in array2)
			{
				if (standardButtonState.Control.isPressed)
				{
					num |= (ushort)(1 << standardButtonState.Number);
				}
			}
			InputStateBlock stateBlock = ((InputControl)mouse).stateBlock;
			InputStateBlock stateBlock2 = ((InputControl)mouse.leftButton).stateBlock;
			int buttonOffset = -1;
			ulong? rawButtonBaseBit = null;
			if (((InputStateBlock)(ref stateBlock2)).bitOffset == 0 && ((InputStateBlock)(ref stateBlock2)).sizeInBits == 1 && ((InputStateBlock)(ref stateBlock2)).byteOffset >= ((InputStateBlock)(ref stateBlock)).byteOffset)
			{
				uint num2 = ((InputStateBlock)(ref stateBlock2)).byteOffset - ((InputStateBlock)(ref stateBlock)).byteOffset;
				if (num2 <= int.MaxValue)
				{
					buttonOffset = (int)num2;
					rawButtonBaseBit = (ulong)num2 * 8uL;
				}
			}
			uint code = (uint)((InputStateBlock)(ref stateBlock)).format.m_Code;
			List<ExtraButtonState> extraButtons = DiscoverExtraButtons(mouse, ((InputStateBlock)(ref stateBlock)).byteOffset, rawButtonBaseBit, array);
			MouseDeviceState mouseDeviceState = new MouseDeviceState(buttonOffset, code, num, array, extraButtons);
			Devices.Add(((Il2CppObjectBase)mouse).Pointer, mouseDeviceState);
			return mouseDeviceState;
		}

		private static List<ExtraButtonState> DiscoverExtraButtons(Mouse mouse, uint deviceByteOffset, ulong? rawButtonBaseBit, IReadOnlyList<StandardButtonState> standardButtons)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			HashSet<IntPtr> hashSet = standardButtons.Select((StandardButtonState button) => ((Il2CppObjectBase)button.Control).Pointer).ToHashSet();
			List<ButtonCandidate> list = new List<ButtonCandidate>();
			ReadOnlyArray<InputControl> allControls = ((InputDevice)mouse).allControls;
			for (int num = 0; num < allControls.Count; num++)
			{
				InputControl obj = allControls[num];
				ButtonControl val = ((obj != null) ? ((Il2CppObjectBase)obj).TryCast<ButtonControl>() : null);
				if (val == null || hashSet.Contains(((Il2CppObjectBase)val).Pointer))
				{
					continue;
				}
				InputStateBlock stateBlock = ((InputControl)val).stateBlock;
				if (((InputStateBlock)(ref stateBlock)).byteOffset != uint.MaxValue && ((InputStateBlock)(ref stateBlock)).sizeInBits != 0 && ((InputStateBlock)(ref stateBlock)).byteOffset >= deviceByteOffset)
				{
					ulong num2 = (ulong)(((long)((InputStateBlock)(ref stateBlock)).byteOffset - (long)deviceByteOffset) * 8 + ((InputStateBlock)(ref stateBlock)).bitOffset);
					if (!rawButtonBaseBit.HasValue || num2 < rawButtonBaseBit.Value || num2 >= rawButtonBaseBit.Value + 16)
					{
						list.Add(new ButtonCandidate(val, num2, ((InputStateBlock)(ref stateBlock)).sizeInBits, ((InputControl)val).path ?? string.Empty));
					}
				}
			}
			list.Sort(delegate(ButtonCandidate left, ButtonCandidate right)
			{
				int num4 = left.StartBit.CompareTo(right.StartBit);
				if (num4 != 0)
				{
					return num4;
				}
				int num5 = left.SizeInBits.CompareTo(right.SizeInBits);
				return (num5 == 0) ? string.CompareOrdinal(left.Path, right.Path) : num5;
			});
			List<ButtonCandidate> list2 = new List<ButtonCandidate>();
			HashSet<(ulong, uint)> hashSet2 = new HashSet<(ulong, uint)>();
			foreach (ButtonCandidate item in list)
			{
				if (hashSet2.Add((item.StartBit, item.SizeInBits)))
				{
					list2.Add(item);
				}
			}
			List<ExtraButtonState> list3 = new List<ExtraButtonState>(list2.Count);
			HashSet<int> hashSet3 = new HashSet<int>(Enumerable.Range(0, 16));
			HashSet<IntPtr> hashSet4 = new HashSet<IntPtr>();
			foreach (ButtonCandidate item2 in list2)
			{
				if (rawButtonBaseBit.HasValue && TryGetNaturalNumber(item2, rawButtonBaseBit.Value, out var number) && hashSet3.Add(number))
				{
					list3.Add(new ExtraButtonState(item2.Control, number, item2.Control.isPressed));
					hashSet4.Add(((Il2CppObjectBase)item2.Control).Pointer);
				}
			}
			int num3 = 16;
			foreach (ButtonCandidate item3 in list2)
			{
				if (!hashSet4.Contains(((Il2CppObjectBase)item3.Control).Pointer))
				{
					for (; hashSet3.Contains(num3); num3++)
					{
					}
					if (num3 > 2147482647)
					{
						throw new NotSupportedException("当前 Mouse 布局公开的按钮数量超出可持久化范围。");
					}
					hashSet3.Add(num3);
					list3.Add(new ExtraButtonState(item3.Control, num3, item3.Control.isPressed));
					num3++;
				}
			}
			list3.Sort((ExtraButtonState left, ExtraButtonState right) => left.Number.CompareTo(right.Number));
			return list3;
		}

		private static bool TryGetNaturalNumber(ButtonCandidate candidate, ulong rawButtonBaseBit, out int number)
		{
			number = -1;
			if (candidate.SizeInBits != 1 || candidate.StartBit < rawButtonBaseBit)
			{
				return false;
			}
			ulong num = candidate.StartBit - rawButtonBaseBit;
			if (num > 2147482647)
			{
				return false;
			}
			number = (int)num;
			return true;
		}

		private unsafe static bool TryReadButtons(byte* eventData, MouseDeviceState state, out ushort buttons)
		{
			buttons = state.Buttons;
			if (state.ButtonOffset < 0)
			{
				return false;
			}
			uint num = *(uint*)eventData;
			int num2 = ((ushort*)eventData)[2];
			if (num2 < 24 || (num != 1413567571 && num != 1096043588) || ((uint*)eventData)[5] != state.StateFormat)
			{
				return false;
			}
			if (num == 1413567571)
			{
				int num3 = num2 - 24;
				if (state.ButtonOffset < 0 || state.ButtonOffset + 2 > num3)
				{
					return false;
				}
				byte* ptr = eventData + 24 + state.ButtonOffset;
				buttons = (ushort)(*ptr | (ptr[1] << 8));
				return true;
			}
			if (num2 < 28)
			{
				return false;
			}
			uint num4 = ((uint*)eventData)[6];
			int num5 = num2 - 28;
			bool result = false;
			for (int i = 0; i < 2; i++)
			{
				uint num6 = (uint)(state.ButtonOffset + i);
				if (num6 >= num4 && num6 - num4 < num5)
				{
					byte b = eventData[28 + num6 - num4];
					int num7 = i * 8;
					buttons = (ushort)((buttons & ~(255 << num7)) | (b << num7));
					result = true;
				}
			}
			return result;
		}

		internal static bool TryGetCurrentButtonState(IntPtr device, int button, out bool pressed)
		{
			lock (Sync)
			{
				pressed = false;
				if (!Devices.TryGetValue(device, out MouseDeviceState value))
				{
					return false;
				}
				foreach (StandardButtonState standardButton in value.StandardButtons)
				{
					if (standardButton.Number == button)
					{
						pressed = standardButton.Control.isPressed;
						ushort num = (ushort)(1 << button);
						value.Buttons = (pressed ? ((ushort)(value.Buttons | num)) : ((ushort)(value.Buttons & ~num)));
						return true;
					}
				}
				foreach (ExtraButtonState extraButton in value.ExtraButtons)
				{
					if (extraButton.Number == button)
					{
						pressed = extraButton.Control.isPressed;
						extraButton.Pressed = pressed;
						return true;
					}
				}
				if ((uint)button >= 16u)
				{
					return false;
				}
				pressed = (value.Buttons & (1 << button)) != 0;
				return true;
			}
		}

		private static void QueueTransition(InputManager manager, InputEventPtr eventPtr, IntPtr device, int button, bool pressed, ref bool contextRead, ref double time, ref CurrentKeyboardModifiersState modifiers)
		{
			//IL_0037: 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)
			if (!contextRead)
			{
				time = ((InputEventPtr)(ref eventPtr)).time;
				modifiers = ReadModifiers(manager);
				contextRead = true;
			}
			Enqueue(new MouseTransition(device, button, pressed, time, ++lastSequence, modifiers));
		}

		private static CurrentKeyboardModifiersState ReadModifiers(InputManager manager)
		{
			//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_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			UnityKeyboardState currentKeyboardState = manager.currentKeyboardState;
			CurrentKeyboardModifiersState result = default(CurrentKeyboardModifiersState);
			((CurrentKeyboardModifiersState)(ref result)).IsCtrlPressed = ((UnityKeyboardState)(ref currentKeyboardState)).IsPressed((Key)55) || ((UnityKeyboardState)(ref currentKeyboardState)).IsPressed((Key)56);
			((CurrentKeyboardModifiersState)(ref result)).IsAltPressed = ((UnityKeyboardState)(ref currentKeyboardState)).IsPressed((Key)53) || ((UnityKeyboardState)(ref currentKeyboardState)).IsPressed((Key)54);
			((CurrentKeyboardModifiersState)(ref result)).IsShiftPressed = ((UnityKeyboardState)(ref currentKeyboardState)).IsPressed((Key)51) || ((UnityKeyboardState)(ref currentKeyboardState)).IsPressed((Key)52);
			return result;
		}

		private static void Enqueue(MouseTransition transition)
		{
			if (Pending.Count >= 256)
			{
				Pending.Clear();
				resetRequested = true;
			}
			Pending.Enqueue(transition);
		}

		private static void Disable(Exception exception)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			lock (Sync)
			{
				disabled = true;
			}
			ManualLogSource logger = Plugin.Logger;
			bool flag;
			BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(12, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("鼠标按钮事件提取已停用:");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(exception);
			}
			logger.LogError(val);
		}
	}
	internal static class MouseKeyCodec
	{
		private const int FirstMouseKey = 1000;

		internal const int MaximumMouseButton = 2147482647;

		internal static Key Encode(int button)
		{
			if (button < 0 || button > 2147482647)
			{
				throw new ArgumentOutOfRangeException("button");
			}
			return (Key)(1000 + button);
		}

		internal static bool TryDecode(Key key, out int button)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Expected I4, but got Unknown
			int num = (int)key;
			if (num < 1000)
			{
				button = -1;
				return false;
			}
			button = num - 1000;
			return true;
		}
	}
	[BepInPlugin("menglei.infalsus.mousekeybindings", "In Falsus Mouse Key Bindings", "1.0.1")]
	[BepInProcess("infalsus.exe")]
	public sealed class Plugin : BasePlugin
	{
		internal const string PluginGuid = "menglei.infalsus.mousekeybindings";

		internal const string PluginVersion = "1.0.1";

		private Harmony? harmony;

		internal static ManualLogSource Logger { get; private set; }

		public override void Load()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			Logger = ((BasePlugin)this).Log;
			WindowsConsoleEncoding.EnsureUtf8(((BasePlugin)this).Log);
			harmony = new Harmony("menglei.infalsus.mousekeybindings");
			harmony.PatchAll(typeof(Plugin).Assembly);
			((BasePlugin)this).Log.LogInfo((object)"加载完成。");
		}
	}
	internal static class WindowsConsoleEncoding
	{
		private const uint Utf8CodePage = 65001u;

		internal static void EnsureUtf8(ManualLogSource logger)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			if (!OperatingSystem.IsWindows() || !ConsoleManager.ConsoleActive || GetConsoleOutputCP() == 65001)
			{
				return;
			}
			bool flag = default(bool);
			if (!SetConsoleOutputCP(65001u))
			{
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(75, 1, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Failed to set the BepInEx console output code page to UTF-8 (Win32 error ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(Marshal.GetLastWin32Error());
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(").");
				}
				logger.LogError(val);
				return;
			}
			uint consoleOutputCP = GetConsoleOutputCP();
			if (consoleOutputCP != 65001)
			{
				BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(54, 2, ref flag);
				if (flag)
				{
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("BepInEx console output code page remained ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<uint>(consoleOutputCP);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral("; expected ");
					((BepInExLogInterpolatedStringHandler)val).AppendFormatted<uint>(65001u);
					((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".");
				}
				logger.LogError(val);
			}
		}

		[DllImport("kernel32.dll")]
		private static extern uint GetConsoleOutputCP();

		[DllImport("kernel32.dll", SetLastError = true)]
		[return: MarshalAs(UnmanagedType.Bool)]
		private static extern bool SetConsoleOutputCP(uint codePage);
	}
}