using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using System.Threading; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.InputSystem; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")] [assembly: AssemblyCompany("HowToFish.ModConsole")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("HowToFish.ModConsole")] [assembly: AssemblyTitle("HowToFish.ModConsole")] [assembly: AssemblyVersion("1.0.0.0")] namespace HowToFish.ModConsole; internal static class CommandLineTokenizer { internal static bool TryTokenize(string line, out string[] tokens, out string error) { List list = new List(); StringBuilder stringBuilder = new StringBuilder(); bool flag = false; bool flag2 = false; string text = line ?? string.Empty; for (int i = 0; i < text.Length; i++) { char c = text[i]; switch (c) { case '"': flag = !flag; flag2 = true; continue; case '\\': if (i + 1 < text.Length) { char c2 = text[i + 1]; if (c2 == '"' || c2 == '\\' || char.IsWhiteSpace(c2)) { stringBuilder.Append(c2); flag2 = true; i++; continue; } } break; } if (!flag && char.IsWhiteSpace(c)) { if (flag2) { list.Add(stringBuilder.ToString()); stringBuilder.Length = 0; flag2 = false; } } else { stringBuilder.Append(c); flag2 = true; } } if (flag) { tokens = null; error = "A quoted argument was not closed."; return false; } if (flag2) { list.Add(stringBuilder.ToString()); } tokens = list.ToArray(); error = null; return true; } } internal sealed class CommandDefinition { internal long Id; internal string OwnerGuid; internal string Name; internal string Description; internal string Usage; internal string[] Aliases; internal Func Handler; } internal sealed class CommandRegistry { private sealed class Registration : IDisposable { private CommandRegistry _registry; private readonly long _id; internal Registration(CommandRegistry registry, long id) { _registry = registry; _id = id; } public void Dispose() { CommandRegistry registry = _registry; _registry = null; registry?.Remove(_id); } } private readonly object _gate = new object(); private readonly Dictionary _lookup = new Dictionary(StringComparer.OrdinalIgnoreCase); private readonly Dictionary _registrations = new Dictionary(); private long _nextId; internal IDisposable Register(string ownerGuid, string name, string description, string usage, Func handler, params string[] aliases) { string canonical = NormalizeName(name); if (string.IsNullOrWhiteSpace(ownerGuid)) { throw new ArgumentException("ownerGuid is required.", "ownerGuid"); } if (handler == null) { throw new ArgumentNullException("handler"); } string[] array = (from alias in (aliases ?? Array.Empty()).Where((string alias) => !string.IsNullOrWhiteSpace(alias)).Select(NormalizeName).Distinct(StringComparer.OrdinalIgnoreCase) where !alias.Equals(canonical, StringComparison.OrdinalIgnoreCase) select alias).ToArray(); lock (_gate) { if (_lookup.ContainsKey(canonical)) { throw new InvalidOperationException("Command '" + canonical + "' is already registered."); } string[] array2 = array; foreach (string text in array2) { if (_lookup.ContainsKey(text)) { throw new InvalidOperationException("Alias '" + text + "' is already registered."); } } CommandDefinition commandDefinition = new CommandDefinition { Id = ++_nextId, OwnerGuid = ownerGuid, Name = canonical, Description = (description ?? string.Empty), Usage = (string.IsNullOrWhiteSpace(usage) ? canonical : usage.Trim()), Aliases = array, Handler = handler }; _registrations.Add(commandDefinition.Id, commandDefinition); _lookup.Add(commandDefinition.Name, commandDefinition); array2 = commandDefinition.Aliases; foreach (string key in array2) { _lookup.Add(key, commandDefinition); } return new Registration(this, commandDefinition.Id); } } internal string Execute(string line) { if (!CommandLineTokenizer.TryTokenize(line, out var tokens, out var error)) { return "ERRO: " + error; } if (tokens.Length == 0) { return string.Empty; } CommandDefinition value; lock (_gate) { _lookup.TryGetValue(tokens[0], out value); } if (value == null) { return "Unknown command: " + tokens[0] + ". Use help."; } string[] array = new string[tokens.Length - 1]; Array.Copy(tokens, 1, array, 0, array.Length); try { return value.Handler(array) ?? string.Empty; } catch (Exception ex) { return "ERROR in " + value.Name + ": " + ex.GetBaseException().Message; } } internal CommandDefinition[] Snapshot() { lock (_gate) { return _registrations.Values.OrderBy((CommandDefinition command) => command.Name, StringComparer.OrdinalIgnoreCase).ToArray(); } } internal CommandDefinition Find(string name) { lock (_gate) { _lookup.TryGetValue(name ?? string.Empty, out var value); return value; } } internal string[] Complete(string prefix) { string value = (prefix ?? string.Empty).Trim(); lock (_gate) { return _lookup.Keys.Where((string name) => name.StartsWith(value, StringComparison.OrdinalIgnoreCase)).OrderBy((string name) => name, StringComparer.OrdinalIgnoreCase).ToArray(); } } private void Remove(long id) { lock (_gate) { if (_registrations.TryGetValue(id, out var value)) { _registrations.Remove(id); _lookup.Remove(value.Name); string[] aliases = value.Aliases; foreach (string key in aliases) { _lookup.Remove(key); } } } } private static string NormalizeName(string value) { string text = (value ?? string.Empty).Trim().ToLowerInvariant(); if (text.Length == 0) { throw new ArgumentException("Command name is required.", "value"); } string text2 = text; foreach (char c in text2) { if (!char.IsLetterOrDigit(c) && c != '_' && c != '-' && c != '.' && c != '?') { throw new ArgumentException("Invalid command name: " + text, "value"); } } return text; } } internal sealed class ConsoleOverlay : IDisposable { private const string InputControlName = "HowToFish.ModConsole.Input"; private readonly ManualLogSource _log; private readonly ConfigEntry _toggleKey; private readonly ConfigEntry _maxLines; private readonly List _lines = new List(); private readonly List _history = new List(); private readonly string _historyPath; private string _input = string.Empty; private string _historyDraft = string.Empty; private int _historyIndex; private Vector2 _scroll; private Rect _windowRect; private bool _requestFocus; private bool _scrollToBottom; private int _openedFrame = -1; private CursorLockMode _previousCursorLock; private bool _previousCursorVisible; private PlayerInput _playerInput; private bool _playerInputWasActive; private Texture2D _background; private GUIStyle _windowStyle; private GUIStyle _titleStyle; private GUIStyle _lineStyle; private GUIStyle _inputStyle; internal ConsoleOverlay(ManualLogSource log, ConfigEntry toggleKey, ConfigEntry maxLines) { _log = log; _toggleKey = toggleKey; _maxLines = maxLines; _historyPath = Path.Combine(Paths.ConfigPath, "fernando.howtofish.modconsole.history.txt"); LoadHistory(); _historyIndex = _history.Count; AddLine("Console Mod 1.0.0 ready. Type help to list commands.", "info"); } internal void Tick() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) ModConsoleApi.DrainPending(AddLine); if (Input.GetKeyDown(_toggleKey.Value)) { if (ModConsoleApi.IsOpen || !ChatManager.IsTyping) { SetOpen(!ModConsoleApi.IsOpen); } } else { _ = ModConsoleApi.IsOpen; } } internal void Draw() { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Invalid comparison between Unknown and I4 //IL_0018: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Invalid comparison between Unknown and I4 //IL_00e7: 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_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Expected O, but got Unknown //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) if (!ModConsoleApi.IsOpen) { return; } Event current = Event.current; if ((int)current.type == 4 && (current.keyCode == _toggleKey.Value || ((int)_toggleKey.Value == 96 && current.character == '`'))) { if (Time.frameCount != _openedFrame) { SetOpen(open: false); } current.Use(); if (!ModConsoleApi.IsOpen) { return; } } EnsureStyles(); if (((Rect)(ref _windowRect)).width <= 0f || ((Rect)(ref _windowRect)).height <= 0f || ((Rect)(ref _windowRect)).xMax > (float)Screen.width + 2f) { _windowRect = new Rect((float)Screen.width * 0.08f, 28f, (float)Screen.width * 0.84f, Mathf.Max(310f, (float)Screen.height * 0.54f)); } _windowRect = GUI.Window(4001890, _windowRect, new WindowFunction(DrawWindow), GUIContent.none, _windowStyle); } private void DrawWindow(int id) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Invalid comparison between Unknown and I4 //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_006d: 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_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Invalid comparison between Unknown and I4 //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Invalid comparison between Unknown and I4 //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Invalid comparison between Unknown and I4 //IL_028f: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_020a: Invalid comparison between Unknown and I4 //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Invalid comparison between Unknown and I4 //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Invalid comparison between Unknown and I4 //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Invalid comparison between Unknown and I4 //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Invalid comparison between Unknown and I4 //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Invalid comparison between Unknown and I4 Event current = Event.current; bool flag = (int)current.type == 4 && (GUI.GetNameOfFocusedControl() == "HowToFish.ModConsole.Input" || (int)current.keyCode == 27); KeyCode val = (KeyCode)(flag ? ((int)current.keyCode) : 0); GUILayout.BeginVertical(Array.Empty()); GUILayout.Label("HOW TO FISH • CONSOLE DE MODS", _titleStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(26f) }); _scroll = GUILayout.BeginScrollView(_scroll, false, true, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) }); foreach (string line in _lines) { GUILayout.Label(line, _lineStyle, Array.Empty()); } if (_scrollToBottom && (int)Event.current.type == 7) { _scroll.y = float.MaxValue; _scrollToBottom = false; } GUILayout.EndScrollView(); GUILayout.BeginHorizontal(Array.Empty()); GUILayout.Label(">", _titleStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(18f) }); GUI.SetNextControlName("HowToFish.ModConsole.Input"); string input = _input; _input = GUILayout.TextField(_input, 4096, _inputStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) }); bool flag2 = (int)_toggleKey.Value == 96 && _input == input + "`"; if (flag2) { _input = input; } GUILayout.EndHorizontal(); GUILayout.Label("Enter runs • ↑/↓ history • Tab completes • Esc closes", _lineStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(21f) }); GUILayout.EndVertical(); if (flag2) { SetOpen(open: false); current.Use(); return; } if (_requestFocus && (int)Event.current.type == 7) { GUI.FocusControl("HowToFish.ModConsole.Input"); _requestFocus = false; } if (flag) { if ((int)val == 13 || (int)val == 271) { ExecuteInput(); current.Use(); } else if ((int)val == 273) { NavigateHistory(-1); current.Use(); } else if ((int)val == 274) { NavigateHistory(1); current.Use(); } else if ((int)val == 9) { CompleteInput(); current.Use(); } else if ((int)val == 27) { SetOpen(open: false); current.Use(); } } GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref _windowRect)).width, 30f)); } internal void AddLine(string text, string level) { string text2 = (string.Equals(level, "error", StringComparison.OrdinalIgnoreCase) ? "[ERRO] " : (string.Equals(level, "warning", StringComparison.OrdinalIgnoreCase) ? "[AVISO] " : string.Empty)); string[] array = (text ?? string.Empty).Replace("\r\n", "\n").Replace('\r', '\n').Split('\n'); foreach (string text3 in array) { _lines.Add(text2 + text3); } int num = Mathf.Clamp(_maxLines.Value, 50, 1000); if (_lines.Count > num) { _lines.RemoveRange(0, _lines.Count - num); } _scrollToBottom = true; } internal void Clear() { //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) _lines.Clear(); _scroll = Vector2.zero; } private void ExecuteInput() { string text = (_input ?? string.Empty).Trim(); _input = string.Empty; _requestFocus = true; if (text.Length == 0) { return; } if (text.Length > 4096) { AddLine("Comando maior que 4.096 caracteres.", "error"); return; } AddLine("> " + text, "command"); if (_history.Count == 0 || !_history[_history.Count - 1].Equals(text, StringComparison.Ordinal)) { _history.Add(text); if (_history.Count > 100) { _history.RemoveAt(0); } SaveHistory(); } _historyIndex = _history.Count; _historyDraft = string.Empty; string text2 = ModConsoleApi.Commands.Execute(text); if (!string.IsNullOrEmpty(text2)) { AddLine(text2, text2.StartsWith("ERRO", StringComparison.OrdinalIgnoreCase) ? "error" : "info"); } } private void NavigateHistory(int direction) { if (_history.Count != 0) { if (_historyIndex == _history.Count) { _historyDraft = _input; } _historyIndex = Mathf.Clamp(_historyIndex + direction, 0, _history.Count); _input = ((_historyIndex == _history.Count) ? _historyDraft : _history[_historyIndex]); _requestFocus = true; } } private void CompleteInput() { string text = (_input ?? string.Empty).TrimStart(); int num = text.IndexOf(' '); if (num >= 0) { text = text.Substring(0, num); } string[] array = ModConsoleApi.Commands.Complete(text); if (array.Length == 1) { _input = array[0] + " "; } else if (array.Length > 1) { AddLine("Matches: " + string.Join(", ", array), "info"); } _requestFocus = true; } private void SetOpen(bool open) { if (ModConsoleApi.IsOpen != open) { if (open) { OpenSafely(); } else { CloseSafely(); } } } private void OpenSafely() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_005d: 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) CursorLockMode lockState = Cursor.lockState; bool visible = Cursor.visible; PlayerInput val = null; bool flag = false; try { try { val = GameInfo.Input; } catch (Exception ex) { _log.LogDebug((object)("Player input was not available while opening Console Mod: " + ex.Message)); } if (Object.op_Implicit((Object)(object)val)) { flag = val.inputIsActive; if (flag) { val.DeactivateInput(); } } Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; _previousCursorLock = lockState; _previousCursorVisible = visible; _playerInput = val; _playerInputWasActive = flag; _requestFocus = true; _scrollToBottom = true; _openedFrame = Time.frameCount; ModConsoleApi.SetOpen(value: true); } catch (Exception ex2) { try { if (Object.op_Implicit((Object)(object)val) && flag) { val.ActivateInput(); } } catch { } Cursor.lockState = lockState; Cursor.visible = visible; _playerInput = null; _playerInputWasActive = false; ModConsoleApi.SetOpen(value: false); _log.LogWarning((object)("Console Mod could not be opened safely: " + ex2.Message)); } } private void CloseSafely() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) try { if (Object.op_Implicit((Object)(object)_playerInput) && _playerInputWasActive) { _playerInput.ActivateInput(); } } catch (Exception ex) { _log.LogWarning((object)("Player input could not be reactivated while closing Console Mod: " + ex.Message)); } try { Cursor.lockState = _previousCursorLock; Cursor.visible = _previousCursorVisible; } catch (Exception ex2) { _log.LogWarning((object)("Cursor state could not be restored while closing Console Mod: " + ex2.Message)); } _playerInput = null; _playerInputWasActive = false; _openedFrame = -1; ModConsoleApi.SetOpen(value: false); } private void EnsureStyles() { //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) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_0047: 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_0073: Expected O, but got Unknown //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: 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_00e4: Expected O, but got Unknown //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0103: 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_011f: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Expected O, but got Unknown //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Expected O, but got Unknown //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Expected O, but got Unknown if (_windowStyle == null) { _background = new Texture2D(1, 1, (TextureFormat)4, false) { name = "ModConsole.Background", hideFlags = (HideFlags)61 }; _background.SetPixel(0, 0, new Color(0.018f, 0.024f, 0.035f, 0.96f)); _background.Apply(false, true); _windowStyle = new GUIStyle(GUI.skin.window); _windowStyle.normal.background = _background; _windowStyle.padding = new RectOffset(14, 14, 10, 12); GUIStyle val = new GUIStyle(GUI.skin.label) { fontSize = 15, fontStyle = (FontStyle)1 }; val.normal.textColor = new Color(0.38f, 0.86f, 1f); _titleStyle = val; GUIStyle val2 = new GUIStyle(GUI.skin.label) { fontSize = 13, wordWrap = true, richText = false }; val2.normal.textColor = new Color(0.87f, 0.91f, 0.94f); _lineStyle = val2; GUIStyle val3 = new GUIStyle(GUI.skin.textField) { fontSize = 14, padding = new RectOffset(8, 8, 6, 5) }; val3.normal.textColor = Color.white; val3.focused.textColor = Color.white; _inputStyle = val3; } } private void LoadHistory() { try { if (!File.Exists(_historyPath)) { return; } foreach (string item in File.ReadAllLines(_historyPath).TakeLast(100)) { if (!string.IsNullOrWhiteSpace(item) && item.Length <= 4096) { _history.Add(item); } } } catch (Exception ex) { _log.LogWarning((object)("Console history could not be loaded: " + ex.Message)); } } private void SaveHistory() { try { File.WriteAllLines(_historyPath, _history); } catch (Exception ex) { _log.LogWarning((object)("Console history could not be saved: " + ex.Message)); } } public void Dispose() { if (ModConsoleApi.IsOpen) { SetOpen(open: false); } SaveHistory(); if (Object.op_Implicit((Object)(object)_background)) { Object.Destroy((Object)(object)_background); } _background = null; } } public static class ModConsoleApi { private sealed class PendingLine { internal readonly string Text; internal readonly string Level; internal PendingLine(string text, string level) { Text = text; Level = level; } } public const int ApiVersion = 1; private const int MaxPendingLines = 2000; private const int MaxLinesPerDrain = 250; private static readonly CommandRegistry Registry = new CommandRegistry(); private static readonly ConcurrentQueue PendingLines = new ConcurrentQueue(); private static int _pendingLineCount; public static bool IsAvailable { get; private set; } public static bool IsOpen { get; private set; } internal static CommandRegistry Commands => Registry; public static IDisposable RegisterCommand(string ownerGuid, string name, string description, string usage, Func handler, params string[] aliases) { return Registry.Register(ownerGuid, name, description, usage, handler, aliases); } public static void WriteLine(string text, string level = "info") { PendingLines.Enqueue(new PendingLine(text ?? string.Empty, level ?? "info")); int num = Interlocked.Increment(ref _pendingLineCount); PendingLine result; while (num > 2000 && PendingLines.TryDequeue(out result)) { num = Interlocked.Decrement(ref _pendingLineCount); } } internal static void Attach() { IsAvailable = true; } internal static void DrainPending(Action writer) { if (writer == null) { return; } for (int i = 0; i < 250; i++) { if (!PendingLines.TryDequeue(out var result)) { break; } Interlocked.Decrement(ref _pendingLineCount); writer(result.Text, result.Level); } } internal static void Detach() { IsOpen = false; IsAvailable = false; PendingLine result; while (PendingLines.TryDequeue(out result)) { Interlocked.Decrement(ref _pendingLineCount); } } internal static void SetOpen(bool value) { IsOpen = value; } } [BepInPlugin("fernando.howtofish.modconsole", "Console Mod", "1.0.0")] [BepInProcess("How to Fish.exe")] public sealed class Plugin : BaseUnityPlugin { [HarmonyPatch(/*Could not decode attribute arguments.*/)] private static class BlockPlayerInputPatch { private static void Postfix(ref bool __result) { __result |= ModConsoleApi.IsOpen; } } [HarmonyPatch(typeof(ChatManager), "Update")] private static class BlockChatPatch { private static bool Prefix() { return !ModConsoleApi.IsOpen; } } [HarmonyPatch(typeof(EventSystem), "Update")] private static class BlockUiPatch { private static bool Prefix() { return !ModConsoleApi.IsOpen; } } public const string PluginGuid = "fernando.howtofish.modconsole"; public const string PluginName = "Console Mod"; public const string PluginVersion = "1.0.0"; private readonly List _registrations = new List(); private ConfigEntry _toggleKey; private ConfigEntry _maxLines; private ConsoleOverlay _overlay; private Harmony _harmony; private void Awake() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown //IL_00bf: Unknown result type (might be due to invalid IL or missing references) _toggleKey = ((BaseUnityPlugin)this).Config.Bind("Console", "Tecla", (KeyCode)96, "Key used to open and close Console Mod."); _maxLines = ((BaseUnityPlugin)this).Config.Bind("Console", "MaximoDeLinhas", 250, new ConfigDescription("Maximum number of lines kept on screen.", (AcceptableValueBase)(object)new AcceptableValueRange(50, 1000), Array.Empty())); _overlay = new ConsoleOverlay(((BaseUnityPlugin)this).Logger, _toggleKey, _maxLines); ModConsoleApi.Attach(); RegisterBuiltIns(); _harmony = Harmony.CreateAndPatchAll(typeof(Plugin).Assembly, "fernando.howtofish.modconsole"); ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} {1} loaded. Key: {2}.", "Console Mod", "1.0.0", _toggleKey.Value)); } private void Update() { _overlay?.Tick(); } private void OnGUI() { _overlay?.Draw(); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } for (int num = _registrations.Count - 1; num >= 0; num--) { _registrations[num].Dispose(); } _registrations.Clear(); _overlay?.Dispose(); _overlay = null; ModConsoleApi.Detach(); } private void RegisterBuiltIns() { _registrations.Add(ModConsoleApi.RegisterCommand("fernando.howtofish.modconsole", "help", "Lists commands or explains a command.", "help [command]", Help, "ajuda", "?")); _registrations.Add(ModConsoleApi.RegisterCommand("fernando.howtofish.modconsole", "clear", "Clears the visible console output.", "clear", delegate { _overlay.Clear(); return string.Empty; }, "limpar")); _registrations.Add(ModConsoleApi.RegisterCommand("fernando.howtofish.modconsole", "plugins", "Lists loaded BepInEx plugins.", "plugins [filter]", Plugins, "mods")); _registrations.Add(ModConsoleApi.RegisterCommand("fernando.howtofish.modconsole", "scene", "Shows the active and loaded scenes.", "scene", Scene, "cena")); _registrations.Add(ModConsoleApi.RegisterCommand("fernando.howtofish.modconsole", "echo", "Prints text back to the console.", "echo ", (string[] args) => string.Join(" ", args))); _registrations.Add(ModConsoleApi.RegisterCommand("fernando.howtofish.modconsole", "console", "Shows Console Mod version and API status.", "console", (string[] args) => string.Format("Console Mod {0}; API {1}; {2} registered commands.", "1.0.0", 1, ModConsoleApi.Commands.Snapshot().Length))); } private static string Help(string[] args) { if (args.Length != 0) { CommandDefinition commandDefinition = ModConsoleApi.Commands.Find(args[0]); if (commandDefinition == null) { return "Unknown command: " + args[0]; } string text = ((commandDefinition.Aliases.Length == 0) ? string.Empty : ("\nAliases: " + string.Join(", ", commandDefinition.Aliases))); return commandDefinition.Name + " — " + commandDefinition.Description + "\nUsage: " + commandDefinition.Usage + text + "\nMod: " + commandDefinition.OwnerGuid; } StringBuilder stringBuilder = new StringBuilder("Available commands:"); CommandDefinition[] array = ModConsoleApi.Commands.Snapshot(); foreach (CommandDefinition commandDefinition2 in array) { stringBuilder.Append("\n ").Append(commandDefinition2.Name.PadRight(12)).Append(" ") .Append(commandDefinition2.Description); } return stringBuilder.ToString(); } private static string Plugins(string[] args) { string filter = ((args.Length != 0) ? args[0] : string.Empty); PluginInfo[] array = Chainloader.PluginInfos.Values.Where((PluginInfo info) => string.IsNullOrEmpty(filter) || info.Metadata.Name.IndexOf(filter, StringComparison.OrdinalIgnoreCase) >= 0 || info.Metadata.GUID.IndexOf(filter, StringComparison.OrdinalIgnoreCase) >= 0).OrderBy((PluginInfo info) => info.Metadata.Name, StringComparer.OrdinalIgnoreCase).ToArray(); if (array.Length == 0) { return "No plugins found."; } return string.Join("\n", array.Select((PluginInfo info) => info.Metadata.Name + " " + info.Metadata.Version?.ToString() + " [" + info.Metadata.GUID + "]")); } private static string Scene(string[] args) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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) Scene activeScene = SceneManager.GetActiveScene(); List list = new List(); for (int i = 0; i < SceneManager.sceneCount; i++) { Scene sceneAt = SceneManager.GetSceneAt(i); list.Add(((Scene)(ref sceneAt)).name + ((sceneAt == activeScene) ? " (active)" : string.Empty)); } return "Loaded scenes: " + string.Join(", ", list); } }