Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Pinsanity v1.0.1
Pinsanity-1.0.0.dll
Decompiled a day 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.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using HarmonyLib; using Microsoft.CodeAnalysis; using Splatform; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyTitle("Pinsanity")] [assembly: AssemblyDescription("Finds and pins nearby resources on the Valheim minimap. Incredibly configurable.")] [assembly: AssemblyCompany("Jeaudoir AKA FoobyScroobs")] [assembly: AssemblyProduct("Valheim Mod")] [assembly: AssemblyCopyright("Copyright Jeaudoir 2026 - MIT License")] [assembly: ComVisible(false)] [assembly: Guid("F4E7D6C5-B8A9-4172-9536-8E4B7A1D2C5F")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Pinsanity { public class ConfigManager { public class ResourceEntry { public string Id { get; } public string DefaultLabel { get; } public string UserLabel { get; set; } public bool Enabled { get; set; } public bool EnabledByDefault { get; } public string Note { get; } public bool LabelIsReadOnly { get; } public ResourceEntry(string id, string defaultLabel, bool enabledByDefault, string note, bool labelIsReadOnly = false) { Id = id; DefaultLabel = defaultLabel; UserLabel = defaultLabel; Enabled = enabledByDefault; EnabledByDefault = enabledByDefault; Note = note; LabelIsReadOnly = labelIsReadOnly; } } public class ResourceCategory { public string Id { get; } public string DefaultLabel { get; } public string Note { get; } public bool Enabled { get; set; } public List<ResourceEntry> Entries { get; } public ResourceCategory(string id, string defaultLabel, string note, bool enabled = true) { Id = id; DefaultLabel = defaultLabel; Note = note; Enabled = enabled; Entries = new List<ResourceEntry>(); } public ResourceEntry FindEntry(string entryId) { return Entries.FirstOrDefault((ResourceEntry e) => e.Id == entryId); } } public class GeneralConfig { public bool Enabled { get; set; } = true; public int ScanRadius { get; set; } = 100; public int ScanInterval { get; set; } = 5000; public bool ShowLabels { get; set; } = true; public bool IsDebug { get; set; } = false; public bool IsTrace { get; set; } = false; public bool IsBenchmark { get; set; } = false; public int WindowHeight { get; set; } = 0; public string HotkeyString { get; set; } = "F8"; public KeyCode HotkeyCode { get; set; } = (KeyCode)289; } public const float DEFAULT_SCAN_RADIUS = 100f; public const float DEFAULT_SCAN_INTERVAL_MS = 5000f; public const float MIN_SCAN_RADIUS = 1f; public const float MIN_SCAN_INTERVAL_MS = 500f; public const float MAX_SCAN_RADIUS = 500f; public const float MAX_SCAN_INTERVAL_MS = 30000f; private const float DEFAULT_FLOAT_FALLBACK = 1f; public const string HOTKEY_DEFAULT = "F8"; public GeneralConfig General = new GeneralConfig(); private HashSet<string> _loadedKeys = new HashSet<string>(); private bool _configNeedsResave = false; private string configFilePath; private Dictionary<string, Action<string>> _configSetters; private static readonly Dictionary<string, (float Min, float Max, float Default)> _intPropertyBounds = new Dictionary<string, (float, float, float)> { { "ScanRadius", (1f, 500f, 100f) }, { "ScanInterval", (500f, 30000f, 5000f) }, { "WindowHeight", (774f, float.MaxValue, 774f) } }; public List<ResourceCategory> Categories { get; private set; } = new List<ResourceCategory>(); public bool ModEnabled => General.Enabled; public float ScanRadius => General.ScanRadius; public float ScanInterval => General.ScanInterval; public bool ShowLabels => General.ShowLabels; public bool IsDebug => General.IsDebug; public bool IsTrace => General.IsTrace; public bool IsBenchmark => General.IsBenchmark; public bool IsResourceEnabled(string id) { return FindEntry(id)?.Enabled ?? false; } public ResourceCategory FindCategory(string categoryId) { return Categories.FirstOrDefault((ResourceCategory c) => c.Id == categoryId); } public ResourceEntry FindEntry(string entryId) { foreach (ResourceCategory category in Categories) { ResourceEntry resourceEntry = category.FindEntry(entryId); if (resourceEntry != null) { return resourceEntry; } } return null; } public void LoadConfig() { configFilePath = Path.Combine(Paths.ConfigPath, "FoobyScroobs.Pinsanity.cfg"); BuildCategoryDefinitions(); InitializeConfigSetters(); DebugLogger.Trace("Loading config from " + configFilePath); if (!File.Exists(configFilePath)) { DebugLogger.Info("Config file not found, creating default"); SaveConfig(); return; } try { ParseConfigFile(); HandleConfigMigration(); } catch (Exception ex) { DebugLogger.Error("Error loading config", ex); DebugLogger.Info($"Falling back to defaults: Enabled={General.Enabled}, ScanRadius={General.ScanRadius}, ScanInterval={General.ScanInterval}, ShowLabels={General.ShowLabels}, IsDebug={General.IsDebug}, IsTrace={General.IsTrace}, IsBenchmark={General.IsBenchmark}, Hotkey={General.HotkeyString}"); SaveConfig(); } } private void BuildCategoryDefinitions() { Categories = new List<ResourceCategory>(); Dictionary<string, ResourceCategory> dictionary = new Dictionary<string, ResourceCategory>(); (string, string, string)[] categories = CategoryDefinitions.Categories; for (int i = 0; i < categories.Length; i++) { (string, string, string) tuple = categories[i]; ResourceCategory resourceCategory = new ResourceCategory(tuple.Item1, tuple.Item2, tuple.Item3); Categories.Add(resourceCategory); dictionary[tuple.Item1] = resourceCategory; } HashSet<string> hashSet = new HashSet<string>(); foreach (ResourceDef definition in RS_ResourceDefinitions.GetDefinitions()) { if (!dictionary.TryGetValue(definition.Category, out var value)) { DebugLogger.Error("BuildCategoryDefinitions: unknown category '" + definition.Category + "' for entry '" + definition.Id + "', skipping"); } else if (hashSet.Contains(definition.Id)) { DebugLogger.Error("BuildCategoryDefinitions: duplicate ID '" + definition.Id + "' in definition table, second entry ignored. Check RS_ResourceDefinitionTable.cs."); } else { hashSet.Add(definition.Id); value.Entries.Add(new ResourceEntry(definition.Id, definition.FriendlyName, definition.EnabledByDefault, definition.Note, definition.IconStrategy == Icon.PickableItem)); } } DebugLogger.Trace($"Built {Categories.Count} categories"); foreach (ResourceCategory category in Categories) { DebugLogger.Trace($" {category.Id}: {category.Entries.Count} entries"); } } private void InitializeConfigSetters() { _configSetters = new Dictionary<string, Action<string>>(); GenerateSettersForClass(General, "General"); GenerateSettersForCategories(); GenerateSettersForEntries(); DebugLogger.Trace($"Generated {_configSetters.Count} config setters"); } private void GenerateSettersForClass(object instance, string sectionName) { Type type = instance.GetType(); PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public); PropertyInfo[] array = properties; foreach (PropertyInfo prop in array) { string text = sectionName + "." + prop.Name; if (_configSetters.ContainsKey(text)) { continue; } if (prop.PropertyType == typeof(bool)) { _configSetters[text] = delegate(string v) { prop.SetValue(instance, ParseBool(v)); }; } else if (prop.PropertyType == typeof(int)) { BuildIntSetter(prop, text, instance); } else if (prop.PropertyType == typeof(float)) { string capturedKey = prop.Name; _configSetters[text] = delegate(string v) { prop.SetValue(instance, ParseFloat(v, capturedKey, 1f, 0f)); }; } else if (prop.PropertyType == typeof(string)) { if (prop.Name == "HotkeyString") { string key = sectionName + ".Hotkey"; _configSetters[key] = delegate(string v) { ParseHotkey(v); }; } else { _configSetters[text] = delegate(string v) { prop.SetValue(instance, v); }; } } else if (!(prop.PropertyType == typeof(KeyCode))) { DebugLogger.Warning($"Unknown property type for {text}: {prop.PropertyType}"); } } } private void BuildIntSetter(PropertyInfo prop, string fullKey, object instance) { string capturedKey = prop.Name; float capturedDefault; float capturedMin; float capturedMax; if (_intPropertyBounds.TryGetValue(prop.Name, out (float, float, float) value)) { capturedDefault = value.Item3; (capturedMin, capturedMax, _) = value; } else { capturedDefault = 1f; capturedMin = 1f; capturedMax = float.MaxValue; } _configSetters[fullKey] = delegate(string v) { prop.SetValue(instance, (int)ParseFloat(v, capturedKey, capturedDefault, capturedMin, capturedMax)); }; } private void GenerateSettersForCategories() { (string, string, string)[] categories = CategoryDefinitions.Categories; for (int i = 0; i < categories.Length; i++) { (string, string, string) tuple = categories[i]; if (tuple.Item1 == "ModSettings") { continue; } string id = tuple.Item1; string key = "Resource Categories.Enable" + id; _configSetters[key] = delegate(string v) { bool enabled = ParseBool(v); ResourceCategory resourceCategory = FindCategory(id); if (resourceCategory != null) { resourceCategory.Enabled = enabled; } }; } } private void GenerateSettersForEntries() { foreach (ResourceCategory category in Categories) { foreach (ResourceEntry entry in category.Entries) { string id = entry.Id; string key = "Resources and Labels.Enable" + id; string key2 = "Resources and Labels." + id + "Label"; _configSetters[key] = delegate(string v) { entry.Enabled = ParseBool(v); }; _configSetters[key2] = delegate(string v) { entry.UserLabel = v; }; } } } private void ApplyConfigValue(string section, string key, string value) { try { string text = section + "." + key; if (_configSetters.TryGetValue(text, out var value2)) { value2(value); } else { DebugLogger.Warning("Unknown config key: " + text); } } catch (Exception ex) { DebugLogger.Warning("Failed to set " + section + "." + key + " = " + value + ": " + ex.Message); } } public void SaveConfig() { try { using StreamWriter writer = new StreamWriter(configFilePath); WriteGeneralSection(writer); WriteCategorySection(writer); WriteItemSection(writer); } catch (Exception ex) { DebugLogger.Error("Error saving config", ex); } } private void WriteGeneralSection(StreamWriter writer) { writer.WriteLine("[General]"); writer.WriteLine("# Values are true or false unless otherwise specified"); writer.WriteLine("Enabled = " + General.Enabled.ToString().ToLower()); writer.WriteLine("ShowLabels = " + General.ShowLabels.ToString().ToLower() + " # false hides all labels regardless of individual settings"); writer.WriteLine("IsBenchmark = " + General.IsBenchmark.ToString().ToLower() + " # For those who love to watch their fps: logs a detailed list of 'how long everything takes' for every scan"); writer.WriteLine("IsDebug = " + General.IsDebug.ToString().ToLower() + " # For testers: logs settings changes, pin state changes, and window actions"); writer.WriteLine("IsTrace = " + General.IsTrace.ToString().ToLower() + " # For developers and extreme nerds: incredibly-detailed firehose of pretty-much-everything (requires IsDebug = true)"); writer.WriteLine($"ScanRadius = {General.ScanRadius} # in meters"); writer.WriteLine($"ScanInterval = {General.ScanInterval} # in milliseconds"); writer.WriteLine("Hotkey = " + General.HotkeyString + " # key to open/close the settings window (examples: F7, F8, Delete, Home)"); writer.WriteLine($"WindowHeight = {(((float)General.WindowHeight < 774f) ? Mathf.RoundToInt(1000f) : Mathf.RoundToInt((float)General.WindowHeight))} # window height (default = 1000)"); writer.WriteLine(); } private void WriteCategorySection(StreamWriter writer) { writer.WriteLine("[Resource Categories]"); writer.WriteLine("# Each category can be enabled/disabled by setting it to true/false below."); writer.WriteLine("# Disabling a category overrides all its individual item toggles."); (string, string, string)[] categories = CategoryDefinitions.Categories; for (int i = 0; i < categories.Length; i++) { (string, string, string) tuple = categories[i]; if (!(tuple.Item1 == "ModSettings")) { bool flag = FindCategory(tuple.Item1)?.Enabled ?? true; writer.WriteLine(); if (!string.IsNullOrEmpty(tuple.Item3)) { writer.WriteLine("# " + tuple.Item3); } writer.WriteLine("Enable" + tuple.Item1 + " = " + flag.ToString().ToLower()); } } writer.WriteLine(); } private void WriteItemSection(StreamWriter writer) { writer.WriteLine("[Resources and Labels]"); writer.WriteLine("# Each resource has two settings:"); writer.WriteLine("# Enable{Name} = true/false"); writer.WriteLine("# {Name}Label = display text shown on the minimap pin"); writer.WriteLine(); Dictionary<string, string> dictionary = (from d in RS_ResourceDefinitions.GetDefinitions() group d by d.Id).ToDictionary((IGrouping<string, ResourceDef> g) => g.Key, (IGrouping<string, ResourceDef> g) => g.First().Note); foreach (ResourceCategory category in Categories) { if (category.Entries.Count == 0 || category.Id == "ModSettings") { continue; } string text = new string('=', Math.Max(0, 44 - category.DefaultLabel.Length)); writer.WriteLine("# " + category.DefaultLabel + " " + text); foreach (ResourceEntry entry in category.Entries) { writer.WriteLine("Enable" + entry.Id + " = " + entry.Enabled.ToString().ToLower()); writer.WriteLine(entry.Id + "Label = \"" + entry.UserLabel + "\""); if (dictionary.TryGetValue(entry.Id, out var value) && !string.IsNullOrEmpty(value)) { writer.WriteLine("# Note: " + value); } writer.WriteLine(); } } } private void ParseConfigFile() { string[] array = File.ReadAllLines(configFilePath); string text = ""; int num = 0; _loadedKeys.Clear(); DebugLogger.Trace($"Read {array.Length} lines from config"); string[] array2 = array; foreach (string text2 in array2) { num++; string text3 = text2.Trim(); if (!string.IsNullOrEmpty(text3) && !text3.StartsWith("#")) { if (text3.StartsWith("[") && text3.EndsWith("]")) { text = text3.Substring(1, text3.Length - 2); DebugLogger.Trace($"Found section [{text}] at line {num}"); } else if (text3.Contains("=")) { ParseConfigLine(text, text3); } } } DebugLogger.Trace($"Config loaded - ShowLabels: {General.ShowLabels}, ScanInterval: {General.ScanInterval}"); } private void ParseConfigLine(string section, string line) { string[] array = line.Split(new char[1] { '=' }, 2); if (array.Length != 2) { return; } string text = array[0].Trim(); string text2 = array[1].Trim(); if (text2.StartsWith("\"") && text2.EndsWith("\"")) { text2 = text2.Substring(1, text2.Length - 2); } else { int num = text2.IndexOf('#'); if (num >= 0) { text2 = text2.Substring(0, num).Trim(); } } DebugLogger.Trace("Setting " + section + "." + text + " = '" + text2 + "'"); string item = section + "." + text; _loadedKeys.Add(item); ApplyConfigValue(section, text, text2); } private void HandleConfigMigration() { List<string> list = _configSetters.Keys.Where((string k) => !_loadedKeys.Contains(k)).ToList(); if (list.Count > 0 || _configNeedsResave) { if (list.Count > 0) { DebugLogger.Info($"Found {list.Count} missing settings, adding with defaults"); foreach (string item in list) { DebugLogger.DebugMessage(" Missing: " + item); } } if (_configNeedsResave) { DebugLogger.Info("Invalid config values were corrected, resaving"); } SaveConfig(); } else { DebugLogger.Trace("Config is up to date"); } } private bool ParseBool(string value) { return string.Equals(value, "true", StringComparison.OrdinalIgnoreCase); } private float ParseFloat(string value, string key = "float", float defaultValue = 1f, float minValue = 1f, float maxValue = float.MaxValue) { if (float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { if (result < minValue) { DebugLogger.Warning($"ConfigManager: '{key}' value ({result}) is too low, minimum is {minValue}, resetting to default ({defaultValue})"); _configNeedsResave = true; return defaultValue; } if (result > maxValue) { DebugLogger.Warning($"ConfigManager: '{key}' value ({result}) is too high, maximum is {maxValue}, resetting to default ({defaultValue})"); _configNeedsResave = true; return defaultValue; } return result; } DebugLogger.Warning($"ConfigManager: '{key}' value ('{value}') is not a valid number, resetting to default ({defaultValue})"); _configNeedsResave = true; return defaultValue; } private void ParseHotkey(string value) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) if (Enum.TryParse<KeyCode>(value, out KeyCode result)) { General.HotkeyString = value; General.HotkeyCode = result; } else { DebugLogger.Warning("ConfigManager: 'Hotkey' value '" + value + "' is not a valid KeyCode, using default (F8)"); General.HotkeyString = "F8"; General.HotkeyCode = (KeyCode)Enum.Parse(typeof(KeyCode), "F8"); } } } public static class Constants { public static class Valheim { public const string CloneSuffix = "(Clone)"; public const string PickablePrefix = "Pickable_"; public const string PickedFieldName = "m_picked"; public const string BeehiveHoneyZdoKey = "level"; public const string PlainRockMaterial = "rock1"; public const string MaterialInstanceSuffix = " (Instance)"; } public static class Pins { public const float WorldSizeFixed = 0f; public const string PinTypePrefix = "Icon"; public const int PinTypePrefixLength = 4; } public static class Scanning { public const int LookupPrefixLength = 5; public const float MsPerSecond = 1000f; public const long TicksToNs = 100L; public const string DepositTypeSentinel = "none"; public const float ScanTimerInitialValue = float.MaxValue; } public static class Plugin { public const string Guid = "FoobyScroobs.Pinsanity"; public const string Name = "Pinsanity"; public const string Version = "1.0.0"; public const string ConfigFile = "FoobyScroobs.Pinsanity.cfg"; } public static class GUI { public const int WindowId = 1138; public const string SettingsFieldPrefix = "SettingsField_"; public const string HiddenLabelPlaceholder = "(none)"; public const float MsPerSecond = 1000f; } public static class Config { public const int SectionDividerWidth = 44; public const string SectionGeneral = "General"; public const string SectionCategories = "Resource Categories"; public const string SectionItems = "Resources and Labels"; public const string HotkeyConfigKey = "Hotkey"; } } public static class DebugLogger { private static string Prefix => typeof(BepInExPlugin).Namespace + " "; public static void DebugMessage(string message) { if (BepInExPlugin.ConfigManager != null && BepInExPlugin.ConfigManager.IsDebug) { Debug.Log((object)(Prefix + message)); } } public static void Trace(string message) { if (BepInExPlugin.ConfigManager != null && BepInExPlugin.ConfigManager.IsDebug && BepInExPlugin.ConfigManager.IsTrace) { Debug.Log((object)(Prefix + message)); } } public static void Benchmark(string message) { if (BepInExPlugin.ConfigManager != null && BepInExPlugin.ConfigManager.IsBenchmark) { Debug.Log((object)(Prefix + message)); } } public static void Info(string message) { Debug.Log((object)(Prefix + message)); } public static void Warning(string message) { Debug.LogWarning((object)(Prefix + message)); } public static void Error(string message, Exception ex = null) { if (ex != null) { Debug.LogError((object)(Prefix + message + ": " + ex.Message + "\n" + ex.StackTrace)); } else { Debug.LogError((object)(Prefix + message)); } } } public class GUI_GuiManager { private float _windowCloseTime = 0f; private float _windowEscCloseTime = 0f; private bool _hasWindowEverOpened = false; private bool _isWindowOpen = false; private Rect _windowRect = new Rect(0f, 60f, 920f, 1000f); private Vector2 _resourceScroll = Vector2.zero; private string _selectedCategoryId = null; private bool _weDidPause = false; private bool _isRebuildPending = false; private bool _isResizing = false; private Vector2 _resizeStartMouse = Vector2.zero; private float _resizeStartHeight = 0f; private int _forceCloseCount = 0; private string _errorMessage = null; private bool _isReopenPending = false; private string _permanentErrorMsg = null; private string _editingEntryId = null; private string _editingFieldValue = ""; private string _focusedLabelFieldId = null; private readonly Dictionary<string, string> _settingsFieldBuffers = new Dictionary<string, string>(); private static readonly GUIContent _labelPrefixContent = new GUIContent("Label:"); private GUIStyle _windowStyle; private GUIStyle _h1Style; private GUIStyle _h2Style; private GUIStyle _h2WarningStyle; private GUIStyle _h3Style; private GUIStyle _bodyStyle; private GUIStyle _h4Style; private GUIStyle _noteStyle; private GUIStyle _textFieldStyle; private GUIStyle _actionButtonStyle; private GUIStyle _navButtonStyle; private GUIStyle _navButtonActiveStyle; private GUIStyle _hideActiveStyle; private GUIStyle _hiddenPlaceholderStyle; private bool _areStylesBuilt = false; private readonly List<Texture2D> _navTextures = new List<Texture2D>(); private Texture2D _texToggleOn; private Texture2D _texToggleOff; private Texture2D _texToggleOnHover; private Texture2D _texToggleOffHover; private Texture2D _texResizeGrip; public bool IsWindowOpen => _isWindowOpen; public bool IsPostCloseSuppressing { get { if (!_hasWindowEverOpened) { return false; } float num = (Time.realtimeSinceStartup - _windowCloseTime) * 1000f; if (num < 200f) { DebugLogger.DebugMessage($"Map click suppressed: {num:F0}ms since window close (suppression window: {200f}ms)"); return true; } return false; } } public bool IsPostCloseEscSuppressing { get { if (!_hasWindowEverOpened) { return false; } float num = (Time.realtimeSinceStartup - _windowEscCloseTime) * 1000f; if (num < 80f) { return true; } return false; } } private void DrawWindowContents(int windowId) { ConfigManager configManager = BepInExPlugin.ConfigManager; GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label("Pinsanity: Settings", _h1Style, Array.Empty<GUILayoutOption>()); GUILayout.EndHorizontal(); GUILayout.Space(2f); if (!BepInExPlugin.ConfigManager.ModEnabled) { GUILayout.Label("Note: mod is TURNED OFF. Re-enable it in Settings", _h2WarningStyle, Array.Empty<GUILayoutOption>()); } else { GUILayout.Label("Turn resources on/off and customize labels. Changes save to the cfg file immediately.", _h2Style, Array.Empty<GUILayoutOption>()); } GUILayout.Space(8f); if (_errorMessage != null) { GUILayout.Label(_errorMessage, _h2WarningStyle, Array.Empty<GUILayoutOption>()); GUILayout.Space(5f); } GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); DrawNavColumn(configManager); DrawContentColumn(configManager); GUILayout.EndHorizontal(); GUILayout.Space(6f); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.FlexibleSpace(); if (GUILayout.Button("Close [" + BepInExPlugin.ConfigManager.General.HotkeyString + " or ESC]", _actionButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(((Rect)(ref _windowRect)).width * 0.88f) })) { DebugLogger.Trace("Close button clicked"); ToggleWindow(); } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); DrawResizeHandle(); } private void DrawNavColumn(ConfigManager cfg) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(300f) }); foreach (ConfigManager.ResourceCategory category in cfg.Categories) { bool flag = category.Id == _selectedCategoryId; GUIStyle val = (flag ? _navButtonActiveStyle : _navButtonStyle); Color color = GUI.color; if (!category.Enabled) { GUI.color = new Color(1f, 1f, 1f, 0.15f); } if (GUILayout.Button(category.DefaultLabel, val, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(300f) }) && !flag) { DebugLogger.Trace("Nav: selected category " + category.Id); CommitLabelEdit(); _settingsFieldBuffers.Clear(); GUI.FocusControl(""); _selectedCategoryId = category.Id; _resourceScroll = Vector2.zero; } GUI.color = color; } GUILayout.EndVertical(); } private void DrawContentColumn(ConfigManager cfg) { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: 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_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_02f0: Unknown result type (might be due to invalid IL or missing references) GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Space(16f); GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(564f) }); ConfigManager.ResourceCategory resourceCategory = cfg.FindCategory(_selectedCategoryId); if (resourceCategory == null) { DebugLogger.Error("DrawContentColumn: unknown category id '" + _selectedCategoryId + "'. This is a bug. Quit and reload your game to recover. If this persists, please report it!"); GUILayout.EndVertical(); GUILayout.EndHorizontal(); return; } if (resourceCategory.Id == "ModSettings") { DrawModSettingsPanel(cfg); } else { DrawCategoryHeader(resourceCategory); Color color = GUI.color; if (!resourceCategory.Enabled) { GUI.color = new Color(1f, 1f, 1f, 0.15f); } _resourceScroll = GUILayout.BeginScrollView(_resourceScroll, Array.Empty<GUILayoutOption>()); if (!string.IsNullOrEmpty(resourceCategory.Note)) { GUILayout.Space(5f); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label(resourceCategory.Note, _noteStyle, Array.Empty<GUILayoutOption>()); GUILayout.EndHorizontal(); GUILayout.Space(5f); } GUILayout.Space(5f); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); float num = 143f; if (GUILayout.Button("All On", _actionButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(num) })) { ApplyToEntries(resourceCategory.Entries, "All On: " + resourceCategory.Id, delegate(ConfigManager.ResourceEntry e) { e.Enabled = true; }, cfg); } GUILayout.Space(8.25f); if (GUILayout.Button("All Off", _actionButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(num) })) { ApplyToEntries(resourceCategory.Entries, "All Off: " + resourceCategory.Id, delegate(ConfigManager.ResourceEntry e) { e.Enabled = false; }, cfg); } GUILayout.Space(8.25f); if (GUILayout.Button("Reset Labels", _actionButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(num) })) { ApplyToEntries(resourceCategory.Entries, "Reset Labels: " + resourceCategory.Id, delegate(ConfigManager.ResourceEntry e) { e.UserLabel = e.DefaultLabel; }, cfg); } GUILayout.EndHorizontal(); GUILayout.Space(20f); foreach (ConfigManager.ResourceEntry entry in resourceCategory.Entries) { DrawEntryRows(entry, cfg); } GUILayout.EndScrollView(); GUI.color = color; } GUILayout.EndVertical(); GUILayout.EndHorizontal(); } private void DrawCategoryHeader(ConfigManager.ResourceCategory cat) { float num = 8.25f; float num2 = Mathf.Max(20f, 30f); GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(num2) }); DrawCustomToggle(cat.Enabled, delegate(bool val) { DebugLogger.DebugMessage($"Category toggle: {cat.Id} = {val}"); SetCategoryEnabled(cat, val, BepInExPlugin.ConfigManager); }); GUILayout.Space(num); GUILayout.Label(cat.DefaultLabel, _h3Style, Array.Empty<GUILayoutOption>()); GUILayout.EndHorizontal(); GUILayout.Space(20f); } private void DrawResizeHandle() { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Invalid comparison between Unknown and I4 //IL_005d: 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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0102: 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) float num = 24f; Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref _windowRect)).width - num - 4f, ((Rect)(ref _windowRect)).height - num - 4f, num, num); bool flag = false; if ((int)Event.current.type == 7) { flag = ((Rect)(ref val)).Contains(Event.current.mousePosition); } Color color = GUI.color; if (flag) { GUI.color = Layout.ResizeHandleHoverColor; GUI.DrawTexture(val, (Texture)(object)Texture2D.whiteTexture); } GUI.color = (flag ? Layout.ResizeHandleTextHover : Layout.ResizeHandleTextNormal); GUI.DrawTexture(val, (Texture)(object)_texResizeGrip, (ScaleMode)2); GUI.color = color; if ((int)Event.current.type == 0 && ((Rect)(ref val)).Contains(Event.current.mousePosition) && !_isResizing) { _isResizing = true; _resizeStartMouse = new Vector2(Input.mousePosition.x, (float)Screen.height - Input.mousePosition.y); _resizeStartHeight = ((Rect)(ref _windowRect)).height; Event.current.Use(); DebugLogger.Trace("Resize started"); } } private void DrawSeparator() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) GUILayout.Space(15f); Color color = GUI.color; GUI.color = Layout.SeparatorColor; Rect lastRect = GUILayoutUtility.GetLastRect(); GUI.DrawTexture(new Rect(0f, ((Rect)(ref lastRect)).yMax, 852f, 1f), (Texture)(object)Texture2D.whiteTexture); GUI.color = color; GUILayout.Space(15f); } private void DrawModSettingsPanel(ConfigManager cfg) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_03af: Unknown result type (might be due to invalid IL or missing references) //IL_03b4: Unknown result type (might be due to invalid IL or missing references) //IL_041a: Unknown result type (might be due to invalid IL or missing references) //IL_03e2: Unknown result type (might be due to invalid IL or missing references) _resourceScroll = GUILayout.BeginScrollView(_resourceScroll, Array.Empty<GUILayoutOption>()); GUILayout.Space(5f); DrawSettingsToggle("Enabled", cfg.General.Enabled, "Enables or disables the entire mod", delegate(bool val) { cfg.General.Enabled = val; if (val) { BepInExPlugin.Scanner.Initialize(); BepInExPlugin.ResetScanTimer(); } else { BepInExPlugin.ClearAllResourcePins(); } cfg.SaveConfig(); }); DrawSettingsToggle("Show Labels", cfg.General.ShowLabels, "Show/hide labels for all resources", delegate(bool val) { cfg.General.ShowLabels = val; _isRebuildPending = true; cfg.SaveConfig(); }); DrawSettingsIntField("Scan Radius", cfg.General.ScanRadius, "How far around the player to scan for objects; default is 100m", delegate(int val) { cfg.General.ScanRadius = (int)Mathf.Clamp((float)val, 1f, 500f); DebugLogger.DebugMessage($"ScanRadius set to {cfg.General.ScanRadius} (input was {val})"); cfg.SaveConfig(); }); DrawSettingsIntField("Scan Interval", cfg.General.ScanInterval, "How often to scan, in milliseconds; default is 5000; min is 500", delegate(int val) { cfg.General.ScanInterval = (int)Mathf.Clamp((float)val, 500f, 30000f); DebugLogger.DebugMessage($"ScanInterval set to {cfg.General.ScanInterval} (input was {val})"); cfg.SaveConfig(); }); DrawSeparator(); GUILayout.Label("All Items", _bodyStyle, Array.Empty<GUILayoutOption>()); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button("On", _actionButtonStyle, Array.Empty<GUILayoutOption>())) { EnableAllItems(cfg); } GUILayout.Space(8.25f); if (GUILayout.Button("Off", _actionButtonStyle, Array.Empty<GUILayoutOption>())) { DisableAllItems(cfg); } GUILayout.Space(8.25f); if (GUILayout.Button("Reset", _actionButtonStyle, Array.Empty<GUILayoutOption>())) { ResetAllItems(cfg); } GUILayout.EndHorizontal(); GUILayout.Label("'Off' disables all resources across all categories; 'On' unleashes the full Pinsanity; 'Reset' puts them all back to defaults (recommended settings)", _noteStyle, Array.Empty<GUILayoutOption>()); GUILayout.Space(15f); GUILayout.Label("All Categories", _bodyStyle, Array.Empty<GUILayoutOption>()); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button("On (Default)", _actionButtonStyle, Array.Empty<GUILayoutOption>())) { EnableAllCategories(cfg); } GUILayout.Space(8.25f); if (GUILayout.Button("Off", _actionButtonStyle, Array.Empty<GUILayoutOption>())) { DisableAllCategories(cfg); } GUILayout.EndHorizontal(); GUILayout.Label("Does not change individual resource settings", _noteStyle, Array.Empty<GUILayoutOption>()); GUILayout.Space(15f); GUILayout.Label("All Labels", _bodyStyle, Array.Empty<GUILayoutOption>()); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button("Clear All", _actionButtonStyle, Array.Empty<GUILayoutOption>())) { ClearAllLabels(cfg); } GUILayout.Space(8.25f); if (GUILayout.Button("Reset All", _actionButtonStyle, Array.Empty<GUILayoutOption>())) { ResetAllLabels(cfg); } GUILayout.EndHorizontal(); GUILayout.Label("To show labels for 1 or 2 resources: 'Clear All' empties all labels, then you can customize labels for individual resources", _noteStyle, Array.Empty<GUILayoutOption>()); GUILayout.Space(15f); if (GUILayout.Button("Reset Everything", _actionButtonStyle, Array.Empty<GUILayoutOption>())) { ResetEverything(cfg); } GUILayout.Label("Resets resources, categories, labels, and general mod settings", _noteStyle, Array.Empty<GUILayoutOption>()); DrawSeparator(); DrawSettingsToggle("Benchmarking", cfg.General.IsBenchmark, "Logs a detailed list of 'how long it all takes' for every scan", delegate(bool val) { cfg.General.IsBenchmark = val; cfg.SaveConfig(); }); DrawSettingsToggle("Debug Logging", cfg.General.IsDebug, "For testers: logs settings changes, pin state changes, and window actions", delegate(bool val) { cfg.General.IsDebug = val; cfg.SaveConfig(); }); Color color = GUI.color; if (!cfg.General.IsDebug) { GUI.color = new Color(1f, 1f, 1f, 0.15f); } DrawSettingsToggle("Trace Logging", cfg.General.IsTrace, "For developers and extreme nerds: incredibly-detailed firehose of pretty-much-everything; requires debug on", delegate(bool val) { cfg.General.IsTrace = val; cfg.SaveConfig(); }); GUI.color = color; GUILayout.EndScrollView(); } private void DrawSettingsToggle(string label, bool current, string note, Action<bool> onChange) { //IL_006f: 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) float num = 8.25f; float num2 = Mathf.Max(20f, 30f); GUILayout.BeginVertical(Array.Empty<GUILayoutOption>()); GUILayout.Space(5f); GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(num2) }); DrawCustomToggle(current, onChange); GUILayout.Space(num); GUILayout.Label(label, _bodyStyle, Array.Empty<GUILayoutOption>()); if (Layout.DebugBorders) { DrawDebugBorder(GUILayoutUtility.GetLastRect(), Color.yellow); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Space(20f + num + 4f); GUILayout.Label(note, _noteStyle, Array.Empty<GUILayoutOption>()); GUILayout.EndHorizontal(); GUILayout.Space(5f); GUILayout.EndVertical(); } private void DrawSettingsIntField(string label, int current, string note, Action<int> onChange) { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Invalid comparison between Unknown and I4 float num = 8.25f; float num2 = 145.2f; float num3 = 88f; string text = "SettingsField_" + label.Replace(" ", ""); GUILayout.BeginVertical(Array.Empty<GUILayoutOption>()); GUILayout.Space(5f); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label(label, _bodyStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(num2) }); if (Layout.DebugBorders) { DrawDebugBorder(GUILayoutUtility.GetLastRect(), Color.red); } GUILayout.Space(num); string value; bool flag = _settingsFieldBuffers.TryGetValue(text, out value); string text2 = (flag ? value : current.ToString()); GUI.SetNextControlName(text); string text3 = GUILayout.TextField(text2, _textFieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(num3) }); if (Layout.DebugBorders) { DrawDebugBorder(GUILayoutUtility.GetLastRect(), Color.cyan); } bool flag2 = GUI.GetNameOfFocusedControl() == text; if (text3 != text2) { _settingsFieldBuffers[text] = text3; } else if (flag && !flag2 && (int)Event.current.type == 7) { _settingsFieldBuffers.Remove(text); if (int.TryParse(value, out var result)) { onChange(result); } else { DebugLogger.DebugMessage("Settings field rejected: " + text + " could not parse '" + value + "'"); } } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label(note, _noteStyle, Array.Empty<GUILayoutOption>()); GUILayout.EndHorizontal(); GUILayout.Space(5f); GUILayout.EndVertical(); } private void DrawEntryRows(ConfigManager.ResourceEntry entry, ConfigManager cfg) { //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: 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_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0317: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Unknown result type (might be due to invalid IL or missing references) //IL_02d5: Unknown result type (might be due to invalid IL or missing references) //IL_02da: Unknown result type (might be due to invalid IL or missing references) //IL_04e1: Unknown result type (might be due to invalid IL or missing references) //IL_04e6: Unknown result type (might be due to invalid IL or missing references) //IL_054c: Unknown result type (might be due to invalid IL or missing references) float num = 8.25f; float num2 = 77f; float num3 = num2 + num; GUILayout.BeginVertical(Array.Empty<GUILayoutOption>()); GUILayout.Space(5f); float num4 = Mathf.Max(20f, 30f); GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(num4) }); GUILayout.Space(20f); DrawCustomToggle(entry.Enabled, delegate(bool val) { DebugLogger.Trace($"Resource toggle: {entry.Id} = {val}"); SetResourceEnabled(entry, val, cfg); }); Color color = GUI.color; if (!entry.Enabled) { GUI.color = new Color(1f, 1f, 1f, 0.15f); } GUILayout.Space(num); GUILayout.Label(entry.DefaultLabel, _bodyStyle, Array.Empty<GUILayoutOption>()); GUILayout.EndHorizontal(); if (entry.Enabled) { color = GUI.color; } if (entry.LabelIsReadOnly) { if (!string.IsNullOrEmpty(entry.Note)) { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Space(52.25f); GUILayout.Label(entry.Note, _noteStyle, Array.Empty<GUILayoutOption>()); GUILayout.EndHorizontal(); } GUI.color = color; GUILayout.Space(5f); GUILayout.EndVertical(); return; } GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Space(40f + num + 4f); float num5 = _h4Style.CalcSize(_labelPrefixContent).x + num; GUILayout.Label("Label:", _h4Style, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(num5) }); if (Layout.DebugBorders) { DrawDebugBorder(GUILayoutUtility.GetLastRect(), Color.red); } GUILayout.Space(num + -11f); string text = "LabelField_" + entry.Id; string nameOfFocusedControl = GUI.GetNameOfFocusedControl(); GUI.SetNextControlName(text); string text2 = ((_editingEntryId == entry.Id) ? _editingFieldValue : entry.UserLabel); if (string.IsNullOrEmpty(entry.UserLabel) && !(_editingEntryId == entry.Id) && nameOfFocusedControl != text) { GUILayout.TextField("(none)", _hiddenPlaceholderStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(240f) }); if (Layout.DebugBorders) { DrawDebugBorder(GUILayoutUtility.GetLastRect(), Color.cyan); } } else { string newFieldValue = GUILayout.TextField(text2, _textFieldStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(240f) }); if (Layout.DebugBorders) { DrawDebugBorder(GUILayoutUtility.GetLastRect(), Color.cyan); } HandleLabelFieldInput(entry, text, text2, newFieldValue, nameOfFocusedControl); } GUILayout.Space(num); bool flag = string.IsNullOrEmpty((_editingEntryId == entry.Id) ? _editingFieldValue : entry.UserLabel); GUI.enabled = !flag; if (GUILayout.Button("None", flag ? _hideActiveStyle : _actionButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(66f) })) { DebugLogger.DebugMessage("Label hidden: " + entry.Id); _editingEntryId = null; SetResourceLabel(entry, "", cfg); } GUI.enabled = true; GUILayout.Space(num); if (entry.UserLabel != entry.DefaultLabel || (_editingEntryId == entry.Id && _editingFieldValue != entry.DefaultLabel)) { if (GUILayout.Button("Reset", _actionButtonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(num2) })) { DebugLogger.DebugMessage("Label reset: " + entry.Id); _editingEntryId = null; SetResourceLabel(entry, entry.DefaultLabel, cfg); } } else { GUILayout.Space(num3); } GUILayout.EndHorizontal(); if (Layout.DebugBorders) { DrawDebugBorder(GUILayoutUtility.GetLastRect(), Color.yellow); } if (!string.IsNullOrEmpty(entry.Note)) { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Space(40f + num + 4f); GUILayout.Label(entry.Note, _noteStyle, Array.Empty<GUILayoutOption>()); GUILayout.EndHorizontal(); } GUI.color = color; GUILayout.Space(5f); GUILayout.EndVertical(); } private void HandleLabelFieldInput(ConfigManager.ResourceEntry entry, string controlName, string currentFieldValue, string newFieldValue, string focusedControl) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Invalid comparison between Unknown and I4 //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Invalid comparison between Unknown and I4 if (focusedControl == controlName && _focusedLabelFieldId != controlName) { _focusedLabelFieldId = controlName; if ((int)Event.current.type == 7) { DebugLogger.Trace("Label field focused: " + controlName); } } else if (focusedControl != controlName && _focusedLabelFieldId == controlName) { _focusedLabelFieldId = null; } if (newFieldValue != currentFieldValue) { if (_editingEntryId != entry.Id) { CommitLabelEdit(); _editingEntryId = entry.Id; } _editingFieldValue = newFieldValue; } if (_editingEntryId == entry.Id && focusedControl != controlName && (int)Event.current.type == 7) { CommitLabelEdit(); } } private void DrawCustomToggle(bool current, Action<bool> onChange) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) float num = 20f; Rect rect = GUILayoutUtility.GetRect(num, num, (GUILayoutOption[])(object)new GUILayoutOption[2] { GUILayout.Width(num), GUILayout.Height(num) }); ((Rect)(ref rect)).y = ((Rect)(ref rect)).y + 8f; bool flag = ((Rect)(ref rect)).Contains(Event.current.mousePosition); Texture2D val = ((!current) ? (flag ? _texToggleOffHover : _texToggleOff) : (flag ? _texToggleOnHover : _texToggleOn)); GUI.DrawTexture(rect, (Texture)(object)val, (ScaleMode)2); if ((int)Event.current.type == 0 && ((Rect)(ref rect)).Contains(Event.current.mousePosition)) { DebugLogger.Trace($"Toggle clicked: {current} -> {!current}"); onChange(!current); Event.current.Use(); } } private void DrawDebugBorder(Rect r, Color color) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0069: 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_00bd: 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) if (Layout.DebugBorders) { Color color2 = GUI.color; GUI.color = color; float num = 1f; GUI.DrawTexture(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, ((Rect)(ref r)).width, num), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y + ((Rect)(ref r)).height, ((Rect)(ref r)).width, num), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(((Rect)(ref r)).x, ((Rect)(ref r)).y, num, ((Rect)(ref r)).height), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(((Rect)(ref r)).x + ((Rect)(ref r)).width, ((Rect)(ref r)).y, num, ((Rect)(ref r)).height), (Texture)(object)Texture2D.whiteTexture); GUI.color = color2; } } public void Cleanup() { _areStylesBuilt = false; if ((Object)(object)_texToggleOn != (Object)null) { Object.Destroy((Object)(object)_texToggleOn); _texToggleOn = null; } if ((Object)(object)_texToggleOff != (Object)null) { Object.Destroy((Object)(object)_texToggleOff); _texToggleOff = null; } if ((Object)(object)_texToggleOnHover != (Object)null) { Object.Destroy((Object)(object)_texToggleOnHover); _texToggleOnHover = null; } if ((Object)(object)_texToggleOffHover != (Object)null) { Object.Destroy((Object)(object)_texToggleOffHover); _texToggleOffHover = null; } if ((Object)(object)_texResizeGrip != (Object)null) { Object.Destroy((Object)(object)_texResizeGrip); _texResizeGrip = null; } foreach (Texture2D navTexture in _navTextures) { if ((Object)(object)navTexture != (Object)null) { Object.Destroy((Object)(object)navTexture); } } _navTextures.Clear(); } public void GenerateToggleTextures() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) Cleanup(); DebugLogger.Trace("Generating toggle textures..."); int size = Mathf.RoundToInt(20f) * 2; _texToggleOn = GUI_TextureUtils.MakeCircleTexture(size, Layout.ToggleOnFill, Layout.ToggleOnBorder, 2f); _texToggleOff = GUI_TextureUtils.MakeCircleTexture(size, Layout.ToggleOffFill, Layout.ToggleOffBorder, 2f); _texToggleOnHover = GUI_TextureUtils.MakeCircleTexture(size, Layout.ToggleOnHoverFill, Layout.ToggleOnHoverBorder, 2f); _texToggleOffHover = GUI_TextureUtils.MakeCircleTexture(size, Layout.ToggleOffHoverFill, Layout.ToggleOffHoverBorder, 2f); _texResizeGrip = GUI_TextureUtils.MakeResizeGripTexture(24, 4, 3, Color.white); DebugLogger.Trace("Toggle textures generated"); } public void Initialize() { ConfigManager configManager = BepInExPlugin.ConfigManager; if ((float)configManager.General.WindowHeight >= 774f) { ((Rect)(ref _windowRect)).height = configManager.General.WindowHeight; DebugLogger.DebugMessage($"Restored window height: {((Rect)(ref _windowRect)).height:F0}"); } else { DebugLogger.DebugMessage("No saved window height or too small, using default"); } if (configManager.Categories.Count > 0) { _selectedCategoryId = configManager.Categories[0].Id; } DebugLogger.Trace("GUI_GuiManager initialized"); DebugLogger.Trace("Press " + BepInExPlugin.ConfigManager.General.HotkeyString + " in-game to open the settings window"); } private void BuildDerivedStyles(GUISkin skin) { //IL_0020: 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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: 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_00d3: Expected O, but got Unknown //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Expected O, but got Unknown //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Expected O, but got Unknown //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Expected O, but got Unknown //IL_013e: 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_0175: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Expected O, but got Unknown //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Expected O, but got Unknown //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02bd: Expected O, but got Unknown //IL_02c8: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) GUI_StyleManager styleManager = BepInExPlugin.StyleManager; Font fontBody = styleManager.FontBody; Font font = styleManager.FontTitle ?? fontBody; _h1Style = MakeLabelStyle(skin, 40, (FontStyle)0, Layout.H1Color, font); _h2Style = MakeLabelStyle(skin, 22, (FontStyle)0, Layout.H2Color, fontBody); _h2WarningStyle = MakeLabelStyle(skin, 22, (FontStyle)0, Layout.H2WarningColor, fontBody); _h3Style = MakeLabelStyle(skin, 22, (FontStyle)1, Layout.H3Color, fontBody); _bodyStyle = MakeLabelStyle(skin, 22, (FontStyle)0, Layout.BodyColor, fontBody); _h4Style = MakeLabelStyle(skin, 22, (FontStyle)0, Layout.H4Color, fontBody, wordWrap: false, 3); _noteStyle = MakeLabelStyle(skin, 18, (FontStyle)0, Layout.NoteColor, fontBody, wordWrap: true); _textFieldStyle = new GUIStyle(skin.textField); _actionButtonStyle = new GUIStyle(skin.button); _windowStyle = new GUIStyle(skin.window); _navButtonStyle = new GUIStyle(skin.button); _navButtonStyle.alignment = (TextAnchor)3; _navButtonStyle.fontSize = 22; _navButtonStyle.padding = Layout.NavButtonPadding; _navButtonStyle.normal.background = TrackNavTex(Layout.NavButtonNormalBgColor); _navButtonStyle.hover.background = TrackNavTex(Layout.NavButtonHoverBgColor); _navButtonStyle.normal.textColor = Layout.H4Color; _navButtonStyle.hover.textColor = Color.white; _navButtonStyle.border = Layout.ZeroBorder; _navButtonActiveStyle = new GUIStyle(_navButtonStyle); _navButtonActiveStyle.normal.background = TrackNavTex(new Color(Layout.H1Color.r, Layout.H1Color.g, Layout.H1Color.b, 0.85f)); _navButtonActiveStyle.normal.textColor = Color.black; _navButtonActiveStyle.hover.background = TrackNavTex(new Color(Layout.H1Color.r, Layout.H1Color.g, Layout.H1Color.b, 1f)); _navButtonActiveStyle.hover.textColor = Color.black; _navButtonActiveStyle.fontStyle = (FontStyle)1; _hideActiveStyle = new GUIStyle(skin.button); _hideActiveStyle.normal.textColor = Color.yellow; _hideActiveStyle.hover.textColor = Color.yellow; _hiddenPlaceholderStyle = new GUIStyle(skin.textField); _hiddenPlaceholderStyle.normal.textColor = Layout.HiddenLabelTextColor; _hiddenPlaceholderStyle.focused.textColor = Layout.HiddenLabelTextColor; _hiddenPlaceholderStyle.fontStyle = (FontStyle)2; } private Texture2D TrackNavTex(Color color) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) Texture2D val = BepInExPlugin.StyleManager.MakeTexture(color, tracked: false); _navTextures.Add(val); return val; } private GUIStyle MakeLabelStyle(GUISkin skin, int size, FontStyle fontStyle, Color color, Font font = null, bool wordWrap = false, int paddingTopAdd = 0) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) GUIStyle val = new GUIStyle(skin.label); val.fontSize = size; val.fontStyle = fontStyle; val.normal.textColor = color; if ((Object)(object)font != (Object)null) { val.font = font; } if (wordWrap) { val.wordWrap = true; } if (paddingTopAdd != 0) { RectOffset padding = val.padding; padding.top += paddingTopAdd; } return val; } public void Update() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) KeyCode hotkeyCode = BepInExPlugin.ConfigManager.General.HotkeyCode; if (Input.GetKeyDown(hotkeyCode)) { DebugLogger.Trace($"{hotkeyCode} pressed"); ToggleWindow(); } if (Input.GetKeyDown((KeyCode)27)) { if (_isWindowOpen) { DebugLogger.DebugMessage("ESC pressed: closing window"); ToggleWindow(closedViaEsc: true); } else if (IsPostCloseEscSuppressing) { float num = (Time.realtimeSinceStartup - _windowEscCloseTime) * 1000f; DebugLogger.DebugMessage($"ESC suppressed: {num:F0}ms since window close (suppression window: {80f}ms)"); } } if (_isReopenPending) { _isReopenPending = false; _isWindowOpen = true; PauseGame(); LockPlayerInput(); BepInExPlugin.ResetPatchSuppressionFlags(); DebugLogger.Warning($"Window reopened after force-close (attempt {_forceCloseCount})"); } if (_isResizing) { if (Input.GetMouseButton(0)) { float num2 = (float)Screen.height - Input.mousePosition.y; float num3 = num2 - _resizeStartMouse.y; ((Rect)(ref _windowRect)).height = Mathf.Max(774f, _resizeStartHeight + num3); } else { _isResizing = false; DebugLogger.DebugMessage($"Window resized to height: {((Rect)(ref _windowRect)).height:F0}"); } } } public void OnGUI() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Invalid comparison between Unknown and I4 //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Invalid comparison between Unknown and I4 //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Expected O, but got Unknown //IL_01d5: 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_0124: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Invalid comparison between Unknown and I4 if (_permanentErrorMsg != null) { GUIStyle val = new GUIStyle(GUI.skin.label); val.fontSize = 22; val.fontStyle = (FontStyle)1; val.normal.textColor = Color.red; GUI.Label(new Rect(((float)Screen.width - 800f) * 0.5f, ((float)Screen.height - 180f) * 0.5f, 800f, 180f), _permanentErrorMsg, val); } else { if (!_isWindowOpen) { return; } try { GUI_StyleManager styleManager = BepInExPlugin.StyleManager; styleManager.EnsureSkinBuilt(); if ((Object)(object)styleManager.BuiltSkin == (Object)null) { DebugLogger.Error("OnGUI: BuiltSkin is null after EnsureSkinBuilt(), skipping frame"); return; } GUI.skin = styleManager.BuiltSkin; if (!_areStylesBuilt) { BuildDerivedStyles(styleManager.BuiltSkin); _areStylesBuilt = true; } if (_editingEntryId != null && (int)Event.current.type == 4 && ((int)Event.current.keyCode == 13 || (int)Event.current.keyCode == 271)) { DebugLogger.Trace("Enter pressed in label field: committing"); CommitLabelEdit(); Event.current.Use(); } GUI.color = new Color(0f, 0f, 0f, 0.65f); GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)Texture2D.whiteTexture); GUI.color = Color.white; GL.sRGBWrite = false; _windowRect = GUI.Window(1138, _windowRect, new WindowFunction(DrawWindowContents), "", _windowStyle); GL.sRGBWrite = true; } catch (Exception ex) { DebugLogger.Error("OnGUI exception, closing window to prevent log spam", ex); ForceCloseWindow(); } } } private void ToggleWindow(bool closedViaEsc = false) { if (_permanentErrorMsg != null) { return; } if (!_isWindowOpen && (Object)(object)Game.instance == (Object)null) { DebugLogger.DebugMessage("Ignoring request for opening settings window (not in-game)"); return; } if (!_isWindowOpen && Menu.IsActive()) { DebugLogger.DebugMessage("Ignoring request for opening settings window (ESC menu is open)"); return; } if (!_isWindowOpen && (Object)(object)Player.m_localPlayer == (Object)null) { DebugLogger.DebugMessage("Ignoring request for opening settings window (character not loaded)"); return; } _isWindowOpen = !_isWindowOpen; if (_isWindowOpen) { OpenWindow(); } else { CloseWindow(closedViaEsc); } } private void OpenWindow() { _hasWindowEverOpened = true; ((Rect)(ref _windowRect)).x = ((float)Screen.width - 920f) * 0.5f; ((Rect)(ref _windowRect)).width = 920f; if (_selectedCategoryId == null) { _selectedCategoryId = BepInExPlugin.ConfigManager.Categories[0].Id; } DebugLogger.DebugMessage($"Settings window OPENED, height: {((Rect)(ref _windowRect)).height:F0}"); _editingEntryId = null; try { PauseGame(); LockPlayerInput(); } catch (Exception ex) { DebugLogger.Error("ToggleWindow: exception during open, restoring state", ex); UnpauseGame(); UnlockPlayerInput(); _isWindowOpen = false; return; } BepInExPlugin.ResetPatchSuppressionFlags(); } private void CloseWindow(bool closedViaEsc) { try { CommitLabelEdit(); FlushSettingsFieldBuffers(); _settingsFieldBuffers.Clear(); DebugLogger.DebugMessage("Settings window CLOSED"); if (_isRebuildPending) { DebugLogger.DebugMessage("Pending rebuild: clearing pins, reinitializing scanner"); BepInExPlugin.ClearAllResourcePins(); BepInExPlugin.Scanner.Initialize(); _isRebuildPending = false; } BepInExPlugin.ResetScanTimer(); ConfigManager configManager = BepInExPlugin.ConfigManager; if (((Rect)(ref _windowRect)).height != (float)configManager.General.WindowHeight) { configManager.General.WindowHeight = Mathf.RoundToInt(((Rect)(ref _windowRect)).height); configManager.SaveConfig(); DebugLogger.DebugMessage($"Window height saved: {((Rect)(ref _windowRect)).height:F0}"); } else { DebugLogger.Trace("Window height unchanged, skipping save"); } _errorMessage = null; _forceCloseCount = 0; _windowCloseTime = Time.realtimeSinceStartup; if (Minimap.IsOpen()) { DebugLogger.DebugMessage($"Window closed, map click suppression active for {200f}ms"); } if (closedViaEsc) { _windowEscCloseTime = Time.realtimeSinceStartup; DebugLogger.DebugMessage($"Window closed, ESC suppression active for {80f}ms"); } } finally { UnpauseGame(); UnlockPlayerInput(); } } private void ForceCloseWindow() { try { CommitLabelEdit(); FlushSettingsFieldBuffers(); _settingsFieldBuffers.Clear(); _editingEntryId = null; } finally { _isWindowOpen = false; _windowCloseTime = Time.realtimeSinceStartup; UnpauseGame(); UnlockPlayerInput(); } _forceCloseCount++; DebugLogger.Warning($"ForceCloseWindow called (attempt {_forceCloseCount})"); if (_forceCloseCount <= 3) { _errorMessage = $"Pinsanity: window was restarted after an internal error (#{_forceCloseCount})."; _isReopenPending = true; } else { _permanentErrorMsg = "Pinsanity: Wow! I didn't think anyone would ever see this. Well, the settings window has been disabled due to repeated errors. The mod is still running normally, but to use the settings GUI, you'll need to restart the game. Please report this (share what you were trying to do) on Nexus Mods or GitHub. Thanks!"; DebugLogger.Error($"ForceCloseWindow: permanent shutdown after {4} failures. Window disabled for this session; displaying big ugly error message"); } } private void PauseGame() { if ((Object)(object)Game.instance != (Object)null) { if (!Game.IsPaused()) { DebugLogger.Trace("Pausing game"); Game.Pause(); _weDidPause = true; } else { DebugLogger.Trace("Game already paused, not pausing again"); _weDidPause = false; } } else { DebugLogger.Trace("Game.instance null, skipping pause"); _weDidPause = false; } } private void UnpauseGame() { if ((Object)(object)Game.instance != (Object)null && _weDidPause) { DebugLogger.Trace("Unpausing game"); Game.Unpause(); } else { DebugLogger.Trace("Skipping unpause (we did not pause the game)"); } _weDidPause = false; } private void LockPlayerInput() { DebugLogger.Trace("Releasing cursor"); Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; } private void UnlockPlayerInput() { DebugLogger.Trace("Re-locking cursor"); Cursor.lockState = (CursorLockMode)1; Cursor.visible = false; } private void SetResourceEnabled(ConfigManager.ResourceEntry entry, bool val, ConfigManager cfg) { entry.Enabled = val; _isRebuildPending = true; cfg.SaveConfig(); } private void SetResourceLabel(ConfigManager.ResourceEntry entry, string label, ConfigManager cfg) { entry.UserLabel = label; _isRebuildPending = true; cfg.SaveConfig(); } private void SetCategoryEnabled(ConfigManager.ResourceCategory cat, bool val, ConfigManager cfg) { cat.Enabled = val; _isRebuildPending = true; cfg.SaveConfig(); } private void ApplyToEntries(IEnumerable<ConfigManager.ResourceEntry> entries, string logMessage, Action<ConfigManager.ResourceEntry> entryAction, ConfigManager cfg, bool andSave = true) { DebugLogger.DebugMessage(logMessage); foreach (ConfigManager.ResourceEntry entry in entries) { DebugLogger.Trace(" " + logMessage + ": '" + entry.Id + "'"); entryAction(entry); } _isRebuildPending = true; if (andSave) { cfg.SaveConfig(); } } private void ApplyToCategories(ConfigManager cfg, string logMessage, Action<ConfigManager.ResourceCategory> action, bool andSave = true) { DebugLogger.DebugMessage(logMessage); foreach (ConfigManager.ResourceCategory category in cfg.Categories) { DebugLogger.Trace(" " + logMessage + ": '" + category.Id + "'"); action(category); } _isRebuildPending = true; if (andSave) { cfg.SaveConfig(); } } private void CommitLabelEdit() { if (_editingEntryId == null) { return; } ConfigManager.ResourceEntry resourceEntry = BepInExPlugin.ConfigManager.FindEntry(_editingEntryId); if (resourceEntry != null) { string text = _editingFieldValue.Trim(); if (text != resourceEntry.UserLabel) { DebugLogger.DebugMessage("Label committed: " + resourceEntry.Id + " = \"" + text + "\""); SetResourceLabel(resourceEntry, text, BepInExPlugin.ConfigManager); } else { DebugLogger.Trace("Label unchanged after trim: " + resourceEntry.Id + " (no save)"); } } _editingEntryId = null; } private void FlushSettingsFieldBuffers() { ConfigManager cfg = BepInExPlugin.ConfigManager; FlushNumericSetting(cfg, "ScanRadius", 1f, 500f, delegate(int val) { cfg.General.ScanRadius = val; }); FlushNumericSetting(cfg, "ScanInterval", 500f, 30000f, delegate(int val) { cfg.General.ScanInterval = val; }); } private void FlushNumericSetting(ConfigManager cfg, string fieldSuffix, float min, float max, Action<int> apply) { string key = "SettingsField_" + fieldSuffix; if (_settingsFieldBuffers.TryGetValue(key, out var value) && int.TryParse(value, out var result)) { apply((int)Mathf.Clamp((float)result, min, max)); DebugLogger.DebugMessage($"Flushed {fieldSuffix}: {result} -> clamped [{min},{max}]"); cfg.SaveConfig(); } } private void EnableAllItems(ConfigManager cfg, bool andSave = true) { ApplyToEntries(cfg.Categories.SelectMany((ConfigManager.ResourceCategory c) => c.Entries), "Enable All Items", delegate(ConfigManager.ResourceEntry e) { e.Enabled = true; }, cfg, andSave); } private void DisableAllItems(ConfigManager cfg, bool andSave = true) { ApplyToEntries(cfg.Categories.SelectMany((ConfigManager.ResourceCategory c) => c.Entries), "Disable All Items", delegate(ConfigManager.ResourceEntry e) { e.Enabled = false; }, cfg, andSave); } private void ResetAllItems(ConfigManager cfg, bool andSave = true) { ApplyToEntries(cfg.Categories.SelectMany((ConfigManager.ResourceCategory c) => c.Entries), "Reset All Items", delegate(ConfigManager.ResourceEntry e) { e.Enabled = e.EnabledByDefault; }, cfg, andSave); } private void ClearAllLabels(ConfigManager cfg, bool andSave = true) { ApplyToEntries(cfg.Categories.SelectMany((ConfigManager.ResourceCategory c) => c.Entries), "Clear All Labels", delegate(ConfigManager.ResourceEntry e) { e.UserLabel = ""; }, cfg, andSave); } private void ResetAllLabels(ConfigManager cfg, bool andSave = true) { ApplyToEntries(cfg.Categories.SelectMany((ConfigManager.ResourceCategory c) => c.Entries), "Reset All Labels", delegate(ConfigManager.ResourceEntry e) { e.UserLabel = e.DefaultLabel; }, cfg, andSave); } private void EnableAllCategories(ConfigManager cfg, bool andSave = true) { ApplyToCategories(cfg, "Enable All Categories", delegate(ConfigManager.ResourceCategory c) { c.Enabled = true; }, andSave); } private void DisableAllCategories(ConfigManager cfg, bool andSave = true) { ApplyToCategories(cfg, "Disable All Categories", delegate(ConfigManager.ResourceCategory c) { c.Enabled = false; }, andSave); } private void ResetGeneralSettings(ConfigManager cfg, bool andSave = true) { cfg.General.Enabled = true; cfg.General.ShowLabels = true; cfg.General.IsDebug = false; cfg.General.IsTrace = false; cfg.General.IsBenchmark = false; cfg.General.ScanRadius = 100; cfg.General.ScanInterval = 5000; DebugLogger.DebugMessage("Reset General Settings"); if (andSave) { cfg.SaveConfig(); } } private void ResetEverything(ConfigManager cfg) { DebugLogger.Info("Reset everything (all resources, categories, labels, mod settings) to factory defaults"); ResetGeneralSettings(cfg, andSave: false); EnableAllCategories(cfg, andSave: false); ResetAllItems(cfg, andSave: false); ResetAllLabels(cfg, andSave: false); cfg.SaveConfig(); } } public static class Layout { public static readonly bool DebugBorders = false; public static readonly Color WindowBgColor = Hex("020202D9"); public const int WindowPadding = 20; public const float NavColumnWidth = 300f; public const float ContentColumnWidth = 580f; public const float WindowWidth = 920f; public const float WindowStartY = 60f; public const float WindowStartHeight = 1000f; public const float MinWindowHeight = 774f; public const float ResizeHandleSize = 24f; public const float OverlayOpacity = 0.65f; public const float PostCloseClickSuppressionMs = 200f; public const float PostCloseEscSuppressionMs = 80f; public const int H1FontSize = 40; public const FontStyle H1FontStyle = 0; public static readonly Color H1Color = Hex("FFA100"); public const int H2FontSize = 22; public const FontStyle H2FontStyle = 0; public static readonly Color H2Color = Hex("CC8100"); public const int H2WarningFontSize = 22; public const FontStyle H2WarningFontStyle = 0; public static readonly Color H2WarningColor = Hex("FF3030"); public const int H3FontSize = 22; public const FontStyle H3FontStyle = 1; public static readonly Color H3Color = Hex("FFFFFF"); public const int H4FontSize = 22; public const FontStyle H4FontStyle = 0; public static readonly Color H4Color = Hex("DDDDDD"); public const int BodyFontSize = 22; public const FontStyle BodyFontStyle = 0; public static readonly Color BodyColor = Hex("FFFFFF"); public const int NoteTextSize = 18; public const FontStyle NoteTextStyle = 0; public static readonly Color NoteColor = Hex("b5b5b5"); public const bool NoteWordWrap = true; public const int FieldFontSize = 24; public const float LabelFieldWidth = 240f; public static readonly RectOffset FieldPadding = new RectOffset(6, 6, 4, 4); public static readonly Color FieldBgColor = Hex("080808"); public static readonly Color FieldHoverBgColor = Hex("191919"); public static readonly Color FieldFocusedBgColor = Hex("202020"); public static readonly Color FieldActiveBgColor = Hex("404040"); public static readonly Color FieldTextColor = Hex("FFFFFF"); public const int SolidColorTextureSize = 2; public const float ToggleSize = 20f; public const float ToggleBorderSize = 2f; public const float ToggleVerticalOffset = 8f; public const int ToggleTextureScale = 2; public static readonly Color ToggleOnBorder = Hex("111111"); public static readonly Color ToggleOnFill = Hex("FF8000"); public static readonly Color ToggleOffBorder = Hex("808080"); public static readonly Color ToggleOffFill = Hex("040404"); public static readonly Color ToggleOnHoverBorder = Hex("FFFFFF"); public static readonly Color ToggleOnHoverFill = Hex("FF8000"); public static readonly Color ToggleOffHoverBorder = Hex("7E7E7E"); public static readonly Color ToggleOffHoverFill = Hex("404040"); public static readonly Color ButtonBgColor = Hex("0F0F0F"); public static readonly Color ButtonHoverColor = Hex("505050"); public static readonly Color ButtonActiveColor = Hex("808080"); public static readonly Color ButtonTextColor = Hex("FFFFFF"); public const int ButtonPadding = 5; public static readonly RectOffset ZeroBorder = new RectOffset(0, 0, 0, 0); public static readonly Color NavButtonNormalBgColor = Hex("1A1A1A"); public static readonly Color NavButtonHoverBgColor = Hex("333333"); public const float NavButtonActiveAlpha = 0.85f; public const float NavButtonFullAlpha = 1f; public static readonly RectOffset NavButtonPadding = new RectOffset(12, 8, 8, 8); public static readonly Color ScrollBgColor = Hex("1F1F1F"); public static readonly Color ScrollThumbColor = Hex("595959"); public static readonly Color ScrollThumbHover = Hex("808080"); public const float ResizeHandleInset = 4f; public const int ResizeHandleDotSize = 4; public const int ResizeHandleDotGap = 3; public const int ResizeHandleTexSize = 24; public const int ResizeGripGridSize = 3; public const int ResizeGripMargin = 3; public static readonly Color ResizeHandleHoverColor = Hex("202020E6"); public static readonly Color HiddenLabelTextColor = Hex("808080"); public static readonly Color ResizeHandleTextNormal = Hex("BFBFBFE6"); public static readonly Color ResizeHandleTextHover = Hex("FFFFFF"); public const float PermanentErrorWidth = 800f; public const float PermanentErrorHeight = 180f; public const int PermanentErrorFontSize = 22; public const int MaxForceCloseRetries = 3; public const string PermanentErrorMessage = "Pinsanity: Wow! I didn't think anyone would ever see this. Well, the settings window has been disabled due to repeated errors. The mod is still running normally, but to use the settings GUI, you'll need to restart the game. Please report this (share what you were trying to do) on Nexus Mods or GitHub. Thanks!"; public const float SectionBreakSpacingMultiplier = 3f; public const float DebugBorderThickness = 1f; public const float RowSpacing = 5f; public const float CategorySpacing = 20f; public const float EntryIndent = 20f; public const int LabelPrefixPaddingTop = 3; public const float LabelFieldOffsetX = -11f; public const float LabelRowIndentOffset = 4f; public const float ContentPaddingLeft = 16f; public const float SettingsNotePaddingLeft = 4f; public const float DisabledOpacity = 0.15f; public static readonly Color SeparatorColor = Hex("FFFFFF4D"); public const float SeparatorPadding = 15f; public const float SeparatorWidthOffset = -28f; public const float RowHeightPadding = 8f; public const float EntryGapMultiplier = 0.375f; public const float TitleSpacing = 2f; public const float SubtitleSpacing = 8f; public const float PreCloseButtonSpacing = 6f; public const float CloseButtonWidthFraction = 0.88f; public const float CategoryButtonWidthMultiplier = 6.5f; public const float ResetButtonWidthMultiplier = 3.5f; public const float HideButtonWidthMultiplier = 3f; public const float SettingsLabelWidthMultiplier = 6.6f; public const float SettingsFieldWidthMultiplier = 4f; public const string NoteSettingsEnabled = "Enables or disables the entire mod"; public const string NoteSettingsShowLabels = "Show/hide labels for all resources"; public const string NoteSettingsScanRadius = "How far around the player to scan for objects; default is 100m"; public const string NoteSettingsScanInterval = "How often to scan, in milliseconds; default is 5000; min is 500"; public const string NoteSettingsAllItems = "'Off' disables all resources across all categories; 'On' unleashes the full Pinsanity; 'Reset' puts them all back to defaults (recommended settings)"; public const string NoteSettingsAllCategories = "Does not change individual resource settings"; public const string NoteSettingsAllLabels = "To show labels for 1 or 2 resources: 'Clear All' empties all labels, then you can customize labels for individual resources"; public const string NoteSettingsResetEverything = "Resets resources, categories, labels, and general mod settings"; public const string NoteSettingsIsBenchmark = "Logs a detailed list of 'how long it all takes' for every scan"; public const string NoteSettingsIsDebug = "For testers: logs settings changes, pin state changes, and window actions"; public const string NoteSettingsIsTrace = "For developers and extreme nerds: incredibly-detailed firehose of pretty-much-everything; requires debug on"; private static Color Hex(string hex) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) Color result = default(Color); ColorUtility.TryParseHtmlString("#" + hex, ref result); return result; } } public class GUI_StyleManager { private readonly List<Texture2D> _skinTextures = new List<Texture2D>(); private Font _fontBody = null; private Font _fontTitle = null; public GUISkin BuiltSkin { get; private set; } internal Font FontBody => _fontBody; internal Font FontTitle => _fontTitle; public void Initialize() { DebugLogger.Trace("GUI_StyleManager initialized"); } public void EnsureSkinBuilt() { if ((Object)(object)_fontBody == (Object)null || (Object)(object)_fontTitle == (Object)null) { FindFonts(); } if ((Object)(object)BuiltSkin == (Object)null) { DebugLogger.Trace("GUI_StyleManager: EnsureSkinBuilt(): first OnGUI call"); BuildSkin(); } } private void FindFonts() { Font[] array = Resources.FindObjectsOfTypeAll<Font>(); foreach (Font val in array) { if (((Object)val).name == "AveriaSerifLibre-Bold") { _fontBody = val; } if (((Object)val).name == "Norsebold") { _fontTitle = val; } } if ((Object)(object)_fontBody == (Object)null) { DebugLogger.Error("Font not found: AveriaSerifLibre-Bold"); } else { DebugLogger.Trace("Font found: AveriaSerifLibre-Bold"); } if ((Object)(object)_fontTitle == (Object)null) { DebugLogger.Error("Font not found: Norsebold"); } else { DebugLogger.Trace("Font found: Norsebold"); } } private void BuildSkin() { DebugLogger.Trace("GUI_StyleManager: BuildSkin()"); foreach (Texture2D skinTexture in _skinTextures) { if ((Object)(object)skinTexture != (Object)null) { Object.Destroy((Object)(object)skinTexture); } } _skinTextures.Clear(); if ((Object)(object)BuiltSkin != (Object)null) { Object.Destroy((Object)(object)BuiltSkin); } GUISkin val = Object.Instantiate<GUISkin>(GUI.skin); val.label.font = _fontBody; val.textField.font = _fontTitle; val.button.font = _fontBody; Object.DontDestroyOnLoad((Object)(object)val); BuildWindowStyle(val); BuildTextFieldStyle(val); BuildButtonStyle(val); BuildScrollbarStyle(val); BuiltSkin = val; DebugLogger.Trace("GUI_StyleManager: BuildSkin() complete"); } private void BuildWindowStyle(GUISkin skin) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown Texture2D background = MakeTexture(Layout.WindowBgColor); skin.window.normal.background = background; skin.window.onNormal.background = background; skin.window.padding = new RectOffset(20, 20, 20, 20); } private void BuildTextFieldStyle(GUISkin skin) { //IL_0021: 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_003b: 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_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_0111: 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_0161: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) skin.textField.fontSize = 24; skin.textField.padding = Layout.FieldPadding; Texture2D background = MakeTexture(Layout.FieldBgColor); Texture2D background2 = MakeTexture(Layout.FieldHoverBgColor); Texture2D background3 = MakeTexture(Layout.FieldFocusedBgColor); Texture2D background4 = MakeTexture(Layout.FieldActiveBgColor); skin.textField.normal.background = background; skin.textField.normal.textColor = Layout.FieldTextColor; skin.textField.hover.background = background2; skin.textField.hover.textColor = Layout.FieldTextColor; skin.textField.focused.background = background3; skin.textField.focused.textColor = Layout.FieldTextColor; skin.textField.active.background = background4; skin.textField.active.textColor = Layout.FieldTextColor; skin.textField.onNormal.background = background; skin.textField.onNormal.textColor = Layout.FieldTextColor; skin.textField.onHover.background = background2; skin.textField.onHover.textColor = Layout.FieldTextColor; skin.textField.onFocused.background = background3; skin.textField.onFocused.textColor = Layout.FieldTextColor; skin.textField.onActive.background = background4; skin.textField.onActive.textColor = Layout.FieldTextColor; skin.settings.cursorColor = Layout.FieldTextColor; } private void BuildButtonStyle(GUISkin skin) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_001c: 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_0032: Expected O, but got Unknown //IL_007b: 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_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_011b: 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) Texture2D background = MakeTexture(Layout.ButtonBgColor); Texture2D background2 = MakeTexture(Layout.ButtonHoverColor); Texture2D background3 = MakeTexture(Layout.ButtonActiveColor); RectOffset padding = new RectOffset(5, 5, 5, 5); skin.button.fontSize = 22; skin.button.padding = padding; skin.button.border = Layout.ZeroBorder; skin.button.normal.background = background; skin.button.normal.textColor = Layout.ButtonTextColor; skin.button.hover.background = background2; skin.button.hover.textColor = Layout.ButtonTextColor; skin.button.active.background = background3; skin.button.active.textColor = Layout.ButtonTextColor; skin.button.onNormal.background = background; skin.button.onNormal.textColor = Layout.ButtonTextColor; skin.button.onHover.background = background2; skin.button.onHover.textColor = Layout.ButtonTextColor; skin.button.onActive.background = background3; skin.button.onActive.textColor = Layout.ButtonTextColor; } private void BuildScrollbarStyle(GUISkin skin) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) Texture2D background = MakeTexture(Layout.ScrollBgColor); Texture2D background2 = MakeTexture(Layout.ScrollThumbColor); Texture2D background3 = MakeTexture(Layout.ScrollThumbHover); skin.verticalScrollbar.normal.background = background; skin.verticalScrollbar.hover.background = background; skin.verticalScrollbarThumb.normal.background = background2; skin.verticalScrollbarThumb.hover.background = background3; skin.verticalScrollbarThumb.active.background = background3; skin.horizontalScrollbar.normal.background = background; skin.horizontalScrollbar.hover.background = background; skin.horizontalScrollbarThumb.normal.background = background2; skin.horizontalScrollbarThumb.hover.background = background3; skin.horizontalScrollbarThumb.active.background = background3; } internal Texture2D MakeTexture(Color color, bool tracked = true) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Expected O, but got Unknown //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: 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_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(2, 2); val.SetPixels((Color[])(object)new Color[4] { color, color, color, color }); val.Apply(); Object.DontDestroyOnLoad((Object)(object)val); if (tracked) { _skinTextures.Add(val); } return val; } public void Cleanup() { foreach (Texture2D skinTexture in _skinTextures) { if ((Object)(object)skinTexture != (Object)null) { Object.Destroy((Object)(object)skinTexture); } } _skinTextures.Clear(); if ((Object)(object)BuiltSkin != (Object)null) { Object.Destroy((Object)(object)BuiltSkin); BuiltSkin = null; } } } public static class GUI_TextureUtils { public static Texture2D MakeCircleTexture(int size, Color fillColor, Color borderColor, float borderSize) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: 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_00dd: 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_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(size, size, (TextureFormat)5, false); ((Texture)val).filterMode = (FilterMode)1; ((Texture)val).wrapMode = (TextureWrapMode)1; float num = (float)(size - 1) * 0.5f; float num2 = (float)(size - 1) * 0.5f; float num3 = (float)(size - 1) * 0.5f; Color bottom = default(Color); Color top = default(Color); Color val2 = default(Color); for (int i = 0; i < size; i++) { for (int j = 0; j < size; j++) { float num4 = (float)j - num; float num5 = (float)i - num2; float num6 = Mathf.Sqrt(num4 * num4 + num5 * num5); float num7 = num3 - num6; if (num7 < -1f) { val.SetPixel(j, i, Color.clear); continue; } float num8 = Mathf.Clamp01(num7 + 0.5f); float num9 = num6 - (num3 - borderSize); float num10 = Mathf.Clamp01(num9 + 0.5f); if (num10 > 0f) { ((Color)(ref bottom))..ctor(fillColor.r, fillColor.g, fillColor.b, num8); ((Color)(ref top))..ctor(borderColor.r, borderColor.g, borderColor.b, num8 * num10); val2 = AlphaBlend(bottom, top); } else { ((Color)(ref val2))..ctor(fillColor.r, fillColor.g, fillColor.b, num8); } val.SetPixel(j, i, val2); } } val.Apply(); Object.DontDestroyOnLoad((Object)(object)val); return val; } public static Texture2D MakeResizeGripTexture(int texSize, int dotSize, int dotGap, Color dotColor) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: 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_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(texSize, texSize, (TextureFormat)5, false); ((Texture)val).filterMode = (FilterMode)1; ((Texture)val).wrapMode = (TextureWrapMode)1; for (int i = 0; i < texSize; i++) { for (int j = 0; j < texSize; j++) { val.SetPixel(j, i, Color.clear); } } int num = 3; int num2 = dotSize + dotGap; int num3 = 3; int num4 = num * num2 - dotGap; int num5 = texSize - num4 - num3; int num6 = texSize - num4 - num3; Color top = default(Color); for (int k = 0; k < num; k++) { for (int l = 0; l < num; l++) { if (l < k) { continue; } int num7 = num5 + l * num2 + dotSize / 2; int num8 = num6 + k * num2 + dotSize / 2; float num9 = (float)dotSize * 0.5f; for (int m = 0; m < texSize; m++) { for (int n = 0; n < texSize; n++) { float num10 = Mathf.Sqrt((float)((n - num7) * (n - num7) + (m - num8) * (m - num8))); float num11 = Mathf.Clamp01(num9 - num10 + 0.5f); if (!(num11 <= 0f)) { Color pixel = val.GetPixel(n, m); ((Color)(ref top))..ctor(dotColor.r, dotColor.g, dotColor.b, dotColor.a * num11); val.SetPixel(n, m, AlphaBlend(pixel, top)); } } } } } val.Apply(); Object.DontDestroyOnLoad((Object)(object)val); return val; } private static Color AlphaBlend(Color bottom, Color top) { //IL_0001: 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) //IL_0012: 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_003c: 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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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_0080: 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 re