Decompiled source of VoicemodKeybinds v1.0.0

Mods/VoicemodKeybinds.dll

Decompiled a day ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BoneLib;
using BoneLib.BoneMenu;
using BoneLib.BoneMenu.UI;
using Il2CppSLZ.Bonelab;
using Il2CppSLZ.Marrow;
using Il2CppTMPro;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using VoicemodKeybinds;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("VoicemodKeybinds")]
[assembly: AssemblyDescription("Bind VR controller inputs to keyboard letters for Voicemod hotkeys")]
[assembly: AssemblyFileVersion("1.0.0")]
[assembly: MelonInfo(typeof(Main), "VoicemodKeybinds", "1.0.0", "MrYetiSpaghetti", null)]
[assembly: MelonGame("Stress Level Zero", "BONELAB")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 VoicemodKeybinds
{
	public class KeybindSlot
	{
		private VRKeybind _keybind;

		private bool _prevState;

		private bool _suppressLetterCallback;

		public int Index { get; }

		public string Letter { get; private set; } = "";


		public StringElement LetterElement { get; set; }

		public EnumElement BindElement { get; set; }

		public VRKeybind Keybind
		{
			get
			{
				return _keybind;
			}
			set
			{
				_keybind = value;
				_prevState = false;
			}
		}

		public KeybindSlot(int index)
		{
			Index = index;
			MelonPreferences_Entry<string> val = Main.PrefCategory.CreateEntry<string>($"Slot{index}_Letter", "", (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			Letter = NormalizeLetter(val.Value);
			MelonPreferences_Entry<VRKeybind> val2 = Main.PrefCategory.CreateEntry<VRKeybind>($"Slot{index}_Bind", VRKeybind.None, (string)null, (string)null, false, false, (ValueValidator)null, (string)null);
			_keybind = val2.Value;
		}

		public void Update()
		{
			if (_keybind != 0 && !string.IsNullOrEmpty(Letter) && VRInput.IsKeybindJustPressed(_keybind, ref _prevState))
			{
				KeyboardInjector.TapLetter(Letter[0]);
			}
		}

		public void OnLetterTyped(string newValue)
		{
			if (_suppressLetterCallback)
			{
				return;
			}
			string text2 = (Letter = NormalizeLetter(newValue));
			SaveLetter();
			if (LetterElement == null || !(newValue != text2))
			{
				return;
			}
			_suppressLetterCallback = true;
			try
			{
				LetterElement.Value = text2;
			}
			finally
			{
				_suppressLetterCallback = false;
			}
		}

		public void OnKeybindCycled(VRKeybind value)
		{
			Keybind = value;
			SaveBind();
		}

		public void ResetToDefault()
		{
			_suppressLetterCallback = true;
			try
			{
				Letter = "";
				Keybind = VRKeybind.None;
				SaveLetter();
				SaveBind();
			}
			finally
			{
				_suppressLetterCallback = false;
			}
		}

		public void SaveLetter()
		{
			MelonPreferences_Entry<string> entry = Main.PrefCategory.GetEntry<string>($"Slot{Index}_Letter");
			if (entry != null)
			{
				entry.Value = Letter;
			}
			Main.PrefCategory.SaveToFile(false);
		}

		public void SaveBind()
		{
			MelonPreferences_Entry<VRKeybind> entry = Main.PrefCategory.GetEntry<VRKeybind>($"Slot{Index}_Bind");
			if (entry != null)
			{
				entry.Value = _keybind;
			}
			Main.PrefCategory.SaveToFile(false);
		}

		private static string NormalizeLetter(string raw)
		{
			if (string.IsNullOrEmpty(raw))
			{
				return "";
			}
			string text = raw.Trim();
			if (text.Length != 1)
			{
				return "";
			}
			char c = text[0];
			if (c >= 'a' && c <= 'z')
			{
				return char.ToUpperInvariant(c).ToString();
			}
			if (c >= 'A' && c <= 'Z')
			{
				return c.ToString();
			}
			return "";
		}
	}
	public static class KeyboardInjector
	{
		private struct INPUT
		{
			public uint type;

			public InputUnion U;
		}

		[StructLayout(LayoutKind.Explicit)]
		private struct InputUnion
		{
			[FieldOffset(0)]
			public KEYBDINPUT ki;

			[FieldOffset(0)]
			public MOUSEINPUT mi;

			[FieldOffset(0)]
			public HARDWAREINPUT hi;
		}

		private struct KEYBDINPUT
		{
			public ushort wVk;

			public ushort wScan;

			public uint dwFlags;

			public uint time;

			public IntPtr dwExtraInfo;
		}

		private struct MOUSEINPUT
		{
			public int dx;

			public int dy;

			public uint mouseData;

			public uint dwFlags;

			public uint time;

			public IntPtr dwExtraInfo;
		}

		private struct HARDWAREINPUT
		{
			public uint uMsg;

			public ushort wParamL;

			public ushort wParamH;
		}

		private const uint INPUT_KEYBOARD = 1u;

		private const uint KEYEVENTF_KEYUP = 2u;

		[DllImport("user32.dll", SetLastError = true)]
		private static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize);

		public static void TapLetter(char letter)
		{
			char c = char.ToUpperInvariant(letter);
			if (c >= 'A' && c <= 'Z')
			{
				ushort wVk = c;
				INPUT[] array = new INPUT[2];
				array[0].type = 1u;
				array[0].U.ki.wVk = wVk;
				array[1].type = 1u;
				array[1].U.ki.wVk = wVk;
				array[1].U.ki.dwFlags = 2u;
				SendInput((uint)array.Length, array, Marshal.SizeOf<INPUT>());
			}
		}
	}
	public class Main : MelonMod
	{
		public const int SlotCount = 10;

		private static readonly KeybindSlot[] _slots = new KeybindSlot[10];

		public static MelonPreferences_Category PrefCategory { get; private set; }

		public override void OnInitializeMelon()
		{
			PrefCategory = MelonPreferences.CreateCategory("VoicemodKeybinds");
			for (int i = 0; i < 10; i++)
			{
				_slots[i] = new KeybindSlot(i + 1);
			}
			MenuSetup.Build(_slots);
		}

		public override void OnUpdate()
		{
			if ((Object)(object)Player.RigManager == (Object)null || HelperMethods.IsLoading())
			{
				return;
			}
			UIRig instance = UIRig.Instance;
			if ((Object)(object)instance != (Object)null && (Object)(object)instance.popUpMenu != (Object)null && instance.popUpMenu.m_IsCursorShown)
			{
				return;
			}
			for (int i = 0; i < _slots.Length; i++)
			{
				try
				{
					_slots[i].Update();
				}
				catch (Exception)
				{
				}
			}
			MenuSetup.ClampScrollVelocity();
		}
	}
	public static class MenuSetup
	{
		private static readonly FieldInfo _enumIndexField = typeof(EnumElement).GetField("_index", BindingFlags.Instance | BindingFlags.NonPublic);

		private static Page _page;

		private static GameObject _navContainer;

		private static Sprite _fillSprite;

		private static Sprite _borderSprite;

		private static ScrollRect _cachedScrollRect;

		private static bool _scrollOverrideActive;

		public static void Build(KeybindSlot[] slots)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: 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_016e: Unknown result type (might be due to invalid IL or missing references)
			Page val2 = (_page = Page.Root.CreatePage("VoicemodKeybinds", Color.cyan, 0, true));
			Menu.OnPageOpened += OnPageOpened;
			foreach (KeybindSlot keybindSlot in slots)
			{
				KeybindSlot capturedSlot = keybindSlot;
				val2.CreateFunction($"--- Keybind {keybindSlot.Index} ---", Color.cyan, (Action)delegate
				{
				});
				StringElement val3 = null;
				val3 = val2.CreateString($"Letter {keybindSlot.Index}", Color.white, keybindSlot.Letter, (Action<string>)delegate(string val)
				{
					capturedSlot.OnLetterTyped(val);
				});
				keybindSlot.LetterElement = val3;
				EnumElement val4 = null;
				val4 = val2.CreateEnum("Controller Keybind", Color.magenta, (Enum)keybindSlot.Keybind, (Action<Enum>)delegate(Enum val)
				{
					capturedSlot.OnKeybindCycled((VRKeybind)(object)val);
				});
				keybindSlot.BindElement = val4;
				val2.CreateFunction($"Reset Keybind {keybindSlot.Index}", Color.red, (Action)delegate
				{
					ResetSlot(capturedSlot);
				});
			}
		}

		private static void ResetSlot(KeybindSlot slot)
		{
			slot.ResetToDefault();
			if (slot.LetterElement != null)
			{
				slot.LetterElement.Value = "";
			}
			if (slot.BindElement != null)
			{
				slot.BindElement.Value = VRKeybind.None;
				if (_enumIndexField != null)
				{
					_enumIndexField.SetValue(slot.BindElement, 0);
				}
			}
		}

		private static void OnPageOpened(Page page)
		{
			if (page == _page)
			{
				if ((Object)(object)_navContainer == (Object)null)
				{
					CreateNavButtons();
				}
				if ((Object)(object)_navContainer != (Object)null)
				{
					_navContainer.SetActive(true);
				}
				ApplyScrollOverride();
			}
			else
			{
				if ((Object)(object)_navContainer != (Object)null)
				{
					_navContainer.SetActive(false);
				}
				RestoreScrollOverride();
			}
		}

		private static void ApplyScrollOverride()
		{
			_scrollOverrideActive = true;
			CacheScrollRect();
		}

		private static void RestoreScrollOverride()
		{
			_scrollOverrideActive = false;
		}

		private static void CacheScrollRect()
		{
			if ((Object)(object)_cachedScrollRect != (Object)null)
			{
				return;
			}
			try
			{
				GUIMenu instance = GUIMenu.Instance;
				if (!((Object)(object)instance == (Object)null))
				{
					Transform val = ((Component)instance).transform.Find("Page/Content/Viewport");
					if ((Object)(object)val != (Object)null)
					{
						_cachedScrollRect = ((Component)val).GetComponent<ScrollRect>();
					}
				}
			}
			catch
			{
			}
		}

		public static void ClampScrollVelocity()
		{
			//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)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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_004f: Unknown result type (might be due to invalid IL or missing references)
			if (!_scrollOverrideActive || (Object)(object)_cachedScrollRect == (Object)null)
			{
				return;
			}
			try
			{
				Vector2 velocity = _cachedScrollRect.velocity;
				if (Mathf.Abs(velocity.y) > 1250f)
				{
					_cachedScrollRect.velocity = new Vector2(velocity.x, Mathf.Sign(velocity.y) * 1250f);
				}
			}
			catch
			{
			}
		}

		private static void CreateNavButtons()
		{
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Expected O, but got Unknown
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: 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_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			//IL_0331: Unknown result type (might be due to invalid IL or missing references)
			//IL_033d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0389: Unknown result type (might be due to invalid IL or missing references)
			//IL_038e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0406: Unknown result type (might be due to invalid IL or missing references)
			//IL_042a: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0526: Unknown result type (might be due to invalid IL or missing references)
			//IL_053d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0542: Unknown result type (might be due to invalid IL or missing references)
			//IL_0555: Unknown result type (might be due to invalid IL or missing references)
			//IL_055c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0567: Unknown result type (might be due to invalid IL or missing references)
			//IL_0572: Unknown result type (might be due to invalid IL or missing references)
			//IL_057c: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_049c: Unknown result type (might be due to invalid IL or missing references)
			GUIMenu instance = GUIMenu.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			Transform val = ((Component)instance).transform.Find("Page/Content");
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Transform val2 = val.Find("Interaction");
			if ((Object)(object)val2 == (Object)null)
			{
				return;
			}
			Transform val3 = val2.Find("ScrollUp");
			Transform val4 = val2.Find("ScrollDown");
			if ((Object)(object)val3 == (Object)null || (Object)(object)val4 == (Object)null)
			{
				return;
			}
			Transform val5 = val.Find("Viewport");
			ScrollRect scrollRect = (((Object)(object)val5 != (Object)null) ? ((Component)val5).GetComponent<ScrollRect>() : null);
			if ((Object)(object)scrollRect == (Object)null)
			{
				return;
			}
			TMP_FontAsset val6 = null;
			TextMeshProUGUI componentInChildren = ((Component)val).GetComponentInChildren<TextMeshProUGUI>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				val6 = ((TMP_Text)componentInChildren).font;
			}
			RectTransform component = ((Component)val3).GetComponent<RectTransform>();
			RectTransform component2 = ((Component)val4).GetComponent<RectTransform>();
			float y = component.anchoredPosition.y;
			float y2 = component2.anchoredPosition.y;
			float num = component.sizeDelta.y;
			float num2 = component.sizeDelta.x;
			if (num2 < 1f)
			{
				num2 = 40f;
			}
			if (num < 1f)
			{
				num = 40f;
			}
			EnsureSprites();
			float num3 = (y + y2) / 2f;
			float num4 = y - num * component.pivot.y;
			float num5 = y2 + num * (1f - component2.pivot.y);
			float num6 = Mathf.Abs(num4 - num5);
			float num7 = 2f;
			float num8 = num2 * 6f;
			_navContainer = new GameObject("VoicemodKeybinds_NavButtons");
			_navContainer.transform.SetParent(val2, false);
			RectTransform obj = _navContainer.AddComponent<RectTransform>();
			obj.anchorMin = component.anchorMin;
			obj.anchorMax = component.anchorMax;
			obj.pivot = new Vector2(0.5f, 0.5f);
			obj.anchoredPosition = new Vector2(component.anchoredPosition.x, num3);
			obj.sizeDelta = new Vector2(num8, num6);
			VerticalLayoutGroup obj2 = _navContainer.AddComponent<VerticalLayoutGroup>();
			((LayoutGroup)obj2).childAlignment = (TextAnchor)4;
			((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = true;
			((HorizontalOrVerticalLayoutGroup)obj2).spacing = num7;
			string[] array = new string[5] { "Top", "Upper", "Middle", "Lower", "Bottom" };
			float[] array2 = new float[5] { 0f, 0.25f, 0.5f, 0.75f, 1f };
			GameObject gameObject = ((Component)val3).gameObject;
			for (int i = 0; i < 5; i++)
			{
				float frac = array2[i];
				string text = array[i];
				GameObject val7 = Object.Instantiate<GameObject>(gameObject, _navContainer.transform);
				((Object)val7).name = text;
				val7.transform.localRotation = Quaternion.identity;
				LayoutElement component3 = val7.GetComponent<LayoutElement>();
				if ((Object)(object)component3 != (Object)null)
				{
					Object.Destroy((Object)(object)component3);
				}
				BoxCollider component4 = val7.GetComponent<BoxCollider>();
				if ((Object)(object)component4 != (Object)null)
				{
					float num9 = (num6 - num7 * 4f) / 5f;
					component4.size = new Vector3(num8, num9, component4.size.z);
					component4.center = Vector3.zero;
				}
				Button component5 = val7.GetComponent<Button>();
				if ((Object)(object)component5 != (Object)null)
				{
					((UnityEventBase)component5.onClick).RemoveAllListeners();
					((UnityEvent)component5.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
					{
						//IL_001c: Unknown result type (might be due to invalid IL or missing references)
						//IL_0031: Unknown result type (might be due to invalid IL or missing references)
						scrollRect.normalizedPosition = new Vector2(0f, 1f - frac);
						scrollRect.velocity = Vector2.zero;
					}));
					ColorBlock colors = ((Selectable)component5).colors;
					((ColorBlock)(ref colors)).normalColor = new Color(1f, 1f, 1f, 0.06f);
					((ColorBlock)(ref colors)).highlightedColor = new Color(1f, 1f, 1f, 0.25f);
					((ColorBlock)(ref colors)).pressedColor = new Color(1f, 1f, 1f, 1f);
					((ColorBlock)(ref colors)).selectedColor = new Color(1f, 1f, 1f, 0.06f);
					((ColorBlock)(ref colors)).colorMultiplier = 1f;
					((ColorBlock)(ref colors)).fadeDuration = 0.08f;
					((Selectable)component5).colors = colors;
				}
				for (int num10 = val7.transform.childCount - 1; num10 >= 0; num10--)
				{
					Object.Destroy((Object)(object)((Component)val7.transform.GetChild(num10)).gameObject);
				}
				Image component6 = val7.GetComponent<Image>();
				if ((Object)(object)component6 != (Object)null)
				{
					if ((Object)(object)_fillSprite != (Object)null)
					{
						component6.sprite = _fillSprite;
						component6.type = (Type)1;
					}
					((Graphic)component6).color = Color.white;
					((Graphic)component6).raycastTarget = true;
				}
				GameObject val8 = new GameObject("Border");
				val8.transform.SetParent(val7.transform, false);
				RectTransform obj3 = val8.AddComponent<RectTransform>();
				obj3.anchorMin = Vector2.zero;
				obj3.anchorMax = Vector2.one;
				obj3.sizeDelta = Vector2.zero;
				obj3.anchoredPosition = Vector2.zero;
				Image val9 = val8.AddComponent<Image>();
				if ((Object)(object)_borderSprite != (Object)null)
				{
					val9.sprite = _borderSprite;
					val9.type = (Type)1;
				}
				((Graphic)val9).color = Color.white;
				((Graphic)val9).raycastTarget = false;
				GameObject val10 = new GameObject("Text");
				val10.transform.SetParent(val7.transform, false);
				RectTransform obj4 = val10.AddComponent<RectTransform>();
				obj4.anchorMin = Vector2.zero;
				obj4.anchorMax = Vector2.one;
				obj4.sizeDelta = Vector2.zero;
				obj4.anchoredPosition = Vector2.zero;
				TextMeshProUGUI val11 = val10.AddComponent<TextMeshProUGUI>();
				((TMP_Text)val11).text = text;
				((TMP_Text)val11).alignment = (TextAlignmentOptions)514;
				((Graphic)val11).color = Color.white;
				((TMP_Text)val11).enableAutoSizing = true;
				((TMP_Text)val11).fontSizeMin = 6f;
				((TMP_Text)val11).fontSizeMax = 42f;
				if ((Object)(object)val6 != (Object)null)
				{
					((TMP_Text)val11).font = val6;
				}
			}
		}

		private static void EnsureSprites()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			//IL_00f0: 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_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_fillSprite != (Object)null)
			{
				return;
			}
			int num = 64;
			int num2 = 12;
			int num3 = 3;
			Texture2D val = new Texture2D(num, num, (TextureFormat)4, false);
			((Texture)val).filterMode = (FilterMode)1;
			Texture2D val2 = new Texture2D(num, num, (TextureFormat)4, false);
			((Texture)val2).filterMode = (FilterMode)1;
			for (int i = 0; i < num; i++)
			{
				for (int j = 0; j < num; j++)
				{
					float num4 = RoundedRectSDF(j, i, num, num, num2);
					bool flag = num4 <= 0f;
					bool flag2 = flag && num4 > (float)(-num3);
					val.SetPixel(j, i, flag ? Color.white : Color.clear);
					val2.SetPixel(j, i, flag2 ? Color.white : Color.clear);
				}
			}
			val.Apply();
			val2.Apply();
			float num5 = (float)num2 + 1f;
			Vector4 val3 = default(Vector4);
			((Vector4)(ref val3))..ctor(num5, num5, num5, num5);
			_fillSprite = Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0, val3);
			_borderSprite = Sprite.Create(val2, new Rect(0f, 0f, (float)num, (float)num), new Vector2(0.5f, 0.5f), 100f, 0u, (SpriteMeshType)0, val3);
		}

		private static float RoundedRectSDF(int px, int py, int w, int h, int r)
		{
			bool num = px < r || px > w - r - 1;
			bool flag = py < r || py > h - r - 1;
			if (num && flag)
			{
				float num2 = ((px < r) ? r : (w - r - 1));
				float num3 = ((py < r) ? r : (h - r - 1));
				float num4 = (float)px - num2;
				float num5 = (float)py - num3;
				return Mathf.Sqrt(num4 * num4 + num5 * num5) - (float)r;
			}
			float num6 = px;
			float num7 = w - 1 - px;
			float num8 = py;
			float num9 = h - 1 - py;
			return 0f - Mathf.Min(Mathf.Min(num6, num7), Mathf.Min(num8, num9));
		}
	}
	public enum VRKeybind
	{
		None,
		BPlusY,
		APlusX,
		BothSticks,
		BothTriggers,
		DoubleTapStick,
		DoubleTapLeftStick,
		DoubleTapRightStick,
		DoubleTapGrips,
		DoubleTapTriggers,
		TripleTapY,
		TripleTapX,
		TripleTapB,
		TripleTapA,
		LeftStick,
		RightStick,
		QuadTapRightGrip,
		QuadTapLeftGrip,
		YPlusA,
		XPlusB
	}
	public static class VRInput
	{
		private class TapState
		{
			public float LastTapTime;

			public int TapCount;

			public bool RawDown;

			public float DownSince;

			public bool Debounced;
		}

		private const float TapWindow = 0.8f;

		private const float GripThreshold = 0.8f;

		private const float TriggerThreshold = 0.8f;

		private const float MinHoldTime = 0.04f;

		private static readonly TapState _dtStick = new TapState();

		private static readonly TapState _dtLeftStick = new TapState();

		private static readonly TapState _dtRightStick = new TapState();

		private static readonly TapState _dtGrips = new TapState();

		private static readonly TapState _dtTriggers = new TapState();

		private static readonly TapState _ttY = new TapState();

		private static readonly TapState _ttX = new TapState();

		private static readonly TapState _ttB = new TapState();

		private static readonly TapState _ttA = new TapState();

		private static readonly TapState _qtRightGrip = new TapState();

		private static readonly TapState _qtLeftGrip = new TapState();

		private static readonly TapState[] _allTapStates = new TapState[11]
		{
			_dtStick, _dtLeftStick, _dtRightStick, _dtGrips, _dtTriggers, _ttY, _ttX, _ttB, _ttA, _qtRightGrip,
			_qtLeftGrip
		};

		private static bool _gripsBlockedByTriggers;

		private static bool _rightGripBlockedByTrigger;

		private static bool _leftGripBlockedByTrigger;

		private static bool _leftGripReleased = true;

		private static bool _rightGripReleased = true;

		private static bool _gripsValidPress;

		private static bool _leftTriggerReleased = true;

		private static bool _rightTriggerReleased = true;

		private static bool _triggersValidPress;

		public static bool IsKeybindHeld(VRKeybind keybind)
		{
			if (keybind == VRKeybind.None)
			{
				return false;
			}
			BaseController leftController = Player.LeftController;
			BaseController rightController = Player.RightController;
			return keybind switch
			{
				VRKeybind.BPlusY => rightController.GetBButton() && leftController.GetBButton(), 
				VRKeybind.APlusX => rightController.GetAButton() && leftController.GetAButton(), 
				VRKeybind.BothSticks => leftController.GetThumbStick() && rightController.GetThumbStick(), 
				VRKeybind.BothTriggers => leftController.GetPrimaryInteractionButtonAxis() > 0.8f && rightController.GetPrimaryInteractionButtonAxis() > 0.8f, 
				VRKeybind.LeftStick => leftController.GetThumbStick(), 
				VRKeybind.RightStick => rightController.GetThumbStick(), 
				VRKeybind.YPlusA => leftController.GetBButton() && rightController.GetAButton(), 
				VRKeybind.XPlusB => leftController.GetAButton() && rightController.GetBButton(), 
				_ => false, 
			};
		}

		public static bool IsKeybindJustPressed(VRKeybind keybind, ref bool previousState)
		{
			switch (keybind)
			{
			case VRKeybind.DoubleTapStick:
			{
				bool num6 = CheckMultiTap(_dtStick, IsEitherStickDown(), 2);
				if (num6)
				{
					ResetAllTapStatesExcept(_dtStick);
				}
				return num6;
			}
			case VRKeybind.DoubleTapLeftStick:
			{
				bool num7 = CheckMultiTap(_dtLeftStick, Player.LeftController.GetThumbStick(), 2);
				if (num7)
				{
					ResetAllTapStatesExcept(_dtLeftStick);
				}
				return num7;
			}
			case VRKeybind.DoubleTapRightStick:
			{
				bool num10 = CheckMultiTap(_dtRightStick, Player.RightController.GetThumbStick(), 2);
				if (num10)
				{
					ResetAllTapStatesExcept(_dtRightStick);
				}
				return num10;
			}
			case VRKeybind.DoubleTapGrips:
			{
				if (AreBothTriggersRaw())
				{
					_gripsBlockedByTriggers = true;
					return false;
				}
				if (_gripsBlockedByTriggers)
				{
					_gripsBlockedByTriggers = false;
					bool flag2 = AreBothGripsDown();
					_dtGrips.RawDown = flag2;
					_dtGrips.Debounced = flag2;
					return false;
				}
				bool num2 = CheckMultiTap(_dtGrips, AreBothGripsDown(), 2);
				if (num2)
				{
					ResetAllTapStatesExcept(_dtGrips);
				}
				return num2;
			}
			case VRKeybind.DoubleTapTriggers:
			{
				bool num = CheckMultiTap(_dtTriggers, AreBothTriggersDown(), 2);
				if (num)
				{
					ResetAllTapStatesExcept(_dtTriggers);
				}
				return num;
			}
			case VRKeybind.TripleTapY:
			{
				bool num9 = CheckMultiTap(_ttY, Player.LeftController.GetBButton(), 3);
				if (num9)
				{
					ResetAllTapStatesExcept(_ttY);
				}
				return num9;
			}
			case VRKeybind.TripleTapX:
			{
				bool num5 = CheckMultiTap(_ttX, Player.LeftController.GetAButton(), 3);
				if (num5)
				{
					ResetAllTapStatesExcept(_ttX);
				}
				return num5;
			}
			case VRKeybind.TripleTapB:
			{
				bool num3 = CheckMultiTap(_ttB, Player.RightController.GetBButton(), 3);
				if (num3)
				{
					ResetAllTapStatesExcept(_ttB);
				}
				return num3;
			}
			case VRKeybind.TripleTapA:
			{
				bool num8 = CheckMultiTap(_ttA, Player.RightController.GetAButton(), 3);
				if (num8)
				{
					ResetAllTapStatesExcept(_ttA);
				}
				return num8;
			}
			case VRKeybind.QuadTapRightGrip:
			{
				if (Player.RightController.GetPrimaryInteractionButtonAxis() > 0.8f)
				{
					_rightGripBlockedByTrigger = true;
					return false;
				}
				if (_rightGripBlockedByTrigger)
				{
					_rightGripBlockedByTrigger = false;
					bool flag4 = IsRightGripDown();
					_qtRightGrip.RawDown = flag4;
					_qtRightGrip.Debounced = flag4;
					return false;
				}
				bool num11 = CheckMultiTap(_qtRightGrip, IsRightGripDown(), 4);
				if (num11)
				{
					ResetAllTapStatesExcept(_qtRightGrip);
				}
				return num11;
			}
			case VRKeybind.QuadTapLeftGrip:
			{
				if (Player.LeftController.GetPrimaryInteractionButtonAxis() > 0.8f)
				{
					_leftGripBlockedByTrigger = true;
					return false;
				}
				if (_leftGripBlockedByTrigger)
				{
					_leftGripBlockedByTrigger = false;
					bool flag3 = IsLeftGripDown();
					_qtLeftGrip.RawDown = flag3;
					_qtLeftGrip.Debounced = flag3;
					return false;
				}
				bool num4 = CheckMultiTap(_qtLeftGrip, IsLeftGripDown(), 4);
				if (num4)
				{
					ResetAllTapStatesExcept(_qtLeftGrip);
				}
				return num4;
			}
			default:
			{
				bool flag = IsKeybindHeld(keybind);
				bool result = flag && !previousState;
				previousState = flag;
				return result;
			}
			}
		}

		private static void ResetAllTapStatesExcept(TapState keep)
		{
			TapState[] allTapStates = _allTapStates;
			foreach (TapState tapState in allTapStates)
			{
				if (tapState != keep)
				{
					tapState.TapCount = 0;
				}
			}
		}

		private static bool IsEitherStickDown()
		{
			if (!Player.LeftController.GetThumbStick())
			{
				return Player.RightController.GetThumbStick();
			}
			return true;
		}

		private static bool AreBothGripsDown()
		{
			if (AreBothTriggersRaw())
			{
				return false;
			}
			bool num = Player.LeftController.GetSecondaryInteractionButtonAxis() > 0.8f;
			bool flag = Player.RightController.GetSecondaryInteractionButtonAxis() > 0.8f;
			if (!num)
			{
				_leftGripReleased = true;
			}
			if (!flag)
			{
				_rightGripReleased = true;
			}
			if (!(num && flag))
			{
				_gripsValidPress = false;
				return false;
			}
			if (_gripsValidPress)
			{
				return true;
			}
			if (_leftGripReleased && _rightGripReleased)
			{
				_leftGripReleased = false;
				_rightGripReleased = false;
				_gripsValidPress = true;
				return true;
			}
			return false;
		}

		private static bool AreBothTriggersDown()
		{
			bool num = Player.LeftController.GetPrimaryInteractionButtonAxis() > 0.8f;
			bool flag = Player.RightController.GetPrimaryInteractionButtonAxis() > 0.8f;
			if (!num)
			{
				_leftTriggerReleased = true;
			}
			if (!flag)
			{
				_rightTriggerReleased = true;
			}
			if (!(num && flag))
			{
				_triggersValidPress = false;
				return false;
			}
			if (_triggersValidPress)
			{
				return true;
			}
			if (_leftTriggerReleased && _rightTriggerReleased)
			{
				_leftTriggerReleased = false;
				_rightTriggerReleased = false;
				_triggersValidPress = true;
				return true;
			}
			return false;
		}

		private static bool IsRightGripDown()
		{
			return Player.RightController.GetSecondaryInteractionButtonAxis() > 0.8f;
		}

		private static bool IsLeftGripDown()
		{
			return Player.LeftController.GetSecondaryInteractionButtonAxis() > 0.8f;
		}

		private static bool AreBothTriggersRaw()
		{
			if (Player.LeftController.GetPrimaryInteractionButtonAxis() > 0.8f)
			{
				return Player.RightController.GetPrimaryInteractionButtonAxis() > 0.8f;
			}
			return false;
		}

		private static bool CheckMultiTap(TapState state, bool rawDown, int requiredTaps)
		{
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			if (rawDown && !state.RawDown)
			{
				state.DownSince = realtimeSinceStartup;
			}
			state.RawDown = rawDown;
			bool flag = rawDown && realtimeSinceStartup - state.DownSince >= 0.04f;
			bool num = flag && !state.Debounced;
			state.Debounced = flag;
			if (!num)
			{
				if (state.TapCount > 0 && realtimeSinceStartup - state.LastTapTime > 0.8f)
				{
					state.TapCount = 0;
				}
				return false;
			}
			state.TapCount++;
			state.LastTapTime = realtimeSinceStartup;
			if (state.TapCount >= requiredTaps)
			{
				state.TapCount = 0;
				return true;
			}
			return false;
		}
	}
}