using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Text; using System.Text.RegularExpressions; using System.Threading; using AdminQoL.LightweightXRay; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using ConsolePanel; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.U2D; using UnityEngine.UI; using YamlDotNet.Core; using YamlDotNet.Core.Events; using YamlDotNet.Core.ObjectPool; using YamlDotNet.Core.Tokens; using YamlDotNet.Helpers; using YamlDotNet.Serialization; using YamlDotNet.Serialization.BufferedDeserialization; using YamlDotNet.Serialization.BufferedDeserialization.TypeDiscriminators; using YamlDotNet.Serialization.Callbacks; using YamlDotNet.Serialization.Converters; using YamlDotNet.Serialization.EventEmitters; using YamlDotNet.Serialization.NamingConventions; using YamlDotNet.Serialization.NodeDeserializers; using YamlDotNet.Serialization.NodeTypeResolvers; using YamlDotNet.Serialization.ObjectFactories; using YamlDotNet.Serialization.ObjectGraphTraversalStrategies; using YamlDotNet.Serialization.ObjectGraphVisitors; using YamlDotNet.Serialization.Schemas; using YamlDotNet.Serialization.TypeInspectors; using YamlDotNet.Serialization.TypeResolvers; using YamlDotNet.Serialization.Utilities; using YamlDotNet.Serialization.ValueDeserializers; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("AdminQoL")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("sighsorry")] [assembly: AssemblyProduct("AdminQoL")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("4358610B-F3F4-4843-B7AF-98B7BC60DCDE")] [assembly: AssemblyFileVersion("1.0.9")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.9.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 ConsolePanel { internal static class ConsoleCommandOwnership { private static readonly Dictionary Owners = new Dictionary(StringComparer.OrdinalIgnoreCase); private static readonly HashSet CommonAliasTokens = new HashSet(StringComparer.OrdinalIgnoreCase) { "a", "an", "and", "the", "mod", "mods", "plugin", "plugins", "valheim", "configuration", "config", "manager", "command", "commands", "data", "world", "expand", "json", "yaml", "dotnet", "detector" }; private static int _terminalInitDepth; internal static void EnterTerminalInit() { _terminalInitDepth++; } internal static void ExitTerminalInit() { _terminalInitDepth = Mathf.Max(0, _terminalInitDepth - 1); } internal static void Record(ConsoleCommand command) { if (command != null && !string.IsNullOrWhiteSpace(command.Command)) { string value = DetectOwner(command.Command); if (!string.IsNullOrWhiteSpace(value)) { Owners[command.Command] = value; } } } internal static string GetOwner(string commandName) { if (!string.IsNullOrWhiteSpace(commandName) && Owners.TryGetValue(commandName, out string value)) { return value; } return InferOwner(commandName); } private static string DetectOwner(string commandName) { string text = InferOwnerFromExplicitCommandName(commandName); if (!string.IsNullOrWhiteSpace(text)) { return text; } StackTrace stackTrace = new StackTrace(fNeedFileInfo: false); bool flag = _terminalInitDepth > 0; Assembly executingAssembly = Assembly.GetExecutingAssembly(); for (int i = 0; i < stackTrace.FrameCount; i++) { Assembly assembly = (stackTrace.GetFrame(i)?.GetMethod())?.DeclaringType?.Assembly; if (assembly == null) { continue; } string text2 = assembly.GetName().Name ?? ""; if (text2.Equals("assembly_valheim", StringComparison.OrdinalIgnoreCase)) { flag = true; } else if ((object)assembly != executingAssembly && !ShouldSkipAssembly(text2)) { string text3 = TryFindPluginName(assembly); if (string.IsNullOrWhiteSpace(text3)) { return text2; } if (!ShouldSkipOwner(text3)) { return text3; } } } string text4 = InferOwner(commandName); if (!string.Equals(text4, "Other Mods", StringComparison.OrdinalIgnoreCase)) { return text4; } if (!flag) { return text4; } return "Valheim"; } private static bool ShouldSkipAssembly(string assemblyName) { if (string.IsNullOrWhiteSpace(assemblyName)) { return true; } switch (assemblyName.ToLowerInvariant()) { case "0harmony": case "mscorlib": case "jotunn": case "system": case "system.core": case "unityengine": case "bepinex": case "unityengine.coremodule": return true; default: return false; } } private static bool ShouldSkipOwner(string owner) { string text = NormalizeIdentifier(owner); if (text == "jotunn" || text == "valheimmoddingjotunn") { return true; } return false; } private static string? TryFindPluginName(Assembly assembly) { string text = SafeLocation(assembly); foreach (PluginInfo value in Chainloader.PluginInfos.Values) { BaseUnityPlugin instance = value.Instance; if ((Object)(object)instance != (Object)null && (object)((object)instance).GetType().Assembly == assembly) { return value.Metadata.Name; } if (!string.IsNullOrWhiteSpace(text) && string.Equals(SafePath(value.Location), text, StringComparison.OrdinalIgnoreCase)) { return value.Metadata.Name; } } return null; } private static string InferOwner(string commandName) { string text = commandName?.Trim().ToLowerInvariant() ?? ""; if (text.Length == 0) { return "Other Mods"; } string text2 = InferOwnerFromExplicitCommandName(text); if (!string.IsNullOrWhiteSpace(text2)) { return text2; } string text3 = InferOwnerFromLoadedPlugins(text); if (!string.IsNullOrWhiteSpace(text3)) { return text3; } return "Other Mods"; } private static string? InferOwnerFromExplicitCommandName(string? commandName) { string text = commandName?.Trim().ToLowerInvariant() ?? ""; if (text.Length == 0) { return null; } if (text.StartsWith("adminqol_", StringComparison.OrdinalIgnoreCase)) { return "AdminQoL"; } if (text.StartsWith("dns:", StringComparison.OrdinalIgnoreCase) || text.StartsWith("dns_", StringComparison.OrdinalIgnoreCase)) { return "DropNSpawn"; } if (text.StartsWith("jewelcrafting", StringComparison.OrdinalIgnoreCase)) { return "Jewelcrafting"; } if (text.StartsWith("epicloot", StringComparison.OrdinalIgnoreCase) || text.StartsWith("magic", StringComparison.OrdinalIgnoreCase)) { return "Epic Loot"; } if (text.StartsWith("vnei_", StringComparison.OrdinalIgnoreCase)) { return "VNEI"; } if (text.StartsWith("esp_", StringComparison.OrdinalIgnoreCase) || string.Equals(text, "esp", StringComparison.OrdinalIgnoreCase)) { return "ESP"; } if (text.StartsWith("ew_mus", StringComparison.OrdinalIgnoreCase) || text.StartsWith("ew_music", StringComparison.OrdinalIgnoreCase)) { return "Expand World Music"; } if (text.StartsWith("ew_event", StringComparison.OrdinalIgnoreCase) || text.StartsWith("expand_events", StringComparison.OrdinalIgnoreCase)) { return "Expand World Events"; } if (text.StartsWith("ew_faction", StringComparison.OrdinalIgnoreCase) || text.StartsWith("expand_factions", StringComparison.OrdinalIgnoreCase)) { return "Expand World Factions"; } if (text.StartsWith("ew_", StringComparison.OrdinalIgnoreCase) || text.StartsWith("expand_", StringComparison.OrdinalIgnoreCase)) { return "Expand World Data"; } if (text.StartsWith("hammer_", StringComparison.OrdinalIgnoreCase) || string.Equals(text, "hammer", StringComparison.OrdinalIgnoreCase)) { return "Infinity Hammer"; } if (text.StartsWith("world_edit", StringComparison.OrdinalIgnoreCase)) { return "World Edit Commands"; } if (text.StartsWith("xray", StringComparison.OrdinalIgnoreCase)) { return "XRayVision"; } return null; } private static string? InferOwnerFromLoadedPlugins(string commandName) { string text = commandName?.Trim().ToLowerInvariant() ?? ""; if (text.Length == 0) { return null; } string normalizedCommand = NormalizeIdentifier(text); string result = null; int num = 0; foreach (PluginInfo value in Chainloader.PluginInfos.Values) { if (ShouldSkipOwner(value.Metadata.Name)) { continue; } foreach (string pluginAlias in GetPluginAliases(value)) { if (pluginAlias.Length > num && CommandStartsWithAlias(text, normalizedCommand, pluginAlias)) { result = value.Metadata.Name; num = pluginAlias.Length; } } } return result; } private static bool CommandStartsWithAlias(string command, string normalizedCommand, string alias) { if (command.StartsWith(alias, StringComparison.OrdinalIgnoreCase)) { if (command.Length != alias.Length) { return IsAliasBoundary(command[alias.Length]); } return true; } return normalizedCommand.StartsWith(alias, StringComparison.OrdinalIgnoreCase); } private static bool IsAliasBoundary(char value) { switch (value) { case ' ': case '-': case '.': case ':': case '_': return true; default: return false; } } private static IEnumerable GetPluginAliases(PluginInfo pluginInfo) { HashSet aliases = new HashSet(StringComparer.OrdinalIgnoreCase); AddAlias(pluginInfo.Metadata.Name); AddAlias(pluginInfo.Metadata.GUID); string location = pluginInfo.Location; if (!string.IsNullOrWhiteSpace(location)) { AddAlias(Path.GetFileNameWithoutExtension(location)); string fileName = Path.GetFileName(Path.GetDirectoryName(location) ?? ""); AddAlias(fileName); if (!string.IsNullOrWhiteSpace(fileName)) { int num = fileName.IndexOf('-'); if (num >= 0 && num + 1 < fileName.Length) { AddAlias(fileName.Substring(num + 1)); } } } foreach (string item in aliases) { yield return item; } void AddAlias(string? raw) { if (!string.IsNullOrWhiteSpace(raw)) { string text = NormalizeIdentifier(raw); if (text.Length >= 3 && !CommonAliasTokens.Contains(text)) { aliases.Add(text); } List list = (from token in SplitIdentifierTokens(raw).Select(NormalizeIdentifier) where token.Length >= 3 && !CommonAliasTokens.Contains(token) select token).ToList(); foreach (string item2 in list) { aliases.Add(item2); } string text2 = string.Concat(list.Select((string token) => token[0])); if (text2.Length >= 2 && !CommonAliasTokens.Contains(text2)) { aliases.Add(text2); } } } } private static IEnumerable SplitIdentifierTokens(string value) { return value.Replace('.', ' ').Replace('_', ' ').Replace('-', ' ') .Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries); } private static string NormalizeIdentifier(string value) { if (string.IsNullOrWhiteSpace(value)) { return ""; } return new string(value.Where(char.IsLetterOrDigit).Select(char.ToLowerInvariant).ToArray()); } private static string SafeLocation(Assembly assembly) { try { return SafePath(assembly.Location); } catch { return ""; } } private static string SafePath(string path) { try { return string.IsNullOrWhiteSpace(path) ? "" : Path.GetFullPath(path); } catch { return path ?? ""; } } } internal static class ConsoleCommandCatalog { private static readonly FieldInfo? CommandsField = AccessTools.Field(typeof(Terminal), "commands"); private static readonly FieldRef>? CommandsAccessor = CreateCommandsAccessor(); internal static List CaptureVisibleCommands(Console? console) { List list = new List(); FieldRef> commandsAccessor = CommandsAccessor; if (commandsAccessor == null) { AddCompatibilityCommands(list); return list; } Dictionary dictionary = commandsAccessor.Invoke(); if (dictionary == null) { AddCompatibilityCommands(list); return list; } foreach (KeyValuePair item in dictionary) { ConsoleCommand value = item.Value; if (value == null || string.IsNullOrWhiteSpace(value.Command)) { continue; } if ((Object)(object)console != (Object)null) { try { if (!value.ShowCommand((Terminal)(object)console)) { continue; } } catch { continue; } } string text = ConsoleCommandOwnership.GetOwner(value.Command); if (string.Equals(text, "Other Mods", StringComparison.OrdinalIgnoreCase) && IsLikelyValheimCommand(value.Command)) { text = "Valheim"; } list.Add(new CommandEntry(value.Command, value.Description ?? "", text)); } AddCompatibilityCommands(list); return list; } private static FieldRef>? CreateCommandsAccessor() { if (!(CommandsField == null)) { return AccessTools.StaticFieldRefAccess>(CommandsField); } return null; } internal static int OwnerSortWeight(string owner) { if (string.Equals(owner, "Valheim", StringComparison.OrdinalIgnoreCase)) { return 0; } if (string.Equals(owner, "AdminQoL", StringComparison.OrdinalIgnoreCase)) { return 1; } if (string.Equals(owner, "Other Mods", StringComparison.OrdinalIgnoreCase)) { return 1000; } return 10; } private static void AddCompatibilityCommands(List entries) { AddCreatureLevelControlCommands(entries); } private static void AddCreatureLevelControlCommands(List entries) { if (IsPluginLoaded("org.bepinex.plugins.creaturelevelcontrol")) { entries.Add(new CommandEntry("cllc", "Show Creature Level & Loot Control command help.", "Creature Level & Loot Control")); entries.Add(new CommandEntry("cllc killall", "Remove all nearby creatures.", "Creature Level & Loot Control")); entries.Add(new CommandEntry("cllc killhighstars", "Remove nearby creatures with at least the given stars. Optional: [stars], default 6.", "Creature Level & Loot Control")); entries.Add(new CommandEntry("cllc worldlevel", "Display the current world level.", "Creature Level & Loot Control")); entries.Add(new CommandEntry("cllc sectorkills", "Display creatures killed in the current sector.", "Creature Level & Loot Control")); entries.Add(new CommandEntry("cllc resetsector", "Reset nearby creature sectors.", "Creature Level & Loot Control")); entries.Add(new CommandEntry("cllc starchance", "Display current star chances. Optional: [creature].", "Creature Level & Loot Control")); entries.Add(new CommandEntry("cllc spawn", "Spawn a creature. Args: [creature] [level] [affix] [extraeffect] [infusion].", "Creature Level & Loot Control")); } } private static bool IsPluginLoaded(string guid) { return Chainloader.PluginInfos.Values.Any((PluginInfo pluginInfo) => string.Equals(pluginInfo.Metadata.GUID, guid, StringComparison.OrdinalIgnoreCase)); } private static bool IsLikelyValheimCommand(string command) { return new string[25] { "help", "devcommands", "debugmode", "spawn", "itemset", "god", "fly", "ghost", "freefly", "save", "ping", "kick", "ban", "unban", "banned", "resetknownitems", "resetcharacter", "resetplayerprefs", "setkey", "removekey", "resetkeys", "players", "fov", "info", "gc" }.Any((string hint) => string.Equals(command, hint, StringComparison.OrdinalIgnoreCase)); } } internal static class ConsolePanelConfig { internal const string PanelSection = "3 - Console Panel"; internal const string FavoritesSection = "4 - Console Panel Favorites"; } internal static class ConsolePanelLayout { internal const int MaxFavoriteTabs = 5; internal const int CanvasSortingOrder = 5000; internal const int UiLayer = 5; internal const float DefaultPanelWidth = 900f; internal const float DefaultPanelHeight = 450f; internal const float DefaultVanillaConsoleBottomOffset = 120f; internal const float PanelLeft = 5f; internal const float RowHeight = 30f; internal const float ScrollbarWidth = 2f; internal const float ScrollSensitivity = 240f; internal const float CommandRefreshSeconds = 3f; internal const float PanelGapBelowConsole = 30f; internal const float CategoryWidth = 150f; internal const float MinPanelWidth = 360f; internal const float MinPanelHeight = 180f; internal const float MinCategoryWidth = 80f; internal const float MaxCategoryWidthRatio = 0.45f; internal const float Gutter = 8f; internal const float MinCommandHeaderWidth = 160f; internal const float SearchReservedWidth = 180f; internal const float SearchExtraWidth = 120f; internal const float SearchMinWidth = 150f; internal const float FavoriteActionSpacing = 3f; internal const float FavoriteActionButtonWidth = 20f; internal const float CompactButtonMinWidth = 14f; internal const float CompactButtonPreferredWidth = 18f; internal const float VirtualCommandPadding = 4f; internal const float VirtualCommandSpacing = 4f; internal const int VirtualCommandLookBehindRows = 2; internal const int VirtualCommandLookAheadRows = 6; internal const int ManualClickSuppressionFrames = 3; } internal static class ConsolePanelInputBlock { private static readonly FieldRef? MouseCaptureAccessor = CreateMouseCaptureAccessor(); private static bool _active; private static bool _hasStoredMouseCapture; private static bool _previousMouseCapture; internal static bool IsActive => _active; internal static void SetActive(bool active, bool releaseMouseCapture = false) { if (_active == active) { if (active && releaseMouseCapture) { ApplyMouseCaptureBlock(); } else if (active) { RestoreMouseCapture(); } } else { _active = active; if (active && releaseMouseCapture) { ApplyMouseCaptureBlock(); } else { RestoreMouseCapture(); } } } private static void ApplyMouseCaptureBlock() { GameCamera instance = GameCamera.instance; FieldRef mouseCaptureAccessor = MouseCaptureAccessor; if (!((Object)(object)instance == (Object)null) && mouseCaptureAccessor != null) { if (!_hasStoredMouseCapture) { _previousMouseCapture = mouseCaptureAccessor.Invoke(instance); _hasStoredMouseCapture = true; } mouseCaptureAccessor.Invoke(instance) = false; instance.UpdateMouseCapture(); } } private static void RestoreMouseCapture() { GameCamera instance = GameCamera.instance; FieldRef mouseCaptureAccessor = MouseCaptureAccessor; if ((Object)(object)instance != (Object)null && mouseCaptureAccessor != null && _hasStoredMouseCapture) { mouseCaptureAccessor.Invoke(instance) = _previousMouseCapture; instance.UpdateMouseCapture(); } _hasStoredMouseCapture = false; } private static FieldRef? CreateMouseCaptureAccessor() { FieldInfo fieldInfo = AccessTools.Field(typeof(GameCamera), "m_mouseCapture"); if (!(fieldInfo == null)) { return AccessTools.FieldRefAccess(fieldInfo); } return null; } } internal static class ConsolePanelModule { private sealed class ConfigurationManagerAttributes { public int? Order { get; set; } } internal static ConfigEntry PanelWidth; internal static ConfigEntry PanelHeight; internal static ConfigEntry VanillaConsoleBottomOffset; internal static ConfigEntry ReleaseMouseCursor; internal static ConfigEntry TogglePanelKey; internal static ConfigEntry VisualStyle; internal static ConfigEntry FavoriteTabCount; internal static ConfigEntry[] FavoriteTabCommands; private static ConfigFile? ConfigFile; private static ConsolePanelController? Controller; internal static void Initialize(GameObject host, ConfigFile config) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Expected O, but got Unknown UnsubscribeFavoriteConfigEvents(); ConfigFile = config; VisualStyle = config.Bind("3 - Console Panel", "Panel Visual Style", PanelVisualStyle.Modern, OrderedDescription("Visual style for ConsolePanel. Off disables ConsolePanel entirely, Wood uses Valheim-style wood panels, Modern uses ConfigurationManager-like flat panels.", 600)); TogglePanelKey = config.Bind("3 - Console Panel", "Toggle Panel Key", new KeyboardShortcut((KeyCode)287, Array.Empty()), OrderedDescription("Keyboard shortcut that toggles ConsolePanel while Valheim's F5 console is visible.", 500)); PanelWidth = config.Bind("3 - Console Panel", "Panel Width", 900f, OrderedDescription("Width of the command browser panel.", 400)); PanelHeight = config.Bind("3 - Console Panel", "Panel Height", 450f, OrderedDescription("Maximum height of the command browser panel. The panel shrinks if needed to preserve the fixed gap below the console.", 300)); VanillaConsoleBottomOffset = config.Bind("3 - Console Panel", "Vanilla Console Bottom Offset", 120f, OrderedDescription("Bottom Y offset applied to Valheim's own console rect while the console panel is visible.", 200)); ReleaseMouseCursor = config.Bind("3 - Console Panel", "Release Mouse Cursor", true, OrderedDescription("Unlock and show the mouse cursor while the F5 console panel is visible so category, command, and favorite buttons can be clicked.", 100)); FavoriteTabCount = config.Bind("4 - Console Panel Favorites", "Favorite Tab Count", 3, new ConfigDescription("Number of numbered favorite command tabs to show.", (AcceptableValueBase)(object)new AcceptableValueRange(1, 5), Array.Empty())); FavoriteTabCommands = new ConfigEntry[5]; for (int i = 0; i < 5; i++) { FavoriteTabCommands[i] = config.Bind("4 - Console Panel Favorites", $"Favorite {i + 1} Commands", "", $"Pipe-separated favorite console commands for numbered favorite tab {i + 1}."); } FavoriteTabCount.SettingChanged += OnFavoriteConfigSettingChanged; for (int j = 0; j < 5; j++) { FavoriteTabCommands[j].SettingChanged += OnFavoriteConfigSettingChanged; } if ((Object)(object)Controller == (Object)null) { Controller = host.AddComponent(); } } internal static void Shutdown() { UnsubscribeFavoriteConfigEvents(); if ((Object)(object)Controller != (Object)null) { Object.Destroy((Object)(object)Controller); Controller = null; } ConfigFile = null; } private static void OnFavoriteConfigSettingChanged(object sender, EventArgs args) { Controller?.OnFavoriteConfigChanged(); } private static void UnsubscribeFavoriteConfigEvents() { if (FavoriteTabCommands == null) { return; } if (FavoriteTabCount != null) { FavoriteTabCount.SettingChanged -= OnFavoriteConfigSettingChanged; } for (int i = 0; i < FavoriteTabCommands.Length; i++) { ConfigEntry val = FavoriteTabCommands[i]; if (val != null) { val.SettingChanged -= OnFavoriteConfigSettingChanged; } } } internal static void UpdateConfigWithoutImmediateSave(Func update) { if (ConfigFile != null) { bool saveOnConfigSet = ConfigFile.SaveOnConfigSet; ConfigFile.SaveOnConfigSet = false; try { if (update()) { ConfigFile.Save(); } return; } finally { ConfigFile.SaveOnConfigSet = saveOnConfigSet; } } update(); } private static ConfigDescription OrderedDescription(string description, int order) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown return new ConfigDescription(description, (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = order } }); } } [HarmonyPatch] internal static class ConsoleCommandConstructorPatch { private static IEnumerable TargetMethods() { return typeof(ConsoleCommand).GetConstructors(BindingFlags.Instance | BindingFlags.Public); } private static void Postfix(ConsoleCommand __instance) { ConsoleCommandOwnership.Record(__instance); } } [HarmonyPatch(typeof(Terminal), "InitTerminal")] internal static class TerminalInitPatch { private static void Prefix() { ConsoleCommandOwnership.EnterTerminalInit(); } private static Exception? Finalizer(Exception? __exception) { ConsoleCommandOwnership.ExitTerminalInit(); return __exception; } } [HarmonyPatch(typeof(Console), "Update")] internal static class ConsoleUpdateLayoutPatch { [HarmonyPriority(800)] private static void Postfix() { ConsolePanelController.ApplyAfterVanillaConsoleUpdate(); } } [HarmonyPatch(typeof(TMP_InputField), "ActivateInputField")] internal static class ConsoleInputActivatePatch { private static bool Prefix(TMP_InputField __instance) { return !ConsolePanelController.ShouldBlockConsoleInputActivation(__instance); } } [HarmonyPatch(typeof(Player), "TakeInput")] internal static class PlayerTakeInputPatch { private static void Postfix(ref bool __result) { if (ConsolePanelInputBlock.IsActive) { __result = false; } } } [HarmonyPatch(typeof(PlayerController), "TakeInput")] internal static class PlayerControllerTakeInputPatch { private static void Postfix(ref bool __result) { if (ConsolePanelInputBlock.IsActive) { __result = false; } } } [HarmonyPatch(typeof(TextInput), "IsVisible")] internal static class ConsolePanelTextInputVisiblePatch { private static void Postfix(ref bool __result) { if (ConsolePanelInputBlock.IsActive && ConsolePanelModule.ReleaseMouseCursor.Value) { __result = true; } } } internal sealed class ConsolePanelController : MonoBehaviour { private enum SurfaceRole { Panel, Header, Search, Scroll, MutedInfo, Button, FavoriteBar, Tooltip, ScrollbarBackground, ScrollbarHandle } private sealed class CommandRowView { private readonly ConsolePanelController _owner; private readonly Button _commandButton; private readonly TextMeshProUGUI? _commandLabel; private readonly Transform _actionsTransform; private readonly LayoutElement _actionElement; private readonly List