Decompiled source of Custom Commands v1.0.1

CustomCommandsFramework.dll

Decompiled a month ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using CustomCommandsFramework;
using HarmonyLib;
using Il2CppFishNet;
using Il2CppScheduleOne;
using Il2CppScheduleOne.AvatarFramework.Customization;
using Il2CppScheduleOne.DevUtilities;
using Il2CppScheduleOne.PlayerScripts;
using Il2CppScheduleOne.UI;
using Il2CppScheduleOne.UI.MainMenu;
using Il2CppScheduleOne.UI.Settings;
using Il2CppSystem.Collections.Generic;
using Il2CppTMPro;
using MelonLoader;
using MelonLoader.Preferences;
using MelonLoader.Utils;
using Newtonsoft.Json;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(global::CustomCommandsFramework.CustomCommandsFramework), "Custom Commands Framework", "1.1.1", "Cubandsweety", null)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: MelonColor(255, 100, 0, 255)]
[assembly: MelonAuthorColor(255, 0, 255, 0)]
[assembly: AssemblyTitle("CustomCommandsFramework")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("CustomCommandsFramework")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("54b45064-bd91-4967-91a7-9684f6a5fbbc")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace CustomCommandsFramework;

internal static class AutoRegisterCommands
{
	internal static void RegisterCommands()
	{
		Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
		for (int i = 0; i < assemblies.Length; i++)
		{
			foreach (Type safeType in CustomCommandsHelper.GetSafeTypes(assemblies[i]))
			{
				RegisterCommandsFromType(safeType);
			}
		}
	}

	private static void RegisterCommandsFromType(Type type)
	{
		MethodInfo[] methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
		foreach (MethodInfo methodInfo in methods)
		{
			CustomCommandAttribute customAttribute = methodInfo.GetCustomAttribute<CustomCommandAttribute>();
			if (customAttribute == null)
			{
				continue;
			}
			if (string.IsNullOrWhiteSpace(customAttribute.Command))
			{
				Logs.LogWarning("Skipped registering method '" + methodInfo.Name + "' due to empty command name.");
				continue;
			}
			try
			{
				TryRegisterMethod(customAttribute, methodInfo);
			}
			catch (Exception ex)
			{
				Logs.LogError("Failed to register command '" + methodInfo.Name + "' in type '" + type.FullName + "': " + ex.Message + ".");
			}
		}
	}

	private static void TryRegisterMethod(CustomCommandAttribute attr, MethodInfo method)
	{
		ParameterInfo[] parameters = method.GetParameters();
		try
		{
			string modNameFromType = CustomCommandsHelper.GetModNameFromType(method.DeclaringType);
			if (parameters.Length == 1 && parameters[0].ParameterType == typeof(string))
			{
				Action<string> action2 = (Action<string>)Delegate.CreateDelegate(typeof(Action<string>), method);
				CommandRegistry.AddCustomCommandHint(attr.Command, modNameFromType, attr.Example, attr.Description, attr.Log);
				CommandRegistry.AddCustomCommand(attr.Command, action2, modNameFromType, attr.Log);
				return;
			}
			if (parameters.Length == 0)
			{
				Action action = (Action)Delegate.CreateDelegate(typeof(Action), method);
				CommandRegistry.AddCustomCommandHint(attr.Command, modNameFromType, attr.Example, attr.Description, attr.Log);
				CommandRegistry.AddCustomCommand(attr.Command, delegate
				{
					action();
				}, modNameFromType, attr.Log);
				return;
			}
			Logs.LogWarning("Invalid parameter setup in method '" + method.Name + "' for custom command '" + attr.Command + "' for mod '" + modNameFromType + "'.");
		}
		catch (Exception ex)
		{
			Logs.LogError("Failed to register method '" + method.Name + "' for command '" + attr.Command + "': " + ex.Message + ".");
		}
	}
}
[HarmonyPatch]
internal static class BindPatch
{
	[HarmonyPatch(typeof(Bind), "Execute")]
	[HarmonyPrefix]
	private static bool Execute(List<string> args)
	{
		//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
		if (args.Contains("consolekey") || args.Contains("bind"))
		{
			CustomNotification.ShowNotification("<b>" + CustomCommandsHelper.SetModPrefix() + " <color=red>Invalid command:</color> Cannot bind current command.</b>");
			Logs.LogWarning("Cannot bind current command.");
			return false;
		}
		string text = args.ToArray()[0];
		string text2 = string.Join(" ", ((IEnumerable<string>)args.ToArray()).Skip(1));
		if (!CustomCommandsHelper.IsValidCommand(text2))
		{
			CustomNotification.ShowNotification("<b>" + CustomCommandsHelper.SetModPrefix() + " <color=red>Invalid command:</color> Binding failed '" + text2 + "' was unknown.</b>");
			Logs.LogWarning("Binding failed '" + text2 + "' was unknown");
			return false;
		}
		if (Enum.TryParse<KeyCode>(text, ignoreCase: true, out KeyCode result))
		{
			Singleton<Console>.Instance.AddBinding(result, text2);
		}
		CustomNotification.ShowNotification("<b>" + CustomCommandsHelper.SetModPrefix() + " <color=green>Binding</color> key <color=orange>'" + text + "'</color> to '" + text2 + "'</b>");
		Logs.LogSuccess("Binding key '" + text + "' to command '" + text2 + "'");
		return true;
	}
}
[HarmonyPatch]
internal static class CharacterCreatorPatch
{
	private static bool wasEnabled;

	[HarmonyPatch(typeof(CharacterCreator), "Done")]
	[HarmonyPrefix]
	private static bool Done()
	{
		if (wasEnabled)
		{
			return true;
		}
		wasEnabled = true;
		SettingsScreenPatch.EnableConsole();
		return true;
	}
}
[HarmonyPatch]
internal static class ClearBindsPatch
{
	[HarmonyPatch(typeof(ClearBinds), "Execute")]
	[HarmonyPrefix]
	private static bool Execute(List<string> args)
	{
		CustomBinds.ClearBinds();
		return true;
	}
}
internal static class Command
{
	internal const string KEY_COMMAND_NAME = "consolekey";

	internal const string LOG_COMMAND_NAME = "logcustomcommands";

	[CustomCommand("consolekey", "consolekey f2", "Changes the console key bind.", false)]
	private static void SetConsoleKey(string args)
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		if (args.Length == 0)
		{
			CustomNotification.ShowNotification($"<b>{CustomCommandsHelper.SetModPrefix()} Current Console Key: <color=orange>'{CustomCommandsFramework.ConsoleKey.Value}'</color>.</b>", 0f, 7.5f);
			Logs.LogInfo($"Current Console Key: '{CustomCommandsFramework.ConsoleKey.Value}'.");
			return;
		}
		string[] array = args.Trim().Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
		if (array.Length > 1)
		{
			CustomNotification.ShowNotification("<b>" + CustomCommandsHelper.SetModPrefix() + " <color=red>Invalid command.</color> \nPlease specify a key. \nExample: consolekey <color=orange>'f2'</color>.</b>", 0f, 7.5f);
			Logs.LogWarning("Invalid command. Please specify a key. Example: consolekey 'f2'.");
			return;
		}
		string text = array[0];
		if (CustomConsoleKeys.KeyAliases.TryGetValue(text, out var value))
		{
			CustomConsoleKeys.SetKey(value);
			return;
		}
		if (Enum.TryParse<KeyCode>(text, ignoreCase: true, out KeyCode result))
		{
			CustomConsoleKeys.SetKey(result);
			return;
		}
		CustomNotification.ShowNotification("<b>" + CustomCommandsHelper.SetModPrefix() + " <color=red>Invalid console key:</color> <color=orange>'" + text + "'</color>.</b>", 0f, 7.5f);
		Logs.LogWarning("Invalid console key: '" + text + "'.");
	}

	[CustomCommand("logcustomcommands", "logcustomcommands", "Logs all custom commands registered via the framework in the MelonLoader console.", false)]
	private static void LogConsoleCommands()
	{
		Logs.LogRegisteredCommands();
	}
}
[HarmonyPatch]
internal static class CommandListScreenPatch
{
	private static bool hasTriggered;

	[HarmonyPatch(typeof(CommandListScreen), "Start")]
	[HarmonyPostfix]
	private static void Start(CommandListScreen __instance)
	{
		if (hasTriggered || !Object.op_Implicit((Object)(object)__instance))
		{
			return;
		}
		hasTriggered = true;
		ScrollRect componentInChildren = ((Component)__instance).GetComponentInChildren<ScrollRect>();
		if (!Object.op_Implicit((Object)(object)componentInChildren) || !Object.op_Implicit((Object)(object)componentInChildren.content))
		{
			Logs.LogError("Could not find ScrollRect or content for CommandListScreen!");
			return;
		}
		Transform content = (Transform)(object)componentInChildren.content;
		if (!Object.op_Implicit((Object)(object)__instance.CommandEntryPrefab))
		{
			Logs.LogError("CommandEntryPrefab is null!");
			return;
		}
		RegisterAllHints(__instance, content);
		DestroyDuplicateCommandListUI(content);
		UpdateText(__instance);
	}

	private static void RegisterAllHints(CommandListScreen instance, Transform content)
	{
		foreach (CustomCommandsData registeredCommandHint in CommandRegistry.RegisteredCommandHints)
		{
			try
			{
				RectTransform val = Object.Instantiate<RectTransform>(instance.CommandEntryPrefab, content);
				if (!Object.op_Implicit((Object)(object)val))
				{
					Logs.LogError("Failed to instantiate command entry for: " + registeredCommandHint.Command + "!");
					continue;
				}
				((Object)val).name = ((registeredCommandHint.Command != null) ? (registeredCommandHint.Command + "_CCF") : "CommandEntry(Clone)");
				Transform transform = ((Component)val).transform;
				SetText(transform, "Command", registeredCommandHint.Command);
				SetText(transform, "Example", registeredCommandHint.Example);
				SetText(transform, "Description", registeredCommandHint.Description);
			}
			catch (Exception arg)
			{
				Logs.LogError($"Error adding command entry: {arg}.");
			}
		}
	}

	private static void SetText(Transform parent, string name, string value)
	{
		Transform obj = parent.Find(name);
		TextMeshProUGUI val = ((obj != null) ? ((Component)obj).GetComponent<TextMeshProUGUI>() : null);
		if (Object.op_Implicit((Object)(object)val))
		{
			((TMP_Text)val).text = value;
		}
	}

	private static void UpdateText(CommandListScreen instance)
	{
		Transform val = ((Component)instance).transform.GetChild(1);
		if (!Object.op_Implicit((Object)(object)val))
		{
			val = ((Component)instance).transform.Find("Title");
		}
		if (!Object.op_Implicit((Object)(object)val))
		{
			Logs.LogError("CommandListScreen Title is null!");
			return;
		}
		TextMeshProUGUI component = ((Component)val).GetComponent<TextMeshProUGUI>();
		if (!(((TMP_Text)component).text == "<color=#6400FF>Custom Console Commands</color>"))
		{
			((TMP_Text)component).text = "<color=#6400FF>Custom Console Commands</color>";
		}
	}

	private static void DestroyDuplicateCommandListUI(Transform content)
	{
		HashSet<string> hashSet = new HashSet<string>();
		for (int num = content.childCount - 1; num >= 0; num--)
		{
			Transform child = content.GetChild(num);
			Transform obj = child.Find("Command");
			TextMeshProUGUI val = ((obj != null) ? ((Component)obj).GetComponent<TextMeshProUGUI>() : null);
			if (Object.op_Implicit((Object)(object)val))
			{
				string item = ((TMP_Text)val).text.Trim();
				if (!hashSet.Add(item))
				{
					Object.Destroy((Object)(object)((Component)child).gameObject);
				}
			}
		}
	}

	internal static void Reset()
	{
		hasTriggered = false;
	}
}
public static class CommandRegistry
{
	internal static readonly List<CustomCommandsData> RegisteredCommandHints = new List<CustomCommandsData>();

	internal static readonly Dictionary<string, Action<string>> RegisteredCommands = new Dictionary<string, Action<string>>();

	private static bool hasLogged;

	public static void AddCustomCommandHint(string command, string example = null, string description = null, bool log = false)
	{
		try
		{
			string callingModName = CustomCommandsHelper.GetCallingModName();
			if (string.IsNullOrWhiteSpace(command))
			{
				Logs.LogWarning("Cannot register a command hint with a null or empty name for '" + callingModName + "'.");
				return;
			}
			string key = command.ToLowerInvariant();
			if (RegisteredCommandHints.Any((CustomCommandsData hint) => hint.Command.Equals(key, StringComparison.InvariantCultureIgnoreCase)))
			{
				Logs.LogWarning("Command Hint '" + command + "' is already registered, but '" + callingModName + "' tried to add it.");
				return;
			}
			RegisteredCommandHints.Add(new CustomCommandsData
			{
				Command = key,
				Example = example,
				Description = description,
				RegisteredBy = callingModName
			});
			if (log)
			{
				Logs.LogSuccess("Loaded Command Hint - \n\n   • Command Name: '" + command + "' \n   • Example: '" + example + "' \n   • Description: '" + description + "' \n   • Mod Name: '" + callingModName + "'.\n");
			}
		}
		catch (Exception ex)
		{
			Logs.LogError("Failed to register command hint '" + command + "' due to an unexpected error: " + ex.Message);
		}
	}

	internal static void AddCustomCommandHint(string command, string modName, string example = null, string description = null, bool log = false)
	{
		if (string.IsNullOrWhiteSpace(command))
		{
			Logs.LogWarning("Cannot register a command hint with a null or empty name for '" + modName + "'.");
			return;
		}
		string key = command.ToLowerInvariant();
		if (RegisteredCommandHints.Any((CustomCommandsData hint) => hint.Command.Equals(key, StringComparison.InvariantCultureIgnoreCase)))
		{
			Logs.LogWarning("Command Hint '" + command + "' is already registered, but '" + modName + "' tried to add it.");
			return;
		}
		RegisteredCommandHints.Add(new CustomCommandsData
		{
			Command = key,
			Example = example,
			Description = description,
			RegisteredBy = modName
		});
		if (log)
		{
			Logs.LogSuccess("Loaded Command Hint - \n\n   • Command Name: '" + command + "' \n   • Example: '" + example + "' \n   • Description: '" + description + "' \n   • Mod Name: '" + modName + "'.\n");
		}
	}

	public static void AddCustomCommand(string command, Action<string> action, bool log = false)
	{
		string callingModName = CustomCommandsHelper.GetCallingModName();
		try
		{
			if (string.IsNullOrWhiteSpace(command))
			{
				Logs.LogWarning("Cannot register a command with a null or empty name for '" + callingModName + "'.");
				return;
			}
			if (action == null)
			{
				Logs.LogWarning("Command '" + command + "' has a null handler and won't be registered for '" + callingModName + "'.");
				return;
			}
			string key = command.ToLowerInvariant();
			if (RegisteredCommands.ContainsKey(key))
			{
				Logs.LogWarning($"Command '{command}' is already registered for '{action.Method}', but '{callingModName}' tried to add it.");
				return;
			}
			RegisteredCommands[key] = action;
			if (log)
			{
				Logs.LogSuccess("Loaded Command - \n\n   • Command Name: '" + command + "' \n   • Mod Name: '" + callingModName + "'.\n");
			}
		}
		catch (Exception ex)
		{
			Logs.LogError($"Failed to register command '{command}' from mod '{callingModName}' for action '{action}' due to an unexpected error: {ex.Message}");
		}
	}

	internal static void AddCustomCommand(string command, Action<string> action, string modName, bool log = false)
	{
		try
		{
			if (string.IsNullOrWhiteSpace(command))
			{
				Logs.LogWarning("Cannot register command with a null or empty name for '" + modName + "'.");
				return;
			}
			if (action == null)
			{
				Logs.LogWarning("Command '" + command + "' has a null handler and won't be registered for '" + modName + "'.");
				return;
			}
			string key = command.ToLowerInvariant();
			if (RegisteredCommands.ContainsKey(key))
			{
				Logs.LogWarning($"Command '{command}' is already registered for '{action.Method}', but '{modName}' tried to add it.");
				return;
			}
			RegisteredCommands[key] = action;
			if (log)
			{
				Logs.LogSuccess("Loaded Command - \n\n   • Command Name: '" + command + "' \n   • Mod Name: '" + modName + "'.\n");
			}
		}
		catch (Exception ex)
		{
			Logs.LogError($"Failed to register command '{command}' from mod '{modName}' for action '{action}' due to an unexpected error: {ex.Message}");
		}
	}

	internal static bool TryHandle(string input)
	{
		if (string.IsNullOrWhiteSpace(input))
		{
			return false;
		}
		input = input.Trim().ToLowerInvariant();
		foreach (string item in RegisteredCommands.Keys.OrderByDescending((string k) => k.Length))
		{
			if (input.StartsWith(item))
			{
				Action<string> action = RegisteredCommands[item];
				string obj = ((input.Length > item.Length) ? input.Substring(item.Length).TrimStart(Array.Empty<char>()) : string.Empty);
				action?.Invoke(obj);
				return true;
			}
		}
		return false;
	}

	internal static void HandleRegisteredLog()
	{
		if (!hasLogged)
		{
			Logs.LogRegisteredCommands();
			hasLogged = true;
		}
	}
}
internal static class CustomBinds
{
	internal const string BINDS_FILENAME = "CustomCommandFrameworkBinds.json";

	internal static Dictionary<KeyCode, string> Binds = new Dictionary<KeyCode, string>();

	internal static void LoadBinds()
	{
		//IL_0064: 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)
		string text = Path.Combine(MelonEnvironment.UserDataDirectory, "CustomCommandFrameworkBinds.json");
		if (!File.Exists(text))
		{
			File.WriteAllText(text, "{}");
			return;
		}
		string text2 = File.ReadAllText(text);
		try
		{
			Dictionary<string, string> obj = JsonConvert.DeserializeObject<Dictionary<string, string>>(text2) ?? new Dictionary<string, string>();
			Binds = new Dictionary<KeyCode, string>();
			foreach (KeyValuePair<string, string> item in obj)
			{
				if (Enum.TryParse<KeyCode>(item.Key, out KeyCode result) && (int)result != 0)
				{
					Binds[result] = item.Value;
				}
			}
			LogBindCount(Binds.Count);
		}
		catch (Exception arg)
		{
			Logs.LogError($"Failed to load binds: {arg}");
			Logs.LogError("If this keeps happening, try deleting '" + text + "'.");
		}
	}

	internal static void AddBinds(KeyCode key, string command)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		if (Binds.ContainsKey(key))
		{
			Binds[key] = command;
			SaveBinds();
		}
		else
		{
			Binds.Add(key, command);
			SaveBinds();
		}
	}

	internal static void RemoveBinds(KeyCode key)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		Binds.Remove(key);
		SaveBinds();
	}

	internal static void ClearBinds()
	{
		if (Binds.Count != 0)
		{
			Binds.Clear();
			File.WriteAllText(Path.Combine(MelonEnvironment.UserDataDirectory, "CustomCommandFrameworkBinds.json"), "{}");
			CustomNotification.ShowNotification("<b>" + CustomCommandsHelper.SetModPrefix() + " All binds <color=green>cleared</color>.</b>");
			Logs.LogSuccess("All binds have been cleared!");
		}
	}

	internal static void SaveBinds()
	{
		string path = Path.Combine(MelonEnvironment.UserDataDirectory, "CustomCommandFrameworkBinds.json");
		Dictionary<string, string> dictionary = Binds.ToDictionary(delegate(KeyValuePair<KeyCode, string> kvp)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			KeyCode key = kvp.Key;
			return ((object)(KeyCode)(ref key)).ToString();
		}, (KeyValuePair<KeyCode, string> kvp) => kvp.Value);
		File.WriteAllText(path, JsonConvert.SerializeObject((object)dictionary, (Formatting)1));
	}

	private static void LogBindCount(int bindCount)
	{
		switch (bindCount)
		{
		case 0:
			break;
		case 1:
			Logs.LogSuccess($"Loaded {Binds.Count} bind!");
			break;
		default:
			Logs.LogSuccess($"Loaded {Binds.Count} binds!");
			break;
		}
	}
}
internal class CustomCommandsData
{
	public string Command;

	public string Example;

	public string Description;

	public string RegisteredBy;
}
[HarmonyPatch]
internal static class ConsolePatch
{
	private static DateTime lastChangeTime = DateTime.MinValue;

	private static readonly TimeSpan changeCooldown = TimeSpan.FromMilliseconds(500.0);

	[HarmonyPatch(typeof(Console), "Awake")]
	[HarmonyPostfix]
	private static void Awake(Console __instance)
	{
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		Dictionary<KeyCode, string> binds = CustomBinds.Binds;
		if (binds.Count == 0)
		{
			return;
		}
		foreach (KeyValuePair<KeyCode, string> item in binds)
		{
			if (!__instance.keyBindings.ContainsKey(item.Key))
			{
				__instance.keyBindings.Add(item.Key, item.Value);
			}
		}
	}

	[HarmonyPatch(typeof(Console), "SubmitCommand", new Type[] { typeof(string) })]
	[HarmonyPrefix]
	private static bool SubmitCommand(string args)
	{
		if (DateTime.Now - lastChangeTime < changeCooldown)
		{
			return true;
		}
		lastChangeTime = DateTime.Now;
		return !CommandRegistry.TryHandle(args);
	}

	[HarmonyPatch(typeof(Console), "AddBinding")]
	[HarmonyPrefix]
	private static bool AddBinding(Console __instance, KeyCode key, string command)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		CustomBinds.AddBinds(key, command);
		return true;
	}

	[HarmonyPatch(typeof(Console), "RemoveBinding")]
	[HarmonyPrefix]
	private static bool RemoveBinding(Console __instance, KeyCode key)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		CustomBinds.RemoveBinds(key);
		return true;
	}
}
[HarmonyPatch]
internal static class ConsoleUIPatch
{
	[HarmonyPatch(typeof(ConsoleUI), "Update")]
	[HarmonyPrefix]
	private static bool Prefix(ConsoleUI __instance)
	{
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		if (Input.GetKeyDown((KeyCode)96) && ((Behaviour)__instance.canvas).enabled)
		{
			return false;
		}
		if (Input.GetKeyDown(CustomCommandsFramework.ConsoleKey.Value) && !Singleton<PauseMenu>.Instance.IsPaused && !((Behaviour)__instance.canvas).enabled)
		{
			GameManager instance = NetworkSingleton<GameManager>.Instance;
			if (!Object.op_Implicit((Object)(object)instance))
			{
				return true;
			}
			if (instance.Settings.ConsoleEnabled)
			{
				__instance.SetIsOpen(true);
			}
		}
		if (!((Behaviour)__instance.canvas).enabled)
		{
			return false;
		}
		if (!Player.Local.Health.IsAlive)
		{
			__instance.SetIsOpen(false);
		}
		return true;
	}
}
[AttributeUsage(AttributeTargets.Method)]
public class CustomCommandAttribute : Attribute
{
	public string Command { get; }

	public string Example { get; }

	public string Description { get; }

	public bool Log { get; }

	public CustomCommandAttribute(string command, string example = null, string description = null, bool log = false)
	{
		Command = command;
		Example = example;
		Description = description;
		Log = log;
	}
}
internal class CustomCommandsFramework : MelonMod
{
	private readonly Harmony harmony = new Harmony("CustomCommandsFramework");

	internal static MelonPreferences_Entry<KeyCode> ConsoleKey;

	internal static MelonPreferences_Category MyCategory;

	internal static bool IsGame { get; private set; }

	public override void OnInitializeMelon()
	{
		harmony.PatchAll();
		InitializeConfig();
		AutoRegisterCommands.RegisterCommands();
		CustomConsoleKeys.CheckKeys();
		CustomBinds.LoadBinds();
		CustomCommandsHelper.CheckPossibleModConflicts();
	}

	public override void OnDeinitializeMelon()
	{
		CustomCommandsHelper.ShutDown();
		SettingsScreenPatch.ShutDown();
		CustomNotification.ShutDown();
		CommandRegistry.RegisteredCommandHints.Clear();
		CommandRegistry.RegisteredCommands.Clear();
		harmony.UnpatchSelf();
		Logs.ShutDown();
	}

	public override void OnSceneWasInitialized(int buildIndex, string sceneName)
	{
		IsGame = sceneName.Equals("Main");
		if (sceneName.Equals("Menu"))
		{
			CommandRegistry.HandleRegisteredLog();
			CommandListScreenPatch.Reset();
		}
	}

	private void InitializeConfig()
	{
		MyCategory = MelonPreferences.CreateCategory("Custom Commands Framework");
		ConsoleKey = MyCategory.CreateEntry<KeyCode>("Key", (KeyCode)96, (string)null, "Keybind to toggle the console.", false, false, (ValueValidator)null, (string)null);
		string text = Path.Combine(MelonEnvironment.UserDataDirectory, "CustomCommandsFramework.cfg");
		MyCategory.SetFilePath(text);
		if (File.Exists(text))
		{
			MyCategory.LoadFromFile(false);
		}
		else
		{
			MyCategory.SaveToFile(false);
		}
	}
}
public static class CustomCommandsHelper
{
	public const string DLLName = "CustomCommandsFramework.dll";

	public static string FormattedName { get; private set; }

	public static bool GetDLLPath()
	{
		return File.Exists(Path.Combine(MelonEnvironment.ModsDirectory, "CustomCommandsFramework.dll"));
	}

	internal static bool IsValidCommand(string command)
	{
		if (string.IsNullOrWhiteSpace(command))
		{
			return false;
		}
		string cmdKeyword = command.Split(new char[1] { ' ' })[0].Trim().ToLowerInvariant();
		if (CommandRegistry.RegisteredCommands.Keys.Any((string k) => k.Equals(cmdKeyword, StringComparison.OrdinalIgnoreCase)))
		{
			return true;
		}
		Enumerator<string, ConsoleCommand> enumerator = Console.commands.GetEnumerator();
		while (enumerator.MoveNext())
		{
			KeyValuePair<string, ConsoleCommand> current = enumerator.Current;
			if (current.Key.Equals(cmdKeyword, StringComparison.OrdinalIgnoreCase) || current.Value.CommandWord.Equals(cmdKeyword, StringComparison.OrdinalIgnoreCase))
			{
				return true;
			}
		}
		return false;
	}

	internal static string GetCallingModName()
	{
		StackTrace stackTrace = new StackTrace();
		for (int i = 2; i < stackTrace.FrameCount; i++)
		{
			Type type = stackTrace.GetFrame(i)?.GetMethod()?.DeclaringType;
			if (!(type == null))
			{
				MelonMod val = ((IEnumerable<MelonMod>)MelonTypeBase<MelonMod>.RegisteredMelons).FirstOrDefault((Func<MelonMod, bool>)((MelonMod m) => ((MelonBase)m).Info.SystemType == type || ((object)m).GetType() == type));
				if (val != null)
				{
					return ((MelonBase)val).Info.Name;
				}
			}
		}
		return "Unknown";
	}

	internal static string GetModNameFromType(Type type)
	{
		try
		{
			foreach (MelonMod registeredMelon in MelonTypeBase<MelonMod>.RegisteredMelons)
			{
				if (((MelonBase)registeredMelon).Info.SystemType.Assembly == type.Assembly || ((object)registeredMelon).GetType().Assembly == type.Assembly)
				{
					return ((MelonBase)registeredMelon).Info.Name;
				}
			}
		}
		catch (Exception ex)
		{
			Logs.LogError("Error in GetModNameFromType for type '" + type.Name + "': " + ex.Message);
		}
		return "Unknown";
	}

	internal static IEnumerable<Type> GetSafeTypes(Assembly assembly)
	{
		try
		{
			return assembly.GetTypes();
		}
		catch (ReflectionTypeLoadException ex)
		{
			return ex.Types.Where((Type t) => t != null);
		}
		catch
		{
			return Enumerable.Empty<Type>();
		}
	}

	internal static string SetModPrefix()
	{
		if (string.IsNullOrEmpty(FormattedName))
		{
			FormattedName = Regex.Replace("CustomCommandsFramework", "(?<!^)([A-Z])", " $1");
		}
		return "[<color=#6400FF>" + FormattedName + "</color>]";
	}

	internal static void CheckPossibleModConflicts()
	{
		List<string> list = (from f in Directory.EnumerateFiles(MelonEnvironment.ModsDirectory, "*", SearchOption.TopDirectoryOnly)
			where Path.GetFileName(f).IndexOf("console", StringComparison.OrdinalIgnoreCase) >= 0
			select f).ToList();
		if (list.Count != 0)
		{
			Logs.LogWarning("Possible conflict found: " + string.Join(", ", list.Select((string f) => "'" + Path.GetFileName(f) + "'")));
		}
	}

	internal static void ShutDown()
	{
		FormattedName = null;
	}
}
internal static class CustomConsoleKeys
{
	internal const KeyCode defaultKey = 96;

	internal static readonly Dictionary<string, KeyCode> KeyAliases = new Dictionary<string, KeyCode>(StringComparer.OrdinalIgnoreCase)
	{
		{
			"`",
			(KeyCode)96
		},
		{
			"tilde",
			(KeyCode)96
		},
		{
			"-",
			(KeyCode)45
		},
		{
			"=",
			(KeyCode)61
		},
		{
			"[",
			(KeyCode)91
		},
		{
			"]",
			(KeyCode)93
		},
		{
			"\\",
			(KeyCode)92
		},
		{
			";",
			(KeyCode)59
		},
		{
			"'",
			(KeyCode)39
		},
		{
			",",
			(KeyCode)44
		},
		{
			".",
			(KeyCode)46
		},
		{
			"/",
			(KeyCode)47
		}
	};

	internal static readonly List<KeyCode> BlockedKeyCodes = new List<KeyCode>
	{
		(KeyCode)323,
		(KeyCode)324,
		(KeyCode)325,
		(KeyCode)13,
		(KeyCode)271,
		(KeyCode)27
	};

	internal static void SetKey(KeyCode key)
	{
		//IL_0005: 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)
		//IL_0061: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		if (BlockedKeyCodes.Contains(key))
		{
			CustomNotification.ShowNotification($"<b>{CustomCommandsHelper.SetModPrefix()} <color=red>Invalid console key:</color> <color=orange>'{key}'</color>.</b>");
			Logs.LogWarning($"Invalid console key: '{key}'.");
			return;
		}
		CustomCommandsFramework.ConsoleKey.Value = key;
		CustomNotification.ShowNotification($"<b>{CustomCommandsHelper.SetModPrefix()} Console key set to: <color=orange>'{key}'</color>.</b>");
		Logs.LogSuccess($"Console key set to: '{key}'.");
		SettingsScreenPatch.UpdateText();
		CustomCommandsFramework.MyCategory.SaveToFile(false);
	}

	internal static void CheckKeys()
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		KeyCode value = CustomCommandsFramework.ConsoleKey.Value;
		if (!Enum.IsDefined(typeof(KeyCode), value) || BlockedKeyCodes.Contains(value))
		{
			Logs.LogWarning($"Console key '{value}' was invalid and reset to default {(object)(KeyCode)96}.");
			CustomCommandsFramework.ConsoleKey.Value = (KeyCode)96;
			CustomCommandsFramework.MyCategory.SaveToFile(false);
		}
	}
}
public static class CustomNotification
{
	[CompilerGenerated]
	private sealed class <NotificationDelay>d__3 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public float delay;

		public HintDisplay instance;

		public string message;

		public float duration;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <NotificationDelay>d__3(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<>2__current = (object)new WaitForSeconds(delay);
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				if (instance.IsOpen)
				{
					instance.QueueHint(message, duration);
					notificationCoroutine = null;
					return false;
				}
				instance.ShowHint(message, duration);
				notificationCoroutine = null;
				return false;
			}
		}

		bool IEnumerator.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			return this.MoveNext();
		}

		[DebuggerHidden]
		void IEnumerator.Reset()
		{
			throw new NotSupportedException();
		}
	}

	[CompilerGenerated]
	private sealed class <TextDelay>d__5 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public float delay;

		public NotificationsManager instance;

		public string header;

		public string message;

		public Sprite sprite;

		public float duration;

		public bool sound;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <TextDelay>d__5(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<>2__current = (object)new WaitForSeconds(delay);
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				break;
			case 2:
				<>1__state = -1;
				break;
			}
			if (instance.NotificationPrefab.activeSelf && instance.entries.Count >= 6)
			{
				<>2__current = (object)new WaitForSeconds(1f);
				<>1__state = 2;
				return true;
			}
			instance.SendNotification(header, message, sprite, duration, sound);
			textCoroutine = null;
			return false;
		}

		bool IEnumerator.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			return this.MoveNext();
		}

		[DebuggerHidden]
		void IEnumerator.Reset()
		{
			throw new NotSupportedException();
		}
	}

	private static Coroutine notificationCoroutine;

	private static Coroutine textCoroutine;

	public static void ShowNotification(string message, float delay = 0f, float duration = 5f)
	{
		//IL_0053: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Expected O, but got Unknown
		if (!CustomCommandsFramework.IsGame || string.IsNullOrEmpty(message))
		{
			return;
		}
		HintDisplay instance = Singleton<HintDisplay>.Instance;
		if (!Object.op_Implicit((Object)(object)instance))
		{
			Logs.LogError("HintDisplay.Instance is null!");
			return;
		}
		if (notificationCoroutine != null)
		{
			MelonCoroutines.Stop((object)notificationCoroutine);
			notificationCoroutine = null;
		}
		notificationCoroutine = (Coroutine)MelonCoroutines.Start(NotificationDelay(instance, message, delay, duration));
	}

	[IteratorStateMachine(typeof(<NotificationDelay>d__3))]
	private static IEnumerator NotificationDelay(HintDisplay instance, string message, float delay, float duration)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <NotificationDelay>d__3(0)
		{
			instance = instance,
			message = message,
			delay = delay,
			duration = duration
		};
	}

	public static void ShowTextNotification(string header, string message, Sprite sprite = null, float delay = 0f, float duration = 5f, bool sound = true)
	{
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Expected O, but got Unknown
		if (CustomCommandsFramework.IsGame)
		{
			NotificationsManager instance = Singleton<NotificationsManager>.Instance;
			if (!Object.op_Implicit((Object)(object)instance))
			{
				Logs.LogError("NotificationsManager.Instance is null!");
			}
			else if (textCoroutine == null)
			{
				textCoroutine = (Coroutine)MelonCoroutines.Start(TextDelay(instance, header, message, sprite, delay, duration, sound));
			}
		}
	}

	[IteratorStateMachine(typeof(<TextDelay>d__5))]
	private static IEnumerator TextDelay(NotificationsManager instance, string header, string message, Sprite sprite, float delay, float duration, bool sound)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <TextDelay>d__5(0)
		{
			instance = instance,
			header = header,
			message = message,
			sprite = sprite,
			delay = delay,
			duration = duration,
			sound = sound
		};
	}

	internal static void ShutDown()
	{
		if (notificationCoroutine != null)
		{
			MelonCoroutines.Stop((object)notificationCoroutine);
			notificationCoroutine = null;
		}
		if (textCoroutine != null)
		{
			MelonCoroutines.Stop((object)textCoroutine);
			textCoroutine = null;
		}
	}
}
internal static class Logs
{
	internal enum LogType
	{
		Error,
		Warning,
		Success,
		Info,
		None
	}

	[CompilerGenerated]
	private sealed class <DebounceLog>d__24 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public float time;

		public LogType logType;

		public string message;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <DebounceLog>d__24(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<>2__current = (object)new WaitForSecondsRealtime(SetMaxTime(time));
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				Log(logType, message);
				logCoroutine = null;
				return false;
			}
		}

		bool IEnumerator.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			return this.MoveNext();
		}

		[DebuggerHidden]
		void IEnumerator.Reset()
		{
			throw new NotSupportedException();
		}
	}

	private static readonly HashSet<string> infoLogs = new HashSet<string>();

	private static readonly HashSet<string> successLogs = new HashSet<string>();

	private static readonly HashSet<string> warningLogs = new HashSet<string>();

	private static readonly HashSet<string> errorLogs = new HashSet<string>();

	private static readonly HashSet<string> loggedMessages = new HashSet<string>();

	private static Coroutine logCoroutine;

	internal static Color ToColor(this ConsoleColor consoleColor)
	{
		return ColorTranslator.FromHtml("#6400ff");
	}

	internal static void ColoredLog(string prefix, string message, int prefixColor = 51)
	{
		MelonLogger.Msg($"\u001b[38;5;{prefixColor}m{prefix}:\u001b[38;5;57m {message}");
	}

	internal static void LogSuccess(string message, float duration = 5f)
	{
		Log(LogType.Success, message, duration);
	}

	internal static void LogInfo(string message, float duration = 5f)
	{
		Log(LogType.Info, message, duration);
	}

	internal static void LogWarning(string message, float duration = 5f)
	{
		Log(LogType.Warning, message, duration);
	}

	internal static void LogError(string message, float duration = 5f)
	{
		Log(LogType.Error, message, duration);
	}

	internal static void Log(LogType type, string message, float duration = 5f, ConsoleColor color = ConsoleColor.White)
	{
		switch (type)
		{
		case LogType.Error:
			LogOnceError(message, duration);
			break;
		case LogType.Warning:
			LogOnceWarning(message, duration);
			break;
		case LogType.Success:
			LogOnceSuccess(message, duration);
			break;
		case LogType.Info:
			LogOnceInfo(message, duration);
			break;
		case LogType.None:
			LogOnce(color, message, duration);
			break;
		default:
			throw new ArgumentOutOfRangeException("type", type, null);
		}
	}

	private static void LogOnceInfo(string message, float delaySeconds)
	{
		if (infoLogs.Add(message))
		{
			ColoredLog("Info", message);
			RemoveInfoAfterDelay(message, delaySeconds);
		}
	}

	private static async Task RemoveInfoAfterDelay(string message, float delaySeconds)
	{
		await Task.Delay(TimeSpan.FromSeconds(SetMaxTime(delaySeconds)));
		infoLogs.Remove(message);
	}

	private static void LogOnceSuccess(string message, float delaySeconds)
	{
		if (successLogs.Add(message))
		{
			ColoredLog("Success", message, 40);
			RemoveSuccessAfterDelay(message, delaySeconds);
		}
	}

	private static async Task RemoveSuccessAfterDelay(string message, float delaySeconds)
	{
		await Task.Delay(TimeSpan.FromSeconds(SetMaxTime(delaySeconds)));
		successLogs.Remove(message);
	}

	private static void LogOnceWarning(string message, float delaySeconds)
	{
		if (warningLogs.Add(message))
		{
			ColoredLog("Warning", message, 226);
			RemoveWarningAfterDelay(message, delaySeconds);
		}
	}

	private static async Task RemoveWarningAfterDelay(string message, float delaySeconds)
	{
		await Task.Delay(TimeSpan.FromSeconds(SetMaxTime(delaySeconds)));
		warningLogs.Remove(message);
	}

	private static void LogOnceError(string message, float delaySeconds)
	{
		if (errorLogs.Add(message))
		{
			ColoredLog("Error", message, 1);
			RemoveErrorAfterDelay(message, delaySeconds);
		}
	}

	private static async Task RemoveErrorAfterDelay(string message, float delaySeconds)
	{
		await Task.Delay(TimeSpan.FromSeconds(SetMaxTime(delaySeconds)));
		errorLogs.Remove(message);
	}

	private static void LogOnce(ConsoleColor color, string message, float delaySeconds)
	{
		if (loggedMessages.Add(message))
		{
			MelonLogger.Msg(color, message);
			RemoveAfterDelay(loggedMessages, message, delaySeconds);
		}
	}

	private static async Task RemoveAfterDelay(HashSet<string> logSet, string message, float delaySeconds)
	{
		await Task.Delay(TimeSpan.FromSeconds(SetMaxTime(delaySeconds)));
		logSet.Remove(message);
	}

	internal static void DelayLog(LogType logType, string message, float time)
	{
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Expected O, but got Unknown
		if (logCoroutine != null)
		{
			MelonCoroutines.Stop((object)logCoroutine);
			logCoroutine = null;
		}
		logCoroutine = (Coroutine)MelonCoroutines.Start(DebounceLog(logType, message, time));
	}

	[IteratorStateMachine(typeof(<DebounceLog>d__24))]
	private static IEnumerator DebounceLog(LogType logType, string message, float time)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <DebounceLog>d__24(0)
		{
			logType = logType,
			message = message,
			time = time
		};
	}

	private static float SetMaxTime(float time)
	{
		return Math.Max(time, 0.1f);
	}

	internal static void LogRegisteredCommands()
	{
		StringBuilder stringBuilder = new StringBuilder();
		int count = CommandRegistry.RegisteredCommands.Count;
		stringBuilder.AppendLine($"\n  =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Registered {count} command(s) =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
		if (CommandRegistry.RegisteredCommandHints.Count > 0)
		{
			foreach (CustomCommandsData item in CommandRegistry.RegisteredCommandHints.OrderBy((CustomCommandsData h) => h.Command))
			{
				stringBuilder.AppendLine("  • " + item.Command + " — " + item.Description + " (Mod: " + item.RegisteredBy + ")");
			}
		}
		stringBuilder.AppendLine($"  =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Registered {count} command(s) =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
		MelonLogger.Msg($"\u001b[38;5;57m {stringBuilder}");
	}

	internal static void ClearAllLogs()
	{
		infoLogs.Clear();
		successLogs.Clear();
		warningLogs.Clear();
		errorLogs.Clear();
		loggedMessages.Clear();
	}

	internal static void ShutDown()
	{
		ClearAllLogs();
		if (logCoroutine != null)
		{
			MelonCoroutines.Stop((object)logCoroutine);
			logCoroutine = null;
		}
	}
}
[HarmonyPatch]
internal static class PlayerPatch
{
	[HarmonyPatch(typeof(Player), "LoadVariable")]
	[HarmonyPrefix]
	private static bool Start()
	{
		SettingsScreenPatch.EnableConsole();
		return true;
	}
}
[HarmonyPatch]
internal static class SettingsScreenPatch
{
	private static TextMeshProUGUI consoleKeyText;

	[HarmonyPatch(typeof(SettingsScreen), "Start")]
	[HarmonyPostfix]
	private static void Start(SettingsScreen __instance)
	{
		if (InstanceFinder.IsHost && Player.Local.IsLocalPlayer)
		{
			EnableConsole();
			GameSettingsWindow componentInChildren = ((Component)__instance).GetComponentInChildren<GameSettingsWindow>();
			if (!componentInChildren.ConsoleToggle.isOn)
			{
				componentInChildren.ConsoleToggle.isOn = true;
			}
			FindCheckMark(componentInChildren);
			FindText(componentInChildren);
		}
	}

	private static void FindText(GameSettingsWindow gameSettingsWindow)
	{
		Transform val = ((Component)gameSettingsWindow).transform.GetChild(0).GetChild(1);
		if (!Object.op_Implicit((Object)(object)val))
		{
			val = ((Component)gameSettingsWindow).transform.Find("Console/Label (1)");
		}
		if (!Object.op_Implicit((Object)(object)val))
		{
			Logs.LogError("Console Label (1) is null!");
			return;
		}
		consoleKeyText = ((Component)val).GetComponent<TextMeshProUGUI>();
		UpdateText();
		((TMP_Text)consoleKeyText).enableWordWrapping = false;
	}

	private static void FindCheckMark(GameSettingsWindow gameSettingsWindow)
	{
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: 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)
		Transform val = ((Component)gameSettingsWindow).transform.GetChild(0).GetChild(2).GetChild(0)
			.GetChild(0);
		if (!Object.op_Implicit((Object)(object)val))
		{
			val = ((Component)gameSettingsWindow).transform.Find("Console/Toggle/Background/Checkmark");
		}
		if (!Object.op_Implicit((Object)(object)val))
		{
			Logs.LogError("Checkmark is null!");
			return;
		}
		Image component = ((Component)val).GetComponent<Image>();
		Color green = Color.green;
		if (!(((Graphic)component).color == green))
		{
			((Graphic)component).color = green;
		}
	}

	internal static void UpdateText()
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		if (Object.op_Implicit((Object)(object)consoleKeyText))
		{
			string text = $"Press <color=orange>{CustomCommandsFramework.ConsoleKey.Value}</color> to toggle the console";
			if (!(((TMP_Text)consoleKeyText).text == text))
			{
				((TMP_Text)consoleKeyText).text = text;
			}
		}
	}

	internal static void EnableConsole()
	{
		if (InstanceFinder.IsHost && Player.Local.IsLocalPlayer)
		{
			GameManager instance = NetworkSingleton<GameManager>.Instance;
			if (!Object.op_Implicit((Object)(object)instance))
			{
				Logs.LogError("GameManager.Instance is null!");
			}
			else if (!instance.Settings.ConsoleEnabled)
			{
				instance.Settings.ConsoleEnabled = true;
			}
		}
	}

	internal static void ShutDown()
	{
		consoleKeyText = null;
	}
}
[HarmonyPatch]
internal static class UnbindPatch
{
	[HarmonyPatch(typeof(Unbind), "Execute")]
	[HarmonyPrefix]
	private static bool Execute(List<string> args)
	{
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		string text = args.ToArray()[0];
		CustomNotification.ShowNotification("<b>" + CustomCommandsHelper.SetModPrefix() + " <color=red>Unbound</color> key <color=orange>'" + text + "'</color></b>");
		Logs.LogSuccess("Unbound key '" + text + "'");
		if (Enum.TryParse<KeyCode>(text, ignoreCase: true, out KeyCode result))
		{
			Singleton<Console>.Instance.RemoveBinding(result);
		}
		return true;
	}
}