Decompiled source of ConsoleMod v1.0.0

BepInEx/plugins/ModConsole/HowToFish.ModConsole.dll

Decompiled 3 hours ago
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<string> list = new List<string>();
		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<string[], string> 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<string, CommandDefinition> _lookup = new Dictionary<string, CommandDefinition>(StringComparer.OrdinalIgnoreCase);

	private readonly Dictionary<long, CommandDefinition> _registrations = new Dictionary<long, CommandDefinition>();

	private long _nextId;

	internal IDisposable Register(string ownerGuid, string name, string description, string usage, Func<string[], string> 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<string>()).Where((string alias) => !string.IsNullOrWhiteSpace(alias)).Select(NormalizeName).Distinct<string>(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, string>((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, string>((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<KeyCode> _toggleKey;

	private readonly ConfigEntry<int> _maxLines;

	private readonly List<string> _lines = new List<string>();

	private readonly List<string> _history = new List<string>();

	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<KeyCode> toggleKey, ConfigEntry<int> 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<GUILayoutOption>());
		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<GUILayoutOption>());
		}
		if (_scrollToBottom && (int)Event.current.type == 7)
		{
			_scroll.y = float.MaxValue;
			_scrollToBottom = false;
		}
		GUILayout.EndScrollView();
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		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<PendingLine> PendingLines = new ConcurrentQueue<PendingLine>();

	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<string[], string> 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<string, string> 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<IDisposable> _registrations = new List<IDisposable>();

	private ConfigEntry<KeyCode> _toggleKey;

	private ConfigEntry<int> _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<KeyCode>("Console", "Tecla", (KeyCode)96, "Key used to open and close Console Mod.");
		_maxLines = ((BaseUnityPlugin)this).Config.Bind<int>("Console", "MaximoDeLinhas", 250, new ConfigDescription("Maximum number of lines kept on screen.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(50, 1000), Array.Empty<object>()));
		_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 <text>", (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, string>((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<string> list = new List<string>();
		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);
	}
}