Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of NativeController v0.6.0
NativeController.dll
Decompiled 6 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using MenuLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.InputSystem.Layouts; using UnityEngine.InputSystem.LowLevel; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("NativeController")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.6.0.0")] [assembly: AssemblyInformationalVersion("0.6.0+2074cbac6ea40b26f02c830fd79b13635a80bf22")] [assembly: AssemblyProduct("NativeController")] [assembly: AssemblyTitle("NativeController")] [assembly: AssemblyVersion("0.6.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace NativeController { internal class AimAssist : MonoBehaviour { internal static bool HasTarget; internal static Vector3 TargetPosition; private const float CastRadius = 0.4f; private const float LosMargin = 0.5f; private const float AcquireFraction = 0.6f; private const float SwitchMarginDeg = 4f; private const float MinDwellSeconds = 0.15f; private const float PointSmoothTime = 0.08f; private static readonly FieldRef<PhysGrabber, PhysGrabObject> GrabbedRef = AccessTools.FieldRefAccess<PhysGrabber, PhysGrabObject>("grabbedPhysGrabObject"); private static readonly FieldRef<EnemyParent, Enemy> EnemyRef = AccessTools.FieldRefAccess<EnemyParent, Enemy>("Enemy"); private static readonly FieldRef<EnemyParent, bool> SpawnedRef = AccessTools.FieldRefAccess<EnemyParent, bool>("Spawned"); private int _itemMask; private int _losMask; private bool _masksReady; private GameObject _lastTarget; private float _dwellTimer; private Vector3 _smoothedPoint; private Vector3 _pointVel; private void Update() { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: 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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_0093: 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) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.Enabled.Value || !Plugin.AimAssistEnabled.Value) { Forget(); return; } CameraAim instance = CameraAim.Instance; Camera main = Camera.main; if ((Object)(object)instance == (Object)null || (Object)(object)main == (Object)null) { Forget(); return; } EnsureMasks(); if (_dwellTimer > 0f) { _dwellTimer -= Time.deltaTime; } Vector3 position = ((Component)main).transform.position; Vector3 forward = ((Component)main).transform.forward; if ((!Plugin.AimAssistEnemies.Value || !IsArmed() || !TryFindEnemy(position, forward, out var pos, out var go)) && (!Plugin.AimAssistItems.Value || !TryFindItem(position, forward, out pos, out go))) { Forget(); return; } if ((Object)(object)go != (Object)(object)_lastTarget) { _lastTarget = go; _smoothedPoint = pos; _pointVel = Vector3.zero; _dwellTimer = 0.15f; Plugin.Log.LogDebug((object)("[AimAssist] target -> " + ((Object)go).name)); } else { _smoothedPoint = Vector3.SmoothDamp(_smoothedPoint, pos, ref _pointVel, 0.08f); } TargetPosition = _smoothedPoint; HasTarget = true; } private void OnDisable() { Forget(); } private void Forget() { HasTarget = false; if ((Object)(object)_lastTarget != (Object)null) { _lastTarget = null; Plugin.Log.LogDebug((object)"[AimAssist] target -> none"); } } private static bool IsArmed() { PhysGrabber instance = PhysGrabber.instance; if ((Object)(object)instance == (Object)null) { return false; } PhysGrabObject val = GrabbedRef.Invoke(instance); if ((Object)(object)val == (Object)null) { return false; } GameObject gameObject = ((Component)val).gameObject; if (!((Object)(object)gameObject.GetComponentInChildren<ItemGun>() != (Object)null) && !((Object)(object)gameObject.GetComponentInChildren<ItemMelee>() != (Object)null)) { return (Object)(object)gameObject.GetComponentInChildren<ValuableWizardStaff>() != (Object)null; } return true; } private bool TryFindEnemy(Vector3 origin, Vector3 fwd, out Vector3 pos, out GameObject go) { //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_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) pos = Vector3.zero; go = null; EnemyDirector instance = EnemyDirector.instance; if ((Object)(object)instance == (Object)null || instance.enemiesSpawned == null) { return false; } float value = Plugin.AimAssistMaxAngle.Value; float num = value * 0.6f; float value2 = Plugin.AimAssistEnemyRange.Value; GameObject bestGo = null; float num2 = value; Vector3 bestPos = Vector3.zero; GameObject curGo = null; float curAngle = value; Vector3 curPos = Vector3.zero; foreach (EnemyParent item in instance.enemiesSpawned) { if ((Object)(object)item == (Object)null || !SpawnedRef.Invoke(item)) { continue; } Enemy val = EnemyRef.Invoke(item); if ((Object)(object)val == (Object)null) { continue; } Transform val2 = (((Object)(object)val.CenterTransform != (Object)null) ? val.CenterTransform : ((Component)val).transform); GameObject gameObject = ((Component)val).gameObject; float maxAngle = (((Object)(object)gameObject == (Object)(object)_lastTarget) ? value : num); if (Passes(origin, fwd, val2.position, value2, maxAngle, out var angle)) { if ((Object)(object)gameObject == (Object)(object)_lastTarget) { curGo = gameObject; curAngle = angle; curPos = val2.position; } if (angle < num2) { num2 = angle; bestGo = gameObject; bestPos = val2.position; } } } return Resolve(bestGo, num2, bestPos, curGo, curAngle, curPos, out pos, out go); } private bool TryFindItem(Vector3 origin, Vector3 fwd, out Vector3 pos, out GameObject go) { //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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) pos = Vector3.zero; go = null; float value = Plugin.AimAssistMaxAngle.Value; float num = value * 0.6f; float value2 = Plugin.AimAssistItemRange.Value; RaycastHit[] array = Physics.SphereCastAll(origin, 0.4f, fwd, value2, _itemMask, (QueryTriggerInteraction)2); GameObject bestGo = null; float num2 = value; Vector3 bestPos = Vector3.zero; GameObject curGo = null; float curAngle = value; Vector3 curPos = Vector3.zero; RaycastHit[] array2 = array; for (int i = 0; i < array2.Length; i++) { RaycastHit val = array2[i]; if (!((Component)((RaycastHit)(ref val)).collider).CompareTag("Phys Grab Object")) { continue; } PhysGrabObject componentInParent = ((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<PhysGrabObject>(); if ((Object)(object)componentInParent == (Object)null) { continue; } GameObject gameObject = ((Component)componentInParent).gameObject; Vector3 centerPoint = componentInParent.centerPoint; float maxAngle = (((Object)(object)gameObject == (Object)(object)_lastTarget) ? value : num); if (Passes(origin, fwd, centerPoint, value2, maxAngle, out var angle)) { if ((Object)(object)gameObject == (Object)(object)_lastTarget) { curGo = gameObject; curAngle = angle; curPos = centerPoint; } if (angle < num2) { num2 = angle; bestGo = gameObject; bestPos = centerPoint; } } } return Resolve(bestGo, num2, bestPos, curGo, curAngle, curPos, out pos, out go); } private bool Resolve(GameObject bestGo, float bestAngle, Vector3 bestPos, GameObject curGo, float curAngle, Vector3 curPos, out Vector3 pos, out GameObject go) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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) if ((Object)(object)curGo != (Object)null && ((Object)(object)bestGo == (Object)(object)curGo || _dwellTimer > 0f || bestAngle > curAngle - 4f)) { pos = curPos; go = curGo; return true; } pos = bestPos; go = bestGo; return (Object)(object)go != (Object)null; } private bool Passes(Vector3 origin, Vector3 fwd, Vector3 target, float range, float maxAngle, out float angle) { //IL_0008: 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_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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) angle = 999f; Vector3 val = target - origin; float magnitude = ((Vector3)(ref val)).magnitude; if (magnitude < 0.05f || magnitude > range) { return false; } angle = Vector3.Angle(fwd, val); if (angle > maxAngle) { return false; } if (Physics.Raycast(origin, val / magnitude, magnitude - 0.5f, _losMask)) { return false; } return true; } private void EnsureMasks() { //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (!_masksReady) { _itemMask = (_losMask = LayerMask.op_Implicit(SemiFunc.LayerMaskGetVisionObstruct())) & ~LayerMask.GetMask(new string[1] { "Player" }); _masksReady = true; } } } internal static class ButtonNames { internal enum Control { South, East, West, North, LB, RB, LT, RT, L3, R3, DpadLeft, DpadUp, DpadRight, DpadDown, Start, Select, LStick, RStick } internal static string Of(Control c, ControllerDetect.Kind kind) { return kind switch { ControllerDetect.Kind.PlayStation => Ps(c), ControllerDetect.Kind.Switch => Sw(c), _ => Xbox(c), }; } private static string Xbox(Control c) { return c switch { Control.South => "A", Control.East => "B", Control.West => "X", Control.North => "Y", Control.LB => "LB", Control.RB => "RB", Control.LT => "LT", Control.RT => "RT", Control.L3 => "L3", Control.R3 => "R3", Control.DpadLeft => "←", Control.DpadUp => "↑", Control.DpadRight => "→", Control.DpadDown => "↓", Control.Start => "Menu", Control.Select => "View", Control.LStick => "L-Stick", Control.RStick => "R-Stick", _ => "?", }; } private static string Ps(Control c) { return c switch { Control.South => "✕", Control.East => "○", Control.West => "□", Control.North => "△", Control.LB => "L1", Control.RB => "R1", Control.LT => "L2", Control.RT => "R2", Control.L3 => "L3", Control.R3 => "R3", Control.DpadLeft => "←", Control.DpadUp => "↑", Control.DpadRight => "→", Control.DpadDown => "↓", Control.Start => "Options", Control.Select => "Create", Control.LStick => "L-Stick", Control.RStick => "R-Stick", _ => "?", }; } private static string Sw(Control c) { return c switch { Control.South => "B", Control.East => "A", Control.West => "Y", Control.North => "X", Control.LB => "L", Control.RB => "R", Control.LT => "ZL", Control.RT => "ZR", Control.L3 => "L3", Control.R3 => "R3", Control.DpadLeft => "←", Control.DpadUp => "↑", Control.DpadRight => "→", Control.DpadDown => "↓", Control.Start => "+", Control.Select => "-", Control.LStick => "L-Stick", Control.RStick => "R-Stick", _ => "?", }; } } internal class ChatKeyboard : MonoBehaviour { private static readonly FieldRef<ChatManager, bool> ChatActiveRef = AccessTools.FieldRefAccess<ChatManager, bool>("chatActive"); private static readonly FieldRef<ChatManager, string> ChatMessageRef = AccessTools.FieldRefAccess<ChatManager, string>("chatMessage"); private static readonly FieldRef<ChatManager, List<string>> ChatHistoryRef = AccessTools.FieldRefAccess<ChatManager, List<string>>("chatHistory"); private static readonly FieldRef<ChatManager, int> ChatHistoryIndexRef = AccessTools.FieldRefAccess<ChatManager, int>("chatHistoryIndex"); private static readonly Action<ChatManager, ChatState> StateSet = AccessTools.MethodDelegate<Action<ChatManager, ChatState>>(AccessTools.Method(typeof(ChatManager), "StateSet", (Type[])null, (Type[])null), (object)null, true); internal static bool Open; internal static float PanelTop; private const int MaxChatLength = 50; private const float PadOpenWindow = 0.25f; private const float FlickFire = 0.6f; private const float FlickRearm = 0.3f; private readonly PadKeyboardCore _core = new PadKeyboardCore(hasSpace: true, "SEND", "CLOSE"); private bool _selectArmed; private float _lastSelectPress = -10f; private bool _prevChatActive; private bool _flickArmed; private static bool _warned; private void Awake() { _core.OnChar = TypeChar; _core.OnConfirm = SendOrClose; _core.OnClose = Cancel; } internal static void ResetState() { Open = false; PanelTop = 0f; } private void Update() { ChatManager instance = ChatManager.instance; Gamepad current = Gamepad.current; if ((Object)(object)instance == (Object)null || !Plugin.Enabled.Value || !Plugin.ChatKeyboardEnabled.Value) { Open = false; return; } bool flag; try { flag = ChatActiveRef.Invoke(instance); } catch (Exception e) { WarnOnce(e); Open = false; return; } if (current != null && current.selectButton.wasPressedThisFrame) { _lastSelectPress = Time.unscaledTime; } if (!flag) { Open = false; _prevChatActive = false; return; } if (!_prevChatActive) { _prevChatActive = true; if (current != null && Time.unscaledTime - _lastSelectPress < 0.25f) { Open = true; PanelTop = 0f; _core.Reset(); _selectArmed = false; _flickArmed = false; } } if (!Open || current == null) { return; } if (!current.selectButton.isPressed && !current.selectButton.wasReleasedThisFrame) { _selectArmed = true; } try { _core.HandleInput(current); HandleHistoryFlick(current, instance); if (_selectArmed && current.selectButton.wasReleasedThisFrame) { Cancel(); } } catch (Exception e2) { WarnOnce(e2); } } private void TypeChar(string s) { //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) ChatManager instance = ChatManager.instance; if (!((Object)(object)instance == (Object)null)) { if ((ChatMessageRef.Invoke(instance) ?? "").Length >= 50) { ((SemiUI)ChatUI.instance).SemiUITextFlashColor(Color.red, 0.2f); ((SemiUI)ChatUI.instance).SemiUISpringShakeX(10f, 10f, 0.3f); ((SemiUI)ChatUI.instance).SemiUISpringScale(0.05f, 5f, 0.2f); MenuManager.instance.MenuEffectClick((MenuClickEffectType)2, (MenuPage)null, 1f, 1f, true); } else { instance.AddLetterToChat(s); ((SemiUI)ChatUI.instance).SemiUITextFlashColor(Color.yellow, 0.2f); ((SemiUI)ChatUI.instance).SemiUISpringShakeY(2f, 5f, 0.2f); MenuManager.instance.MenuEffectClick((MenuClickEffectType)4, (MenuPage)null, 2f, 0.2f, true); } } } private void HandleHistoryFlick(Gamepad gp, ChatManager chat) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) if (chat.StateIsActive() && Plugin.ChatHistoryRecallEnabled.Value) { float y = ((InputControl<Vector2>)(object)gp.rightStick).ReadValue().y; if (Mathf.Abs(y) < Mathf.Max(0.3f, Plugin.StickDeadzone.Value)) { _flickArmed = true; } else if (_flickArmed && !(Mathf.Abs(y) < 0.6f)) { _flickArmed = false; HistoryStep(chat, y > 0f); } } } private void HistoryStep(ChatManager chat, bool older) { //IL_007f: Unknown result type (might be due to invalid IL or missing references) List<string> list = ChatHistoryRef.Invoke(chat); if (list == null || list.Count == 0) { return; } ref int reference = ref ChatHistoryIndexRef.Invoke(chat); if (older) { if (reference > 0) { reference--; } else { reference = list.Count - 1; } } else if (reference < list.Count - 1) { reference++; } else { reference = 0; } string text = list[reference]; ChatMessageRef.Invoke(chat) = text; ((TMP_Text)chat.chatText).text = text; ((SemiUI)ChatUI.instance).SemiUITextFlashColor(Color.cyan, 0.2f); ((SemiUI)ChatUI.instance).SemiUISpringShakeY(2f, 5f, 0.2f); MenuManager.instance.MenuEffectClick((MenuClickEffectType)4, (MenuPage)null, 1f, 0.2f, true); } private void SendOrClose() { ChatManager instance = ChatManager.instance; if (!((Object)(object)instance == (Object)null)) { if ((ChatMessageRef.Invoke(instance) ?? "") != "") { instance.ForceConfirmChat(); return; } StateSet(instance, (ChatState)0); Open = false; } } private void Cancel() { ChatManager instance = ChatManager.instance; if (!((Object)(object)instance == (Object)null)) { StateSet(instance, (ChatState)0); ((SemiUI)ChatUI.instance).SemiUISpringShakeX(10f, 10f, 0.3f); ((SemiUI)ChatUI.instance).SemiUISpringScale(0.05f, 5f, 0.2f); MenuManager.instance.MenuEffectClick((MenuClickEffectType)2, (MenuPage)null, 1f, 1f, true); Open = false; } } private static void WarnOnce(Exception e) { if (!_warned) { _warned = true; Plugin.Log.LogWarning((object)("[ChatKeyboard] Error (further warnings suppressed): " + e.Message)); } } private void OnGUI() { if (Open) { float value = Plugin.ChatScale.Value; _core.Draw(value, Mathf.Max(40f * value, (float)Screen.height * 0.13f)); PanelTop = _core.LastPanelTop; } } } [HarmonyPatch] internal static class ChatKeyboardMapGuard { [HarmonyPatch(typeof(InputManager), "KeyDown")] [HarmonyPostfix] private static void KeyDownPostfix(InputKey key, ref bool __result) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 if (__result && (int)key == 8 && ChatKeyboard.Open) { __result = false; } } [HarmonyPatch(typeof(InputManager), "KeyHold")] [HarmonyPostfix] private static void KeyHoldPostfix(InputKey key, ref bool __result) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 if (__result && (int)key == 8 && ChatKeyboard.Open) { __result = false; } } } internal class ChatLog : MonoBehaviour { private struct Entry { public string Name; public string Text; } private const int MaxEntries = 30; private const float FadeSeconds = 1f; private static readonly List<Entry> Entries = new List<Entry>(); private static float _lastMessageTime = -1000f; private static int _entriesVersion; private GUIStyle _line; private GUIStyle _name; private float _styleScale = -1f; private int _layoutVersion = -1; private int _layoutCount; private float _layoutScale = -1f; private float _panelW; private float _layoutScreenW = -1f; private float[] _nameWidths; internal static void Append(string name, string text) { Entries.Add(new Entry { Name = (string.IsNullOrEmpty(name) ? "???" : name) + ":", Text = " " + text }); if (Entries.Count > 30) { Entries.RemoveAt(0); } _lastMessageTime = Time.unscaledTime; _entriesVersion++; } private void OnGUI() { //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Expected O, but got Unknown //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Expected O, but got Unknown //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: Unknown result type (might be due to invalid IL or missing references) //IL_0304: Unknown result type (might be due to invalid IL or missing references) //IL_0329: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.Enabled.Value || !Plugin.ChatLogEnabled.Value || Entries.Count == 0) { return; } float num = VisibleAlpha(); if (num <= 0f) { return; } float num2 = Plugin.ChatScale.Value * 2.142857f; EnsureStyles(num2); int num3 = Mathf.Min(Plugin.ChatLogMaxVisible.Value, Entries.Count); float num4 = 20f * num2; float num5 = 8f * num2; float num6 = 5f * num2; float num7 = 12f * num2; if (_layoutVersion != _entriesVersion || !Mathf.Approximately(_layoutScale, num2) || _layoutCount != num3 || !Mathf.Approximately(_layoutScreenW, (float)Screen.width)) { _layoutVersion = _entriesVersion; _layoutScale = num2; _layoutCount = num3; _layoutScreenW = Screen.width; if (_nameWidths == null || _nameWidths.Length < num3) { _nameWidths = new float[num3]; } _panelW = 0f; for (int i = 0; i < num3; i++) { Entry entry = Entries[Entries.Count - num3 + i]; float x = _name.CalcSize(new GUIContent(entry.Name)).x; float x2 = _line.CalcSize(new GUIContent(entry.Text)).x; _nameWidths[i] = x; _panelW = Mathf.Max(_panelW, x + x2); } _panelW = Mathf.Min(_panelW + 2f * num5, (float)Screen.width - 2f * num7); } float num8 = (float)num3 * num4 + 2f * num6; float num9 = (float)Screen.height - num7; if (ChatKeyboard.Open && ChatKeyboard.PanelTop > 0f) { num9 = ChatKeyboard.PanelTop - num7; } float num10 = num7; float num11 = num9 - num8; GUI.color = new Color(0f, 0f, 0f, 0.55f * num); GUI.DrawTexture(new Rect(num10, num11, _panelW, num8), (Texture)(object)Texture2D.whiteTexture); for (int j = 0; j < num3; j++) { Entry entry2 = Entries[Entries.Count - num3 + j]; float num12 = num11 + num6 + (float)j * num4; GUI.color = new Color(1f, 0.85f, 0.3f, num); GUI.Label(new Rect(num10 + num5, num12, _nameWidths[j], num4), entry2.Name, _name); GUI.color = new Color(1f, 1f, 1f, num); GUI.Label(new Rect(num10 + num5 + _nameWidths[j], num12, Mathf.Max(0f, _panelW - 2f * num5 - _nameWidths[j]), num4), entry2.Text, _line); } GUI.color = Color.white; } private static float VisibleAlpha() { ChatManager instance = ChatManager.instance; if ((Object)(object)instance != (Object)null && !instance.StateIsInactive()) { return 1f; } float value = Plugin.ChatLogVisibleSeconds.Value; if (value <= 0f) { return 0f; } float num = value - (Time.unscaledTime - _lastMessageTime); if (num <= 0f) { return 0f; } if (!(num >= 1f)) { return num / 1f; } return 1f; } private void EnsureStyles(float scale) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0064: 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) //IL_0075: Expected O, but got Unknown if (_line == null || !Mathf.Approximately(_styleScale, scale)) { _styleScale = scale; _line = new GUIStyle(GUI.skin.label) { fontSize = (int)(14f * scale), alignment = (TextAnchor)3 }; _line.normal.textColor = Color.white; _name = new GUIStyle(_line) { fontStyle = (FontStyle)1 }; _layoutScale = -1f; } } } [HarmonyPatch] internal static class ChatLogCapturePatch { private static readonly FieldRef<PlayerAvatar, string> PlayerNameRef; private static bool _warned; static ChatLogCapturePatch() { try { PlayerNameRef = AccessTools.FieldRefAccess<PlayerAvatar, string>("playerName"); } catch { PlayerNameRef = null; } } [HarmonyPatch(typeof(PlayerAvatar), "ChatMessageSpeak")] [HarmonyPostfix] private static void Postfix(PlayerAvatar __instance, string _message) { if (!Plugin.Enabled.Value || !Plugin.ChatLogEnabled.Value) { return; } try { if (PlayerNameRef == null) { WarnOnce("playerName field not found"); } else { ChatLog.Append(PlayerNameRef.Invoke(__instance), _message); } } catch (Exception ex) { WarnOnce(ex.Message); } } private static void WarnOnce(string why) { if (!_warned) { _warned = true; Plugin.Log.LogWarning((object)("[ChatLog] Capture disabled (further warnings suppressed): " + why)); } } } internal static class ControllerDetect { internal enum Kind { None, Xbox, PlayStation, Switch, Generic } internal enum Style { Auto, Xbox, PlayStation, Switch } private static Kind _detected; private static bool _padActiveInit; internal static Kind Current => ((Plugin.GlyphStyle != null) ? Plugin.GlyphStyle.Value : Style.Auto) switch { Style.Xbox => Kind.Xbox, Style.PlayStation => Kind.PlayStation, Style.Switch => Kind.Switch, _ => _detected, }; internal static bool PadActive { get; private set; } internal static bool PadTouchedThisLevel { get; private set; } internal static void ResetLevelTouch() { PadTouchedThisLevel = false; } internal static void TrackActiveInput() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) Gamepad current = Gamepad.current; if (current == null) { PadActive = false; _padActiveInit = true; return; } if (!_padActiveInit) { _padActiveInit = true; PadActive = true; } Vector2 val = ((InputControl<Vector2>)(object)current.leftStick).ReadValue(); if (!(((Vector2)(ref val)).sqrMagnitude > 0.02f)) { val = ((InputControl<Vector2>)(object)current.rightStick).ReadValue(); if (!(((Vector2)(ref val)).sqrMagnitude > 0.02f) && !(((InputControl<Vector2>)(object)current.dpad).ReadValue() != Vector2.zero) && !current.buttonSouth.isPressed && !current.buttonEast.isPressed && !current.buttonWest.isPressed && !current.buttonNorth.isPressed && !current.leftTrigger.isPressed && !current.rightTrigger.isPressed && !current.leftShoulder.isPressed && !current.rightShoulder.isPressed && !current.startButton.isPressed && !current.selectButton.isPressed && !current.leftStickButton.isPressed && !current.rightStickButton.isPressed) { Mouse current2 = Mouse.current; int num; if (current2 != null) { val = ((InputControl<Vector2>)(object)((Pointer)current2).delta).ReadValue(); num = ((((Vector2)(ref val)).sqrMagnitude > 4f || current2.leftButton.isPressed || current2.rightButton.isPressed) ? 1 : 0); } else { num = 0; } Keyboard current3 = Keyboard.current; bool flag = current3 != null && ((ButtonControl)current3.anyKey).isPressed; if (((uint)num | (flag ? 1u : 0u)) != 0) { PadActive = false; } return; } } PadActive = true; PadTouchedThisLevel = true; } internal static void Init() { Detect(); InputSystem.onDeviceChange += delegate(InputDevice device, InputDeviceChange change) { if (device is Gamepad) { Detect(); } }; } private static void Detect() { Gamepad current = Gamepad.current; Kind kind = Classify(current); if (kind != _detected) { _detected = kind; string arg = ((current == null) ? "none" : (((InputControl)current).displayName + " (layout=" + ((InputControl)current).layout + ")")); Style style = ((Plugin.GlyphStyle != null) ? Plugin.GlyphStyle.Value : Style.Auto); string arg2 = ((style == Style.Auto) ? "" : $" (glyph override active: {style})"); Plugin.Log.LogInfo((object)$"[Gamepad] Detected controller: {kind} — {arg}{arg2}"); } } private static Kind Classify(Gamepad gp) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) if (gp == null) { return Kind.None; } InputDeviceDescription description = ((InputDevice)gp).description; string text = (((InputDeviceDescription)(ref description)).manufacturer + " " + ((InputDeviceDescription)(ref description)).product + " " + ((InputControl)gp).layout + " " + ((InputControl)gp).name).ToLowerInvariant(); if (text.Contains("dualsense") || text.Contains("dualshock") || text.Contains("sony") || text.Contains("playstation") || text.Contains("wireless controller")) { return Kind.PlayStation; } if (text.Contains("switch") || text.Contains("pro controller") || text.Contains("nintendo") || text.Contains("joy-con")) { return Kind.Switch; } if (text.Contains("xinput") || text.Contains("xbox")) { return Kind.Xbox; } return Kind.Generic; } } internal static class ControllerGlyphs { private static Font _symbol; private static bool _tried; private static GUIStyle _shapeStyle; private static Font Symbol() { if (!_tried) { _tried = true; try { _symbol = Font.CreateDynamicFontFromOSFont(new string[4] { "Arial Unicode MS", "Segoe UI Symbol", "Segoe UI", "Arial" }, 16); } catch { _symbol = null; } } return _symbol; } private static bool IsSymbol(char c) { if (c != '○' && c != '□' && c != '△' && c != '←' && c != '↑' && c != '→') { return c == '↓'; } return true; } private static bool HasSymbol(string s) { for (int i = 0; i < s.Length; i++) { if (IsSymbol(s[i])) { return true; } } return false; } internal static void DrawLabel(Rect rect, string text, GUIStyle style) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0052: 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Expected O, but got Unknown //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Expected O, but got Unknown //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) Font val = Symbol(); if ((Object)(object)val == (Object)null || !HasSymbol(text)) { GUI.Label(rect, text, style); return; } if (_shapeStyle == null) { _shapeStyle = new GUIStyle(); } _shapeStyle.font = val; _shapeStyle.fontSize = style.fontSize; _shapeStyle.fontStyle = style.fontStyle; _shapeStyle.alignment = (TextAnchor)0; _shapeStyle.normal.textColor = style.normal.textColor; float num = ((Rect)(ref rect)).x; int i = 0; while (i < text.Length) { if (IsSymbol(text[i])) { string text2 = text[i].ToString(); float x = _shapeStyle.CalcSize(new GUIContent(text2)).x; GUI.Label(new Rect(num, ((Rect)(ref rect)).y, x, ((Rect)(ref rect)).height), text2, _shapeStyle); num += x; i++; continue; } int num2 = i; for (; i < text.Length && !IsSymbol(text[i]); i++) { } string text3 = text.Substring(num2, i - num2); float x2 = style.CalcSize(new GUIContent(text3)).x; GUI.Label(new Rect(num, ((Rect)(ref rect)).y, x2, ((Rect)(ref rect)).height), text3, style); num += x2; } } } internal class ControllerLayoutOverlay : MonoBehaviour { private static readonly FieldRef<MenuManager, int> StateRef = AccessTools.FieldRefAccess<MenuManager, int>("currentMenuState"); internal static bool Visible; private static int _openFrame; private GUIStyle _title; private GUIStyle _row; private GUIStyle _key; internal static void Toggle() { Visible = !Visible; if (Visible) { _openFrame = Time.frameCount; } } private static bool MenuOpen() { MenuManager instance = MenuManager.instance; if ((Object)(object)instance != (Object)null) { return StateRef.Invoke(instance) == 0; } return false; } private void Update() { if (!Plugin.Enabled.Value) { Visible = false; return; } Gamepad current = Gamepad.current; if (current == null) { Visible = false; return; } if (Visible && Time.frameCount > _openFrame + 1 && (AnyButtonPressed(current) || MouseClicked())) { Visible = false; } if (!MenuOpen()) { Visible = false; } } private static bool MouseClicked() { Mouse current = Mouse.current; if (current != null) { if (!current.leftButton.wasPressedThisFrame) { return current.rightButton.wasPressedThisFrame; } return true; } return false; } private static bool AnyButtonPressed(Gamepad gp) { if (!gp.buttonSouth.wasPressedThisFrame && !gp.buttonEast.wasPressedThisFrame && !gp.buttonWest.wasPressedThisFrame && !gp.buttonNorth.wasPressedThisFrame && !gp.leftShoulder.wasPressedThisFrame && !gp.rightShoulder.wasPressedThisFrame && !gp.leftTrigger.wasPressedThisFrame && !gp.rightTrigger.wasPressedThisFrame && !gp.dpad.up.wasPressedThisFrame && !gp.dpad.down.wasPressedThisFrame && !gp.dpad.left.wasPressedThisFrame && !gp.dpad.right.wasPressedThisFrame && !gp.startButton.wasPressedThisFrame && !gp.selectButton.wasPressedThisFrame && !gp.leftStickButton.wasPressedThisFrame) { return gp.rightStickButton.wasPressedThisFrame; } return true; } private void OnGUI() { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_0129: 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) if (!Visible) { return; } EnsureStyles(); List<KeyValuePair<string, string>> list = Rows(ControllerDetect.Current); GUI.color = new Color(0f, 0f, 0f, 0.6f); GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)Texture2D.whiteTexture); float num = 520f; float num2 = 26f; float num3 = 60f + (float)list.Count * num2; float num4 = ((float)Screen.width - num) / 2f; float num5 = ((float)Screen.height - num3) / 2f; GUI.color = new Color(0.1f, 0.1f, 0.1f, 0.95f); GUI.DrawTexture(new Rect(num4, num5, num, num3), (Texture)(object)Texture2D.whiteTexture); GUI.color = Color.white; GUI.Label(new Rect(num4, num5 + 12f, num, 30f), "Controller Layout", _title); float num6 = num5 + 50f; foreach (KeyValuePair<string, string> item in list) { GUI.Label(new Rect(num4 + 24f, num6, num * 0.55f, num2), item.Key, _row); ControllerGlyphs.DrawLabel(new Rect(num4 + num * 0.55f, num6, num * 0.4f, num2), item.Value, _key); num6 += num2; } } private static List<KeyValuePair<string, string>> Rows(ControllerDetect.Kind k) { List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>(); list.Add(R("Move / Look", N(ButtonNames.Control.LStick) + " / " + N(ButtonNames.Control.RStick))); list.Add(R("Jump", N(ButtonNames.Control.South))); list.Add(R("Interact", N(ButtonNames.Control.West))); list.Add(R("Tumble", N(ButtonNames.Control.East))); list.Add(R("Map", N(ButtonNames.Control.North))); list.Add(R("Sprint / Crouch", N(ButtonNames.Control.L3) + " / " + N(ButtonNames.Control.R3))); list.Add(R("Grab / Rotate", N(ButtonNames.Control.RT) + " / " + N(ButtonNames.Control.LT))); list.Add(R("Push / Pull", N(ButtonNames.Control.RB) + " / " + N(ButtonNames.Control.LB))); list.Add(R("Pause / Chat", N(ButtonNames.Control.Start) + " / " + N(ButtonNames.Control.Select))); list.Add(R("Inventory 1 / 2 / 3", N(ButtonNames.Control.DpadLeft) + " / " + N(ButtonNames.Control.DpadUp) + " / " + N(ButtonNames.Control.DpadRight))); list.Add(R("Emotes", "hold " + N(ButtonNames.Control.DpadDown))); list.Add(R("View this layout", "Settings menu")); list.Add(R("Menu: Select / Back", N(ButtonNames.Control.South) + " / " + N(ButtonNames.Control.East))); return list; string N(ButtonNames.Control c) { return ButtonNames.Of(c, k); } static KeyValuePair<string, string> R(string a, string b) { return new KeyValuePair<string, string>(a, b); } } private void EnsureStyles() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_003f: 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_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown //IL_00b9: Unknown result type (might be due to invalid IL or missing references) if (_title == null) { _title = new GUIStyle(GUI.skin.label) { fontSize = 22, fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }; _title.normal.textColor = Color.white; _row = new GUIStyle(GUI.skin.label) { fontSize = 16 }; _row.normal.textColor = Color.white; _key = new GUIStyle(GUI.skin.label) { fontSize = 16, fontStyle = (FontStyle)1 }; _key.normal.textColor = new Color(1f, 0.85f, 0.3f); } } } internal class EmoteWheel : MonoBehaviour { private static readonly FieldRef<MenuManager, int> MenuStateRef; private static readonly FieldRef<ChatManager, bool> ChatActiveRef; private static readonly Action<PlayerExpression, int, float, bool> DoExpression; private static readonly FieldRef<DataDirector, bool> ToggleMuteRef; internal static bool Open; private const int SegmentCount = 7; private const int ExpressionCount = 6; private const int MuteSegment = 7; private const float MinDeflection = 0.35f; private static readonly float[] SegmentAngles; private static readonly Dictionary<int, float> Active; private static readonly List<int> Expired; private static string[] _labels; private static bool _warned; private static bool _muteWarned; private int _hovered; private static Transform _previewCam; private static bool _camMoved; private static Vector3 _camHomeLocal; private GUIStyle _title; private GUIStyle _label; private GUIStyle _labelHover; private GUIStyle _labelActive; private GUIStyle _labelDisabled; static EmoteWheel() { MenuStateRef = AccessTools.FieldRefAccess<MenuManager, int>("currentMenuState"); ChatActiveRef = AccessTools.FieldRefAccess<ChatManager, bool>("chatActive"); DoExpression = AccessTools.MethodDelegate<Action<PlayerExpression, int, float, bool>>(AccessTools.Method(typeof(PlayerExpression), "DoExpression", (Type[])null, (Type[])null), (object)null, true); SegmentAngles = new float[8] { 0f, 15f, 45f, 75f, 105f, 135f, 165f, 270f }; Active = new Dictionary<int, float>(); Expired = new List<int>(); try { ToggleMuteRef = AccessTools.FieldRefAccess<DataDirector, bool>("toggleMute"); } catch { ToggleMuteRef = null; } } internal static void ResetState() { Active.Clear(); _labels = null; Open = false; _previewCam = null; _camMoved = false; } private void Update() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.Enabled.Value || !Plugin.EmoteWheelEnabled.Value) { Close(); return; } Gamepad current = Gamepad.current; if (current == null || !InGameplay()) { Close(); return; } if (current.dpad.down.isPressed) { Open = true; _hovered = HoveredSegment(((InputControl<Vector2>)(object)current.rightStick).ReadValue()); } else if (Open) { int num = HoveredSegment(((InputControl<Vector2>)(object)current.rightStick).ReadValue()); if (num == 0) { num = _hovered; } Close(); switch (num) { case 7: ToggleMute(); break; default: ToggleExpression(num); break; case 0: break; } } DriveActiveExpressions(); } private void LateUpdate() { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: 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_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) if (!Open && Active.Count <= 0) { RestoreCamera(); return; } PlayerExpressionsUI instance = PlayerExpressionsUI.instance; if ((Object)(object)instance == (Object)null) { return; } Transform val = FindPreviewCamera(instance); if (!((Object)(object)val == (Object)null)) { if (!_camMoved) { _camHomeLocal = val.localPosition; _camMoved = true; } val.localPosition = _camHomeLocal; val.position += val.forward * (0f - Plugin.EmoteZoomOut.Value) + val.up * (0f - Plugin.EmoteCameraLower.Value); } } private static Transform FindPreviewCamera(PlayerExpressionsUI ui) { if ((Object)(object)_previewCam != (Object)null) { return _previewCam; } if ((Object)(object)ui.PlayerAvatarMenu == (Object)null) { return null; } PlayerAvatarMenu component = ui.PlayerAvatarMenu.GetComponent<PlayerAvatarMenu>(); if ((Object)(object)component == (Object)null || (Object)(object)component.cameraAndStuff == (Object)null) { return null; } Camera componentInChildren = ((Component)component.cameraAndStuff).GetComponentInChildren<Camera>(true); if ((Object)(object)componentInChildren == (Object)null) { return null; } _previewCam = ((Component)componentInChildren).transform; return _previewCam; } private static void RestoreCamera() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (_camMoved) { _camMoved = false; if ((Object)(object)_previewCam != (Object)null) { _previewCam.localPosition = _camHomeLocal; } } } private static void DriveActiveExpressions() { if (Active.Count == 0) { return; } PlayerAvatar instance = PlayerAvatar.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.playerExpression == (Object)null) { return; } PlayerExpression val = (((Object)(object)PlayerExpressionsUI.instance != (Object)null) ? PlayerExpressionsUI.instance.playerExpression : null); Expired.Clear(); if (Plugin.EmoteDurationSeconds.Value > 0f) { foreach (int item in new List<int>(Active.Keys)) { Active[item] -= Time.deltaTime; if (Active[item] <= 0f) { Expired.Add(item); } } foreach (int item2 in Expired) { Active.Remove(item2); } if (Active.Count == 0) { return; } } try { foreach (int key in Active.Keys) { DoExpression(instance.playerExpression, key, 100f, arg4: true); if ((Object)(object)val != (Object)null) { val.OverrideExpressionSet(key, 100f); } } } catch (Exception ex) { if (!_warned) { Plugin.Log.LogWarning((object)("[EmoteWheel] DoExpression failed: " + ex.Message)); _warned = true; } } } private void Close() { Open = false; _hovered = 0; } private static bool InGameplay() { MenuManager instance = MenuManager.instance; if ((Object)(object)instance != (Object)null && MenuStateRef.Invoke(instance) == 0) { return false; } ChatManager instance2 = ChatManager.instance; if ((Object)(object)instance2 != (Object)null && ChatActiveRef.Invoke(instance2)) { return false; } return (Object)(object)PlayerAvatar.instance != (Object)null; } private int HoveredSegment(Vector2 stick) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Max(Plugin.StickDeadzone.Value, 0.35f); if (((Vector2)(ref stick)).magnitude < num) { return 0; } float num2 = Mathf.Atan2(stick.x, stick.y) * 57.29578f; int result = 0; float num3 = float.MaxValue; for (int i = 1; i <= 7; i++) { float num4 = Mathf.Abs(Mathf.DeltaAngle(num2, SegmentAngles[i])); if (num4 < num3) { num3 = num4; result = i; } } return result; } private static void ToggleExpression(int index) { PlayerAvatar instance = PlayerAvatar.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.playerExpression == (Object)null) { return; } try { if (Active.Remove(index)) { Plugin.Log.LogDebug((object)$"[EmoteWheel] Expression {index} OFF"); return; } Active.Clear(); DoExpression(instance.playerExpression, index, 100f, arg4: true); float value = Plugin.EmoteDurationSeconds.Value; Active[index] = ((value > 0f) ? value : float.PositiveInfinity); Plugin.Log.LogDebug((object)$"[EmoteWheel] Expression {index} ON"); } catch (Exception ex) { if (!_warned) { Plugin.Log.LogWarning((object)("[EmoteWheel] Expression call failed: " + ex.Message)); _warned = true; } } } private static void ToggleMute() { if (!SemiFunc.IsMultiplayer()) { return; } DataDirector instance = DataDirector.instance; if ((Object)(object)instance == (Object)null) { return; } if (ToggleMuteRef == null) { if (!_muteWarned) { Plugin.Log.LogWarning((object)"[EmoteWheel] DataDirector.toggleMute not found -- mute slot disabled."); _muteWarned = true; } return; } try { ref bool reference = ref ToggleMuteRef.Invoke(instance); reference = !reference; Plugin.Log.LogDebug((object)("[EmoteWheel] Mic mute " + (reference ? "ON" : "OFF"))); } catch (Exception ex) { if (!_muteWarned) { Plugin.Log.LogWarning((object)("[EmoteWheel] Mute toggle failed: " + ex.Message)); _muteWarned = true; } } } private static bool IsMuted() { DataDirector instance = DataDirector.instance; if ((Object)(object)instance == (Object)null || ToggleMuteRef == null) { return false; } try { return ToggleMuteRef.Invoke(instance); } catch { return false; } } private void OnGUI() { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Unknown result type (might be due to invalid IL or missing references) if (!Open) { return; } EnsureStyles(); EnsureLabels(); float num = (float)Screen.width / 2f; float num2 = (float)Screen.height / 2f; float num3 = 190f; GUI.color = new Color(0f, 0f, 0f, 0.35f); GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)Texture2D.whiteTexture); GUI.color = Color.white; GUI.Label(new Rect(num - 200f, num2 - num3 - 70f, 400f, 30f), "Emotes", _title); Rect val = default(Rect); for (int i = 1; i <= 7; i++) { float num4 = SegmentAngles[i] * (MathF.PI / 180f); float num5 = num + Mathf.Sin(num4) * num3; float num6 = num2 - Mathf.Cos(num4) * num3; ((Rect)(ref val))..ctor(num5 - 80f, num6 - 20f, 160f, 40f); bool flag = i != 7 || SemiFunc.IsMultiplayer(); GUI.color = ((i == _hovered && flag) ? new Color(0.3f, 0.26f, 0.08f, 0.95f) : new Color(0.1f, 0.1f, 0.1f, 0.9f)); GUI.DrawTexture(val, (Texture)(object)Texture2D.whiteTexture); GUI.color = Color.white; if (i == 7) { bool num7 = SemiFunc.IsMultiplayer(); bool flag2 = num7 && IsMuted(); string text = ((!num7) ? "Mute (MP only)" : (flag2 ? "Unmute Mic" : "Mute Mic")); GUIStyle val2 = ((!num7) ? _labelDisabled : ((i == _hovered) ? _labelHover : (flag2 ? _labelActive : _label))); GUI.Label(val, text, val2); } else { GUIStyle val3 = ((i == _hovered) ? _labelHover : (Active.ContainsKey(i) ? _labelActive : _label)); GUI.Label(val, _labels[i], val3); } } } private static void EnsureLabels() { if (_labels != null) { return; } _labels = new string[8]; List<ExpressionSettings> list = null; PlayerAvatar instance = PlayerAvatar.instance; if ((Object)(object)instance != (Object)null && (Object)(object)instance.playerExpression != (Object)null) { list = instance.playerExpression.expressions; } for (int i = 1; i <= 6; i++) { string text = null; if (list != null && i < list.Count && list[i] != null) { text = list[i].expressionName; } _labels[i] = (string.IsNullOrEmpty(text) ? $"Expression {i}" : text); } } private void EnsureStyles() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_003f: 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_0059: 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_006d: Expected O, but got Unknown //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Expected O, but got Unknown //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Expected O, but got Unknown //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Expected O, but got Unknown //IL_0125: Unknown result type (might be due to invalid IL or missing references) if (_title == null) { _title = new GUIStyle(GUI.skin.label) { fontSize = 22, fontStyle = (FontStyle)1, alignment = (TextAnchor)4 }; _title.normal.textColor = Color.white; _label = new GUIStyle(GUI.skin.label) { fontSize = 16, alignment = (TextAnchor)4 }; _label.normal.textColor = Color.white; _labelHover = new GUIStyle(_label) { fontStyle = (FontStyle)1 }; _labelHover.normal.textColor = new Color(1f, 0.85f, 0.3f); _labelActive = new GUIStyle(_label) { fontStyle = (FontStyle)1 }; _labelActive.normal.textColor = new Color(0.55f, 0.8f, 1f); _labelDisabled = new GUIStyle(_label); _labelDisabled.normal.textColor = new Color(0.5f, 0.5f, 0.5f); } } } internal enum PadButton { None, South, East, West, North, LB, RB, LT, RT, L3, R3, DpadLeft, DpadUp, DpadRight, DpadDown, Start, Select } [HarmonyPatch] internal static class GamepadBindingsPatch { private static InputManager _injected; private static string _pttPath; private static string PathOf(PadButton b) { return b switch { PadButton.South => "<Gamepad>/buttonSouth", PadButton.East => "<Gamepad>/buttonEast", PadButton.West => "<Gamepad>/buttonWest", PadButton.North => "<Gamepad>/buttonNorth", PadButton.LB => "<Gamepad>/leftShoulder", PadButton.RB => "<Gamepad>/rightShoulder", PadButton.LT => "<Gamepad>/leftTrigger", PadButton.RT => "<Gamepad>/rightTrigger", PadButton.L3 => "<Gamepad>/leftStickPress", PadButton.R3 => "<Gamepad>/rightStickPress", PadButton.DpadLeft => "<Gamepad>/dpad/left", PadButton.DpadUp => "<Gamepad>/dpad/up", PadButton.DpadRight => "<Gamepad>/dpad/right", PadButton.DpadDown => "<Gamepad>/dpad/down", PadButton.Start => "<Gamepad>/start", PadButton.Select => "<Gamepad>/select", _ => null, }; } [HarmonyPatch(typeof(InputManager), "InitializeInputs")] [HarmonyPostfix] public static void Postfix(InputManager __instance) { if (!Plugin.Enabled.Value || _injected == __instance) { return; } _injected = __instance; try { Bind(__instance, (InputKey)0, "<Gamepad>/leftStick"); Bind(__instance, (InputKey)1, "<Gamepad>/buttonSouth"); Bind(__instance, (InputKey)2, "<Gamepad>/buttonWest"); Bind(__instance, (InputKey)14, "<Gamepad>/buttonEast"); Bind(__instance, (InputKey)8, "<Gamepad>/buttonNorth"); Bind(__instance, (InputKey)15, "<Gamepad>/leftStickPress"); Bind(__instance, (InputKey)12, "<Gamepad>/rightStickPress"); Bind(__instance, (InputKey)10, "<Gamepad>/rightTrigger"); Bind(__instance, (InputKey)11, "<Gamepad>/leftTrigger"); Bind(__instance, (InputKey)6, "<Gamepad>/start"); Bind(__instance, (InputKey)7, "<Gamepad>/select"); Bind(__instance, (InputKey)13, "<Gamepad>/buttonEast"); Bind(__instance, (InputKey)19, "<Gamepad>/dpad/left"); Bind(__instance, (InputKey)20, "<Gamepad>/dpad/up"); Bind(__instance, (InputKey)21, "<Gamepad>/dpad/right"); if (Plugin.PushToTalkButton.Value != PadButton.None) { _pttPath = PathOf(Plugin.PushToTalkButton.Value); Bind(__instance, (InputKey)25, _pttPath); } else { _pttPath = null; } Plugin.Log.LogInfo((object)"[Gamepad] Bindings injected."); } catch (Exception arg) { Plugin.Log.LogError((object)$"[Gamepad] Binding injection failed: {arg}"); } } [HarmonyPatch(typeof(InputManager), "LoadKeyBindings")] [HarmonyPostfix] public static void LoadKeyBindingsPostfix() { if (Plugin.Enabled.Value) { RebindPushToTalk(); } } [HarmonyPatch(typeof(InputManager), "ResetKeyToDefault")] [HarmonyPostfix] public static void ResetKeyToDefaultPostfix(InputKey key) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 if ((int)key == 25 && Plugin.Enabled.Value) { RebindPushToTalk(); } } internal static void RebindPushToTalk() { //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_injected == (Object)null) { return; } try { InputAction action = _injected.GetAction((InputKey)25); if (action == null) { return; } bool enabled = action.enabled; if (enabled) { action.Disable(); } try { if (_pttPath != null) { for (int i = 0; i < action.bindings.Count; i++) { InputBinding val = action.bindings[i]; if (((InputBinding)(ref val)).path == _pttPath) { BindingSyntax val2 = InputActionSetupExtensions.ChangeBinding(action, i); ((BindingSyntax)(ref val2)).Erase(); break; } } _pttPath = null; } PadButton value = Plugin.PushToTalkButton.Value; if (value != PadButton.None) { _pttPath = PathOf(value); InputActionSetupExtensions.AddBinding(action, _pttPath, (string)null, (string)null, (string)null); } } finally { if (enabled) { action.Enable(); } } Plugin.Log.LogInfo((object)$"[Gamepad] PushToTalk binding -> {Plugin.PushToTalkButton.Value}."); } catch (Exception arg) { Plugin.Log.LogError((object)$"[Gamepad] PushToTalk rebind failed: {arg}"); } } internal static void Bind(InputManager im, InputKey key, string path, string processors = null) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) InputAction action = im.GetAction(key); if (action == null) { Plugin.Log.LogWarning((object)$"[Gamepad] No action for {key}"); return; } bool enabled = action.enabled; if (enabled) { action.Disable(); } if (string.IsNullOrEmpty(processors)) { InputActionSetupExtensions.AddBinding(action, path, (string)null, (string)null, (string)null); } else { BindingSyntax val = InputActionSetupExtensions.AddBinding(action, path, (string)null, (string)null, (string)null); ((BindingSyntax)(ref val)).WithProcessors(processors); } if (enabled) { action.Enable(); } } } internal class GrabPromptOverlay : MonoBehaviour { private struct Prompt { public string Rich; public string Plain; } private struct SlotLabel { public TextMeshProUGUI Text; public string Original; public int SpotIndex; } private static readonly FieldRef<MenuManager, int> MenuStateRef = AccessTools.FieldRefAccess<MenuManager, int>("currentMenuState"); private static FieldRef<Aim, State> _aimStateRef; private static bool _aimRefFailed; private ControllerDetect.Kind _cachedKind = (ControllerDetect.Kind)(-1); private Prompt _grab; private Prompt _letGo; private Prompt _rotate; private Prompt _climb; private Prompt _rightLine; private Prompt _leftLine; private GUIStyle _style; private bool _showArrows; private bool _labelsSwapped; private InventorySpot[] _spots; private readonly Vector3[] _corners = (Vector3[])(object)new Vector3[4]; private readonly List<SlotLabel> _slotLabels = new List<SlotLabel>(8); private void Update() { //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Expected I4, but got Unknown ControllerDetect.TrackActiveInput(); InputDisplayPatch.TickCacheInvalidation(); _rightLine = default(Prompt); _leftLine = default(Prompt); _showArrows = false; if (!Plugin.Enabled.Value || !Plugin.PromptsEnabled.Value || Gamepad.current == null || !ControllerDetect.PadActive || EmoteWheel.Open) { return; } MenuManager instance = MenuManager.instance; if ((Object)(object)instance != (Object)null && MenuStateRef.Invoke(instance) == 0) { return; } _showArrows = Plugin.InventoryArrows.Value && ControllerDetect.PadTouchedThisLevel; Aim instance2 = Aim.instance; if ((Object)(object)instance2 == (Object)null || !EnsureAimRef()) { return; } EnsureNames(); State val = _aimStateRef.Invoke(instance2); switch (val - 1) { case 0: _rightLine = _grab; break; case 1: case 2: if (Plugin.GrabToggle.Value) { _rightLine = _letGo; } _leftLine = _rotate; break; case 4: _rightLine = _climb; break; case 3: break; } } private static bool EnsureAimRef() { if (_aimStateRef != null) { return true; } if (_aimRefFailed) { return false; } try { _aimStateRef = AccessTools.FieldRefAccess<Aim, State>("currentState"); return true; } catch (Exception ex) { _aimRefFailed = true; Plugin.Log.LogWarning((object)("[Prompts] Aim.currentState unavailable — prompts disabled: " + ex.Message)); return false; } } private void EnsureNames() { ControllerDetect.Kind current = ControllerDetect.Current; if (current != _cachedKind || _grab.Plain == null) { _cachedKind = current; string button = ButtonNames.Of(ButtonNames.Control.RT, current); string button2 = ButtonNames.Of(ButtonNames.Control.LT, current); _grab = Make("GRAB", button); _letGo = Make("LET GO", button); _rotate = Make("ROTATE", button2); _climb = Make("CLIMB", button); } } private static Prompt Make(string action, string button) { return new Prompt { Rich = "<color=#FFA21C>" + action + "</color> <color=#FFFFFF>[" + button + "]</color>", Plain = action + " [" + button + "]" }; } private void LateUpdate() { if (!_showArrows && !_labelsSwapped) { return; } if (NeedSlotLabelRefresh()) { _slotLabels.Clear(); _labelsSwapped = false; _spots = Object.FindObjectsOfType<InventorySpot>(); InventorySpot[] spots = _spots; foreach (InventorySpot val in spots) { int inventorySpotIndex = val.inventorySpotIndex; if (inventorySpotIndex < 0 || inventorySpotIndex > 2) { continue; } string text = (inventorySpotIndex + 1).ToString(); TextMeshProUGUI[] componentsInChildren = ((Component)val).GetComponentsInChildren<TextMeshProUGUI>(true); foreach (TextMeshProUGUI val2 in componentsInChildren) { if ((Object)(object)val2 == (Object)(object)val.noItem || ((TMP_Text)val2).text.Trim() == text) { _slotLabels.Add(new SlotLabel { Text = val2, Original = ((TMP_Text)val2).text, SpotIndex = inventorySpotIndex }); } } } if (_slotLabels.Count == 0) { return; } } ControllerDetect.Kind current = ControllerDetect.Current; foreach (SlotLabel slotLabel in _slotLabels) { if ((Object)(object)slotLabel.Text == (Object)null) { continue; } if (_showArrows) { string text2 = ((slotLabel.SpotIndex == 0) ? ButtonNames.Of(ButtonNames.Control.DpadLeft, current) : ((slotLabel.SpotIndex == 1) ? ButtonNames.Of(ButtonNames.Control.DpadUp, current) : ButtonNames.Of(ButtonNames.Control.DpadRight, current))); if (((TMP_Text)slotLabel.Text).text != text2) { ((TMP_Text)slotLabel.Text).text = text2; } } else if (((TMP_Text)slotLabel.Text).text != slotLabel.Original) { ((TMP_Text)slotLabel.Text).text = slotLabel.Original; } } _labelsSwapped = _showArrows; } private bool NeedSlotLabelRefresh() { if (_spots == null || _spots.Length == 0 || (Object)(object)_spots[0] == (Object)null || _slotLabels.Count == 0) { return true; } foreach (SlotLabel slotLabel in _slotLabels) { if ((Object)(object)slotLabel.Text == (Object)null) { return true; } } return false; } private void OnGUI() { if (_rightLine.Plain == null && _leftLine.Plain == null) { return; } EnsureStyles(); if (TryInventoryScreenBounds(out var minX, out var maxX, out var centerY)) { float guiCenterY = (float)Screen.height - centerY; if (_rightLine.Plain != null) { DrawChip(_rightLine, maxX + 14f, guiCenterY, rightSide: true); } if (_leftLine.Plain != null) { DrawChip(_leftLine, minX - 14f, guiCenterY, rightSide: false); } return; } float cx = (float)Screen.width / 2f; float num = (float)Screen.height / 2f + 35f; if (_rightLine.Plain != null) { DrawChipCentered(_rightLine, cx, num); num += 28f; } if (_leftLine.Plain != null) { DrawChipCentered(_leftLine, cx, num); } } private void DrawChip(Prompt p, float anchorX, float guiCenterY, bool rightSide) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) float num = _style.CalcSize(new GUIContent(p.Plain)).x + 18f; Rect val = new Rect(rightSide ? anchorX : (anchorX - num), guiCenterY - 12f, num, 24f); GUI.color = new Color(0.08f, 0.08f, 0.08f, 0.85f); GUI.DrawTexture(val, (Texture)(object)Texture2D.whiteTexture); GUI.color = Color.white; GUI.Label(val, p.Rich, _style); } private void DrawChipCentered(Prompt p, float cx, float y) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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) float num = _style.CalcSize(new GUIContent(p.Plain)).x + 18f; Rect val = new Rect(cx - num / 2f, y, num, 24f); GUI.color = new Color(0.08f, 0.08f, 0.08f, 0.85f); GUI.DrawTexture(val, (Texture)(object)Texture2D.whiteTexture); GUI.color = Color.white; GUI.Label(val, p.Rich, _style); } private bool TryInventoryScreenBounds(out float minX, out float maxX, out float centerY) { //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: 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_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) minX = float.MaxValue; maxX = float.MinValue; centerY = 0f; CameraOverlay instance = CameraOverlay.instance; RenderTextureMain instance2 = RenderTextureMain.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance2 == (Object)null || (Object)(object)instance2.overlayRawImage == (Object)null) { return false; } Camera component = ((Component)instance).GetComponent<Camera>(); if ((Object)(object)component == (Object)null) { return false; } if (_spots == null || _spots.Length == 0 || (Object)(object)_spots[0] == (Object)null) { _spots = Object.FindObjectsOfType<InventorySpot>(); if (_spots.Length == 0) { return false; } } ((Graphic)instance2.overlayRawImage).rectTransform.GetWorldCorners(_corners); Vector2 val = Vector2.op_Implicit(_corners[0]); Vector2 val2 = Vector2.op_Implicit(_corners[2]); float num = 0f; int num2 = 0; InventorySpot[] spots = _spots; foreach (InventorySpot val3 in spots) { if ((Object)(object)val3 == (Object)null) { continue; } Transform transform = ((Component)val3).transform; RectTransform val4 = (RectTransform)(object)((transform is RectTransform) ? transform : null); if ((Object)(object)val4 == (Object)null) { continue; } val4.GetWorldCorners(_corners); for (int j = 0; j < 4; j++) { Vector3 val5 = component.WorldToViewportPoint(_corners[j]); float num3 = Mathf.Lerp(val.x, val2.x, val5.x); float num4 = Mathf.Lerp(val.y, val2.y, val5.y); if (num3 < minX) { minX = num3; } if (num3 > maxX) { maxX = num3; } num += num4; } num2++; } if (num2 == 0) { return false; } centerY = num / (float)(num2 * 4); return true; } private void EnsureStyles() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_0046: Unknown result type (might be due to invalid IL or missing references) if (_style == null) { _style = new GUIStyle(GUI.skin.label) { fontSize = 14, fontStyle = (FontStyle)1, alignment = (TextAnchor)4, richText = true }; _style.normal.textColor = Color.white; } } } [HarmonyPatch] internal static class InputDisplayPatch { private static readonly FieldRef<MenuManager, int> MenuStateRef = AccessTools.FieldRefAccess<MenuManager, int>("currentMenuState"); private static readonly FieldRef<ItemAttributes, string> ItemTagRef = AccessTools.FieldRefAccess<ItemAttributes, string>("itemTag"); private static bool _lastControllerActive; [HarmonyPatch(typeof(InputManager), "InputDisplayGet")] [HarmonyPostfix] private static void InputDisplayGetPostfix(InputKey _inputKey, KeyType _keyType, MovementDirection _movementDirection, ref string __result) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Invalid comparison between Unknown and I4 //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.Enabled.Value || !Plugin.ControllerKeyTags.Value || Gamepad.current == null || !ControllerDetect.PadActive) { return; } MenuManager instance = MenuManager.instance; if ((Object)(object)instance != (Object)null && MenuStateRef.Invoke(instance) == 0) { return; } if ((int)_keyType == 1) { __result = (((int)_movementDirection == 0) ? "L-STICK" : ""); return; } string text = NameFor(_inputKey, ControllerDetect.Current); if (text != null) { __result = text.ToUpper(); } } private static string NameFor(InputKey key, ControllerDetect.Kind kind) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected I4, but got Unknown switch (key - 1) { case 0: return B(ButtonNames.Control.South, kind); case 1: return B(ButtonNames.Control.West, kind); case 13: return B(ButtonNames.Control.East, kind); case 7: return B(ButtonNames.Control.North, kind); case 14: return "L3"; case 11: return "R3"; case 9: return B(ButtonNames.Control.RT, kind); case 10: return B(ButtonNames.Control.LT, kind); case 5: return B(ButtonNames.Control.Start, kind); case 6: return B(ButtonNames.Control.Select, kind); case 18: return B(ButtonNames.Control.DpadLeft, kind); case 19: return B(ButtonNames.Control.DpadUp, kind); case 20: return B(ButtonNames.Control.DpadRight, kind); case 3: return B(ButtonNames.Control.RB, kind); case 4: return B(ButtonNames.Control.LB, kind); case 25: case 26: case 27: case 28: case 29: case 30: return B(ButtonNames.Control.DpadDown, kind) + " (wheel)"; default: return null; } } private static string B(ButtonNames.Control c, ControllerDetect.Kind kind) { return ButtonNames.Of(c, kind); } internal static void TickCacheInvalidation() { if (!Plugin.Enabled.Value || !Plugin.ControllerKeyTags.Value) { return; } bool flag = ControllerDetect.PadActive && Gamepad.current != null; if (flag == _lastControllerActive) { return; } _lastControllerActive = flag; try { ItemAttributes[] array = Object.FindObjectsOfType<ItemAttributes>(); foreach (ItemAttributes val in array) { ItemTagRef.Invoke(val) = ""; } } catch (Exception ex) { Plugin.Log.LogDebug((object)("[Prompts] item tag cache clear failed: " + ex.Message)); } } } [HarmonyPatch(typeof(InputManager))] internal static class LookPatch { private const float AimSpeedFloor = 0.0001f; [HarmonyPatch("GetMouseX")] [HarmonyPostfix] public static void GetMouseXPostfix(ref float __result) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: 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) if (!Plugin.Enabled.Value || EmoteWheel.Open || ChatKeyboard.Open) { return; } Gamepad current = Gamepad.current; if (current != null) { float num = Deadzone(((InputControl<Vector2>)(object)current.rightStick).ReadValue().x); if (Plugin.InvertX.Value) { num = 0f - num; } __result += num * Plugin.LookSpeedX.Value; } if (!Plugin.AimAssistEnabled.Value || !AimAssist.HasTarget) { return; } CameraAim instance = CameraAim.Instance; Camera main = Camera.main; if (!((Object)(object)instance == (Object)null) && !((Object)(object)main == (Object)null)) { Vector3 forward = ((Component)main).transform.forward; Vector3 val = AimAssist.TargetPosition - ((Component)main).transform.position; Vector3 val2 = Vector3.ProjectOnPlane(forward, Vector3.up); Vector3 val3 = Vector3.ProjectOnPlane(val, Vector3.up); if (!(((Vector3)(ref val2)).sqrMagnitude < 0.0001f) && !(((Vector3)(ref val3)).sqrMagnitude < 0.0001f)) { float axisErrDeg = Vector3.SignedAngle(val2, val3, Vector3.up); float totalErrDeg = Vector3.Angle(forward, val); __result += Correction(axisErrDeg, totalErrDeg, __result, instance.AimSpeedMouse); } } } [HarmonyPatch("GetMouseY")] [HarmonyPostfix] public static void GetMouseYPostfix(ref float __result) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: 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_00de: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.Enabled.Value || EmoteWheel.Open || ChatKeyboard.Open) { return; } Gamepad current = Gamepad.current; if (current != null) { float num = Deadzone(((InputControl<Vector2>)(object)current.rightStick).ReadValue().y); if (Plugin.InvertY.Value) { num = 0f - num; } __result += num * Plugin.LookSpeedY.Value; } if (Plugin.AimAssistEnabled.Value && AimAssist.HasTarget) { CameraAim instance = CameraAim.Instance; Camera main = Camera.main; if (!((Object)(object)instance == (Object)null) && !((Object)(object)main == (Object)null)) { Vector3 forward = ((Component)main).transform.forward; Vector3 val = AimAssist.TargetPosition - ((Component)main).transform.position; float num2 = Mathf.Asin(Mathf.Clamp(((Vector3)(ref val)).normalized.y, -1f, 1f)) * 57.29578f; float num3 = Mathf.Asin(Mathf.Clamp(((Vector3)(ref forward)).normalized.y, -1f, 1f)) * 57.29578f; float axisErrDeg = num2 - num3; float totalErrDeg = Vector3.Angle(forward, val); __result += Correction(axisErrDeg, totalErrDeg, __result, instance.AimSpeedMouse); } } } private static float Correction(float axisErrDeg, float totalErrDeg, float playerResult, float aimSpeed) { aimSpeed = Mathf.Max(0.0001f, aimSpeed); float value = Plugin.AimAssistDeadZone.Value; float value2 = Plugin.AimAssistMaxAngle.Value; float num = ((totalErrDeg <= value) ? 0f : ((!(totalErrDeg >= value2)) ? Mathf.SmoothStep(0f, 1f, (totalErrDeg - value) / Mathf.Max(0.001f, value2 - value)) : 1f)); if (num <= 0f) { return 0f; } float num2 = Plugin.AimAssistGain.Value * axisErrDeg * num; float num3 = Mathf.Abs(playerResult) * aimSpeed; float num4 = ((!(num3 > Plugin.AimAssistActiveThreshold.Value)) ? Mathf.Min(Plugin.AimAssistIdleDrift.Value * num, Plugin.AimAssistMaxDegPerFrame.Value) : Mathf.Min(Plugin.AimAssistMaxFraction.Value * num3, Plugin.AimAssistMaxDegPerFrame.Value)); return Mathf.Clamp(num2, 0f - num4, num4) / aimSpeed; } private static float Deadzone(float v) { float value = Plugin.StickDeadzone.Value; if (!(Mathf.Abs(v) < value)) { return v; } return 0f; } } [HarmonyPatch(typeof(MenuButton), "ProcessHover")] internal static class MenuButtonHoverPatch { private static readonly FieldRef<MenuButton, bool> HoveringRef = AccessTools.FieldRefAccess<MenuButton, bool>("hovering"); private static readonly FieldInfo ButtonTextField = AccessTools.Field(typeof(MenuButton), "buttonText"); private static PropertyInfo s_colorProp; [HarmonyPostfix] public static void Postfix(MenuButton __instance) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) if (!MenuNavigator.ControllerActive) { return; } bool flag = __instance == MenuNavigator.Selected; HoveringRef.Invoke(__instance) = flag; object obj = ((ButtonTextField != null) ? ButtonTextField.GetValue(__instance) : null); if (obj != null) { if (s_colorProp == null) { s_colorProp = obj.GetType().GetProperty("color"); } s_colorProp?.SetValue(obj, flag ? __instance.colorHover : __instance.colorNormal); } if (flag) { __instance.OnHovering(); } } } [HarmonyPatch(typeof(MenuCursor), "Show")] internal static class MenuCursorHidePatch { [HarmonyPrefix] private static bool Prefix() { if (!Plugin.Enabled.Value || !Plugin.HideMouseCursorOnPad.Value) { return true; } return !MenuNavigator.ControllerActive; } } internal class MenuKeyboard : MonoBehaviour { private static readonly FieldRef<MenuManager, bool> TextInputActiveRef = AccessTools.FieldRefAccess<MenuManager, bool>("textInputActive"); private static readonly FieldRef<MenuTextInput, string> TextCurrentRef = AccessTools.FieldRefAccess<MenuTextInput, string>("textCurrent"); private static readonly FieldRef<MenuPagePassword, string> PasswordRef = AccessTools.FieldRefAccess<MenuPagePassword, string>("password"); internal static bool Open; private PadKeyboardCore _core; private bool _coreHasSpace; private MenuTextInput _textInput; private MenuPagePassword _password; private bool _dismissed; private bool _selectArmed; private static bool _warned; internal static void ResetState() { Open = false; } private void Update() { MenuManager instance = MenuManager.instance; Gamepad current = Gamepad.current; if ((Object)(object)instance == (Object)null || current == null || !Plugin.Enabled.Value || !Plugin.MenuKeyboardEnabled.Value) { Open = false; return; } bool flag; try { flag = TextInputActiveRef.Invoke(instance); } catch (Exception e) { WarnOnce(e); Open = false; return; } if (!flag) { Open = false; _dismissed = false; _textInput = null; _password = null; return; } if (!Open && !_dismissed && MenuNavigator.ControllerActive) { try { if (AcquireTarget()) { OpenPanel(); } } catch (Exception e2) { WarnOnce(e2); return; } } if (!Open) { return; } if (!MenuNavigator.ControllerActive) { Open = false; return; } if (((Object)(object)_password != (Object)null && !((Behaviour)_password).isActiveAndEnabled) || ((Object)(object)_password == (Object)null && ((Object)(object)_textInput == (Object)null || !((Behaviour)_textInput).isActiveAndEnabled))) { Open = false; _textInput = null; _password = null; return; } if (!current.selectButton.isPressed && !current.selectButton.wasReleasedThisFrame) { _selectArmed = true; } try { _core.HandleInput(current); if (current.buttonEast.wasPressedThisFrame) { Backspace(); } if (_selectArmed && current.selectButton.wasReleasedThisFrame) { Dismiss(); } } catch (Exception e3) { WarnOnce(e3); } } private bool AcquireTarget() { _password = null; _textInput = null; MenuPagePassword[] array = Object.FindObjectsOfType<MenuPagePassword>(); foreach (MenuPagePassword val in array) { if (((Behaviour)val).isActiveAndEnabled) { _password = val; break; } } if ((Object)(object)_password == (Object)null) { MenuTextInput[] array2 = Object.FindObjectsOfType<MenuTextInput>(); foreach (MenuTextInput val2 in array2) { if (((Behaviour)val2).isActiveAndEnabled) { _textInput = val2; break; } } } if (!((Object)(object)_password != (Object)null)) { return (Object)(object)_textInput != (Object)null; } return true; } private void OpenPanel() { bool flag = (Object)(object)_password == (Object)null; if (_core == null || _coreHasSpace != flag) { _core = new PadKeyboardCore(flag, "ENTER", "HIDE"); _core.OnChar = TypeChar; _core.OnConfirm = Confirm; _core.OnClose = Dismiss; _coreHasSpace = flag; } _core.Reset(); _selectArmed = false; Open = true; } private void TypeChar(string s) { if ((Object)(object)_password != (Object)null) { if (!(s == " ")) { PasswordRef.Invoke(_password) = PasswordRef.Invoke(_password) + s; } } else if ((Object)(object)_textInput != (Object)null) { string text = TextCurrentRef.Invoke(_textInput) ?? ""; if (text == "\b") { text = ""; } TextCurrentRef.Invoke(_textInput) = text + s; } } private void Backspace() { if ((Object)(object)_password != (Object)null) { string text = PasswordRef.Invoke(_password) ?? ""; if (text.Length > 0) { PasswordRef.Invoke(_password) = text.Remove(text.Length - 1); } } else if ((Object)(object)_textInput != (Object)null) { string text2 = TextCurrentRef.Invoke(_textInput) ?? ""; if (!(text2 == "\b") && text2.Length != 0) { TextCurrentRef.Invoke(_textInput) = text2.Remove(text2.Length - 1); } } } private void Confirm() { if ((Object)(object)_password != (Object)null) { _password.ConfirmButton(); } else { if ((Object)(object)_textInput == (Object)null) { return; } MenuPageServerListCreateNew val = FindPage<MenuPageServerListCreateNew>(); if ((Object)(object)val != (Object)null) { val.ButtonConfirm(); return; } MenuPageSavesRename val2 = FindPage<MenuPageSavesRename>(); if ((Object)(object)val2 != (Object)null) { val2.ButtonConfirm(); return; } MenuPageServerListSearch val3 = FindPage<MenuPageServerListSearch>(); if ((Object)(object)val3 != (Object)null) { val3.ButtonConfirm(); } else { WarnOnce(new Exception("active MenuTextInput has no known confirm owner")); } } } private T FindPage<T>() where T : MonoBehaviour { if ((Object)(object)_textInput == (Object)null) { return default(T); } T componentInParent = ((Component)_textInput).GetComponentInParent<T>(); if ((Object)(object)componentInParent != (Object)null) { return componentInParent; } T[] array = Object.FindObjectsOfType<T>(); foreach (T val in array) { if (((Behaviour)(object)val).isActiveAndEnabled) { return val; } } return default(T); } private void Dismiss() { Open = false; _dismissed = true; } private static void WarnOnce(Exception e) { if (!_warned) { _warned = true; Plugin.Log.LogWarning((object)("[MenuKeyboard] Error (further warnings suppressed): " + e.Message)); } } private void OnGUI() { if (Open && _core != null) { _core.Draw(Plugin.ChatScale.Value, 40f * Plugin.ChatScale.Value); } } } internal class MenuNavigator : MonoBehaviour { private struct NavEntry { public MenuButton Btn; public MenuElementHover Hover; public Vector2 Pos; public Vector2 Min; public Vector2 Max; } private enum PickMode { Beam, Cone, Any } private static readonly FieldRef<MenuManager, int> StateRef = AccessTools.FieldRefAccess<MenuManager, int>("currentMenuState"); private static readonly FieldRef<MenuManager, List<MenuButton>> ButtonsRef = AccessTools.FieldRefAccess<MenuManager, List<MenuButton>>("allMenuButtons"); private static readonly FieldRef<MenuManager, MenuPage> CurrentPageRef = AccessTools.FieldRefAccess<MenuManager, MenuPage>("currentMenuPage"); private static readonly FieldRef<MenuManager, List<MenuPage>> AddedPagesRef = AccessTools.FieldRefAccess<MenuManager, List<MenuPage>>("addedPagesOnTop"); private static readonly FieldRef<MenuPage, bool> AddedOnTopRef = AccessTools.FieldRefAccess<MenuPage, bool>("addedPageOnTop"); private static readonly FieldRef<MenuButton, MenuPage> ParentPageRef = AccessTools.FieldRefAccess<MenuButton, MenuPage>("parentPage"); private static readonly FieldRef<MenuButton, bool> DisabledRef = AccessTools.FieldRefAccess<MenuButton, bool>("disabled"); private static readonly FieldRef<MenuButton, bool> HoveringRef = AccessTools.FieldRefAccess<MenuButton, bool>("hovering"); private static readonly FieldRef<MenuPage, PageState> PageStateRef = AccessTools.FieldRefAccess<MenuPage, PageState>("currentPageState"); private static readonly MethodInfo OnSelectMethod = AccessTools.Method(typeof(MenuButton), "OnSelect", (Type[])null, (Type[])null); private static readonly FieldInfo ButtonTextField = AccessTools.Field(typeof(MenuButton), "buttonText"); private static PropertyInfo s_textProp; private static readonly Vector3[] s_corners = (Vector3[])(object)new Vector3[4]; internal static MenuButton Selected; internal static bool ControllerActive; internal static RectTransform SelectedHoverRect; internal static float SnapSelectionBoxUntil; private const float SnapJumpDistance = 150f; private static readonly FieldRef<MenuElementSaveFile, string> SaveFileNameRef = AccessTools.FieldRefAccess<MenuElementSaveFile, string>("saveFileName"); private static readonly FieldRef<MenuElementSaveFile, List<string>> SaveFileBackupsRef = AccessTools.FieldRefAccess<MenuElementSaveFile, List<string>>("saveFileBackups"); private static readonly FieldRef<SpringFloat, float> SpringVelocityRef = AccessTools.FieldRefAccess<SpringFloat, float>("springVelocity"); private MenuButton _selected; private MenuElementHover _selectedHover; private bool _active; private float _navCooldown; private GUIStyle _style; private MenuPage _focusPage; private MenuPage _focusOverride; private MenuPage _lastTop; private readonly Dictionary<MenuPage, MenuButton> _lastByPage = new Dictionary<MenuPage, MenuButton>(); private static FieldInfo s_repoLastClicked; private static bool s_repoLookupDone; private bool MenuOpen(out MenuManager mm) { mm = MenuManager.instance; if ((Object)(object)mm != (Object)null) { return StateRef.Invoke(mm) == 0; } return false; } private void Update() { //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) ControllerActive = false; Selected = null; SelectedHoverRect = null; if (!Plugin.Enabled.Value) { return; } Gamepad current = Gamepad.current; if (current == null) { return; } if (!MenuOpen(out var mm)) { _selected = null; _selectedHover = null; _focusOverride = null; _focusPage = null; _lastTop = null; _lastByPage.Clear(); return; } ResolveFocus(mm); List<MenuButton> list = Candidates(mm, _focusPage); List<MenuElementHover> list2 = HoverCandidates(_focusPage); if (list.Count == 0 && list2.Count == 0) { _selected = null; _selectedHover = null; return; } if (AnyControllerInput(current)) { _active = true; } if (Mouse.current != null) { Vector2 val = ((InputControl<Vector2>)(object)((Pointer)Mouse.current).delta).ReadValue(); if (((Vector2)(ref val)).sqrMagnitude > 4f) { _active = false; } } if (_active) { if (MenuKeyboard.Open)