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 val = Main.PrefCategory.CreateEntry($"Slot{index}_Letter", "", (string)null, (string)null, false, false, (ValueValidator)null, (string)null); Letter = NormalizeLetter(val.Value); MelonPreferences_Entry val2 = Main.PrefCategory.CreateEntry($"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 entry = Main.PrefCategory.GetEntry($"Slot{Index}_Letter"); if (entry != null) { entry.Value = Letter; } Main.PrefCategory.SaveToFile(false); } public void SaveBind() { MelonPreferences_Entry entry = Main.PrefCategory.GetEntry($"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()); } } } 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)delegate(string val) { capturedSlot.OnLetterTyped(val); }); keybindSlot.LetterElement = val3; EnumElement val4 = null; val4 = val2.CreateEnum("Controller Keybind", Color.magenta, (Enum)keybindSlot.Keybind, (Action)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(); } } } 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() : null); if ((Object)(object)scrollRect == (Object)null) { return; } TMP_FontAsset val6 = null; TextMeshProUGUI componentInChildren = ((Component)val).GetComponentInChildren(); if ((Object)(object)componentInChildren != (Object)null) { val6 = ((TMP_Text)componentInChildren).font; } RectTransform component = ((Component)val3).GetComponent(); RectTransform component2 = ((Component)val4).GetComponent(); 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(); 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(); ((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, _navContainer.transform); ((Object)val7).name = text; val7.transform.localRotation = Quaternion.identity; LayoutElement component3 = val7.GetComponent(); if ((Object)(object)component3 != (Object)null) { Object.Destroy((Object)(object)component3); } BoxCollider component4 = val7.GetComponent(); 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