Decompiled source of ModSettingsMenu v2.0.3
BepInEx/plugins/ModSettingsMenu.dll
Decompiled 2 weeks 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.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Sparroh.UI; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.InputSystem.Utilities; 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("ModSettingsMenu")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ModSettingsMenu")] [assembly: AssemblyTitle("ModSettingsMenu")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } public static class FreeCursor { private sealed class FreeCursorDriver : MonoBehaviour { private void Update() { Apply(); } private void LateUpdate() { Apply(); } private void OnApplicationFocus(bool hasFocus) { if (hasFocus) { Apply(); } } } private static int _holders; private static bool _usedPlayerInput; private static FreeCursorDriver _driver; public static bool IsHeld => _holders > 0; public static void Acquire() { EnsureDriver(); if (_holders == 0) { UnlockViaGame(); } _holders++; Apply(); } public static void Release() { if (_holders > 0) { _holders--; if (_holders == 0) { LockViaGame(); } } } public static void Apply() { //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (_holders > 0) { Cursor.lockState = PlayerInput.CursorMenuMode; Cursor.visible = true; } } private static void UnlockViaGame() { try { PlayerInput.UnlockCursor(); _usedPlayerInput = true; } catch { _usedPlayerInput = false; Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; } } private static void LockViaGame() { //IL_0020: 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) if (_usedPlayerInput) { try { PlayerInput.LockCursor(); } catch { } finally { _usedPlayerInput = false; } } try { if (PlayerInput.IsMenuEnabled) { Cursor.lockState = PlayerInput.CursorMenuMode; Cursor.visible = true; return; } } catch { } try { if ((Object)(object)Menu.Instance != (Object)null && Menu.Instance.IsOpen) { Cursor.lockState = PlayerInput.CursorMenuMode; Cursor.visible = true; } } catch { } } private static void EnsureDriver() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown if (!((Object)(object)_driver != (Object)null)) { GameObject val = new GameObject("ModSettingsMenu_FreeCursor"); Object.DontDestroyOnLoad((Object)val); _driver = val.AddComponent<FreeCursorDriver>(); } } } public static class HudRepositionAPI { public sealed class HudElement { public string Id { get; internal set; } public string DisplayName { get; internal set; } public RectTransform Rect { get; internal set; } public ConfigEntry<float> AnchorX { get; internal set; } public ConfigEntry<float> AnchorY { get; internal set; } public bool IsAutoDetected { get; internal set; } } private static readonly Dictionary<string, HudElement> Elements = new Dictionary<string, HudElement>(StringComparer.OrdinalIgnoreCase); public static bool IsRepositionModeActive => HudRepositionMode.IsActive; public static void Register(string id, string displayName, RectTransform rect, ConfigEntry<float> anchorX, ConfigEntry<float> anchorY) { if (string.IsNullOrEmpty(id)) { throw new ArgumentException("id is required", "id"); } if ((Object)(object)rect == (Object)null) { throw new ArgumentNullException("rect"); } if (anchorX == null) { throw new ArgumentNullException("anchorX"); } if (anchorY == null) { throw new ArgumentNullException("anchorY"); } Elements[id] = new HudElement { Id = id, DisplayName = (string.IsNullOrEmpty(displayName) ? id : displayName), Rect = rect, AnchorX = anchorX, AnchorY = anchorY, IsAutoDetected = false }; ManualLogSource logger = SparrohPlugin.Logger; if (logger != null) { logger.LogInfo((object)("[HudReposition] Registered '" + displayName + "' (" + id + ")")); } } public static void Unregister(string id) { if (!string.IsNullOrEmpty(id) && Elements.Remove(id)) { ManualLogSource logger = SparrohPlugin.Logger; if (logger != null) { logger.LogInfo((object)("[HudReposition] Unregistered '" + id + "'")); } } } public static IReadOnlyList<HudElement> GetRegistered() { CleanupDestroyed(); return Elements.Values.ToList(); } public static void ToggleRepositionMode() { HudRepositionMode.Toggle(); } public static void EnterRepositionMode() { HudRepositionMode.Enter(); } public static void ExitRepositionMode() { HudRepositionMode.Exit(); } internal static void RegisterAutoDetected(string id, string displayName, RectTransform rect, ConfigEntry<float> anchorX, ConfigEntry<float> anchorY) { if (!Elements.ContainsKey(id)) { Elements[id] = new HudElement { Id = id, DisplayName = displayName, Rect = rect, AnchorX = anchorX, AnchorY = anchorY, IsAutoDetected = true }; } } internal static void ClearAutoDetected() { foreach (string item in (from kv in Elements where kv.Value.IsAutoDetected select kv.Key).ToList()) { Elements.Remove(item); } } internal static void CleanupDestroyed() { foreach (string item in (from kv in Elements where (Object)(object)kv.Value.Rect == (Object)null select kv.Key).ToList()) { Elements.Remove(item); } } } public class HudRepositionMode : MonoBehaviour { private sealed class AnchorPair { public string ConfigPath; public string Section; public string Prefix; public string KeyX; public string KeyY; public float DefaultX; public float DefaultY; } private HudRepositionAPI.HudElement _dragging; private Vector2 _dragGrabOffset; private bool _cursorHeld; private readonly Dictionary<string, ConfigFile> _autoConfigFiles = new Dictionary<string, ConfigFile>(StringComparer.OrdinalIgnoreCase); private static readonly Regex AnchorPairRegex = new Regex("^(?<prefix>.+)AnchorX$", RegexOptions.IgnoreCase | RegexOptions.Compiled); private const float MinHitWidth = 180f; private const float MinHitHeight = 36f; public static HudRepositionMode Instance { get; private set; } public static bool IsActive { get; private set; } public static void EnsureExists() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown if (!((Object)(object)Instance != (Object)null)) { GameObject val = new GameObject("HudRepositionMode"); Object.DontDestroyOnLoad((Object)val); Instance = val.AddComponent<HudRepositionMode>(); } } public static void Toggle() { EnsureExists(); if (IsActive) { Exit(); } else { Enter(); } } public static void Enter() { EnsureExists(); if (!IsActive) { IsActive = true; Instance.HoldCursor(); Instance.RunAutoDetect(); HudRepositionAPI.CleanupDestroyed(); int count = HudRepositionAPI.GetRegistered().Count; SparrohPlugin.Logger.LogInfo((object)$"[HudReposition] Reposition mode ON — {count} element(s). Drag to move, Esc/F9 to exit."); } } public static void Exit() { if (!IsActive) { return; } if ((Object)(object)Instance != (Object)null) { if (Instance._dragging != null) { Instance.CommitDrag(Instance._dragging); Instance._dragging = null; } Instance.ReleaseCursor(); HudRepositionAPI.ClearAutoDetected(); Instance._autoConfigFiles.Clear(); } IsActive = false; SparrohPlugin.Logger.LogInfo((object)"[HudReposition] Reposition mode OFF"); } private void Update() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) if (!IsActive) { return; } FreeCursor.Apply(); InputBlocker.SoftSuppressMouseFire(); if (Keyboard.current != null && ((ButtonControl)Keyboard.current.escapeKey).wasPressedThisFrame) { Exit(); return; } Mouse current = Mouse.current; if (current != null) { Vector2 screenPos = ((InputControl<Vector2>)(object)((Pointer)current).position).ReadValue(); ProcessDragInput(screenPos, current.leftButton.wasPressedThisFrame, current.leftButton.isPressed, current.leftButton.wasReleasedThisFrame); } } private void OnGUI() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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_0036: 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_005e: Invalid comparison between Unknown and I4 //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Invalid comparison between Unknown and I4 //IL_0046: 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_008c: Unknown result type (might be due to invalid IL or missing references) if (!IsActive) { return; } Event current = Event.current; if (current != null) { Vector2 mousePosition = current.mousePosition; Vector2 screenPos = default(Vector2); ((Vector2)(ref screenPos))..ctor(mousePosition.x, (float)Screen.height - mousePosition.y); if ((int)current.type == 0 && current.button == 0) { ProcessDragInput(screenPos, pressed: true, held: true, released: false); current.Use(); } else if ((int)current.type == 3 && current.button == 0) { ProcessDragInput(screenPos, pressed: false, held: true, released: false); current.Use(); } else if ((int)current.type == 1 && current.button == 0) { ProcessDragInput(screenPos, pressed: false, held: false, released: true); current.Use(); } } DrawOverlay(); } private void ProcessDragInput(Vector2 screenPos, bool pressed, bool held, bool released) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: 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_0072: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: 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_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: 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_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) HudRepositionAPI.CleanupDestroyed(); IReadOnlyList<HudRepositionAPI.HudElement> registered = HudRepositionAPI.GetRegistered(); if (pressed) { _dragging = FindElementAtScreenPos(registered, screenPos); if (_dragging != null && (Object)(object)_dragging.Rect != (Object)null) { if (TryScreenToNormalizedParent(_dragging.Rect, screenPos, out var normalized)) { _dragGrabOffset = _dragging.Rect.anchorMin - normalized; } else { _dragGrabOffset = Vector2.zero; } SparrohPlugin.Logger.LogInfo((object)("[HudReposition] Drag start: " + _dragging.DisplayName)); } } if (_dragging != null && (Object)(object)_dragging.Rect != (Object)null && held && TryScreenToNormalizedParent(_dragging.Rect, screenPos, out var normalized2)) { Vector2 val = normalized2 + _dragGrabOffset; val.x = Mathf.Clamp01(val.x); val.y = Mathf.Clamp01(val.y); ApplyAnchorsLive(_dragging.Rect, val); } if (released && _dragging != null) { CommitDrag(_dragging); _dragging = null; } } private void DrawOverlay() { //IL_0015: 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_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: 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_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Expected O, but got Unknown //IL_00ee: 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_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: 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) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: 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) //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Expected O, but got Unknown //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Expected O, but got Unknown //IL_02b1: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) Rect val = new Rect(0f, 0f, (float)Screen.width, 36f); GUI.color = new Color(0f, 0f, 0f, 0.75f); GUI.DrawTexture(val, (Texture)(object)Texture2D.whiteTexture); GUI.color = Color.white; IReadOnlyList<HudRepositionAPI.HudElement> registered = HudRepositionAPI.GetRegistered(); string text = ((registered.Count == 0) ? "HUD Reposition Mode — no HUD elements found (is the HUD visible in-mission?) · Esc/F9 to exit" : $"HUD Reposition Mode — {registered.Count} element(s) · drag boxes to move · Esc/F9 to exit"); GUIStyle val2 = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, fontSize = 15, fontStyle = (FontStyle)1 }; val2.normal.textColor = Color.white; GUIStyle val3 = val2; GUI.Label(val, text, val3); Rect val7 = default(Rect); foreach (HudRepositionAPI.HudElement item in registered) { if ((Object)(object)item.Rect == (Object)null || !TryGetScreenRect(item.Rect, out var guiRect)) { continue; } guiRect = EnsureMinHitSize(ExpandRect(guiRect, 10f, 8f)); int num; Color val4; if (_dragging != null) { num = ((_dragging.Id == item.Id) ? 1 : 0); if (num != 0) { val4 = new Color(0.2f, 0.85f, 0.4f, 0.4f); goto IL_015f; } } else { num = 0; } val4 = new Color(0.2f, 0.55f, 1f, 0.35f); goto IL_015f; IL_015f: Color color = val4; Color color2 = ((num != 0) ? new Color(0.2f, 1f, 0.4f, 1f) : new Color(0.5f, 0.85f, 1f, 1f)); GUI.color = color; GUI.DrawTexture(guiRect, (Texture)(object)Texture2D.whiteTexture); GUI.color = color2; DrawBorder(guiRect, 2f); GUI.color = Color.white; Vector2 anchorMin = item.Rect.anchorMin; string text2 = $"{item.DisplayName} ({anchorMin.x:F3}, {anchorMin.y:F3})"; GUIStyle val5 = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)0, fontSize = 13, fontStyle = (FontStyle)1 }; val5.normal.textColor = Color.white; GUIStyle val6 = val5; ((Rect)(ref val7))..ctor(((Rect)(ref guiRect)).x, Mathf.Max(40f, ((Rect)(ref guiRect)).y - 18f), Mathf.Max(((Rect)(ref guiRect)).width, 240f), 18f); GUIStyle val8 = new GUIStyle(val6); val8.normal.textColor = Color.black; GUIStyle val9 = val8; GUI.Label(new Rect(((Rect)(ref val7)).x + 1f, ((Rect)(ref val7)).y + 1f, ((Rect)(ref val7)).width, ((Rect)(ref val7)).height), text2, val9); GUI.Label(val7, text2, val6); } } private void CommitDrag(HudRepositionAPI.HudElement element) { //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)element?.Rect == (Object)null) { return; } Vector2 anchorMin = element.Rect.anchorMin; float num = Mathf.Clamp01(anchorMin.x); float num2 = Mathf.Clamp01(anchorMin.y); try { bool flag = false; if (!Mathf.Approximately(element.AnchorX.Value, num)) { element.AnchorX.Value = num; flag = true; } if (!Mathf.Approximately(element.AnchorY.Value, num2)) { element.AnchorY.Value = num2; flag = true; } if (flag) { ((ConfigEntryBase)element.AnchorX).ConfigFile.Save(); SparrohPlugin.Logger.LogInfo((object)$"[HudReposition] Saved '{element.DisplayName}' → ({num:F4}, {num2:F4})"); } } catch (Exception ex) { SparrohPlugin.Logger.LogError((object)("[HudReposition] Failed to save '" + element.DisplayName + "': " + ex.Message)); } ApplyAnchorsLive(element.Rect, new Vector2(num, num2)); } private static void ApplyAnchorsLive(RectTransform rect, Vector2 anchors) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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) rect.anchorMin = anchors; rect.anchorMax = anchors; rect.anchoredPosition = Vector2.zero; } private static HudRepositionAPI.HudElement FindElementAtScreenPos(IReadOnlyList<HudRepositionAPI.HudElement> elements, Vector2 screenPos) { //IL_0035: 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_004f: Unknown result type (might be due to invalid IL or missing references) HudRepositionAPI.HudElement result = null; float num = float.MaxValue; foreach (HudRepositionAPI.HudElement element in elements) { if ((Object)(object)element.Rect == (Object)null || !TryGetScreenRectRaw(element.Rect, out var screenRect)) { continue; } screenRect = EnsureMinHitSize(ExpandRect(screenRect, 10f, 8f)); if (((Rect)(ref screenRect)).Contains(screenPos)) { float num2 = ((Rect)(ref screenRect)).width * ((Rect)(ref screenRect)).height; if (num2 < num) { num = num2; result = element; } } } return result; } private static bool TryGetScreenRectRaw(RectTransform rect, out Rect screenRect) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013e: 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_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: 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_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) screenRect = default(Rect); if ((Object)(object)rect == (Object)null) { return false; } Camera val = null; Canvas componentInParent = ((Component)rect).GetComponentInParent<Canvas>(); if ((Object)(object)componentInParent != (Object)null && (int)componentInParent.renderMode != 0) { val = componentInParent.worldCamera ?? Camera.main; } Vector3[] array = (Vector3[])(object)new Vector3[4]; rect.GetWorldCorners(array); float num = float.MaxValue; float num2 = float.MinValue; float num3 = float.MaxValue; float num4 = float.MinValue; Vector2 val2 = default(Vector2); for (int i = 0; i < 4; i++) { if ((Object)(object)val != (Object)null) { val2 = RectTransformUtility.WorldToScreenPoint(val, array[i]); } else { ((Vector2)(ref val2))..ctor(array[i].x, array[i].y); } num = Mathf.Min(num, val2.x); num2 = Mathf.Max(num2, val2.x); num3 = Mathf.Min(num3, val2.y); num4 = Mathf.Max(num4, val2.y); } if (num2 - num < 1f || num4 - num3 < 1f) { Vector2 val3 = AnchorToScreenPoint(rect); screenRect = new Rect(val3.x - 90f, val3.y - 18f, 180f, 36f); return true; } screenRect = new Rect(num, num3, num2 - num, num4 - num3); return true; } private static Vector2 AnchorToScreenPoint(RectTransform rect) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: 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_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_001c: 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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: 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_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) Transform parent = ((Transform)rect).parent; RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null); if ((Object)(object)val == (Object)null) { return new Vector2((float)Screen.width * rect.anchorMin.x, (float)Screen.height * rect.anchorMin.y); } Rect rect2 = val.rect; Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(((Rect)(ref rect2)).xMin + rect.anchorMin.x * ((Rect)(ref rect2)).width, ((Rect)(ref rect2)).yMin + rect.anchorMin.y * ((Rect)(ref rect2)).height); Vector3 val3 = ((Transform)val).TransformPoint(Vector2.op_Implicit(val2)); Camera val4 = null; Canvas componentInParent = ((Component)rect).GetComponentInParent<Canvas>(); if ((Object)(object)componentInParent != (Object)null && (int)componentInParent.renderMode != 0) { val4 = componentInParent.worldCamera ?? Camera.main; } if ((Object)(object)val4 != (Object)null) { return RectTransformUtility.WorldToScreenPoint(val4, val3); } return new Vector2(val3.x, val3.y); } private static bool TryGetScreenRect(RectTransform rect, out Rect guiRect) { //IL_0001: 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_0044: Unknown result type (might be due to invalid IL or missing references) guiRect = default(Rect); if (!TryGetScreenRectRaw(rect, out var screenRect)) { return false; } guiRect = new Rect(((Rect)(ref screenRect)).x, (float)Screen.height - ((Rect)(ref screenRect)).y - ((Rect)(ref screenRect)).height, ((Rect)(ref screenRect)).width, ((Rect)(ref screenRect)).height); return true; } private static Rect ExpandRect(Rect r, float padX, float padY) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) return new Rect(((Rect)(ref r)).x - padX, ((Rect)(ref r)).y - padY, ((Rect)(ref r)).width + padX * 2f, ((Rect)(ref r)).height + padY * 2f); } private static Rect EnsureMinHitSize(Rect r) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Max(((Rect)(ref r)).width, 180f); float num2 = Mathf.Max(((Rect)(ref r)).height, 36f); float num3 = ((Rect)(ref r)).x + ((Rect)(ref r)).width * 0.5f; float num4 = ((Rect)(ref r)).y + ((Rect)(ref r)).height * 0.5f; return new Rect(num3 - num * 0.5f, num4 - num2 * 0.5f, num, num2); } private static void DrawBorder(Rect r, float thickness) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: 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) GUI.DrawTexture(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, ((Rect)(ref r)).width, thickness), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).yMax - thickness, ((Rect)(ref r)).width, thickness), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, thickness, ((Rect)(ref r)).height), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(((Rect)(ref r)).xMax - thickness, ((Rect)(ref r)).y, thickness, ((Rect)(ref r)).height), (Texture)(object)Texture2D.whiteTexture); } private static bool TryScreenToNormalizedParent(RectTransform rect, Vector2 screenPos, out Vector2 normalized) { //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_002c: 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_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_009b: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) normalized = Vector2.zero; if ((Object)(object)rect == (Object)null) { return false; } Transform parent = ((Transform)rect).parent; RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null); if ((Object)(object)val == (Object)null) { normalized = new Vector2(Mathf.Clamp01(screenPos.x / Mathf.Max(1f, (float)Screen.width)), Mathf.Clamp01(screenPos.y / Mathf.Max(1f, (float)Screen.height))); return true; } Camera val2 = null; Canvas componentInParent = ((Component)rect).GetComponentInParent<Canvas>(); if ((Object)(object)componentInParent != (Object)null && (int)componentInParent.renderMode != 0) { val2 = componentInParent.worldCamera ?? Camera.main; } Vector2 val3 = default(Vector2); if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(val, screenPos, val2, ref val3)) { normalized = new Vector2(Mathf.Clamp01(screenPos.x / Mathf.Max(1f, (float)Screen.width)), Mathf.Clamp01(screenPos.y / Mathf.Max(1f, (float)Screen.height))); return true; } Rect rect2 = val.rect; if (((Rect)(ref rect2)).width <= 0f || ((Rect)(ref rect2)).height <= 0f) { return false; } normalized = new Vector2((val3.x - ((Rect)(ref rect2)).xMin) / ((Rect)(ref rect2)).width, (val3.y - ((Rect)(ref rect2)).yMin) / ((Rect)(ref rect2)).height); return true; } private void HoldCursor() { if (!_cursorHeld) { FreeCursor.Acquire(); _cursorHeld = true; } } private void ReleaseCursor() { if (_cursorHeld) { FreeCursor.Release(); _cursorHeld = false; } } private void RunAutoDetect() { //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Expected O, but got Unknown try { List<AnchorPair> list = DiscoverAnchorPairs(); List<GameObject> list2 = FindHudRoots(); SparrohPlugin.Logger.LogInfo((object)$"[HudReposition] Auto-detect: {list.Count} anchor pair(s), {list2.Count} HUD root(s)"); foreach (AnchorPair pair in list) { string id = "auto::" + Path.GetFileNameWithoutExtension(pair.ConfigPath) + "::" + pair.Prefix; if (HudRepositionAPI.GetRegistered().Any((HudRepositionAPI.HudElement e) => e.AnchorX != null && string.Equals(((ConfigEntryBase)e.AnchorX).Definition.Key, pair.KeyX, StringComparison.OrdinalIgnoreCase) && string.Equals(((ConfigEntryBase)e.AnchorY).Definition.Key, pair.KeyY, StringComparison.OrdinalIgnoreCase))) { continue; } GameObject val = ((IEnumerable<GameObject>)list2).FirstOrDefault((Func<GameObject, bool>)((GameObject r) => NameMatchesPrefix(((Object)r).name, pair.Prefix))); if ((Object)(object)val == (Object)null && list2.Count > 0) { val = ((IEnumerable<GameObject>)list2).FirstOrDefault((Func<GameObject, bool>)((GameObject r) => ((Object)r).name.IndexOf(pair.Prefix.Substring(0, Math.Min(4, pair.Prefix.Length)), StringComparison.OrdinalIgnoreCase) >= 0)); } if ((Object)(object)val == (Object)null) { continue; } RectTransform component = val.GetComponent<RectTransform>(); if (!((Object)(object)component == (Object)null)) { if (!_autoConfigFiles.TryGetValue(pair.ConfigPath, out var value)) { value = new ConfigFile(pair.ConfigPath, true); _autoConfigFiles[pair.ConfigPath] = value; } ConfigEntry<float> anchorX = value.Bind<float>(pair.Section, pair.KeyX, pair.DefaultX, (ConfigDescription)null); ConfigEntry<float> anchorY = value.Bind<float>(pair.Section, pair.KeyY, pair.DefaultY, (ConfigDescription)null); HudRepositionAPI.RegisterAutoDetected(id, string.IsNullOrEmpty(pair.Prefix) ? ((Object)val).name : pair.Prefix, component, anchorX, anchorY); SparrohPlugin.Logger.LogInfo((object)("[HudReposition] Auto-detected '" + ((Object)val).name + "' ← " + pair.KeyX + "/" + pair.KeyY)); } } } catch (Exception ex) { SparrohPlugin.Logger.LogWarning((object)("[HudReposition] Auto-detect failed: " + ex.Message)); } } private static List<AnchorPair> DiscoverAnchorPairs() { List<AnchorPair> list = new List<AnchorPair>(); if (!Directory.Exists(Paths.ConfigPath)) { return list; } string[] files = Directory.GetFiles(Paths.ConfigPath, "*.cfg"); foreach (string text in files) { try { string item = ""; Dictionary<string, (string, float)> dictionary = new Dictionary<string, (string, float)>(StringComparer.OrdinalIgnoreCase); foreach (string item2 in File.ReadLines(text)) { string text2 = item2.Trim(); if (text2.Length == 0 || text2.StartsWith("#")) { continue; } if (text2.StartsWith("[") && text2.EndsWith("]")) { item = text2.Substring(1, text2.Length - 2); continue; } int num = text2.IndexOf('='); if (num > 0) { string key = text2.Substring(0, num).Trim(); string s = text2.Substring(num + 1).Trim(); if (float.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out var result) || float.TryParse(s, NumberStyles.Float, CultureInfo.CurrentCulture, out result)) { dictionary[key] = (item, result); } } } foreach (KeyValuePair<string, (string, float)> item3 in dictionary) { Match match = AnchorPairRegex.Match(item3.Key); if (match.Success) { string value = match.Groups["prefix"].Value; string text3 = value + "AnchorY"; if (dictionary.TryGetValue(text3, out var value2)) { list.Add(new AnchorPair { ConfigPath = text, Section = (string.IsNullOrEmpty(item3.Value.Item1) ? "HUD Positioning" : item3.Value.Item1), Prefix = value, KeyX = item3.Key, KeyY = text3, DefaultX = item3.Value.Item2, DefaultY = value2.Item2 }); } } } } catch (Exception ex) { SparrohPlugin.Logger.LogDebug((object)("[HudReposition] Could not parse " + text + ": " + ex.Message)); } } return list; } private static List<GameObject> FindHudRoots() { //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Expected O, but got Unknown List<GameObject> roots = new List<GameObject>(); HashSet<int> seen = new HashSet<int>(); try { Type type = Type.GetType("Pigeon.Movement.Player, Assembly-CSharp") ?? AppDomain.CurrentDomain.GetAssemblies().SelectMany(delegate(Assembly a) { try { return a.GetTypes(); } catch { return Type.EmptyTypes; } }).FirstOrDefault((Type t) => t.Name == "Player" && t.Namespace != null && t.Namespace.Contains("Pigeon")); if (type != null) { object obj = type.GetProperty("LocalPlayer", BindingFlags.Static | BindingFlags.Public)?.GetValue(null); if (obj != null) { object obj2 = (obj.GetType().GetProperty("PlayerLook") ?? obj.GetType().GetProperty("playerLook"))?.GetValue(obj); if (obj2 != null) { object? obj3 = (obj2.GetType().GetProperty("Reticle") ?? obj2.GetType().GetProperty("reticle"))?.GetValue(obj2); Transform val = (Transform)((obj3 is Transform) ? obj3 : null); if ((Object)(object)val != (Object)null) { foreach (Transform item in val) { Transform val2 = item; if ((Object)(object)((Component)val2).GetComponent<RectTransform>() != (Object)null) { Add(((Component)val2).gameObject); } } SparrohPlugin.Logger.LogInfo((object)$"[HudReposition] Found reticle with {val.childCount} child(ren)"); } } } } } catch (Exception ex) { SparrohPlugin.Logger.LogDebug((object)("[HudReposition] Reticle scan failed: " + ex.Message)); } try { RectTransform[] array = Object.FindObjectsOfType<RectTransform>(); foreach (RectTransform val3 in array) { string name = ((Object)((Component)val3).gameObject).name; if (name.IndexOf("HUD", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Meter", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Speedometer", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Altimeter", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Carnometer", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Tracker", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("GunStats", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("BossTimer", StringComparison.OrdinalIgnoreCase) >= 0) { Add(((Component)val3).gameObject); } } } catch (Exception ex2) { SparrohPlugin.Logger.LogDebug((object)("[HudReposition] Global HUD scan failed: " + ex2.Message)); } return roots; void Add(GameObject go) { if (!((Object)(object)go == (Object)null)) { int instanceID = ((Object)go).GetInstanceID(); if (seen.Add(instanceID)) { roots.Add(go); } } } } private static bool NameMatchesPrefix(string goName, string prefix) { if (string.IsNullOrEmpty(goName) || string.IsNullOrEmpty(prefix)) { return false; } string text = goName.Replace(" ", "").Replace("_", ""); string text2 = prefix.Replace(" ", "").Replace("_", ""); if (text.IndexOf(text2, StringComparison.OrdinalIgnoreCase) >= 0) { return true; } if (text2.StartsWith("Gun", StringComparison.OrdinalIgnoreCase) && text.IndexOf("Gun", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } if (text2.Length >= 4) { string value = text2.Substring(0, Math.Min(8, text2.Length)); if (text.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) { return true; } } return false; } } public static class InputBlocker { private static bool _patched; private static Harmony _harmony; public static bool ShouldBlockGameplayInput { get { if (!FreeCursor.IsHeld && !HudRepositionMode.IsActive) { return ModConfigGUI.IsVisible; } return true; } } public static void EnsurePatched(Harmony harmony) { //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Expected O, but got Unknown //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Expected O, but got Unknown if (_patched) { return; } _harmony = harmony; try { Type type = AccessTools.TypeByName("Gun") ?? AccessTools.TypeByName("Pigeon.Gun") ?? FindTypeBySimpleName("Gun"); if (type != null) { MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (methodInfo.IsSpecialName || methodInfo.IsGenericMethod) { continue; } string name = methodInfo.Name; if ((name.IndexOf("Fire", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Shoot", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Attack", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Primary", StringComparison.OrdinalIgnoreCase) >= 0) && name.IndexOf("OnFired", StringComparison.OrdinalIgnoreCase) < 0) { try { HarmonyMethod val = new HarmonyMethod(typeof(InputBlocker), "BlockIfUiOpen", (Type[])null); harmony.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); SparrohPlugin.Logger.LogInfo((object)("[InputBlocker] Patched " + type.Name + "." + methodInfo.Name)); } catch (Exception ex) { SparrohPlugin.Logger.LogDebug((object)("[InputBlocker] Skip " + methodInfo.Name + ": " + ex.Message)); } } } } Type type2 = AccessTools.TypeByName("Pigeon.Movement.Player") ?? AccessTools.TypeByName("Player"); if (type2 != null) { MethodInfo[] methods = type2.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo2 in methods) { string name2 = methodInfo2.Name; if (name2.IndexOf("Fire", StringComparison.OrdinalIgnoreCase) >= 0 || name2.IndexOf("Shoot", StringComparison.OrdinalIgnoreCase) >= 0 || name2.IndexOf("Attack", StringComparison.OrdinalIgnoreCase) >= 0) { try { HarmonyMethod val2 = new HarmonyMethod(typeof(InputBlocker), "BlockIfUiOpen", (Type[])null); harmony.Patch((MethodBase)methodInfo2, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); SparrohPlugin.Logger.LogInfo((object)("[InputBlocker] Patched " + type2.Name + "." + methodInfo2.Name)); } catch { } } } } _patched = true; } catch (Exception ex2) { SparrohPlugin.Logger.LogWarning((object)("[InputBlocker] Patch setup failed: " + ex2.Message)); } } public static bool BlockIfUiOpen() { return !ShouldBlockGameplayInput; } public static void SoftSuppressMouseFire() { _ = ShouldBlockGameplayInput; } private static Type FindTypeBySimpleName(string simpleName) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { try { Type type = assembly.GetTypes().FirstOrDefault((Type x) => x.Name == simpleName); if (type != null) { return type; } } catch { } } return null; } } public class ModConfigGUI : MonoBehaviour { private sealed class ModBlockState { public string Key; public GameObject Body; public TextMeshProUGUI Chevron; public RectTransform TitleRect; public string TitleRichText; public bool IsExpanded; } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static Action <>9__50_0; public static Action <>9__50_1; public static Action<string> <>9__51_0; public static Action <>9__51_1; public static UnityAction <>9__51_2; public static Action<int, string> <>9__51_3; public static Action<bool> <>9__51_4; public static Action<bool> <>9__51_5; public static Action <>9__51_6; public static Comparison<ModInfo> <>9__82_0; public static Comparison<ModInfo> <>9__82_1; public static Comparison<ModInfo> <>9__82_2; public static Comparison<ModInfo> <>9__82_3; public static Func<string, string> <>9__91_0; internal void <CreateGUI>b__50_0() { if (_visible) { _visible = false; ClearActiveEditing(); ReleaseCursor(); if ((Object)(object)EventSystem.current != (Object)null) { EventSystem.current.SetSelectedGameObject((GameObject)null); } } } internal void <CreateGUI>b__50_1() { Hide(); HudRepositionMode.Enter(); } internal void <CreateToolbar>b__51_0(string query) { if (!_suppressToolbarCallbacks) { _searchQuery = query ?? ""; RefreshMods(resetScroll: true, preserveSearchFocus: true); } } internal void <CreateToolbar>b__51_1() { if (!_suppressToolbarCallbacks) { SetToolbarFiltersCollapsed(!_toolbarFiltersCollapsed, persist: true); } } internal void <CreateToolbar>b__51_2() { bool isOpen = _sortDropdown.IsOpen; ClearActiveEditing(); if (!isOpen) { _sortDropdown.OpenList(); RegisterOpenDropdown(_sortDropdown); } } internal void <CreateToolbar>b__51_3(int idx, string _) { if (!_suppressToolbarCallbacks) { string text = SortModeIds[Mathf.Clamp(idx, 0, SortModeIds.Length - 1)]; if (SparrohPlugin.ModSortMode != null && SparrohPlugin.ModSortMode.Value != text) { SparrohPlugin.ModSortMode.Value = text; ((ConfigEntryBase)SparrohPlugin.ModSortMode).ConfigFile.Save(); } UnregisterDropdown(_sortDropdown); RefreshMods(resetScroll: true); } } internal void <CreateToolbar>b__51_4(bool val) { if (!_suppressToolbarCallbacks) { if (SparrohPlugin.HideModsWithoutConfig != null && SparrohPlugin.HideModsWithoutConfig.Value != val) { SparrohPlugin.HideModsWithoutConfig.Value = val; ((ConfigEntryBase)SparrohPlugin.HideModsWithoutConfig).ConfigFile.Save(); } RefreshMods(resetScroll: true); } } internal void <CreateToolbar>b__51_5(bool val) { if (!_suppressToolbarCallbacks) { if (SparrohPlugin.GroupModsByAuthor != null && SparrohPlugin.GroupModsByAuthor.Value != val) { SparrohPlugin.GroupModsByAuthor.Value = val; ((ConfigEntryBase)SparrohPlugin.GroupModsByAuthor).ConfigFile.Save(); } RefreshMods(resetScroll: true); } } internal void <CreateToolbar>b__51_6() { if (!_suppressToolbarCallbacks) { ToggleExpandCollapseAll(); } } internal int <SortMods>b__82_0(ModInfo a, ModInfo b) { return string.Compare(((ModInfo)(ref b)).Name, ((ModInfo)(ref a)).Name, StringComparison.OrdinalIgnoreCase); } internal int <SortMods>b__82_1(ModInfo a, ModInfo b) { int num = ((ModInfo)(ref b)).IsSandbox.CompareTo(((ModInfo)(ref a)).IsSandbox); if (num != 0) { return num; } return string.Compare(((ModInfo)(ref a)).Name, ((ModInfo)(ref b)).Name, StringComparison.OrdinalIgnoreCase); } internal int <SortMods>b__82_2(ModInfo a, ModInfo b) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) bool value = ModHasConfig(a); int num = ModHasConfig(b).CompareTo(value); if (num != 0) { return num; } return string.Compare(((ModInfo)(ref a)).Name, ((ModInfo)(ref b)).Name, StringComparison.OrdinalIgnoreCase); } internal int <SortMods>b__82_3(ModInfo a, ModInfo b) { return string.Compare(((ModInfo)(ref a)).Name, ((ModInfo)(ref b)).Name, StringComparison.OrdinalIgnoreCase); } internal string <ParseModConfig>b__91_0(string s) { return s.Trim(); } } private const float ClickDragThresholdPx = 8f; private const float FontTitleRef = 26f; private const float FontModTitleRef = 22f; private const float FontSectionRef = 18f; private const float FontLabelRef = 17f; private const float FontBodyRef = 16f; private const float FontSmallRef = 14f; private static UIWindow _window; private static bool _visible; private static bool _cursorHeld; private static TMP_InputField _activeInput; private static readonly List<UIDropdown> _openDropdowns = new List<UIDropdown>(); private static StickyModTitleController _stickyTitles; private static RectTransform _toolbarRoot; private static RectTransform _toolbarFiltersBody; private static RectTransform _toolbarScrollRt; private static UIInputField _searchField; private static UIDropdown _sortDropdown; private static UIToggle _hideEmptyToggle; private static UIToggle _groupByAuthorToggle; private static UIButton _expandCollapseAllBtn; private static UIButton _toolbarFiltersToggleBtn; private static readonly List<UIButton> _filterChipButtons = new List<UIButton>(); private static string _searchQuery = ""; private static bool _suppressToolbarCallbacks; private static bool _toolbarFiltersCollapsed; private static float _toolbarHExpanded; private static float _toolbarHCollapsed; private static string[] _cfgFilesCache; private static readonly HashSet<string> _collapsedMods = new HashSet<string>(StringComparer.OrdinalIgnoreCase); private static readonly List<ModBlockState> _modBlocks = new List<ModBlockState>(); private static readonly string[] SortModeIds = new string[5] { "Alphabetical", "AlphabeticalDesc", "LoadOrder", "SandboxFirst", "HasConfigFirst" }; private static readonly string[] SortModeLabels = new string[5] { "A–Z", "Z–A", "Load order", "Sandbox first", "Has config first" }; private static readonly string[] FilterChipIds = new string[3] { "All", "Sandbox", "ClientSide" }; private static readonly string[] FilterChipLabels = new string[3] { "All", "Sandbox", "Client-side" }; public static TMP_InputField KeyBindInput; public static TMP_InputField RepositionKeyBindInput; private static Dictionary<string, Dictionary<string, string[]>> _cachedOptions = new Dictionary<string, Dictionary<string, string[]>>(); public static bool IsVisible => _visible; internal static void ClearActiveEditing() { if ((Object)(object)_activeInput != (Object)null) { _activeInput.DeactivateInputField(false); _activeInput = null; } for (int num = _openDropdowns.Count - 1; num >= 0; num--) { UIDropdown val = _openDropdowns[num]; if (val != null) { val.CloseList(); } } _openDropdowns.Clear(); if ((Object)(object)EventSystem.current != (Object)null) { EventSystem.current.SetSelectedGameObject((GameObject)null); } } private static void RegisterOpenDropdown(UIDropdown dropdown) { if (dropdown != null && !_openDropdowns.Contains(dropdown)) { _openDropdowns.Add(dropdown); } } private static void UnregisterDropdown(UIDropdown dropdown) { _openDropdowns.Remove(dropdown); } private static void ActivateInput(TMP_InputField input) { if (!((Object)(object)input == (Object)null)) { if ((Object)(object)_activeInput != (Object)null && (Object)(object)_activeInput != (Object)(object)input) { _activeInput.DeactivateInputField(false); } _activeInput = input; ((Selectable)input).interactable = true; input.ActivateInputField(); if ((Object)(object)EventSystem.current != (Object)null) { EventSystem.current.SetSelectedGameObject(((Component)input).gameObject); } } } public static void Toggle() { if (_window == null || (Object)(object)_window.GameObject == (Object)null) { try { CreateGUI(); } catch (Exception arg) { SparrohPlugin.Logger.LogError((object)$"Error creating GUI: {arg}"); return; } } if (_visible) { Hide(); } else { Show(); } } public static void Show() { if (_window == null || (Object)(object)_window.GameObject == (Object)null) { try { CreateGUI(); } catch (Exception arg) { SparrohPlugin.Logger.LogError((object)$"Error creating GUI: {arg}"); return; } } if (!_visible) { if (HudRepositionMode.IsActive) { HudRepositionMode.Exit(); } _visible = true; _window.Show(); HoldCursor(); _searchQuery = ""; if (_searchField != null) { _suppressToolbarCallbacks = true; _searchField.Text = ""; _suppressToolbarCallbacks = false; } SyncToolbarFromConfig(); RefreshMods(resetScroll: true); if ((Object)(object)EventSystem.current != (Object)null) { EventSystem.current.SetSelectedGameObject((GameObject)null); } } } public static void Hide() { if (_visible) { _visible = false; ClearActiveEditing(); if (_window != null) { _window.Hide(false); } ReleaseCursor(); if ((Object)(object)EventSystem.current != (Object)null) { EventSystem.current.SetSelectedGameObject((GameObject)null); } } } private static void HoldCursor() { if (!_cursorHeld) { FreeCursor.Acquire(); _cursorHeld = true; } } private static void ReleaseCursor() { if (_cursorHeld) { FreeCursor.Release(); _cursorHeld = false; } } private static void CreateGUI() { //IL_0014: 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_010f: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) UITheme.Initialize(); _window = UIWindow.Create("ModConfig", (Vector2?)new Vector2(520f, 640f), "Mod Configs", true, true, (int?)(UITheme.WindowSortingOrder + 10)); _window.OnClose((Action)delegate { if (_visible) { _visible = false; ClearActiveEditing(); ReleaseCursor(); if ((Object)(object)EventSystem.current != (Object)null) { EventSystem.current.SetSelectedGameObject((GameObject)null); } } }); if ((Object)(object)_window.TitleText != (Object)null) { ((TMP_Text)_window.TitleText).fontSize = UITheme.S(26f); ((TMP_Text)_window.TitleText).fontStyle = (FontStyles)1; ((Graphic)_window.TitleText).color = UIColors.TextPrimary; ((TMP_Text)_window.TitleText).alignment = (TextAlignmentOptions)513; UIHelpers.SetFillParent(((TMP_Text)_window.TitleText).rectTransform, UITheme.S(8f)); ((TMP_Text)_window.TitleText).rectTransform.offsetMax = new Vector2(0f - UITheme.S(200f), 0f - UITheme.S(4f)); ((TMP_Text)_window.TitleText).rectTransform.offsetMin = new Vector2(UITheme.S(10f), UITheme.S(4f)); } try { RectTransform val = (RectTransform)(((Object)(object)_window.TitleText != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null); if ((Object)(object)val != (Object)null) { UIButton val2 = UIButton.Create((Transform)(object)val, "Reposition HUDs", (Action)delegate { Hide(); HudRepositionMode.Enter(); }, (UIButtonStyle)1, "RepositionButton", (float?)UITheme.S(28f)); RectTransform rect = val2.Rect; Vector2 anchorMin = (rect.anchorMax = new Vector2(1f, 0.5f)); rect.anchorMin = anchorMin; rect.pivot = new Vector2(1f, 0.5f); rect.sizeDelta = new Vector2(UITheme.S(150f), UITheme.S(28f)); rect.anchoredPosition = new Vector2(0f - UITheme.S(48f), 0f); LayoutElement component = val2.GameObject.GetComponent<LayoutElement>(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } if ((Object)(object)val2.Label != (Object)null) { ((TMP_Text)val2.Label).fontSize = UITheme.S(14f); ((TMP_Text)val2.Label).fontStyle = (FontStyles)1; } } } catch (Exception ex) { SparrohPlugin.Logger.LogWarning((object)("Could not add Reposition button to title bar: " + ex.Message)); } if (_window.ScrollView != null) { ScrollRect scrollRect = _window.ScrollView.ScrollRect; scrollRect.scrollSensitivity = 0f; _stickyTitles = CreateStickyModTitleOverlay(_window.ScrollView); _window.ScrollView.GameObject.AddComponent<ItemStepScrollHandler>().Initialize(scrollRect, _stickyTitles); CreateToolbar(_window.ScrollView); } _window.Hide(false); _visible = false; } private static void CreateToolbar(UIScrollView scrollView) { //IL_00ab: 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_00c8: 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_0135: Unknown result type (might be due to invalid IL or missing references) //IL_014a: 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) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Expected O, but got Unknown //IL_0412: Unknown result type (might be due to invalid IL or missing references) //IL_0421: Expected O, but got Unknown //IL_046f: Unknown result type (might be due to invalid IL or missing references) //IL_047e: Expected O, but got Unknown //IL_0560: Unknown result type (might be due to invalid IL or missing references) //IL_0565: Unknown result type (might be due to invalid IL or missing references) //IL_056b: Expected O, but got Unknown //IL_0692: Unknown result type (might be due to invalid IL or missing references) //IL_06a1: Expected O, but got Unknown //IL_0815: Unknown result type (might be due to invalid IL or missing references) //IL_0824: Expected O, but got Unknown Transform parent = ((Transform)scrollView.Rect).parent; RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null); if ((Object)(object)val == (Object)null) { return; } float num = UITheme.S(4f); float num2 = UITheme.S(34f); float num3 = UITheme.S(30f); float num4 = UITheme.S(5f); _toolbarHExpanded = num + num2 + num4 + num3 + num4 + num3 + num4 + num3 + num; _toolbarHCollapsed = num + num2 + num; _toolbarScrollRt = scrollView.Rect; _toolbarFiltersCollapsed = SparrohPlugin.ToolbarFiltersCollapsed?.Value ?? false; float num5 = (_toolbarFiltersCollapsed ? _toolbarHCollapsed : _toolbarHExpanded); _toolbarScrollRt.offsetMax = new Vector2(_toolbarScrollRt.offsetMax.x, 0f - num5); Image obj = UIFactory.CreateImage("Toolbar", (Transform)(object)val, UIColors.Surface, true); UIFactory.ApplyWhiteSprite(obj); _toolbarRoot = ((Graphic)obj).rectTransform; UIHelpers.SetTopStretch(_toolbarRoot, num5, 0f, 0f, 0f); ((Transform)_toolbarRoot).SetAsLastSibling(); Image obj2 = UIFactory.CreateImage("ToolbarAccent", (Transform)(object)_toolbarRoot, UIColors.BorderAccent, false); UIFactory.ApplyWhiteSprite(obj2); RectTransform rectTransform = ((Graphic)obj2).rectTransform; rectTransform.anchorMin = new Vector2(0f, 0f); rectTransform.anchorMax = new Vector2(1f, 0f); rectTransform.pivot = new Vector2(0.5f, 0f); rectTransform.sizeDelta = new Vector2(0f, UITheme.S(2f)); rectTransform.anchoredPosition = Vector2.zero; ((Component)obj2).gameObject.AddComponent<LayoutElement>().ignoreLayout = true; UIFactory.AddVerticalLayout(((Component)obj).gameObject, num4, UITheme.ScaledPadding(8, 8, 6, 8), (TextAnchor)0, true, false, true, true); RectTransform obj3 = UIFactory.CreateRect("SearchRow", (Transform)(object)_toolbarRoot); GameObject gameObject = ((Component)obj3).gameObject; float? num6 = num2; float? num7 = num2; UIHelpers.EnsureLayoutElement(gameObject, (float?)null, num6, num7); UIFactory.AddHorizontalLayout(((Component)obj3).gameObject, UITheme.S(6f), new RectOffset(0, 0, 0, 0), (TextAnchor)3, true, false, true, true); _searchField = UIInputField.Create((Transform)(object)obj3, "", "Search mods…", (Action<string>)delegate(string query) { if (!_suppressToolbarCallbacks) { _searchQuery = query ?? ""; RefreshMods(resetScroll: true, preserveSearchFocus: true); } }, "SearchField"); GameObject gameObject2 = _searchField.GameObject; num7 = num2; num6 = num2; UIHelpers.EnsureLayoutElement(gameObject2, (float?)null, num7, num6).flexibleWidth = 1f; if ((Object)(object)_searchField.TextComponent != (Object)null) { ((TMP_Text)_searchField.TextComponent).fontSize = UITheme.S(16f); ((TMP_Text)_searchField.TextComponent).alignment = (TextAlignmentOptions)513; } if ((Object)(object)_searchField.Placeholder != (Object)null) { ((TMP_Text)_searchField.Placeholder).fontSize = UITheme.S(16f); ((TMP_Text)_searchField.Placeholder).alignment = (TextAlignmentOptions)513; } _toolbarFiltersToggleBtn = UIButton.Create((Transform)(object)obj3, _toolbarFiltersCollapsed ? "+" : "-", (Action)delegate { if (!_suppressToolbarCallbacks) { SetToolbarFiltersCollapsed(!_toolbarFiltersCollapsed, persist: true); } }, (UIButtonStyle)0, "ToolbarFiltersToggle", (float?)num2); UIHelpers.EnsureLayoutElement(_toolbarFiltersToggleBtn.GameObject, (float?)num2, (float?)num2, (float?)num2).flexibleWidth = 0f; if ((Object)(object)_toolbarFiltersToggleBtn.Label != (Object)null) { ((TMP_Text)_toolbarFiltersToggleBtn.Label).fontSize = UITheme.S(22f); ((TMP_Text)_toolbarFiltersToggleBtn.Label).fontStyle = (FontStyles)1; } _toolbarFiltersBody = UIFactory.CreateRect("FiltersBody", (Transform)(object)_toolbarRoot); float value = num3 + num4 + num3 + num4 + num3; GameObject gameObject3 = ((Component)_toolbarFiltersBody).gameObject; num6 = value; num7 = value; UIHelpers.EnsureLayoutElement(gameObject3, (float?)null, num6, num7); UIFactory.AddVerticalLayout(((Component)_toolbarFiltersBody).gameObject, num4, new RectOffset(0, 0, 0, 0), (TextAnchor)0, true, false, true, true); RectTransform obj4 = UIFactory.CreateRect("SortRow", (Transform)(object)_toolbarFiltersBody); GameObject gameObject4 = ((Component)obj4).gameObject; num7 = num3; num6 = num3; UIHelpers.EnsureLayoutElement(gameObject4, (float?)null, num7, num6); UIFactory.AddHorizontalLayout(((Component)obj4).gameObject, UITheme.S(8f), new RectOffset(0, 0, 0, 0), (TextAnchor)3, true, false, true, true); int num8 = IndexOfSortMode(SparrohPlugin.ModSortMode?.Value); _sortDropdown = UIDropdown.Create((Transform)(object)obj4, (IList<string>)SortModeLabels, num8, (Action<int, string>)null, "SortDropdown"); UIHelpers.EnsureLayoutElement(_sortDropdown.GameObject, (float?)UITheme.S(160f), (float?)num3, (float?)num3).flexibleWidth = 1f; if ((Object)(object)_sortDropdown.Label != (Object)null) { ((TMP_Text)_sortDropdown.Label).fontSize = UITheme.S(14f); ((TMP_Text)_sortDropdown.Label).fontStyle = (FontStyles)1; } Button componentInChildren = _sortDropdown.GameObject.GetComponentInChildren<Button>(); if ((Object)(object)componentInChildren != (Object)null) { ((UnityEventBase)componentInChildren.onClick).RemoveAllListeners(); ButtonClickedEvent onClick = componentInChildren.onClick; object obj5 = <>c.<>9__51_2; if (obj5 == null) { UnityAction val2 = delegate { bool isOpen = _sortDropdown.IsOpen; ClearActiveEditing(); if (!isOpen) { _sortDropdown.OpenList(); RegisterOpenDropdown(_sortDropdown); } }; <>c.<>9__51_2 = val2; obj5 = (object)val2; } ((UnityEvent)onClick).AddListener((UnityAction)obj5); } _sortDropdown.OnChanged((Action<int, string>)delegate(int idx, string _) { if (!_suppressToolbarCallbacks) { string text3 = SortModeIds[Mathf.Clamp(idx, 0, SortModeIds.Length - 1)]; if (SparrohPlugin.ModSortMode != null && SparrohPlugin.ModSortMode.Value != text3) { SparrohPlugin.ModSortMode.Value = text3; ((ConfigEntryBase)SparrohPlugin.ModSortMode).ConfigFile.Save(); } UnregisterDropdown(_sortDropdown); RefreshMods(resetScroll: true); } }); _hideEmptyToggle = UIToggle.Create((Transform)(object)obj4, "Hide empty", SparrohPlugin.HideModsWithoutConfig?.Value ?? true, (Action<bool>)delegate(bool flag2) { if (!_suppressToolbarCallbacks) { if (SparrohPlugin.HideModsWithoutConfig != null && SparrohPlugin.HideModsWithoutConfig.Value != flag2) { SparrohPlugin.HideModsWithoutConfig.Value = flag2; ((ConfigEntryBase)SparrohPlugin.HideModsWithoutConfig).ConfigFile.Save(); } RefreshMods(resetScroll: true); } }, "HideEmptyToggle"); UIHelpers.EnsureLayoutElement(_hideEmptyToggle.GameObject, (float?)UITheme.S(120f), (float?)num3, (float?)null).flexibleWidth = 0f; if ((Object)(object)_hideEmptyToggle.Label != (Object)null) { ((TMP_Text)_hideEmptyToggle.Label).fontSize = UITheme.S(14f); } RectTransform val3 = UIFactory.CreateRect("ChipRow", (Transform)(object)_toolbarFiltersBody); GameObject gameObject5 = ((Component)val3).gameObject; num6 = num3; num7 = num3; UIHelpers.EnsureLayoutElement(gameObject5, (float?)null, num6, num7); UIFactory.AddHorizontalLayout(((Component)val3).gameObject, UITheme.S(6f), new RectOffset(0, 0, 0, 0), (TextAnchor)3, true, true, true, true); _filterChipButtons.Clear(); string b = NormalizeFilter(SparrohPlugin.ModListFilter?.Value); for (int num9 = 0; num9 < FilterChipIds.Length; num9++) { string text = FilterChipIds[num9]; string text2 = FilterChipLabels[num9]; bool flag = string.Equals(text, b, StringComparison.OrdinalIgnoreCase); UIButton val4 = UIButton.Create((Transform)(object)val3, text2, (Action)null, (UIButtonStyle)(flag ? 3 : 0), "Filter_" + text, (float?)num3); GameObject gameObject6 = val4.GameObject; num7 = num3; num6 = num3; LayoutElement obj6 = UIHelpers.EnsureLayoutElement(gameObject6, (float?)null, num7, num6); obj6.flexibleWidth = 1f; obj6.preferredWidth = -1f; if ((Object)(object)val4.Label != (Object)null) { ((TMP_Text)val4.Label).fontSize = UITheme.S(14f); ((TMP_Text)val4.Label).fontStyle = (FontStyles)1; } string capturedId = text; val4.OnClick((Action)delegate { if (!_suppressToolbarCallbacks) { ApplyFilterChip(capturedId); } }); _filterChipButtons.Add(val4); } RectTransform obj7 = UIFactory.CreateRect("DensityRow", (Transform)(object)_toolbarFiltersBody); GameObject gameObject7 = ((Component)obj7).gameObject; num6 = num3; num7 = num3; UIHelpers.EnsureLayoutElement(gameObject7, (float?)null, num6, num7); UIFactory.AddHorizontalLayout(((Component)obj7).gameObject, UITheme.S(8f), new RectOffset(0, 0, 0, 0), (TextAnchor)3, true, false, true, true); _groupByAuthorToggle = UIToggle.Create((Transform)(object)obj7, "Group by author", SparrohPlugin.GroupModsByAuthor?.Value ?? false, (Action<bool>)delegate(bool flag2) { if (!_suppressToolbarCallbacks) { if (SparrohPlugin.GroupModsByAuthor != null && SparrohPlugin.GroupModsByAuthor.Value != flag2) { SparrohPlugin.GroupModsByAuthor.Value = flag2; ((ConfigEntryBase)SparrohPlugin.GroupModsByAuthor).ConfigFile.Save(); } RefreshMods(resetScroll: true); } }, "GroupByAuthorToggle"); UIHelpers.EnsureLayoutElement(_groupByAuthorToggle.GameObject, (float?)UITheme.S(150f), (float?)num3, (float?)null).flexibleWidth = 1f; if ((Object)(object)_groupByAuthorToggle.Label != (Object)null) { ((TMP_Text)_groupByAuthorToggle.Label).fontSize = UITheme.S(14f); } _expandCollapseAllBtn = UIButton.Create((Transform)(object)obj7, "Collapse all", (Action)delegate { if (!_suppressToolbarCallbacks) { ToggleExpandCollapseAll(); } }, (UIButtonStyle)0, "ExpandCollapseAll", (float?)num3); UIHelpers.EnsureLayoutElement(_expandCollapseAllBtn.GameObject, (float?)UITheme.S(120f), (float?)num3, (float?)null).flexibleWidth = 0f; if ((Object)(object)_expandCollapseAllBtn.Label != (Object)null) { ((TMP_Text)_expandCollapseAllBtn.Label).fontSize = UITheme.S(14f); ((TMP_Text)_expandCollapseAllBtn.Label).fontStyle = (FontStyles)1; } ApplyToolbarFiltersCollapsed(persist: false); } private static void SetToolbarFiltersCollapsed(bool collapsed, bool persist) { _toolbarFiltersCollapsed = collapsed; ApplyToolbarFiltersCollapsed(persist); } private static void ApplyToolbarFiltersCollapsed(bool persist) { //IL_0076: 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) if ((Object)(object)_toolbarFiltersBody != (Object)null) { ((Component)_toolbarFiltersBody).gameObject.SetActive(!_toolbarFiltersCollapsed); } float num = (_toolbarFiltersCollapsed ? _toolbarHCollapsed : _toolbarHExpanded); if ((Object)(object)_toolbarRoot != (Object)null) { UIHelpers.SetTopStretch(_toolbarRoot, num, 0f, 0f, 0f); } if ((Object)(object)_toolbarScrollRt != (Object)null) { _toolbarScrollRt.offsetMax = new Vector2(_toolbarScrollRt.offsetMax.x, 0f - num); } if (_toolbarFiltersToggleBtn != null) { _toolbarFiltersToggleBtn.SetText(_toolbarFiltersCollapsed ? "+" : "-"); } if (_toolbarFiltersCollapsed && _sortDropdown != null) { _sortDropdown.CloseList(); UnregisterDropdown(_sortDropdown); } if (persist && SparrohPlugin.ToolbarFiltersCollapsed != null && SparrohPlugin.ToolbarFiltersCollapsed.Value != _toolbarFiltersCollapsed) { SparrohPlugin.ToolbarFiltersCollapsed.Value = _toolbarFiltersCollapsed; ((ConfigEntryBase)SparrohPlugin.ToolbarFiltersCollapsed).ConfigFile.Save(); } } private static void SyncToolbarFromConfig() { _suppressToolbarCallbacks = true; try { if (_sortDropdown != null) { int num = IndexOfSortMode(SparrohPlugin.ModSortMode?.Value); _sortDropdown.Select(num, false); } if (_hideEmptyToggle != null && SparrohPlugin.HideModsWithoutConfig != null) { _hideEmptyToggle.IsOn = SparrohPlugin.HideModsWithoutConfig.Value; } if (_groupByAuthorToggle != null && SparrohPlugin.GroupModsByAuthor != null) { _groupByAuthorToggle.IsOn = SparrohPlugin.GroupModsByAuthor.Value; } RefreshFilterChipStyles(NormalizeFilter(SparrohPlugin.ModListFilter?.Value)); UpdateExpandCollapseAllLabel(); bool flag = SparrohPlugin.ToolbarFiltersCollapsed?.Value ?? false; if (flag != _toolbarFiltersCollapsed) { SetToolbarFiltersCollapsed(flag, persist: false); } else { ApplyToolbarFiltersCollapsed(persist: false); } } finally { _suppressToolbarCallbacks = false; } } private static void ApplyFilterChip(string filterId) { filterId = NormalizeFilter(filterId); if (SparrohPlugin.ModListFilter != null && !string.Equals(SparrohPlugin.ModListFilter.Value, filterId, StringComparison.OrdinalIgnoreCase)) { SparrohPlugin.ModListFilter.Value = filterId; ((ConfigEntryBase)SparrohPlugin.ModListFilter).ConfigFile.Save(); } RefreshFilterChipStyles(filterId); RefreshMods(resetScroll: true); } private static void RefreshFilterChipStyles(string activeFilter) { activeFilter = NormalizeFilter(activeFilter); for (int i = 0; i < _filterChipButtons.Count && i < FilterChipIds.Length; i++) { bool flag = string.Equals(FilterChipIds[i], activeFilter, StringComparison.OrdinalIgnoreCase); _filterChipButtons[i].SetStyle((UIButtonStyle)(flag ? 3 : 0)); } } private static int IndexOfSortMode(string mode) { if (string.IsNullOrEmpty(mode)) { return 0; } for (int i = 0; i < SortModeIds.Length; i++) { if (string.Equals(SortModeIds[i], mode, StringComparison.OrdinalIgnoreCase)) { return i; } } return 0; } private static string NormalizeFilter(string filter) { if (string.IsNullOrEmpty(filter)) { return "All"; } for (int i = 0; i < FilterChipIds.Length; i++) { if (string.Equals(FilterChipIds[i], filter, StringComparison.OrdinalIgnoreCase)) { return FilterChipIds[i]; } } return "All"; } private static string GetModKey(ModInfo mod) { if (!string.IsNullOrEmpty(((ModInfo)(ref mod)).GUID)) { return ((ModInfo)(ref mod)).GUID; } return ((ModInfo)(ref mod)).Name ?? ""; } private static string GetAuthorGroup(ModInfo mod) { string gUID = ((ModInfo)(ref mod)).GUID; if (string.IsNullOrEmpty(gUID)) { return "Other"; } int num = gUID.IndexOf('.'); if (num <= 0) { return "Other"; } return gUID.Substring(0, num); } private static void LoadCollapsedFromConfig() { _collapsedMods.Clear(); string text = SparrohPlugin.CollapsedMods?.Value; if (string.IsNullOrWhiteSpace(text)) { return; } string[] array = text.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < array.Length; i++) { string text2 = array[i].Trim(); if (text2.Length > 0) { _collapsedMods.Add(text2); } } } private static void SaveCollapsedToConfig() { if (SparrohPlugin.CollapsedMods != null) { string text = ((_collapsedMods.Count == 0) ? "" : string.Join(",", _collapsedMods)); if (!(SparrohPlugin.CollapsedMods.Value == text)) { SparrohPlugin.CollapsedMods.Value = text; ((ConfigEntryBase)SparrohPlugin.CollapsedMods).ConfigFile.Save(); } } } private static bool IsModExpanded(string key) { return !_collapsedMods.Contains(key); } private static void SetModExpanded(string key, bool expanded) { if (!string.IsNullOrEmpty(key)) { if (expanded) { _collapsedMods.Remove(key); } else { _collapsedMods.Add(key); } SaveCollapsedToConfig(); } } private static void ApplyBlockExpanded(ModBlockState block, bool expanded, bool persist) { if (block != null) { block.IsExpanded = expanded; if ((Object)(object)block.Body != (Object)null) { block.Body.SetActive(expanded); } if ((Object)(object)block.Chevron != (Object)null) { ((TMP_Text)block.Chevron).text = (expanded ? "-" : "+"); } if (persist) { SetModExpanded(block.Key, expanded); } SyncStickyTitleForBlock(block); } } private static string FormatStickyTitle(ModBlockState block) { if (block == null) { return ""; } return (block.IsExpanded ? "- " : "+ ") + block.TitleRichText; } private static void SyncStickyTitleForBlock(ModBlockState block) { if (block != null && !((Object)(object)block.TitleRect == (Object)null)) { _stickyTitles?.UpdateTitle(block.TitleRect, FormatStickyTitle(block)); } } private static void ToggleModBlock(ModBlockState block) { if (block != null) { ClearActiveEditing(); ApplyBlockExpanded(block, !block.IsExpanded, persist: true); _stickyTitles?.Refresh(); UpdateExpandCollapseAllLabel(); } } private static ModBlockState FindModBlock(string key) { if (string.IsNullOrEmpty(key)) { return null; } for (int i = 0; i < _modBlocks.Count; i++) { ModBlockState modBlockState = _modBlocks[i]; if (modBlockState != null && string.Equals(modBlockState.Key, key, StringComparison.OrdinalIgnoreCase)) { return modBlockState; } } return null; } internal static void ToggleModBlockByKey(string key) { ToggleModBlock(FindModBlock(key)); } private static void ToggleExpandCollapseAll() { bool flag = false; for (int i = 0; i < _modBlocks.Count; i++) { if (_modBlocks[i] != null && _modBlocks[i].IsExpanded) { flag = true; break; } } bool flag2 = !flag; for (int j = 0; j < _modBlocks.Count; j++) { ModBlockState modBlockState = _modBlocks[j]; if (modBlockState != null) { ApplyBlockExpanded(modBlockState, flag2, persist: false); if (flag2) { _collapsedMods.Remove(modBlockState.Key); } else { _collapsedMods.Add(modBlockState.Key); } } } SaveCollapsedToConfig(); UpdateExpandCollapseAllLabel(); _stickyTitles?.Refresh(); } private static void UpdateExpandCollapseAllLabel() { UIButton expandCollapseAllBtn = _expandCollapseAllBtn; if ((Object)(object)((expandCollapseAllBtn != null) ? expandCollapseAllBtn.Label : null) == (Object)null) { return; } bool flag = false; if (_modBlocks.Count == 0) { flag = _collapsedMods.Count == 0; } else { for (int i = 0; i < _modBlocks.Count; i++) { if (_modBlocks[i] != null && _modBlocks[i].IsExpanded) { flag = true; break; } } } _expandCollapseAllBtn.SetText(flag ? "Collapse all" : "Expand all"); } private static void CreateGroupHeader(Transform parent, string groupName) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) Image val = UIFactory.CreateImage("Group_" + groupName, parent, UIColors.SectionBar, false); UIFactory.ApplyWhiteSprite(val); GameObject gameObject = ((Component)val).gameObject; float? num = UITheme.S(28f); float? num2 = UITheme.S(28f); UIHelpers.EnsureLayoutElement(gameObject, (float?)null, num, num2); string text = (string.IsNullOrEmpty(groupName) ? "Other" : groupName); UIHelpers.SetFillParent(((TMP_Text)UIFactory.CreateTmp("Text", (Transform)(object)((Graphic)val).rectTransform, RichText.Bold(text), UITheme.S(18f), (Color?)UIColors.TextSecondary, (TextAlignmentOptions)4097, false)).rectTransform, UITheme.S(8f)); } private static StickyModTitleController CreateStickyModTitleOverlay(UIScrollView scrollView) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0056: 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_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: 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_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) float num = UITheme.S(44f); Image obj = UIFactory.CreateImage("StickyModTitle", (Transform)(object)scrollView.Viewport, UIColors.TitleBar, true); UIFactory.ApplyWhiteSprite(obj); RectTransform rectTransform = ((Graphic)obj).rectTransform; UIHelpers.SetTopStretch(rectTransform, num, 0f, 0f, 0f); ((Transform)rectTransform).SetAsLastSibling(); Image obj2 = UIFactory.CreateImage("Accent", (Transform)(object)rectTransform, UIColors.BorderAccent, false); UIFactory.ApplyWhiteSprite(obj2); RectTransform rectTransform2 = ((Graphic)obj2).rectTransform; rectTransform2.anchorMin = new Vector2(0f, 0f); rectTransform2.anchorMax = new Vector2(1f, 0f); rectTransform2.pivot = new Vector2(0.5f, 0f); rectTransform2.sizeDelta = new Vector2(0f, UITheme.S(2f)); rectTransform2.anchoredPosition = Vector2.zero; TextMeshProUGUI val = UIFactory.CreateTmp("Text", (Transform)(object)rectTransform, "", UITheme.S(22f), (Color?)UIColors.TextPrimary, (TextAlignmentOptions)4097, false); ((TMP_Text)val).fontStyle = (FontStyles)1; ((Graphic)val).raycastTarget = false; UIHelpers.SetFillParent(((TMP_Text)val).rectTransform, UITheme.S(10f)); ((Component)obj).gameObject.SetActive(false); StickyModTitleController controller = scrollView.GameObject.AddComponent<StickyModTitleController>(); controller.Initialize(scrollView.ScrollRect, rectTransform, val, num); ((Component)obj).gameObject.AddComponent<ClickVsDragToggle>().Initialize(initialValue: true, 8f, delegate { controller.ToggleActiveMod(); }); return controller; } public static void RefreshMods() { RefreshMods(resetScroll: false); } public static void RefreshMods(bool resetScroll, bool preserveSearchFocus = false) { //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_0133: 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) if (_window == null || (Object)(object)_window.Content == (Object)null) { return; } if (preserveSearchFocus) { for (int num = _openDropdowns.Count - 1; num >= 0; num--) { UIDropdown val = _openDropdowns[num]; if (val != null) { val.CloseList(); } } _openDropdowns.Clear(); } else { ClearActiveEditing(); } _stickyTitles?.Clear(); _modBlocks.Clear(); UIHelpers.DestroyChildren(_window.Content); _cfgFilesCache = null; LoadCollapsedFromConfig(); try { IReadOnlyList<ModInfo> mods = ModManager.Mods; if (mods == null) { ShowEmptyState("No mods loaded"); _stickyTitles?.Refresh(); UpdateExpandCollapseAllLabel(); if (resetScroll) { ResetScrollToTop(); } return; } List<ModInfo> list = BuildVisibleMods(mods); if (list.Count == 0) { ShowEmptyState("No mods match"); _stickyTitles?.Refresh(); UpdateExpandCollapseAllLabel(); if (resetScroll) { ResetScrollToTop(); } if (preserveSearchFocus) { RestoreSearchFocus(); } return; } bool num2 = SparrohPlugin.GroupModsByAuthor?.Value ?? false; bool flag = true; if (num2) { SortedDictionary<string, List<ModInfo>> sortedDictionary = new SortedDictionary<string, List<ModInfo>>(StringComparer.OrdinalIgnoreCase); for (int i = 0; i < list.Count; i++) { string authorGroup = GetAuthorGroup(list[i]); if (!sortedDictionary.TryGetValue(authorGroup, out var value)) { value = (sortedDictionary[authorGroup] = new List<ModInfo>()); } value.Add(list[i]); } foreach (KeyValuePair<string, List<ModInfo>> item in sortedDictionary) { if (!flag) { UISeparator.Create(_window.Content, "Separator", true); } flag = false; CreateGroupHeader(_window.Content, item.Key); for (int j = 0; j < item.Value.Count; j++) { try { if (j > 0) { UISeparator.Create(_window.Content, "Separator", true); } CreateModConfig(item.Value[j], _window.Content); } catch (Exception ex) { ManualLogSource logger = SparrohPlugin.Logger; ModInfo val2 = item.Value[j]; logger.LogError((object)("Error creating config for mod " + ((ModInfo)(ref val2)).Name + ": " + ex.Message)); } } } } else { foreach (ModInfo item2 in list) { ModInfo current2 = item2; try { if (!flag) { UISeparator.Create(_window.Content, "Separator", true); } flag = false; CreateModConfig(current2, _window.Content); } catch (Exception ex2) { SparrohPlugin.Logger.LogError((object)("Error creating config for mod " + ((ModInfo)(ref current2)).Name + ": " + ex2.Message)); } } } } catch (Exception ex3) { SparrohPlugin.Logger.LogError((object)("Error refreshing mods list: " + ex3.Message)); } _stickyTitles?.Refresh(); UpdateExpandCollapseAllLabel(); if (resetScroll) { ResetScrollToTop(); } if (preserveSearchFocus) { RestoreSearchFocus(); } } private static void ShowEmptyState(string message) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) GameObject gameObject = UIText.Create(_window.Content, "EmptyState", message, UITheme.S(16f), (Color?)UIColors.TextMuted, (TextAlignmentOptions)514, false).GameObject; float? num = UITheme.S(48f); float? num2 = UITheme.S(48f); UIHelpers.EnsureLayoutElement(gameObject, (float?)null, num, num2); } private static void ResetScrollToTop() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) UIWindow window = _window; object obj; if (window == null) { obj = null; } else { UIScrollView scrollView = window.ScrollView; obj = ((scrollView != null) ? scrollView.ScrollRect : null); } if (!((Object)obj == (Object)null)) { ScrollRect scrollRect = _window.ScrollView.ScrollRect; scrollRect.velocity = Vector2.zero; scrollRect.verticalNormalizedPosition = 1f; } } private static void RestoreSearchFocus() { UIInputField searchField = _searchField; if (!((Object)(object)((searchField != null) ? searchField.Input : null) == (Object)null)) { _activeInput = _searchField.Input; _searchField.Input.ActivateInputField(); if ((Object)(object)EventSystem.current != (Object)null) { EventSystem.current.SetSelectedGameObject(((Component)_searchField.Input).gameObject); } } } private static List<ModInfo> BuildVisibleMods(IReadOnlyList<ModInfo> source) { //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_0074: 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_00ad: Unknown result type (might be due to invalid IL or missing references) string query = (_searchQuery ?? "").Trim(); bool flag = SparrohPlugin.HideModsWithoutConfig?.Value ?? true; string text = NormalizeFilter(SparrohPlugin.ModListFilter?.Value); string mode = SparrohPlugin.ModSortMode?.Value ?? "Alphabetical"; List<ModInfo> list = new List<ModInfo>(source.Count); for (int i = 0; i < source.Count; i++) { ModInfo val = source[i]; if (ModMatchesSearch(val, query) && (!(text == "Sandbox") || ((ModInfo)(ref val)).IsSandbox) && (!(text == "ClientSide") || ((ModInfo)(ref val)).IsClientSide) && (!flag || ModHasConfig(val))) { list.Add(val); } } SortMods(list, mode); return list; } private static bool ModMatchesSearch(ModInfo mod, string query) { if (string.IsNullOrEmpty(query)) { return true; } if (!string.IsNullOrEmpty(((ModInfo)(ref mod)).Name) && ((ModInfo)(ref mod)).Name.IndexOf(query, StringComparison.OrdinalIgnoreCase) >= 0) { return true; } if (!string.IsNullOrEmpty(((ModInfo)(ref mod)).GUID) && ((ModInfo)(ref mod)).GUID.IndexOf(query, StringComparison.OrdinalIgnoreCase) >= 0) { return true; } return false; } private static void SortMods(List<ModInfo> list, string mode) { if (list == null || list.Count <= 1) { return; } mode = mode ?? "Alphabetical"; if (string.Equals(mode, "LoadOrder", StringComparison.OrdinalIgnoreCase)) { return; } if (string.Equals(mode, "AlphabeticalDesc", StringComparison.OrdinalIgnoreCase)) { list.Sort((ModInfo a, ModInfo b) => string.Compare(((ModInfo)(ref b)).Name, ((ModInfo)(ref a)).Name, StringComparison.OrdinalIgnoreCase)); } else if (string.Equals(mode, "SandboxFirst", StringComparison.OrdinalIgnoreCase)) { list.Sort(delegate(ModInfo a, ModInfo b) { int num = ((ModInfo)(ref b)).IsSandbox.CompareTo(((ModInfo)(ref a)).IsSandbox); return (num != 0) ? num : string.Compare(((ModInfo)(ref a)).Name, ((ModInfo)(ref b)).Name, StringComparison.OrdinalIgnoreCase); }); } else if (string.Equals(mode, "HasConfigFirst", StringComparison.OrdinalIgnoreCase)) { list.Sort(delegate(ModInfo a, ModInfo b) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) bool value = ModHasConfig(a); int num = ModHasConfig(b).CompareTo(value); return (num != 0) ? num : string.Compare(((ModInfo)(ref a)).Name, ((ModInfo)(ref b)).Name, StringComparison.OrdinalIgnoreCase); }); } else { list.Sort((ModInfo a, ModInfo b) => string.Compare(((ModInfo)(ref a)).Name, ((ModInfo)(ref b)).Name, StringComparison.OrdinalIgnoreCase)); } } private static string[] GetCfgFiles() { if (_cfgFilesCache != null) { return _cfgFilesCache; } try { if (Directory.Exists(Paths.ConfigPath)) { _cfgFilesCache = Directory.GetFiles(Paths.ConfigPath, "*.cfg"); } else { _cfgFilesCache = Array.Empty<string>(); } } catch (Exception ex) { SparrohPlugin.Logger.LogWarning((object)("Could not enumerate config files: " + ex.Message)); _cfgFilesCache = Array.Empty<string>(); } return _cfgFilesCache; } private static bool TryFindConfigPath(ModInfo mod, out string configPath) { configPath = null; if (string.IsNullOrEmpty(((ModInfo)(ref mod)).Name)) { return false; } string value = ((ModInfo)(ref mod)).Name.ToLowerInvariant(); string[] cfgFiles = GetCfgFiles(); foreach (string text in cfgFiles) { string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(text); if (fileNameWithoutExtension != null && fileNameWithoutExtension.ToLowerInvariant().Contains(value)) { configPath = text; return true; } } return false; } private static bool ModHasConfig(ModInfo mod) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) string configPath; return TryFindConfigPath(mod, out configPath); } private static void ApplySettingValue(ModInfo mod, string configPath, string section, string key, string value, ConfigEntry<string> fileFallback) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) if (!TrySetLiveConfigValue(mod, configPath, section, key, value) && fileFallback != null) { fileFallback.Value = value ?? ""; ((ConfigEntryBase)fileFallback).ConfigFile.Save(); } } private static bool TrySetLiveConfigValue(ModInfo mod, string configPath, string section, string key, string value) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) try { BaseUnityPlugin val = FindPluginForConfig(mod, configPath); if (((val != null) ? val.Config : null) == null) { return false; } ConfigEntryBase val2 = FindLiveEntry(val.Config, section, key); if (val2 == null) { return false; } val2.SetSerializedValue(value ?? ""); val.Config.Save(); return true; } catch (Exception ex) { SparrohPlugin.Logger.LogWarning((object)("Live config set failed for [" + section + "] " + key + ": " + ex.Message)); return false; } } private static BaseUnityPlugin FindPluginForConfig(ModInfo mod, string configPath) { if (!string.IsNullOrEmpty(((ModInfo)(ref mod)).GUID) && Chainloader.PluginInfos != null && Chainloader.PluginInfos.TryGetValue(((ModInfo)(ref mod)).GUID, out var value)) { BaseUnityPlugin val = ((value != null) ? value.Instance : null); if (val != null) { return val; } } if (Chainloader.PluginInfos == null || string.IsNullOrEmpty(configPath)) { return null; } foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos) { PluginInfo value2 = pluginInfo.Value; BaseUnityPlugin val2 = ((value2 != null) ? value2.Instance : null); if (val2 != null && val2.Config != null) { string configFilePath = val2.Config.ConfigFilePath; if (!string.IsNullOrEmpty(configFilePath) && string.Equals(configFilePath, configPath, StringComparison.OrdinalIgnoreCase)) { return val2; } } } return null; } private static ConfigEntryBase FindLiveEntry(ConfigFile config, string section, string key) { if (config == null || string.IsNullOrEmpty(section) || string.IsNullOrEmpty(key)) { return null; } foreach (KeyValuePair<ConfigDefinition, ConfigEntryBase> item in config) { if (!(item.Key == (ConfigDefinition)null) && item.Value != null && string.Equals(item.Key.Section, section, StringComparison.OrdinalIgnoreCase) && string.Equals(item.Key.Key, key, StringComparison.OrdinalIgnoreCase)) { return item.Value; } } return null; } private static string GetLiveOrFileValue(ModInfo mod, string configPath, string section, string key, string fileValue) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) try { BaseUnityPlugin val = FindPluginForConfig(mod, configPath); ConfigEntryBase val2 = (((Object)(object)val != (Object)null) ? FindLiveEntry(val.Config, section, key) : null); if (val2 != null) { string serializedValue = val2.GetSerializedValue(); if (serializedValue != null) { return serializedValue; } } } catch { } return fileValue ?? ""; } private static Dictionary<string, List<(string entry, string[] options)>> ParseModConfig(string configPath) { try { Dictionary<string, List<(string, string[])>> dictionary = new Dictionary<string, List<(string, string[])>>(); string key = ""; List<string> list = new List<string>(); foreach (string item2 in File.ReadLines(configPath)) { if (string.IsNullOrWhiteSpace(item2)) { continue; } if (item2.StartsWith("#")) { list.Add(item2.TrimStart('#').Trim()); } else if (item2.StartsWith("[") && item2.EndsWith("]")) { key = item2.Trim(); if (!dictionary.ContainsKey(key)) { dictionary[key] = new List<(string, string[])>(); } list.Clear(); } else { if (!item2.Contains("=")) { continue; } if (!dictionary.ContainsKey(key)) { dictionary[key] = new List<(string, string[])>(); } string[] item = null; foreach (string item3 in list) { if (item3.StartsWith("Acceptable values:")) { item = (from s in item3.Substring("Acceptable values:".Length).Split(',') select s.Trim()).ToArray(); break; } } dictionary[key].Add((item2.Trim(), item)); list.Clear(); } } return dictionary; } catch (Exception ex) { SparrohPlugin.Logger.LogError((object)("Error parsing config file '" + configPath + "': " + ex.Message)); return new Dictionary<string, List<(string, string[])>>(); } } private static void CreateModConfig(ModInfo mod, Transform parent) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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_005f: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Expected O, but got Unknown //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_0374: Unknown result type (might be due to invalid IL or missing references) //IL_03d0: Unknown result type (might be due to invalid IL or missing references) //IL_03d7: Expected O, but got Unknown //IL_0646: Unknown result type (might be due to invalid IL or missing references) //IL_06e5: Unknown result type (might be due to invalid IL or missing references) //IL_0765: Unknown result type (might be due to invalid IL or missing references) //IL_08af: Unknown result type (might be due to invalid IL or missing references) //IL_08a8: Unknown result type (might be due to invalid IL or missing references) //IL_0a4b: Unknown result type (might be due to invalid IL or missing references) //IL_0a55: Expected O, but got Unknown //IL_091d: Unknown result type (might be due to invalid IL or missing references) //IL_0916: Unknown result type (might be due to invalid IL or missing references) //IL_0b7b: Unknown result type (might be due to invalid IL or missing references) //IL_0c24: Unknown result type (might be due to invalid IL or missing references) //IL_0c29: Unknown result type (might be due to invalid IL or missing references) //IL_0c2b: Unknown result type (might be due to invalid IL or missing references) //IL_0c32: Expected O, but got Unknown try { ModInfo modLocal = mod; string modKey = GetModKey(modLocal); bool flag = IsModExpanded(modKey); RectTransform val = UIFactory.CreateRect("ModBlock_" + ((ModInfo)(ref modLocal)).Name, parent); UIFactory.AddVerticalLayout(((Component)val).gameObject, UITheme.S(UITheme.SpacingTight), new RectOffset(0, 0, 0, 0), (TextAnchor)0, true, false, true, true); UIFactory.AddContentSizeFitter(((Component)val).gameObject, (FitMode)0, (FitMode)2); Image val2 = UIFactory.CreateImage(((ModInfo)(ref modLocal)).Name + " Title", (Transform)(object)val, UIColors.TitleBar, true); UIFactory.ApplyWhiteSprite(val2); GameObject gameObject = ((Component)val2).gameObject; float? num = UITheme.S(44f); float? num2 = UITheme.S(44f); UIHelpers.EnsureLayoutElement(gameObject, (float?)null, num, num2); UIFactory.AddHorizontalLayout(((Component)val2).gameObject, UITheme.S(6f), UITheme.ScaledPadding(10, 10, 4, 4), (TextAnchor)3, true, false, true, true); TextMeshProUGUI val3 = UIFactory.CreateTmp("Chevron", (Transform)(object)((Graphic)val2).rectTransform, flag ? "-" : "+", UITheme.S(22f), (Color?)UIColors.TextSecondary, (TextAlignmentOptions)514, false); ((TMP_Text)val3).fontStyle = (FontStyles)1; ((Graphic)val3).raycastTarget = false; UIHelpers.EnsureLayoutElement(((Component)val3).gameObject, (float?)UITheme.S(28f), (float?)UITheme.S(36f), (float?)null).flexibleWidth = 0f; string text = RichText.Bold(((ModInfo)(ref modLocal)).Name); if (((ModInfo)(ref modLocal)).IsSandbox) { text = text + " " + RichText.Size("[" + RichText.Italic(RichText.Colorize("Sandbox", UIColors.Rose)) + "]", 55); } TextMeshProUGUI obj = UIFactory.CreateTmp("Text", (Transform)(object)((Graphic)val2).rectTransform, text, UITheme.S(22f), (Color?)UIColors.TextPrimary, (TextAlignmentOptions)4097, false); ((TMP_Text)obj).fontStyle = (FontStyles)1; ((Graphic)obj).raycastTarget = false; GameObject gameObject2 = ((Component)obj).gameObject; num2 = UITheme.S(36f); UIHelpers.EnsureLayoutElement(gameObject2, (float?)null, num2, (float?)null).flexibleWidth = 1f; RectTransform val4 = UIFactory.CreateRect("Body", (Transform)(object)val); UIFactory.AddVerticalLayout(((Component)val4).gameObject, UITheme.S(UITheme.SpacingTight), new RectOffset(0, 0, 0, 0), (TextAnchor)0, true, false, true, true); UIFactory.AddContentSizeFitter(((Component)val4).gameObject, (FitMode)0, (FitMode)2); ((Component)val4).gameObject.SetActive(flag); ModBlockState blockState = new ModBlockState { Key = modKey, Body = ((Component)val4).gameObject, Chevron = val3, TitleRect = ((Graphic)val2).rectTransform, TitleRichText = text, IsExpanded = flag }; _modBlocks.Add(blockState); _stickyTitles?.Register(((Graphic)val2).r