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 GoblinHotkeyInspector v0.1.0
plugins\GoblinHotkeyInspector\GoblinHotkeyInspector.dll
Decompiled 11 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("GoblinStudio")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Read-only OnGUI KeyboardShortcut inspector runtime candidate.")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: AssemblyInformationalVersion("0.1.0")] [assembly: AssemblyProduct("GoblinHotkeyInspector")] [assembly: AssemblyTitle("GoblinHotkeyInspector")] [assembly: AssemblyVersion("0.1.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace GoblinStudio.GoblinHotkeyInspector { [BepInPlugin("GoblinStudio.GoblinHotkeyInspector", "Goblin Hotkey Inspector", "0.1.0")] public sealed class GoblinHotkeyInspectorPlugin : BaseUnityPlugin { public const string PluginGuid = "GoblinStudio.GoblinHotkeyInspector"; public const string PluginName = "Goblin Hotkey Inspector"; public const string PluginVersion = "0.1.0"; private ConfigEntry<KeyboardShortcut>? _openInspector; private ConfigEntry<bool>? _showUnique; private ConfigEntry<bool>? _showDisabled; private bool _windowOpen; private Rect _windowRect; private Vector2 _scrollPosition; private ScanSnapshot? _snapshot; private GUIStyle? _titleStyle; private GUIStyle? _sectionStyle; private GUIStyle? _descriptionStyle; private GUIStyle? _mutedStyle; private void Awake() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) _openInspector = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "OpenInspector", new KeyboardShortcut((KeyCode)290, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }), "Open or close the Goblin Hotkey Inspector window."); _showUnique = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowUnique", true, "Show shortcuts that are used by only one configured entry."); _showDisabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowDisabled", true, "Show disabled KeyboardShortcut entries."); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Goblin Hotkey Inspector 0.1.0 loaded."); ((BaseUnityPlugin)this).Logger.LogInfo((object)("OpenInspector shortcut: " + FormatShortcut(_openInspector.Value))); } private void Update() { //IL_000e: 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) if (_openInspector == null) { return; } KeyboardShortcut value = _openInspector.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { _windowOpen = !_windowOpen; if (_windowOpen) { EnsureWindowRect(); ScanNow(); } } } private void OnGUI() { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_003b: 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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) if (_windowOpen && _snapshot != null) { EnsureStyles(); EnsureWindowRect(); _windowRect = GUI.Window(((Object)this).GetInstanceID(), _windowRect, new WindowFunction(DrawWindow), "Goblin Hotkey Inspector"); _windowRect = ClampWindowRect(_windowRect); } } private void DrawWindow(int windowId) { //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) ScanSnapshot snapshot = _snapshot; GUILayout.BeginVertical(Array.Empty<GUILayoutOption>()); GUILayout.Label("Scan completed", _mutedStyle, Array.Empty<GUILayoutOption>()); GUILayout.Label($"Configured shortcuts: {snapshot.ActiveShortcuts} active / {snapshot.DisabledShortcuts} disabled " + $"Shared groups: {snapshot.SharedGroups} Unsupported entries: {snapshot.UnsupportedEntries}", _mutedStyle, Array.Empty<GUILayoutOption>()); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); if (GUILayout.Button("Rescan", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) })) { ScanNow(); } if (GUILayout.Button("Close", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) })) { _windowOpen = false; } GUILayout.EndHorizontal(); _scrollPosition = GUILayout.BeginScrollView(_scrollPosition, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) }); DrawGroups("Shared Shortcuts", snapshot.Groups.Where((ShortcutGroupDto group) => group.Status == GroupStatus.Shared)); if (_showUnique.Value) { DrawGroups("Unique Shortcuts", snapshot.Groups.Where((ShortcutGroupDto group) => group.Status == GroupStatus.Unique)); } if (_showDisabled.Value) { DrawDisabled(snapshot.DisabledEntries); } if (snapshot.Groups.All((ShortcutGroupDto group) => group.Status != GroupStatus.Shared)) { GUILayout.Label("No shared shortcuts found", _mutedStyle, Array.Empty<GUILayoutOption>()); } if (snapshot.UnsupportedEntries > 0) { GUILayout.Label($"{snapshot.UnsupportedEntries} config entries were not KeyboardShortcut entries and were not inspected.", _mutedStyle, Array.Empty<GUILayoutOption>()); } GUILayout.EndScrollView(); GUILayout.EndVertical(); GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref _windowRect)).width, 24f)); } private void DrawGroups(string heading, IEnumerable<ShortcutGroupDto> groups) { List<ShortcutGroupDto> list = groups.ToList(); if (list.Count == 0) { return; } GUILayout.Label(heading, _sectionStyle, Array.Empty<GUILayoutOption>()); foreach (ShortcutGroupDto item in list) { GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>()); GUILayout.Label(item.ShortcutText, Array.Empty<GUILayoutOption>()); GUILayout.Label($"{item.Status.ToString().ToUpperInvariant()} · {item.Entries.Count} entries", _mutedStyle, Array.Empty<GUILayoutOption>()); DrawEntries(item.Entries); if (item.Status == GroupStatus.Shared) { GUILayout.Label("Shared shortcut detected.", _descriptionStyle, Array.Empty<GUILayoutOption>()); GUILayout.Label("Runtime conflict depends on each mod's input handling and active context.", _descriptionStyle, Array.Empty<GUILayoutOption>()); } GUILayout.EndVertical(); } } private void DrawDisabled(IReadOnlyList<HotkeyEntryDto> entries) { if (entries.Count == 0) { return; } GUILayout.Label("Disabled Shortcuts", _sectionStyle, Array.Empty<GUILayoutOption>()); foreach (HotkeyEntryDto entry in entries) { GUILayout.BeginVertical(GUI.skin.box, Array.Empty<GUILayoutOption>()); GUILayout.Label("DISABLED · None", _mutedStyle, Array.Empty<GUILayoutOption>()); DrawEntries(new HotkeyEntryDto[1] { entry }); GUILayout.EndVertical(); } } private static void DrawEntries(IReadOnlyList<HotkeyEntryDto> entries) { foreach (HotkeyEntryDto entry in entries) { GUILayout.Label(entry.PluginName + " " + entry.PluginVersion, Array.Empty<GUILayoutOption>()); GUILayout.Label(entry.Section + " / " + entry.ConfigKey, Array.Empty<GUILayoutOption>()); GUILayout.Label("GUID: " + entry.PluginGuid, Array.Empty<GUILayoutOption>()); GUILayout.Label(entry.Description, GUI.skin.label, Array.Empty<GUILayoutOption>()); } } private void ScanNow() { _snapshot = HotkeyScanner.Scan(((BaseUnityPlugin)this).Logger); HotkeyScanner.LogSummary(((BaseUnityPlugin)this).Logger, _snapshot); } private void EnsureWindowRect() { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //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_007d: Unknown result type (might be due to invalid IL or missing references) if (((Rect)(ref _windowRect)).width <= 0f || ((Rect)(ref _windowRect)).height <= 0f) { _windowRect = new Rect(Mathf.Max(16f, ((float)Screen.width - 760f) / 2f), Mathf.Max(16f, ((float)Screen.height - 560f) / 2f), 760f, 560f); } _windowRect = ClampWindowRect(_windowRect); } private static Rect ClampWindowRect(Rect rect) { //IL_009c: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Min(((Rect)(ref rect)).width, Mathf.Max(360f, (float)Screen.width - 32f)); float num2 = Mathf.Min(((Rect)(ref rect)).height, Mathf.Max(260f, (float)Screen.height - 32f)); float num3 = Mathf.Clamp(((Rect)(ref rect)).x, 16f, Mathf.Max(16f, (float)Screen.width - num - 16f)); float num4 = Mathf.Clamp(((Rect)(ref rect)).y, 16f, Mathf.Max(16f, (float)Screen.height - num2 - 16f)); return new Rect(num3, num4, num, num2); } private void EnsureStyles() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_0038: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown if (_titleStyle == null) { _titleStyle = new GUIStyle(GUI.skin.label) { fontStyle = (FontStyle)1, fontSize = 16 }; _sectionStyle = new GUIStyle(GUI.skin.label) { fontStyle = (FontStyle)1, fontSize = 14 }; _descriptionStyle = new GUIStyle(GUI.skin.label) { wordWrap = true }; _mutedStyle = new GUIStyle(GUI.skin.label) { wordWrap = true }; } } private unsafe static string FormatShortcut(KeyboardShortcut shortcut) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) if ((int)((KeyboardShortcut)(ref shortcut)).MainKey == 0) { return "None; OpenInspector must be configured before the window can open."; } string[] array = (from key in ((KeyboardShortcut)(ref shortcut)).Modifiers.Distinct() orderby (int)key select ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString()).ToArray(); if (array.Length != 0) { return string.Join(" + ", array) + " + " + ((object)((KeyboardShortcut)(ref shortcut)).MainKey/*cast due to .constrained prefix*/).ToString(); } return ((object)((KeyboardShortcut)(ref shortcut)).MainKey/*cast due to .constrained prefix*/).ToString(); } } internal static class HotkeyScanner { internal static ScanSnapshot Scan(ManualLogSource log) { //IL_00fd: 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_014b: Unknown result type (might be due to invalid IL or missing references) Stopwatch stopwatch = Stopwatch.StartNew(); ScanSnapshot scanSnapshot = new ScanSnapshot(); Dictionary<string, List<HotkeyEntryDto>> dictionary = new Dictionary<string, List<HotkeyEntryDto>>(StringComparer.Ordinal); IReadOnlyDictionary<string, PluginInfo> pluginInfos = Chainloader.PluginInfos; scanSnapshot.ActivePlugins = pluginInfos.Count; foreach (KeyValuePair<string, PluginInfo> item in pluginInfos) { try { BaseUnityPlugin instance = item.Value.Instance; ConfigFile val = ((instance != null) ? instance.Config : null); if (val == null) { scanSnapshot.Errors++; log.LogWarning((object)("ghi_scan skipped plugin '" + item.Key + "': ConfigFile unavailable.")); continue; } ConfigEntryBase[] configEntries = val.GetConfigEntries(); foreach (ConfigEntryBase val2 in configEntries) { scanSnapshot.ConfigEntries++; try { if (val2.SettingType != typeof(KeyboardShortcut)) { scanSnapshot.UnsupportedEntries++; continue; } if (!(val2.BoxedValue is KeyboardShortcut shortcut)) { scanSnapshot.Errors++; log.LogWarning((object)$"ghi_scan skipped '{item.Key}/{val2.Definition}': invalid KeyboardShortcut value."); continue; } HotkeyEntryDto hotkeyEntryDto = CreateEntry(item.Key, item.Value, val2, shortcut); scanSnapshot.KeyboardShortcuts++; if (hotkeyEntryDto.IsDisabled) { scanSnapshot.DisabledShortcuts++; scanSnapshot.DisabledEntries.Add(hotkeyEntryDto); continue; } scanSnapshot.ActiveShortcuts++; if (!dictionary.TryGetValue(hotkeyEntryDto.ShortcutText, out var value)) { value = new List<HotkeyEntryDto>(); dictionary.Add(hotkeyEntryDto.ShortcutText, value); } value.Add(hotkeyEntryDto); } catch (Exception ex) { scanSnapshot.Errors++; log.LogWarning((object)("ghi_scan skipped entry from '" + item.Key + "': " + ex.GetType().Name + ": " + ex.Message)); } } } catch (Exception ex2) { scanSnapshot.Errors++; log.LogWarning((object)("ghi_scan skipped plugin '" + item.Key + "': " + ex2.GetType().Name + ": " + ex2.Message)); } } foreach (KeyValuePair<string, List<HotkeyEntryDto>> item2 in dictionary) { item2.Value.Sort(EntryComparer); scanSnapshot.Groups.Add(new ShortcutGroupDto(item2.Key, (item2.Value.Count <= 1) ? GroupStatus.Unique : GroupStatus.Shared, item2.Value)); } scanSnapshot.Groups.Sort(delegate(ShortcutGroupDto left, ShortcutGroupDto right) { int num = left.Status.CompareTo(right.Status); return (num == 0) ? StringComparer.Ordinal.Compare(left.ShortcutText, right.ShortcutText) : num; }); scanSnapshot.DisabledEntries.Sort(EntryComparer); scanSnapshot.SharedGroups = scanSnapshot.Groups.Count((ShortcutGroupDto group) => group.Status == GroupStatus.Shared); scanSnapshot.UniqueGroups = scanSnapshot.Groups.Count((ShortcutGroupDto group) => group.Status == GroupStatus.Unique); scanSnapshot.ElapsedMilliseconds = stopwatch.Elapsed.TotalMilliseconds; return scanSnapshot; } internal static void LogSummary(ManualLogSource log, ScanSnapshot snapshot) { log.LogInfo((object)($"ghi_scan_hotkeys completed: activePlugins={snapshot.ActivePlugins}, configEntries={snapshot.ConfigEntries}, " + $"keyboardShortcuts={snapshot.KeyboardShortcuts}, activeShortcuts={snapshot.ActiveShortcuts}, " + $"disabled={snapshot.DisabledShortcuts}, groups={snapshot.Groups.Count}, sharedGroups={snapshot.SharedGroups}, " + $"unsupported={snapshot.UnsupportedEntries}, errors={snapshot.Errors}, elapsedMs={snapshot.ElapsedMilliseconds:F3}")); } private unsafe static HotkeyEntryDto CreateEntry(string guid, PluginInfo pluginInfo, ConfigEntryBase entry, KeyboardShortcut shortcut) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Invalid comparison between Unknown and I4 string[] array = (from val in ((KeyboardShortcut)(ref shortcut)).Modifiers.Distinct() orderby (int)val select ((object)(*(KeyCode*)(&val))/*cast due to .constrained prefix*/).ToString()).ToArray(); string shortcutText = (((int)((KeyboardShortcut)(ref shortcut)).MainKey == 0) ? "None" : ((array.Length == 0) ? ((object)((KeyboardShortcut)(ref shortcut)).MainKey/*cast due to .constrained prefix*/).ToString() : (string.Join(" + ", array) + " + " + ((object)((KeyboardShortcut)(ref shortcut)).MainKey/*cast due to .constrained prefix*/).ToString()))); BepInPlugin metadata = pluginInfo.Metadata; object obj = ((metadata != null) ? metadata.Name : null); if (obj == null) { BepInPlugin metadata2 = pluginInfo.Metadata; obj = ((metadata2 != null) ? metadata2.GUID : null) ?? guid; } BepInPlugin metadata3 = pluginInfo.Metadata; string pluginVersion = ((metadata3 == null) ? null : metadata3.Version?.ToString()) ?? "unknown"; string section = entry.Definition.Section; string key = entry.Definition.Key; ConfigDescription description = entry.Description; return new HotkeyEntryDto((string)obj, guid, pluginVersion, section, key, ((description != null) ? description.Description : null) ?? string.Empty, shortcutText, (int)((KeyboardShortcut)(ref shortcut)).MainKey == 0); } private static int EntryComparer(HotkeyEntryDto left, HotkeyEntryDto right) { int num = StringComparer.Ordinal.Compare(left.PluginName, right.PluginName); if (num != 0) { return num; } num = StringComparer.Ordinal.Compare(left.Section, right.Section); if (num == 0) { return StringComparer.Ordinal.Compare(left.ConfigKey, right.ConfigKey); } return num; } } internal sealed class ScanSnapshot { internal int ActivePlugins { get; set; } internal int ConfigEntries { get; set; } internal int KeyboardShortcuts { get; set; } internal int ActiveShortcuts { get; set; } internal int DisabledShortcuts { get; set; } internal int UniqueGroups { get; set; } internal int SharedGroups { get; set; } internal int UnsupportedEntries { get; set; } internal int Errors { get; set; } internal double ElapsedMilliseconds { get; set; } internal List<ShortcutGroupDto> Groups { get; } = new List<ShortcutGroupDto>(); internal List<HotkeyEntryDto> DisabledEntries { get; } = new List<HotkeyEntryDto>(); } internal sealed class ShortcutGroupDto { internal string ShortcutText { get; } internal GroupStatus Status { get; } internal IReadOnlyList<HotkeyEntryDto> Entries { get; } internal ShortcutGroupDto(string shortcutText, GroupStatus status, IReadOnlyList<HotkeyEntryDto> entries) { ShortcutText = shortcutText; Status = status; Entries = entries; } } internal sealed class HotkeyEntryDto { internal string PluginName { get; } internal string PluginGuid { get; } internal string PluginVersion { get; } internal string Section { get; } internal string ConfigKey { get; } internal string Description { get; } internal string ShortcutText { get; } internal bool IsDisabled { get; } internal HotkeyEntryDto(string pluginName, string pluginGuid, string pluginVersion, string section, string configKey, string description, string shortcutText, bool isDisabled) { PluginName = pluginName; PluginGuid = pluginGuid; PluginVersion = pluginVersion; Section = section; ConfigKey = configKey; Description = description; ShortcutText = shortcutText; IsDisabled = isDisabled; } } internal enum GroupStatus { Shared, Unique } }