Decompiled source of Emote Deck v1.1.0

plugins/Emote_Deck/Emote_Deck.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;
using UnityEngine.Events;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("Project too-many-emotes")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Project too-many-emotes")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("a36e8062-eaaf-433e-bd67-e49ec781b591")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.1.0.0")]
namespace ATLYSSEmoteDeck;

[BepInPlugin("com.eleen.atlyss.emotedeck", "Emote Deck", "1.1.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInProcess("ATLYSS.exe")]
[DefaultExecutionOrder(-9000)]
public class EmoteDeckPlugin : BaseUnityPlugin
{
	public const string PluginGuid = "com.eleen.atlyss.emotedeck";

	public const string PluginName = "Emote Deck";

	public const string PluginVersion = "1.1.0";

	public const int MaxPages = 10;

	public const int MaxSlots = 100;

	internal static EmoteDeckPlugin Instance;

	internal static ManualLogSource Log;

	internal static ConfigEntry<string> CfgMainWindowKey;

	internal static ConfigEntry<string> CfgGridWindowKey;

	internal static ConfigEntry<float> CfgMainX;

	internal static ConfigEntry<float> CfgMainY;

	internal static ConfigEntry<float> CfgMainW;

	internal static ConfigEntry<float> CfgMainH;

	internal static ConfigEntry<float> CfgMainOpacity;

	internal static ConfigEntry<float> CfgGridX;

	internal static ConfigEntry<float> CfgGridY;

	internal static ConfigEntry<float> CfgGridW;

	internal static ConfigEntry<float> CfgGridH;

	internal static ConfigEntry<float> CfgGridOpacity;

	internal static ConfigEntry<int> CfgGridColumns;

	internal static ConfigEntry<float> CfgGridIconAspect;

	internal static ConfigEntry<bool> CfgGridAutoColumns;

	internal static ConfigEntry<bool> CfgGridAutoIconAspect;

	internal static ConfigEntry<bool> CfgCloseGridAfterEmote;

	internal static ConfigEntry<string> CfgGridViewMode;

	internal static ConfigEntry<string> CfgGridMouseMode;

	internal static ConfigEntry<bool> CfgGridShowHeaderControls;

	internal static ConfigEntry<int> CfgActiveSlotCount;

	internal static ConfigEntry<bool> CfgBlockGameInputWhileMainWindowOpen;

	internal static ConfigEntry<bool> CfgBlockGameInputWhileGridWindowOpen;

	internal static ConfigEntry<bool> CfgDebugLogging;

	internal static ConfigEntry<bool> CfgIncludeNativeVanillaWhenWheelBaseExists;

	internal static ConfigEntry<string> CfgHiddenPackages;

	internal static ConfigEntry<bool> CfgEnablePages;

	internal static ConfigEntry<int> CfgPageCount;

	internal static ConfigEntry<int> CfgCurrentPage;

	internal static ConfigEntry<string>[] CfgPageSlotKeys = new ConfigEntry<string>[10];

	internal static ConfigEntry<bool> CfgEnableRecent;

	internal static ConfigEntry<int> CfgRecentLimit;

	internal static ConfigEntry<string> CfgRecentKeys;

	internal static ConfigEntry<bool> CfgEnableFavorites;

	internal static ConfigEntry<string> CfgFavoriteKeys;

	internal static ConfigEntry<bool> CfgAutoRescanEnabled;

	internal static ConfigEntry<bool> CfgPickerAutoAdvanceSlot;

	internal static ConfigEntry<bool> CfgPickerHideAssigned;

	internal static ConfigEntry<bool> CfgMigratedAutoAdvanceDefaultOff;

	internal static readonly ConfigEntry<string>[] CfgSlotEmoteKeys = new ConfigEntry<string>[100];

	private KeyCode _mainWindowKey = (KeyCode)121;

	private KeyCode _gridWindowKey = (KeyCode)116;

	private EmoteDeckWindow _window;

	private Harmony _harmony;

	private float _nextAutoRefreshTime;

	private bool _forceNextAutoRefresh;

	private bool _configSaveQueued;

	private float _configSaveAt;

	private readonly HashSet<KeyCode> _suppressedHotkeyActivations = new HashSet<KeyCode>();

	private int _suppressHotkeysUntilFrame;

	internal readonly List<EmoteEntry> AllEmotes = new List<EmoteEntry>();

	internal readonly Dictionary<string, EmoteEntry> EmotesByKey = new Dictionary<string, EmoteEntry>(StringComparer.OrdinalIgnoreCase);

	internal readonly List<string> PackageIds = new List<string>();

	internal readonly HashSet<string> HiddenPackages = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

	internal readonly string[][] PageSlotKeys = new string[10][];

	internal readonly List<string> RecentKeys = new List<string>();

	internal readonly List<string> FavoriteKeys = new List<string>();

	private int _lastRegistryFingerprint;

	private static FieldInfo _chatEmoteBufferField;

	internal bool EmoteWheelBridgeAvailable { get; private set; }

	internal int LastWheelEmoteCount { get; private set; }

	internal int LastNativeEmoteCount { get; private set; }

	internal float LastRegistryRefreshTime { get; private set; }

	internal int RegistryRevision { get; private set; }

	internal int FilterRevision { get; private set; }

	internal int RecentRevision { get; private set; }

	internal int FavoriteRevision { get; private set; }

	internal KeyCode MainWindowKey => _mainWindowKey;

	internal KeyCode GridWindowKey => _gridWindowKey;

	private void Awake()
	{
		Instance = this;
		Log = ((BaseUnityPlugin)this).Logger;
		BindConfig();
		ReloadHotkeysFromConfig();
		LoadHiddenPackagesFromConfig();
		LoadPageSlotsFromConfig();
		LoadRecentAndFavoritesFromConfig();
		RefreshEmoteRegistry();
		ScheduleAutoRescan(1f, force: false);
		TryPatchHarmonyHooks();
		_window = new EmoteDeckWindow(this);
		TrySetupEasySettingsBridge();
		Log.LogInfo((object)("[EmoteDeck] Loaded 1.1.0 mainKey=" + ((object)(KeyCode)(ref _mainWindowKey)).ToString() + " gridKey=" + ((object)(KeyCode)(ref _gridWindowKey)).ToString() + " emotes=" + AllEmotes.Count));
	}

	private void BindConfig()
	{
		CfgMainWindowKey = ((BaseUnityPlugin)this).Config.Bind<string>("Input", "MainWindowKey", "Y", "Open/close the Emote Deck main window. This key cannot be cleared from the UI.");
		CfgGridWindowKey = ((BaseUnityPlugin)this).Config.Bind<string>("Input", "GridWindowKey", "T", "Open/close the Emote Grid window. Set to None to disable the global grid hotkey.");
		CfgMainX = ((BaseUnityPlugin)this).Config.Bind<float>("MainWindow", "X", 240f, "Main window X position.");
		CfgMainY = ((BaseUnityPlugin)this).Config.Bind<float>("MainWindow", "Y", 120f, "Main window Y position.");
		CfgMainW = ((BaseUnityPlugin)this).Config.Bind<float>("MainWindow", "Width", 620f, "Main window width.");
		CfgMainH = ((BaseUnityPlugin)this).Config.Bind<float>("MainWindow", "Height", 640f, "Main window height.");
		CfgMainOpacity = ((BaseUnityPlugin)this).Config.Bind<float>("MainWindow", "ContentOpacity", 0.92f, "Opacity for main window content/background below the header. 0 = transparent, 1 = opaque.");
		CfgGridX = ((BaseUnityPlugin)this).Config.Bind<float>("GridWindow", "X", 260f, "Grid window X position.");
		CfgGridY = ((BaseUnityPlugin)this).Config.Bind<float>("GridWindow", "Y", 160f, "Grid window Y position.");
		CfgGridW = ((BaseUnityPlugin)this).Config.Bind<float>("GridWindow", "Width", 720f, "Grid window width.");
		CfgGridH = ((BaseUnityPlugin)this).Config.Bind<float>("GridWindow", "Height", 480f, "Grid window height.");
		CfgGridOpacity = ((BaseUnityPlugin)this).Config.Bind<float>("GridWindow", "Opacity", 0.88f, "Grid window content/background opacity. 0 = transparent, 1 = opaque.");
		CfgGridColumns = ((BaseUnityPlugin)this).Config.Bind<int>("GridWindow", "Columns", 8, "Column count when AutoColumns is off.");
		CfgGridIconAspect = ((BaseUnityPlugin)this).Config.Bind<float>("GridWindow", "IconAspectRatio", 1f, "Icon width/height ratio when AutoIconAspectRatio is off. 1.0 = square, 1.3 = wider, 0.8 = taller.");
		CfgGridAutoColumns = ((BaseUnityPlugin)this).Config.Bind<bool>("GridWindow", "AutoColumns", true, "Choose columns from the current grid width. This prevents clipped columns and horizontal scrolling.");
		CfgGridAutoIconAspect = ((BaseUnityPlugin)this).Config.Bind<bool>("GridWindow", "AutoIconAspectRatio", true, "Use icon cells that scale with the grid width.");
		CfgCloseGridAfterEmote = ((BaseUnityPlugin)this).Config.Bind<bool>("GridWindow", "CloseAfterEmote", true, "Close the grid window after clicking an emote.");
		CfgGridViewMode = ((BaseUnityPlugin)this).Config.Bind<string>("GridWindow", "View", "Standard", "Grid view: Standard, Compact, Mini, or Names.");
		CfgGridViewMode.Value = NormalizeGridViewModeValue(CfgGridViewMode.Value);
		CfgGridMouseMode = ((BaseUnityPlugin)this).Config.Bind<string>("GridWindow", "MouseMode", "Auto", "Grid mouse mode: Auto, Always, or Off. Auto unlocks only when Close grid after emote is on.");
		CfgGridMouseMode.Value = NormalizeGridMouseModeValue(CfgGridMouseMode.Value);
		CfgGridShowHeaderControls = ((BaseUnityPlugin)this).Config.Bind<bool>("GridWindow", "ShowHeaderControls", true, "Show the second header row in the grid window.");
		CfgActiveSlotCount = ((BaseUnityPlugin)this).Config.Bind<int>("Behavior", "ActiveSlotCount", 24, "Number of slots shown on each deck page. Range 1-100.");
		CfgBlockGameInputWhileMainWindowOpen = ((BaseUnityPlugin)this).Config.Bind<bool>("Behavior", "BlockGameInputWhileMainWindowOpen", false, "Block player movement, combat, hotbar, and interact input while the main window is open.");
		CfgBlockGameInputWhileGridWindowOpen = ((BaseUnityPlugin)this).Config.Bind<bool>("Behavior", "BlockGameInputWhileGridWindowOpen", false, "Block player movement, combat, hotbar, and interact input while the grid window is open.");
		CfgIncludeNativeVanillaWhenWheelBaseExists = ((BaseUnityPlugin)this).Config.Bind<bool>("Behavior", "IncludeNativeVanillaWhenWheelBaseExists", false, "Show native /emote commands even when Emote Wheel Base is available. Usually false avoids duplicates.");
		CfgHiddenPackages = ((BaseUnityPlugin)this).Config.Bind<string>("Filters", "HiddenPackages", "", "Semicolon-separated package IDs hidden in Picker and Grid.");
		CfgEnablePages = ((BaseUnityPlugin)this).Config.Bind<bool>("Pages", "EnablePages", false, "Enable separate Emote Deck pages. Page 1 uses the normal Slots config.");
		CfgPageCount = ((BaseUnityPlugin)this).Config.Bind<int>("Pages", "PageCount", 4, "Number of deck pages when pages are enabled. Range 1-10.");
		CfgCurrentPage = ((BaseUnityPlugin)this).Config.Bind<int>("Pages", "CurrentPage", 1, "Current deck page. Range 1-10.");
		for (int i = 1; i < 10; i++)
		{
			CfgPageSlotKeys[i] = ((BaseUnityPlugin)this).Config.Bind<string>("Pages", "Page" + (i + 1).ToString("D2", CultureInfo.InvariantCulture) + "Slots", "", "Packed slot keys for page " + (i + 1) + ".");
		}
		CfgEnableRecent = ((BaseUnityPlugin)this).Config.Bind<bool>("Recent", "EnableRecent", false, "Show a Recent grid mode.");
		CfgRecentLimit = ((BaseUnityPlugin)this).Config.Bind<int>("Recent", "RecentLimit", 24, "Maximum recent emotes to keep. Range 1-100.");
		CfgRecentKeys = ((BaseUnityPlugin)this).Config.Bind<string>("Recent", "RecentKeys", "", "Packed recent emote keys.");
		CfgEnableFavorites = ((BaseUnityPlugin)this).Config.Bind<bool>("Favorites", "EnableFavorites", false, "Show a Favorites grid mode and star buttons.");
		CfgFavoriteKeys = ((BaseUnityPlugin)this).Config.Bind<string>("Favorites", "FavoriteKeys", "", "Packed favorite emote keys.");
		CfgAutoRescanEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Behavior", "AutoRescan", true, "Rescan after windows open so new emotes can show up.");
		CfgPickerAutoAdvanceSlot = ((BaseUnityPlugin)this).Config.Bind<bool>("Behavior", "PickerAutoAdvanceSlot", false, "After setting an emote in Picker, move to the next slot automatically.");
		CfgPickerHideAssigned = ((BaseUnityPlugin)this).Config.Bind<bool>("Behavior", "PickerHideAssigned", false, "Hide emotes already assigned on the current page from Picker results.");
		CfgMigratedAutoAdvanceDefaultOff = ((BaseUnityPlugin)this).Config.Bind<bool>("Migrations", "AutoAdvanceDefaultOff_0110", false, "Internal migration flag. Do not edit.");
		if (!CfgMigratedAutoAdvanceDefaultOff.Value)
		{
			CfgPickerAutoAdvanceSlot.Value = false;
			CfgMigratedAutoAdvanceDefaultOff.Value = true;
		}
		CfgDebugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "DebugLogging", false, "Enable debug logs.");
		for (int j = 0; j < 100; j++)
		{
			string text = string.Empty;
			switch (j)
			{
			case 0:
				text = "Base:Point";
				break;
			case 1:
				text = "Base:Clap";
				break;
			case 2:
				text = "Base:Think";
				break;
			case 3:
				text = "Base:Shrug";
				break;
			case 4:
				text = "Base:Dance";
				break;
			case 5:
				text = "Base:Taunt";
				break;
			}
			CfgSlotEmoteKeys[j] = ((BaseUnityPlugin)this).Config.Bind<string>("Slots", "Slot" + (j + 1).ToString("D3", CultureInfo.InvariantCulture), text, "Emote key for slot " + (j + 1) + ". Empty = unassigned.");
		}
	}

	internal static string NormalizeGridViewModeValue(string value)
	{
		if (string.IsNullOrEmpty(value))
		{
			return "Standard";
		}
		if (string.Equals(value, "Standard", StringComparison.OrdinalIgnoreCase))
		{
			return "Standard";
		}
		if (string.Equals(value, "Compact", StringComparison.OrdinalIgnoreCase))
		{
			return "Compact";
		}
		if (string.Equals(value, "Mini", StringComparison.OrdinalIgnoreCase))
		{
			return "Mini";
		}
		if (string.Equals(value, "Names", StringComparison.OrdinalIgnoreCase))
		{
			return "Names";
		}
		if (string.Equals(value, "Names only", StringComparison.OrdinalIgnoreCase))
		{
			return "Names";
		}
		return "Standard";
	}

	internal static string GridViewModeLabel(string value)
	{
		value = NormalizeGridViewModeValue(value);
		if (value == "Names")
		{
			return "Names only";
		}
		return value;
	}

	internal static string NormalizeGridMouseModeValue(string value)
	{
		if (string.IsNullOrEmpty(value))
		{
			return "Auto";
		}
		if (string.Equals(value, "Auto", StringComparison.OrdinalIgnoreCase))
		{
			return "Auto";
		}
		if (string.Equals(value, "Always", StringComparison.OrdinalIgnoreCase))
		{
			return "Always";
		}
		if (string.Equals(value, "Off", StringComparison.OrdinalIgnoreCase))
		{
			return "Off";
		}
		if (string.Equals(value, "Never", StringComparison.OrdinalIgnoreCase))
		{
			return "Off";
		}
		return "Auto";
	}

	internal static string GridMouseModeLabel(string value)
	{
		return NormalizeGridMouseModeValue(value);
	}

	internal static bool IsBlockedMouseBindKey(KeyCode key)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0007: Invalid comparison between Unknown and I4
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Invalid comparison between Unknown and I4
		return (int)key == 323 || (int)key == 324;
	}

	internal static string KeyLabel(string value)
	{
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		if (string.IsNullOrEmpty(value))
		{
			return "None";
		}
		if (!Enum.TryParse<KeyCode>(value, ignoreCase: true, out KeyCode result))
		{
			return value;
		}
		return KeyLabel(result);
	}

	internal static string KeyLabel(KeyCode key)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0003: Invalid comparison between Unknown and I4
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Invalid comparison between Unknown and I4
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0031: Invalid comparison between Unknown and I4
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Invalid comparison between Unknown and I4
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_005b: Invalid comparison between Unknown and I4
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Invalid comparison between Unknown and I4
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Invalid comparison between Unknown and I4
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Invalid comparison between Unknown and I4
		if ((int)key == 0)
		{
			return "None";
		}
		if ((int)key == 323)
		{
			return "Left Mouse";
		}
		if ((int)key == 324)
		{
			return "Right Mouse";
		}
		if ((int)key == 325)
		{
			return "Middle Mouse";
		}
		if ((int)key == 326)
		{
			return "Mouse 4";
		}
		if ((int)key == 327)
		{
			return "Mouse 5";
		}
		if ((int)key == 328)
		{
			return "Mouse 6";
		}
		if ((int)key == 329)
		{
			return "Mouse 7";
		}
		return ((object)(KeyCode)(ref key)).ToString();
	}

	internal void SavePluginConfig()
	{
		try
		{
			_configSaveQueued = false;
			((BaseUnityPlugin)this).Config.Save();
		}
		catch (Exception ex)
		{
			Log.LogWarning((object)("[EmoteDeck] Config save failed: " + ex.Message));
		}
	}

	internal void QueueConfigSave(float delaySeconds)
	{
		if (delaySeconds < 0.05f)
		{
			delaySeconds = 0.05f;
		}
		_configSaveQueued = true;
		_configSaveAt = Time.unscaledTime + delaySeconds;
	}

	internal void QueueConfigSave()
	{
		QueueConfigSave(0.6f);
	}

	internal void ScheduleAutoRescan(float delaySeconds, bool force)
	{
		if (CfgAutoRescanEnabled != null && CfgAutoRescanEnabled.Value)
		{
			if (delaySeconds < 0.05f)
			{
				delaySeconds = 0.05f;
			}
			float num = Time.unscaledTime + delaySeconds;
			if (_nextAutoRefreshTime <= 0f || num < _nextAutoRefreshTime)
			{
				_nextAutoRefreshTime = num;
			}
			if (force)
			{
				_forceNextAutoRefresh = true;
			}
		}
	}

	private void FlushQueuedConfigSaveIfDue()
	{
		if (_configSaveQueued && Time.unscaledTime >= _configSaveAt)
		{
			SavePluginConfig();
		}
	}

	private void OnDestroy()
	{
		//IL_0004: 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_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		EmoteDeckInputBlocker.SetWindowState(mainOpen: false, default(Rect), gridOpen: false, default(Rect), blockGameplayInput: false);
		try
		{
			if (_harmony != null)
			{
				_harmony.UnpatchSelf();
				_harmony = null;
			}
		}
		catch
		{
		}
		if (_window != null)
		{
			_window.SaveOpenWindowRects();
		}
		if (_configSaveQueued)
		{
			SavePluginConfig();
		}
	}

	private void TryPatchHarmonyHooks()
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Expected O, but got Unknown
		try
		{
			if (_harmony == null)
			{
				_harmony = new Harmony("com.eleen.atlyss.emotedeck");
			}
		}
		catch (Exception ex)
		{
			Log.LogWarning((object)("[EmoteDeck] Harmony init failed. Guards were skipped: " + ex.Message));
			return;
		}
		TryPatchScrollRectOnScroll();
		TryPatchGameplayInputGuards();
	}

	private void TryPatchScrollRectOnScroll()
	{
		//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Expected O, but got Unknown
		try
		{
			Type type = FindType("UnityEngine.UI.ScrollRect");
			Type type2 = FindType("UnityEngine.EventSystems.PointerEventData");
			if (type == null || type2 == null)
			{
				Log.LogWarning((object)"[EmoteDeck] ScrollRect.OnScroll guard skipped: Unity UI/EventSystems types were not found.");
				return;
			}
			MethodInfo methodInfo = AccessTools.Method(type, "OnScroll", new Type[1] { type2 }, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(EmoteDeckScrollRectOnScrollPatch), "Prefix", (Type[])null, (Type[])null);
			if (methodInfo == null || methodInfo2 == null)
			{
				Log.LogWarning((object)"[EmoteDeck] ScrollRect.OnScroll guard skipped: method lookup failed.");
				return;
			}
			_harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			Log.LogInfo((object)"[EmoteDeck] ScrollRect.OnScroll guard patched.");
		}
		catch (Exception ex)
		{
			Log.LogWarning((object)("[EmoteDeck] ScrollRect.OnScroll guard failed and was skipped: " + ex.Message));
		}
	}

	private void TryPatchGameplayInputGuards()
	{
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0149: Expected O, but got Unknown
		try
		{
			int patched = 0;
			MethodInfo prefix = AccessTools.Method(typeof(EmoteDeckGameplayInputPatch), "Prefix", (Type[])null, (Type[])null);
			MethodInfo methodInfo = AccessTools.Method(typeof(EmoteDeckPlayerLocalParamsPatch), "Postfix", (Type[])null, (Type[])null);
			TryPatchPrefix(typeof(PlayerMove), "Handle_MovementControl", prefix, ref patched);
			TryPatchPrefix(typeof(PlayerMove), "Handle_DashControl", prefix, ref patched);
			TryPatchPrefix(typeof(PlayerMove), "Handle_JumpControl", prefix, ref patched);
			TryPatchPrefix(typeof(PlayerCasting), "Client_SkillControl", prefix, ref patched);
			TryPatchPrefix(typeof(ActionBarManager), "OnActionkeyPress", prefix, ref patched);
			TryPatchPrefix(typeof(PlayerCombat), "Client_Handle_WeaponSheatheControl", prefix, ref patched);
			TryPatchPrefix(typeof(PlayerCombat), "Client_Handle_QuickSwapWeaponControl", prefix, ref patched);
			TryPatchPrefix(typeof(PlayerCombat), "Client_Handle_CombatControl", prefix, ref patched);
			TryPatchPrefix(typeof(PlayerInteract), "Handle_InteractControl", prefix, ref patched);
			MethodInfo methodInfo2 = FindPlayerLocalParamsMethod();
			if (methodInfo2 != null && methodInfo != null)
			{
				_harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(methodInfo), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				patched++;
			}
			else
			{
				Log.LogWarning((object)"[EmoteDeck] Player._inUI postfix guard skipped: method lookup failed.");
			}
			Log.LogInfo((object)("[EmoteDeck] Gameplay input guards patched: " + patched + "."));
		}
		catch (Exception ex)
		{
			Log.LogWarning((object)("[EmoteDeck] Gameplay input guard patch failed and was skipped: " + ex.Message));
		}
	}

	private void TryPatchPrefix(Type type, string methodName, MethodInfo prefix, ref int patched)
	{
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Expected O, but got Unknown
		try
		{
			if (!(type == null) && !(prefix == null))
			{
				MethodInfo methodInfo = AccessTools.Method(type, methodName, (Type[])null, (Type[])null);
				if (methodInfo == null)
				{
					Log.LogWarning((object)("[EmoteDeck] Input guard skipped: " + type.Name + "." + methodName + " not found."));
				}
				else
				{
					_harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(prefix), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					patched++;
				}
			}
		}
		catch (Exception ex)
		{
			Log.LogWarning((object)("[EmoteDeck] Input guard failed: " + type.Name + "." + methodName + ": " + ex.Message));
		}
	}

	private static MethodInfo FindPlayerLocalParamsMethod()
	{
		try
		{
			MethodInfo[] methods = typeof(Player).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MethodInfo methodInfo in methods)
			{
				if (!(methodInfo == null))
				{
					string text = methodInfo.Name ?? string.Empty;
					if (text.IndexOf("Handle_LocalParams", StringComparison.Ordinal) >= 0)
					{
						return methodInfo;
					}
				}
			}
		}
		catch
		{
		}
		return null;
	}

	internal void ReloadHotkeysFromConfig()
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0018: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		_mainWindowKey = ParseRequiredKeyCode(CfgMainWindowKey.Value, (KeyCode)121, "MainWindowKey");
		_gridWindowKey = ParseOptionalKeyCode(CfgGridWindowKey.Value, "GridWindowKey");
	}

	private void TrySetupEasySettingsBridge()
	{
		EmoteDeckEasySettingsBridge.TryInstall(this);
		((MonoBehaviour)this).StartCoroutine(EmoteDeckEasySettingsBridge.DelayedInstall(this));
	}

	internal void SetMainWindowKeyFromEasySettings(KeyCode key)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		if ((int)key == 0 || IsBlockedMouseBindKey(key))
		{
			EmoteDeckEasySettingsBridge.ResetMainKeyButton(this);
			return;
		}
		CfgMainWindowKey.Value = ((object)(KeyCode)(ref key)).ToString();
		ReloadHotkeysFromConfig();
		EmoteDeckEasySettingsBridge.SyncButtonsFromConfig(this);
		SuppressHotkeyActivationUntilReleased(key);
		QueueConfigSave(0.15f);
	}

	internal void SetGridWindowKeyFromEasySettings(KeyCode key)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		if (IsBlockedMouseBindKey(key))
		{
			EmoteDeckEasySettingsBridge.ResetGridKeyButton(this);
			return;
		}
		CfgGridWindowKey.Value = (((int)key == 0) ? "None" : ((object)(KeyCode)(ref key)).ToString());
		ReloadHotkeysFromConfig();
		EmoteDeckEasySettingsBridge.SyncButtonsFromConfig(this);
		SuppressHotkeyActivationUntilReleased(key);
		QueueConfigSave(0.15f);
	}

	internal static KeyCode ParseRequiredKeyCode(string value, KeyCode fallback, string name)
	{
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		if (!string.IsNullOrWhiteSpace(value) && Enum.TryParse<KeyCode>(value, ignoreCase: true, out KeyCode result) && (int)result != 0 && !IsBlockedMouseBindKey(result))
		{
			return result;
		}
		if (Log != null)
		{
			Log.LogWarning((object)("[EmoteDeck] Invalid or disabled required key " + name + "='" + value + "'. Falling back to " + ((object)(KeyCode)(ref fallback)).ToString() + "."));
		}
		return fallback;
	}

	internal static KeyCode ParseOptionalKeyCode(string value, string name)
	{
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0087: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: 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)
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		if (string.IsNullOrWhiteSpace(value) || string.Equals(value, "None", StringComparison.OrdinalIgnoreCase))
		{
			return (KeyCode)0;
		}
		if (Enum.TryParse<KeyCode>(value, ignoreCase: true, out KeyCode result) && !IsBlockedMouseBindKey(result))
		{
			return result;
		}
		if (Log != null)
		{
			Log.LogWarning((object)("[EmoteDeck] Invalid optional key " + name + "='" + value + "'. Disabling it."));
		}
		return (KeyCode)0;
	}

	internal void SuppressHotkeyActivationUntilReleased(KeyCode key)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0003: Invalid comparison between Unknown and I4
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		if ((int)key != 0 && !IsBlockedMouseBindKey(key))
		{
			_suppressedHotkeyActivations.Add(key);
			int num = Time.frameCount + 2;
			if (num > _suppressHotkeysUntilFrame)
			{
				_suppressHotkeysUntilFrame = num;
			}
		}
	}

	private void UpdateSuppressedHotkeyActivations()
	{
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0049: Unknown result type (might be due to invalid IL or missing references)
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		if (_suppressedHotkeyActivations.Count == 0 || Time.frameCount <= _suppressHotkeysUntilFrame)
		{
			return;
		}
		List<KeyCode> list = null;
		foreach (KeyCode suppressedHotkeyActivation in _suppressedHotkeyActivations)
		{
			if (!IsKeyCurrentlyHeld(suppressedHotkeyActivation))
			{
				if (list == null)
				{
					list = new List<KeyCode>();
				}
				list.Add(suppressedHotkeyActivation);
			}
		}
		if (list != null)
		{
			for (int i = 0; i < list.Count; i++)
			{
				_suppressedHotkeyActivations.Remove(list[i]);
			}
		}
	}

	private bool IsHotkeyActivationSuppressed(KeyCode key)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0003: Invalid comparison between Unknown and I4
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		if ((int)key == 0)
		{
			return false;
		}
		return _suppressedHotkeyActivations.Contains(key);
	}

	private static bool IsKeyCurrentlyHeld(KeyCode key)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0003: Invalid comparison between Unknown and I4
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		if ((int)key == 0)
		{
			return false;
		}
		try
		{
			return Input.GetKey(key);
		}
		catch
		{
			return false;
		}
	}

	private void Update()
	{
		//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_0115: Unknown result type (might be due to invalid IL or missing references)
		//IL_011b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_0139: Unknown result type (might be due to invalid IL or missing references)
		if (_window == null)
		{
			return;
		}
		UpdateSuppressedHotkeyActivations();
		EmoteDeckEasySettingsBridge.PollSync(this);
		if (_window.IsCapturingKeyBind)
		{
			return;
		}
		if (CfgAutoRescanEnabled.Value && Time.unscaledTime >= _nextAutoRefreshTime)
		{
			bool flag = _forceNextAutoRefresh || AllEmotes.Count == 0;
			_forceNextAutoRefresh = false;
			if (flag)
			{
				RefreshEmoteRegistry();
			}
			else
			{
				RefreshEmoteRegistryIfChanged();
			}
			_nextAutoRefreshTime = Time.unscaledTime + ((AllEmotes.Count == 0) ? 3f : 10f);
		}
		if (!IsChatTyping())
		{
			if ((int)_mainWindowKey != 0 && Input.GetKeyDown(_mainWindowKey) && !IsHotkeyActivationSuppressed(_mainWindowKey))
			{
				_window.ToggleMainWindow();
				return;
			}
			if ((int)_gridWindowKey != 0 && _gridWindowKey != _mainWindowKey && Input.GetKeyDown(_gridWindowKey) && !IsHotkeyActivationSuppressed(_gridWindowKey))
			{
				_window.ToggleGridWindow();
				return;
			}
		}
		FlushQueuedConfigSaveIfDue();
	}

	private void LateUpdate()
	{
		if (_window != null)
		{
			_window.MaintainInputState();
		}
	}

	private void OnGUI()
	{
		if (_window != null)
		{
			_window.OnGUI();
		}
	}

	internal int GetActiveSlotCount()
	{
		int num = CfgActiveSlotCount.Value;
		if (num < 1)
		{
			num = 1;
		}
		if (num > 100)
		{
			num = 100;
		}
		return num;
	}

	internal int GetPageCount()
	{
		int num = CfgPageCount.Value;
		if (num < 1)
		{
			num = 1;
		}
		if (num > 10)
		{
			num = 10;
		}
		return num;
	}

	internal int GetCurrentPageIndex()
	{
		if (!CfgEnablePages.Value)
		{
			return 0;
		}
		int pageCount = GetPageCount();
		int num = CfgCurrentPage.Value - 1;
		if (num < 0)
		{
			num = 0;
		}
		if (num >= pageCount)
		{
			num = pageCount - 1;
		}
		return num;
	}

	internal int GetEffectiveDeckPageCount()
	{
		return (!CfgEnablePages.Value) ? 1 : GetPageCount();
	}

	internal int GetTotalDeckSlotCapacity()
	{
		return GetActiveSlotCount() * GetEffectiveDeckPageCount();
	}

	internal string GetSlotKeyForPage(int pageIndex, int index)
	{
		if (index < 0 || index >= 100)
		{
			return string.Empty;
		}
		if (!CfgEnablePages.Value || pageIndex <= 0)
		{
			return CfgSlotEmoteKeys[index].Value ?? string.Empty;
		}
		if (pageIndex >= 10)
		{
			return string.Empty;
		}
		EnsurePageSlotArray(pageIndex);
		return PageSlotKeys[pageIndex][index] ?? string.Empty;
	}

	internal int CountAssignedSlotsInPage(int pageIndex)
	{
		int num = 0;
		int activeSlotCount = GetActiveSlotCount();
		for (int i = 0; i < activeSlotCount; i++)
		{
			if (!string.IsNullOrEmpty(GetSlotKeyForPage(pageIndex, i)))
			{
				num++;
			}
		}
		return num;
	}

	internal int CountAssignedSlotsAcrossEnabledPages()
	{
		int num = 0;
		int effectiveDeckPageCount = GetEffectiveDeckPageCount();
		for (int i = 0; i < effectiveDeckPageCount; i++)
		{
			num += CountAssignedSlotsInPage(i);
		}
		return num;
	}

	internal void SetCurrentPageIndex(int pageIndex)
	{
		int pageCount = GetPageCount();
		if (pageIndex < 0)
		{
			pageIndex = 0;
		}
		if (pageIndex >= pageCount)
		{
			pageIndex = pageCount - 1;
		}
		CfgCurrentPage.Value = pageIndex + 1;
		QueueConfigSave();
	}

	internal string GetSlotKey(int index)
	{
		return GetSlotKeyForPage(GetCurrentPageIndex(), index);
	}

	internal void SetSlotKey(int index, string key)
	{
		if (index >= 0 && index < 100)
		{
			int currentPageIndex = GetCurrentPageIndex();
			if (!CfgEnablePages.Value || currentPageIndex <= 0)
			{
				CfgSlotEmoteKeys[index].Value = key ?? string.Empty;
			}
			else
			{
				EnsurePageSlotArray(currentPageIndex);
				PageSlotKeys[currentPageIndex][index] = key ?? string.Empty;
				SavePageSlotConfig(currentPageIndex);
			}
			SavePluginConfig();
		}
	}

	internal bool TryGetSlotEmote(int index, out EmoteEntry entry)
	{
		entry = null;
		string slotKey = GetSlotKey(index);
		if (string.IsNullOrEmpty(slotKey))
		{
			return false;
		}
		return EmotesByKey.TryGetValue(slotKey, out entry);
	}

	internal bool IsAssignedOnCurrentDeck(string key)
	{
		if (string.IsNullOrEmpty(key))
		{
			return false;
		}
		int activeSlotCount = GetActiveSlotCount();
		for (int i = 0; i < activeSlotCount; i++)
		{
			if (string.Equals(GetSlotKey(i), key, StringComparison.OrdinalIgnoreCase))
			{
				return true;
			}
		}
		return false;
	}

	private void LoadPageSlotsFromConfig()
	{
		for (int i = 1; i < 10; i++)
		{
			EnsurePageSlotArray(i);
			string text = ((CfgPageSlotKeys[i] != null) ? CfgPageSlotKeys[i].Value : string.Empty);
			string[] array = (text ?? string.Empty).Split(new char[1] { ';' }, StringSplitOptions.None);
			for (int j = 0; j < 100; j++)
			{
				PageSlotKeys[i][j] = ((j < array.Length) ? array[j] : string.Empty);
			}
		}
	}

	private void EnsurePageSlotArray(int page)
	{
		if (page >= 0 && page < 10 && (PageSlotKeys[page] == null || PageSlotKeys[page].Length != 100))
		{
			PageSlotKeys[page] = new string[100];
		}
	}

	private void SavePageSlotConfig(int page)
	{
		if (page > 0 && page < 10 && CfgPageSlotKeys[page] != null)
		{
			EnsurePageSlotArray(page);
			CfgPageSlotKeys[page].Value = string.Join(";", PageSlotKeys[page]);
		}
	}

	internal void MoveToNextPage()
	{
		if (CfgEnablePages.Value)
		{
			int pageCount = GetPageCount();
			int currentPageIndex = GetCurrentPageIndex();
			if (currentPageIndex + 1 < pageCount)
			{
				SetCurrentPageIndex(currentPageIndex + 1);
			}
		}
	}

	internal void MoveToPreviousPage()
	{
		if (CfgEnablePages.Value)
		{
			int currentPageIndex = GetCurrentPageIndex();
			if (currentPageIndex > 0)
			{
				SetCurrentPageIndex(currentPageIndex - 1);
			}
		}
	}

	private static List<string> ParseKeyList(string raw)
	{
		List<string> list = new List<string>();
		string[] array = (raw ?? string.Empty).Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries);
		for (int i = 0; i < array.Length; i++)
		{
			string text = array[i].Trim();
			if (text.Length > 0 && !ContainsString(list, text))
			{
				list.Add(text);
			}
		}
		return list;
	}

	private static bool ContainsString(List<string> list, string key)
	{
		for (int i = 0; i < list.Count; i++)
		{
			if (string.Equals(list[i], key, StringComparison.OrdinalIgnoreCase))
			{
				return true;
			}
		}
		return false;
	}

	private static void RemoveString(List<string> list, string key)
	{
		for (int num = list.Count - 1; num >= 0; num--)
		{
			if (string.Equals(list[num], key, StringComparison.OrdinalIgnoreCase))
			{
				list.RemoveAt(num);
			}
		}
	}

	private void LoadRecentAndFavoritesFromConfig()
	{
		RecentKeys.Clear();
		FavoriteKeys.Clear();
		RecentKeys.AddRange(ParseKeyList(CfgRecentKeys.Value));
		FavoriteKeys.AddRange(ParseKeyList(CfgFavoriteKeys.Value));
	}

	private void SaveRecentKeys()
	{
		CfgRecentKeys.Value = string.Join(";", RecentKeys.ToArray());
		RecentRevision++;
		QueueConfigSave();
	}

	private void SaveFavoriteKeys()
	{
		CfgFavoriteKeys.Value = string.Join(";", FavoriteKeys.ToArray());
		FavoriteRevision++;
		QueueConfigSave();
	}

	internal void NoteRecent(EmoteEntry entry)
	{
		if (entry != null && CfgEnableRecent.Value && !string.IsNullOrEmpty(entry.Key))
		{
			RemoveString(RecentKeys, entry.Key);
			RecentKeys.Insert(0, entry.Key);
			int num = Mathf.Clamp(CfgRecentLimit.Value, 1, 100);
			while (RecentKeys.Count > num)
			{
				RecentKeys.RemoveAt(RecentKeys.Count - 1);
			}
			SaveRecentKeys();
		}
	}

	internal bool IsFavorite(string key)
	{
		if (string.IsNullOrEmpty(key))
		{
			return false;
		}
		return ContainsString(FavoriteKeys, key);
	}

	internal void ToggleFavorite(EmoteEntry entry)
	{
		if (entry != null && !string.IsNullOrEmpty(entry.Key))
		{
			if (IsFavorite(entry.Key))
			{
				RemoveString(FavoriteKeys, entry.Key);
			}
			else
			{
				FavoriteKeys.Add(entry.Key);
			}
			SaveFavoriteKeys();
		}
	}

	internal void BuildEntryListFromKeys(List<string> keys, List<EmoteEntry> dest)
	{
		dest.Clear();
		for (int i = 0; i < keys.Count; i++)
		{
			if (EmotesByKey.TryGetValue(keys[i], out var value) && value != null)
			{
				dest.Add(value);
			}
		}
	}

	internal List<EmoteEntry> GetVisibleEmotes()
	{
		List<EmoteEntry> list = new List<EmoteEntry>();
		for (int i = 0; i < AllEmotes.Count; i++)
		{
			EmoteEntry emoteEntry = AllEmotes[i];
			if (emoteEntry != null && IsPackageVisible(emoteEntry.PackageId))
			{
				list.Add(emoteEntry);
			}
		}
		return list;
	}

	internal bool IsPackageVisible(string packageId)
	{
		string item = (string.IsNullOrEmpty(packageId) ? "Unknown" : packageId);
		return !HiddenPackages.Contains(item);
	}

	internal void SetPackageVisible(string packageId, bool visible)
	{
		string item = (string.IsNullOrEmpty(packageId) ? "Unknown" : packageId);
		if (visible)
		{
			HiddenPackages.Remove(item);
		}
		else
		{
			HiddenPackages.Add(item);
		}
		SaveHiddenPackagesToConfig();
	}

	internal void ShowAllPackages()
	{
		HiddenPackages.Clear();
		SaveHiddenPackagesToConfig();
	}

	internal void HideAllPackages()
	{
		HiddenPackages.Clear();
		for (int i = 0; i < PackageIds.Count; i++)
		{
			HiddenPackages.Add(PackageIds[i]);
		}
		SaveHiddenPackagesToConfig();
	}

	private void LoadHiddenPackagesFromConfig()
	{
		HiddenPackages.Clear();
		string text = CfgHiddenPackages.Value ?? string.Empty;
		string[] array = text.Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries);
		for (int i = 0; i < array.Length; i++)
		{
			string text2 = array[i].Trim();
			if (text2.Length > 0)
			{
				HiddenPackages.Add(text2);
			}
		}
	}

	private void SaveHiddenPackagesToConfig()
	{
		List<string> list = new List<string>(HiddenPackages);
		list.Sort(StringComparer.OrdinalIgnoreCase);
		CfgHiddenPackages.Value = string.Join(";", list.ToArray());
		FilterRevision++;
		SavePluginConfig();
	}

	private bool IsChatTyping()
	{
		try
		{
			Player mainPlayer = Player._mainPlayer;
			if ((Object)(object)mainPlayer != (Object)null)
			{
				if (mainPlayer._inChat)
				{
					return true;
				}
				if ((Object)(object)mainPlayer._chatBehaviour != (Object)null && mainPlayer._chatBehaviour._focusedInChat)
				{
					return true;
				}
			}
		}
		catch
		{
		}
		try
		{
			ChatBehaviour current = ChatBehaviour._current;
			if ((Object)(object)current != (Object)null && current._focusedInChat)
			{
				return true;
			}
		}
		catch
		{
		}
		return IsUnityTextInputFocused();
	}

	private static bool IsUnityTextInputFocused()
	{
		try
		{
			Type type = FindType("UnityEngine.EventSystems.EventSystem");
			if (type == null)
			{
				return false;
			}
			PropertyInfo property = type.GetProperty("current", BindingFlags.Static | BindingFlags.Public);
			object obj = ((property != null) ? property.GetValue(null, null) : null);
			if (obj == null)
			{
				return false;
			}
			PropertyInfo property2 = type.GetProperty("currentSelectedGameObject", BindingFlags.Instance | BindingFlags.Public);
			GameObject val = (GameObject)((property2 != null) ? /*isinst with value type is only supported in some contexts*/: null);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			Type type2 = FindType("UnityEngine.UI.InputField");
			if (type2 != null && (Object)(object)val.GetComponent(type2) != (Object)null)
			{
				return true;
			}
			Type type3 = FindType("TMPro.TMP_InputField");
			if (type3 != null && (Object)(object)val.GetComponent(type3) != (Object)null)
			{
				return true;
			}
		}
		catch
		{
		}
		return false;
	}

	private void RefreshEmoteRegistryIfChanged()
	{
		int lastRegistryFingerprint = _lastRegistryFingerprint;
		int num = ComputeRegistryFingerprintCheap();
		if (num != lastRegistryFingerprint)
		{
			RefreshEmoteRegistry();
		}
	}

	private int ComputeRegistryFingerprintCheap()
	{
		int num = 17;
		try
		{
			Type type = FindType("AtlyssEmotes.EmoteManager");
			if (type != null)
			{
				PropertyInfo property = type.GetProperty("allEmotes", BindingFlags.Static | BindingFlags.Public);
				object obj = ((property != null) ? property.GetValue(null, null) : null);
				if (obj is IDictionary dictionary)
				{
					num = num * 31 + dictionary.Count;
				}
			}
		}
		catch
		{
		}
		try
		{
			ScriptableEmoteList nativeScriptableEmoteList = GetNativeScriptableEmoteList();
			if ((Object)(object)nativeScriptableEmoteList != (Object)null && nativeScriptableEmoteList._emoteCommandList != null)
			{
				num = num * 31 + nativeScriptableEmoteList._emoteCommandList.Length;
			}
		}
		catch
		{
		}
		return num;
	}

	internal void RefreshEmoteRegistry()
	{
		Dictionary<string, EmoteEntry> dictionary = new Dictionary<string, EmoteEntry>(StringComparer.OrdinalIgnoreCase);
		EmoteWheelBridgeAvailable = FindType("AtlyssEmotes.EmoteManager") != null;
		int lastWheelEmoteCount = CollectEmoteWheelEntries(dictionary);
		bool flag = false;
		foreach (EmoteEntry value in dictionary.Values)
		{
			if (value != null && string.Equals(value.PackageId, "Base", StringComparison.OrdinalIgnoreCase))
			{
				flag = true;
				break;
			}
		}
		int lastNativeEmoteCount = 0;
		if (!flag || CfgIncludeNativeVanillaWhenWheelBaseExists.Value)
		{
			lastNativeEmoteCount = CollectNativeVanillaEntries(dictionary);
		}
		AllEmotes.Clear();
		foreach (EmoteEntry value2 in dictionary.Values)
		{
			if (value2 != null && !string.Equals(value2.Key, "None", StringComparison.OrdinalIgnoreCase))
			{
				AllEmotes.Add(value2);
			}
		}
		AllEmotes.Sort(CompareEmotes);
		EmotesByKey.Clear();
		PackageIds.Clear();
		HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
		for (int i = 0; i < AllEmotes.Count; i++)
		{
			EmoteEntry emoteEntry = AllEmotes[i];
			if (!EmotesByKey.ContainsKey(emoteEntry.Key))
			{
				EmotesByKey.Add(emoteEntry.Key, emoteEntry);
			}
			string item = (string.IsNullOrEmpty(emoteEntry.PackageId) ? "Unknown" : emoteEntry.PackageId);
			if (hashSet.Add(item))
			{
				PackageIds.Add(item);
			}
		}
		PackageIds.Sort(StringComparer.OrdinalIgnoreCase);
		LastWheelEmoteCount = lastWheelEmoteCount;
		LastNativeEmoteCount = lastNativeEmoteCount;
		LastRegistryRefreshTime = Time.unscaledTime;
		RegistryRevision++;
		_lastRegistryFingerprint = ComputeRegistryFingerprintCheap();
		if (CfgDebugLogging.Value)
		{
			Log.LogInfo((object)("[EmoteDeck] Registry refreshed. total=" + AllEmotes.Count + " wheel=" + lastWheelEmoteCount + " native=" + lastNativeEmoteCount + " packages=" + PackageIds.Count));
		}
	}

	private static int CompareEmotes(EmoteEntry a, EmoteEntry b)
	{
		int num = string.Compare(a.PackageId, b.PackageId, StringComparison.OrdinalIgnoreCase);
		if (num != 0)
		{
			return num;
		}
		return string.Compare(a.DisplayName, b.DisplayName, StringComparison.OrdinalIgnoreCase);
	}

	private int CollectEmoteWheelEntries(Dictionary<string, EmoteEntry> merged)
	{
		int num = 0;
		try
		{
			Type type = FindType("AtlyssEmotes.EmoteManager");
			if (type == null)
			{
				return 0;
			}
			PropertyInfo property = type.GetProperty("allEmotes", BindingFlags.Static | BindingFlags.Public);
			object obj = ((property != null) ? property.GetValue(null, null) : null);
			if (!(obj is IDictionary dictionary))
			{
				return 0;
			}
			foreach (DictionaryEntry item in dictionary)
			{
				string text = item.Key as string;
				object value = item.Value;
				if (!string.IsNullOrEmpty(text) && value != null && !string.Equals(text, "None", StringComparison.OrdinalIgnoreCase))
				{
					Type type2 = value.GetType();
					string text2 = ReadFieldString(type2, value, "emoteName");
					string text3 = ReadFieldString(type2, value, "emoteID");
					string text4 = ReadFieldString(type2, value, "packageName");
					bool flag = ReadFieldBool(type2, value, "isVanilla");
					Sprite icon = ReadFieldSprite(type2, value, "icon");
					if (string.IsNullOrEmpty(text4))
					{
						text4 = ExtractPackageFromKey(text);
					}
					if (string.IsNullOrEmpty(text2))
					{
						text2 = ExtractNameFromKey(text);
					}
					EmoteEntry emoteEntry = new EmoteEntry();
					emoteEntry.Key = text;
					emoteEntry.DisplayName = text2;
					emoteEntry.PackageId = text4;
					emoteEntry.Source = "Emote Wheel";
					emoteEntry.AnimationTag = (flag ? text3 : text);
					emoteEntry.IsVanilla = flag;
					emoteEntry.Icon = icon;
					emoteEntry.SortName = text4 + ":" + text2;
					if (!string.IsNullOrEmpty(emoteEntry.AnimationTag) && !merged.ContainsKey(emoteEntry.Key))
					{
						merged.Add(emoteEntry.Key, emoteEntry);
						num++;
					}
				}
			}
		}
		catch (Exception ex)
		{
			Log.LogWarning((object)("[EmoteDeck] Emote Wheel reflection failed: " + ex.GetType().Name + ": " + ex.Message));
		}
		return num;
	}

	private int CollectNativeVanillaEntries(Dictionary<string, EmoteEntry> merged)
	{
		int num = 0;
		try
		{
			ScriptableEmoteList nativeScriptableEmoteList = GetNativeScriptableEmoteList();
			if ((Object)(object)nativeScriptableEmoteList == (Object)null || nativeScriptableEmoteList._emoteCommandList == null)
			{
				return 0;
			}
			for (int i = 0; i < nativeScriptableEmoteList._emoteCommandList.Length; i++)
			{
				EmoteCommand val = nativeScriptableEmoteList._emoteCommandList[i];
				if (val != null && !string.IsNullOrEmpty(val._emoteChatCommand) && !string.IsNullOrEmpty(val._emoteAnimationTag))
				{
					string key = "Vanilla:" + val._emoteChatCommand;
					if (!merged.ContainsKey(key))
					{
						EmoteEntry emoteEntry = new EmoteEntry();
						emoteEntry.Key = key;
						emoteEntry.DisplayName = PrettyCommandName(val._emoteChatCommand);
						emoteEntry.PackageId = "Vanilla";
						emoteEntry.Source = "Game";
						emoteEntry.AnimationTag = val._emoteAnimationTag;
						emoteEntry.IsVanilla = true;
						emoteEntry.Icon = null;
						emoteEntry.SortName = "Vanilla:" + emoteEntry.DisplayName;
						merged.Add(key, emoteEntry);
						num++;
					}
				}
			}
		}
		catch (Exception ex)
		{
			Log.LogWarning((object)("[EmoteDeck] Native emote reflection failed: " + ex.GetType().Name + ": " + ex.Message));
		}
		return num;
	}

	private static ScriptableEmoteList GetNativeScriptableEmoteList()
	{
		ChatBehaviour current = ChatBehaviour._current;
		if ((Object)(object)current == (Object)null)
		{
			return null;
		}
		FieldInfo field = typeof(ChatBehaviour).GetField("_scriptableEmoteList", BindingFlags.Instance | BindingFlags.NonPublic);
		if (field == null)
		{
			return null;
		}
		object? value = field.GetValue(current);
		return (ScriptableEmoteList)((value is ScriptableEmoteList) ? value : null);
	}

	private static Type FindType(string fullName)
	{
		Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
		for (int i = 0; i < assemblies.Length; i++)
		{
			Type type = null;
			try
			{
				type = assemblies[i].GetType(fullName, throwOnError: false);
			}
			catch
			{
			}
			if (type != null)
			{
				return type;
			}
		}
		return null;
	}

	private static string ReadFieldString(Type t, object obj, string fieldName)
	{
		try
		{
			FieldInfo field = t.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field == null)
			{
				return string.Empty;
			}
			object value = field.GetValue(obj);
			return (value as string) ?? string.Empty;
		}
		catch
		{
			return string.Empty;
		}
	}

	private static bool ReadFieldBool(Type t, object obj, string fieldName)
	{
		try
		{
			FieldInfo field = t.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field == null)
			{
				return false;
			}
			object value = field.GetValue(obj);
			return value is bool && (bool)value;
		}
		catch
		{
			return false;
		}
	}

	private static Sprite ReadFieldSprite(Type t, object obj, string fieldName)
	{
		try
		{
			FieldInfo field = t.GetField(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field == null)
			{
				return null;
			}
			object? value = field.GetValue(obj);
			return (Sprite)((value is Sprite) ? value : null);
		}
		catch
		{
			return null;
		}
	}

	private static string ExtractPackageFromKey(string key)
	{
		int num = key.IndexOf(':');
		if (num > 0)
		{
			return key.Substring(0, num);
		}
		return "Unknown";
	}

	private static string ExtractNameFromKey(string key)
	{
		int num = key.IndexOf(':');
		if (num >= 0 && num + 1 < key.Length)
		{
			return key.Substring(num + 1);
		}
		return key;
	}

	private static string PrettyCommandName(string cmd)
	{
		if (string.IsNullOrEmpty(cmd))
		{
			return "Emote";
		}
		string text = cmd.Trim();
		if (text.StartsWith("/"))
		{
			text = text.Substring(1);
		}
		if (text.Length == 0)
		{
			return cmd;
		}
		return char.ToUpperInvariant(text[0]) + ((text.Length > 1) ? text.Substring(1) : string.Empty);
	}

	internal bool TryPlayEmote(EmoteEntry entry, out string status)
	{
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_0079: Invalid comparison between Unknown and I4
		status = string.Empty;
		if (entry == null)
		{
			status = "No emote selected.";
			return false;
		}
		if (string.IsNullOrEmpty(entry.AnimationTag))
		{
			status = "Selected emote has no animation tag.";
			return false;
		}
		try
		{
			Player mainPlayer = Player._mainPlayer;
			if ((Object)(object)mainPlayer == (Object)null || (Object)(object)mainPlayer._pVisual == (Object)null)
			{
				status = "No local player/visual found.";
				return false;
			}
			if ((int)mainPlayer._currentPlayerCondition != 2)
			{
				status = "Player is not active.";
				return false;
			}
			ChatBehaviour current = ChatBehaviour._current;
			if ((Object)(object)current != (Object)null)
			{
				float num = ReadChatEmoteBuffer(current);
				if (num > 0f)
				{
					status = "Emote buffer is still cooling down.";
					return false;
				}
			}
			mainPlayer._pVisual.Cmd_CrossFadeAnim(entry.AnimationTag, 0.1f, 11);
			mainPlayer._pVisual.Local_CrossFadeAnim(entry.AnimationTag, 0.1f, 11);
			if ((Object)(object)current != (Object)null)
			{
				WriteChatEmoteBuffer(current, 0.85f);
			}
			NoteRecent(entry);
			status = "Played " + entry.DisplayName + ".";
			if (CfgDebugLogging.Value)
			{
				Log.LogInfo((object)("[EmoteDeck] Play " + entry.Key + " tag=" + entry.AnimationTag + " source=" + entry.Source));
			}
			return true;
		}
		catch (Exception ex)
		{
			status = "Play failed: " + ex.GetType().Name + ": " + ex.Message;
			Log.LogWarning((object)("[EmoteDeck] " + status));
			return false;
		}
	}

	private static float ReadChatEmoteBuffer(ChatBehaviour chat)
	{
		try
		{
			if (_chatEmoteBufferField == null)
			{
				_chatEmoteBufferField = typeof(ChatBehaviour).GetField("_emoteBuffer", BindingFlags.Instance | BindingFlags.NonPublic);
			}
			if (_chatEmoteBufferField == null)
			{
				return 0f;
			}
			object value = _chatEmoteBufferField.GetValue(chat);
			if (value is float)
			{
				return (float)value;
			}
		}
		catch
		{
		}
		return 0f;
	}

	private static void WriteChatEmoteBuffer(ChatBehaviour chat, float value)
	{
		try
		{
			if (_chatEmoteBufferField == null)
			{
				_chatEmoteBufferField = typeof(ChatBehaviour).GetField("_emoteBuffer", BindingFlags.Instance | BindingFlags.NonPublic);
			}
			if (_chatEmoteBufferField != null)
			{
				_chatEmoteBufferField.SetValue(chat, value);
			}
		}
		catch
		{
		}
	}
}
internal sealed class EmoteEntry
{
	public string Key;

	public string DisplayName;

	public string PackageId;

	public string Source;

	public string AnimationTag;

	public bool IsVanilla;

	public Sprite Icon;

	public string SortName;
}
internal enum BindTarget
{
	None,
	MainWindow,
	GridWindow
}
internal enum GridMode
{
	Deck,
	Recent,
	Favorites
}
internal static class EmoteDeckEasySettingsBridge
{
	[Serializable]
	[CompilerGenerated]
	private sealed class <>c
	{
		public static readonly <>c <>9 = new <>c();

		public static UnityAction <>9__12_0;

		internal void <TrySubscribe>b__12_0()
		{
			TryRegisterIfReady(EmoteDeckPlugin.Instance);
		}
	}

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

		private object <>2__current;

		public EmoteDeckPlugin plugin;

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

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

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

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

		private bool MoveNext()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Expected O, but got Unknown
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<>2__current = (object)new WaitForSeconds(0.5f);
				<>1__state = 1;
				return true;
			case 1:
				<>1__state = -1;
				TryInstall(plugin);
				<>2__current = (object)new WaitForSeconds(1.5f);
				<>1__state = 2;
				return true;
			case 2:
				<>1__state = -1;
				TryRegisterIfReady(plugin);
				<>2__current = (object)new WaitForSeconds(4f);
				<>1__state = 3;
				return true;
			case 3:
				<>1__state = -1;
				TryRegisterIfReady(plugin);
				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 const string EasySettingsTypeName = "Nessie.ATLYSS.EasySettings.Settings";

	private static bool _subscribed;

	private static bool _registered;

	private static bool _registering;

	private static bool _loggedMissing;

	private static bool _syncingButtons;

	private static KeyCode _lastSyncedMainKey;

	private static KeyCode _lastSyncedGridKey;

	private static object _mainKeyButton;

	private static object _gridKeyButton;

	internal static void TryInstall(EmoteDeckPlugin plugin)
	{
		if (!((Object)(object)plugin == (Object)null))
		{
			TrySubscribe(plugin);
			TryRegisterIfReady(plugin);
		}
	}

	[IteratorStateMachine(typeof(<DelayedInstall>d__11))]
	internal static IEnumerator DelayedInstall(EmoteDeckPlugin plugin)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <DelayedInstall>d__11(0)
		{
			plugin = plugin
		};
	}

	private static void TrySubscribe(EmoteDeckPlugin plugin)
	{
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Expected O, but got Unknown
		if (_subscribed)
		{
			return;
		}
		Type type = FindType("Nessie.ATLYSS.EasySettings.Settings");
		if (type == null)
		{
			LogMissingOnce(plugin);
			return;
		}
		try
		{
			PropertyInfo property = type.GetProperty("OnInitialized", BindingFlags.Static | BindingFlags.Public);
			object obj = ((property != null) ? property.GetValue(null, null) : null);
			if (obj == null)
			{
				return;
			}
			MethodInfo method = obj.GetType().GetMethod("AddListener", new Type[1] { typeof(UnityAction) });
			if (method == null)
			{
				return;
			}
			object obj2 = <>c.<>9__12_0;
			if (obj2 == null)
			{
				UnityAction val = delegate
				{
					TryRegisterIfReady(EmoteDeckPlugin.Instance);
				};
				<>c.<>9__12_0 = val;
				obj2 = (object)val;
			}
			UnityAction val2 = (UnityAction)obj2;
			method.Invoke(obj, new object[1] { val2 });
			_subscribed = true;
		}
		catch (Exception ex)
		{
			if (EmoteDeckPlugin.CfgDebugLogging != null && EmoteDeckPlugin.CfgDebugLogging.Value && EmoteDeckPlugin.Log != null)
			{
				EmoteDeckPlugin.Log.LogWarning((object)("[EmoteDeck] EasySettings hook failed: " + ex.GetType().Name + ": " + ex.Message));
			}
		}
	}

	private static void TryRegisterIfReady(EmoteDeckPlugin plugin)
	{
		//IL_016b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0195: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)plugin == (Object)null || _registered || _registering)
		{
			return;
		}
		Type type = FindType("Nessie.ATLYSS.EasySettings.Settings");
		if (type == null)
		{
			LogMissingOnce(plugin);
		}
		else
		{
			if (!IsEasySettingsReady(type))
			{
				return;
			}
			_registering = true;
			try
			{
				MethodInfo method = type.GetMethod("GetOrAddCustomTab", BindingFlags.Static | BindingFlags.Public, null, new Type[1] { typeof(string) }, null);
				if (method == null)
				{
					return;
				}
				object obj = method.Invoke(null, new object[1] { "Eleen's Lab" });
				if (obj == null)
				{
					return;
				}
				Type type2 = obj.GetType();
				MethodInfo method2 = type2.GetMethod("AddHeader", BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { typeof(string) }, null);
				MethodInfo method3 = type2.GetMethod("AddKeyButton", BindingFlags.Instance | BindingFlags.Public, null, new Type[2]
				{
					typeof(string),
					typeof(KeyCode)
				}, null);
				if (!(method3 == null))
				{
					if (method2 != null)
					{
						method2.Invoke(obj, new object[1] { "Emote Deck" });
					}
					_mainKeyButton = method3.Invoke(obj, new object[2] { "Main window", plugin.MainWindowKey });
					_gridKeyButton = method3.Invoke(obj, new object[2] { "Emote grid", plugin.GridWindowKey });
					HookKeyButton(_mainKeyButton, main: true);
					HookKeyButton(_gridKeyButton, main: false);
					_registered = true;
					SyncButtonsFromConfig(plugin);
					TryUpdateEasySettingsVisibility(type);
					if (EmoteDeckPlugin.CfgDebugLogging != null && EmoteDeckPlugin.CfgDebugLogging.Value && EmoteDeckPlugin.Log != null)
					{
						EmoteDeckPlugin.Log.LogInfo((object)"[EmoteDeck] EasySettings keys registered.");
					}
				}
			}
			catch (Exception ex)
			{
				if (EmoteDeckPlugin.CfgDebugLogging != null && EmoteDeckPlugin.CfgDebugLogging.Value && EmoteDeckPlugin.Log != null)
				{
					EmoteDeckPlugin.Log.LogWarning((object)("[EmoteDeck] EasySettings registration failed: " + ex.GetType().Name + ": " + ex.Message));
				}
			}
			finally
			{
				_registering = false;
			}
		}
	}

	private static bool IsEasySettingsReady(Type settingsType)
	{
		try
		{
			if ((Object)(object)SettingsManager._current == (Object)null)
			{
				return false;
			}
			PropertyInfo property = settingsType.GetProperty("ModTab", BindingFlags.Static | BindingFlags.Public);
			object obj = ((property != null) ? property.GetValue(null, null) : null);
			if (obj == null)
			{
				return false;
			}
			FieldInfo field = obj.GetType().GetField("Content", BindingFlags.Instance | BindingFlags.Public);
			object obj2 = ((field != null) ? field.GetValue(obj) : null);
			if (obj2 == null)
			{
				return false;
			}
			Type type = FindType("Nessie.ATLYSS.EasySettings.TemplateManager");
			if (type != null)
			{
				FieldInfo field2 = type.GetField("_keyButtonTemplate", BindingFlags.Static | BindingFlags.NonPublic);
				if (field2 != null && field2.GetValue(null) == null)
				{
					return false;
				}
			}
			return true;
		}
		catch
		{
			return false;
		}
	}

	private static void TryUpdateEasySettingsVisibility(Type settingsType)
	{
		try
		{
			MethodInfo method = settingsType.GetMethod("UpdateTabVisibility", BindingFlags.Static | BindingFlags.NonPublic);
			if (method != null)
			{
				method.Invoke(null, null);
			}
		}
		catch
		{
		}
	}

	private static void HookKeyButton(object keyButton, bool main)
	{
		if (keyButton == null)
		{
			return;
		}
		try
		{
			PropertyInfo property = keyButton.GetType().GetProperty("OnValueChanged", BindingFlags.Instance | BindingFlags.Public);
			object obj = ((property != null) ? property.GetValue(keyButton, null) : null);
			if (obj != null)
			{
				MethodInfo method = obj.GetType().GetMethod("AddListener", new Type[1] { typeof(UnityAction<KeyCode>) });
				if (!(method == null))
				{
					UnityAction<KeyCode> val = (main ? new UnityAction<KeyCode>(OnMainKeyChanged) : new UnityAction<KeyCode>(OnGridKeyChanged));
					method.Invoke(obj, new object[1] { val });
				}
			}
		}
		catch (Exception ex)
		{
			if (EmoteDeckPlugin.CfgDebugLogging != null && EmoteDeckPlugin.CfgDebugLogging.Value && EmoteDeckPlugin.Log != null)
			{
				EmoteDeckPlugin.Log.LogWarning((object)("[EmoteDeck] EasySettings key hook failed: " + ex.GetType().Name + ": " + ex.Message));
			}
		}
	}

	private static void OnMainKeyChanged(KeyCode key)
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		if (!_syncingButtons)
		{
			EmoteDeckPlugin instance = EmoteDeckPlugin.Instance;
			if (!((Object)(object)instance == (Object)null))
			{
				instance.SetMainWindowKeyFromEasySettings(key);
			}
		}
	}

	private static void OnGridKeyChanged(KeyCode key)
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		if (!_syncingButtons)
		{
			EmoteDeckPlugin instance = EmoteDeckPlugin.Instance;
			if (!((Object)(object)instance == (Object)null))
			{
				instance.SetGridWindowKeyFromEasySettings(key);
			}
		}
	}

	internal static void ResetMainKeyButton(EmoteDeckPlugin plugin)
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)plugin == (Object)null))
		{
			SetButtonValueSilent(_mainKeyButton, plugin.MainWindowKey);
			_lastSyncedMainKey = plugin.MainWindowKey;
		}
	}

	internal static void ResetGridKeyButton(EmoteDeckPlugin plugin)
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)plugin == (Object)null))
		{
			SetButtonValueSilent(_gridKeyButton, plugin.GridWindowKey);
			_lastSyncedGridKey = plugin.GridWindowKey;
		}
	}

	internal static void PollSync(EmoteDeckPlugin plugin)
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		if (_registered && !((Object)(object)plugin == (Object)null) && !_registering && (plugin.MainWindowKey != _lastSyncedMainKey || plugin.GridWindowKey != _lastSyncedGridKey))
		{
			SyncButtonsFromConfig(plugin);
		}
	}

	internal static void SyncButtonsFromConfig(EmoteDeckPlugin plugin)
	{
		//IL_0025: 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)
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Unknown result type (might be due to invalid IL or missing references)
		if (!_registered || (Object)(object)plugin == (Object)null)
		{
			return;
		}
		_syncingButtons = true;
		try
		{
			SetButtonValueSilent(_mainKeyButton, plugin.MainWindowKey);
			SetButtonValueSilent(_gridKeyButton, plugin.GridWindowKey);
			_lastSyncedMainKey = plugin.MainWindowKey;
			_lastSyncedGridKey = plugin.GridWindowKey;
		}
		finally
		{
			_syncingButtons = false;
		}
	}

	private static void SetButtonValueSilent(object keyButton, KeyCode key)
	{
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: 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)
		if (keyButton == null)
		{
			return;
		}
		try
		{
			Type type = keyButton.GetType();
			FieldInfo field = type.GetField("_value", BindingFlags.Instance | BindingFlags.NonPublic);
			if (field != null)
			{
				field.SetValue(keyButton, key);
			}
			FieldInfo field2 = type.GetField("<AppliedValue>k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic);
			if (field2 != null)
			{
				field2.SetValue(keyButton, key);
			}
			object fieldValue = GetFieldValue(type, keyButton, "ButtonLabel");
			SetTextObject(fieldValue, ((object)(KeyCode)(ref key)).ToString());
			SyncRegisteredEasySettingsKeyBind(keyButton, fieldValue, key);
		}
		catch
		{
		}
	}

	private static object GetFieldValue(Type t, object obj, string name)
	{
		try
		{
			FieldInfo field = t.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field == null)
			{
				return null;
			}
			return field.GetValue(obj);
		}
		catch
		{
			return null;
		}
	}

	private static void SetTextObject(object textObject, string text)
	{
		if (textObject == null)
		{
			return;
		}
		try
		{
			PropertyInfo property = textObject.GetType().GetProperty("text", BindingFlags.Instance | BindingFlags.Public);
			if (property != null && property.CanWrite)
			{
				property.SetValue(textObject, text, null);
			}
		}
		catch
		{
		}
	}

	private static void SyncRegisteredEasySettingsKeyBind(object keyButton, object buttonLabel, KeyCode key)
	{
		try
		{
			SettingsManager current = SettingsManager._current;
			if ((Object)(object)current == (Object)null)
			{
				return;
			}
			FieldInfo field = typeof(SettingsManager).GetField("keyBindButtons", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			Array array = ((field != null) ? (field.GetValue(current) as Array) : null);
			if (array == null)
			{
				return;
			}
			string text = ((object)(KeyCode)(ref key)).ToString();
			object fieldValue = GetFieldValue(keyButton.GetType(), keyButton, "Button");
			for (int i = 0; i < array.Length; i++)
			{
				object value = array.GetValue(i);
				if (value == null)
				{
					continue;
				}
				Type type = value.GetType();
				object fieldValue2 = GetFieldValue(type, value, "_buttonLabel");
				object fieldValue3 = GetFieldValue(type, value, "_button");
				if (fieldValue2 == buttonLabel || fieldValue3 == fieldValue)
				{
					FieldInfo field2 = type.GetField("_keyBind", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
					if (field2 != null)
					{
						field2.SetValue(value, text);
					}
					SetTextObject(fieldValue2, text);
					break;
				}
			}
		}
		catch
		{
		}
	}

	private static void LogMissingOnce(EmoteDeckPlugin plugin)
	{
		if (!_loggedMissing)
		{
			_loggedMissing = true;
			if ((Object)(object)plugin != (Object)null && EmoteDeckPlugin.CfgDebugLogging != null && EmoteDeckPlugin.CfgDebugLogging.Value && EmoteDeckPlugin.Log != null)
			{
				EmoteDeckPlugin.Log.LogInfo((object)"[EmoteDeck] EasySettings not found. Native settings tab integration skipped.");
			}
		}
	}

	private static Type FindType(string fullName)
	{
		Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
		for (int i = 0; i < assemblies.Length; i++)
		{
			Type type = null;
			try
			{
				type = assemblies[i].GetType(fullName, throwOnError: false);
			}
			catch
			{
			}
			if (type != null)
			{
				return type;
			}
		}
		return null;
	}
}
internal static class EmoteDeckInputBlocker
{
	private static bool _mainOpen;

	private static bool _gridOpen;

	private static Rect _mainRect;

	private static Rect _gridRect;

	private static bool _blockGameplayInput;

	public static void SetWindowState(bool mainOpen, Rect mainRect, bool gridOpen, Rect gridRect, bool blockGameplayInput)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_0008: 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_0014: Unknown result type (might be due to invalid IL or missing references)
		_mainOpen = mainOpen;
		_mainRect = mainRect;
		_gridOpen = gridOpen;
		_gridRect = gridRect;
		_blockGameplayInput = blockGameplayInput && (_mainOpen || _gridOpen);
	}

	public static bool ShouldBlockGameplayInput()
	{
		return _blockGameplayInput;
	}

	public static bool IsMouseOverEmoteDeckWindow()
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0009: 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_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		Vector3 mousePosition = Input.mousePosition;
		Vector2 val = default(Vector2);
		((Vector2)(ref val))..ctor(mousePosition.x, (float)Screen.height - mousePosition.y);
		if (_mainOpen && ((Rect)(ref _mainRect)).Contains(val))
		{
			return true;
		}
		if (_gridOpen && ((Rect)(ref _gridRect)).Contains(val))
		{
			return true;
		}
		return false;
	}

	public static bool HasNonZeroScrollDelta(object pointerEventData)
	{
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Unknown result type (might be due to invalid IL or missing references)
		if (pointerEventData == null)
		{
			return false;
		}
		try
		{
			Type type = pointerEventData.GetType();
			object obj = null;
			PropertyInfo property = type.GetProperty("scrollDelta", BindingFlags.Instance | BindingFlags.Public);
			if (property != null)
			{
				obj = property.GetValue(pointerEventData, null);
			}
			else
			{
				FieldInfo field = type.GetField("scrollDelta", BindingFlags.Instance | BindingFlags.Public);
				if (field != null)
				{
					obj = field.GetValue(pointerEventData);
				}
			}
			if (obj is Vector2)
			{
				Vector2 val = (Vector2)obj;
				return ((Vector2)(ref val)).sqrMagnitude > 0.0001f;
			}
		}
		catch
		{
		}
		return false;
	}
}
internal static class EmoteDeckScrollRectOnScrollPatch
{
	private static bool Prefix(object __0)
	{
		if (EmoteDeckInputBlocker.HasNonZeroScrollDelta(__0) && EmoteDeckInputBlocker.IsMouseOverEmoteDeckWindow())
		{
			return false;
		}
		return true;
	}
}
internal static class EmoteDeckGameplayInputPatch
{
	private static bool Prefix(object __instance)
	{
		if (!EmoteDeckInputBlocker.ShouldBlockGameplayInput())
		{
			return true;
		}
		TryNeutralizeInstance(__instance);
		return false;
	}

	private static void TryNeutralizeInstance(object instance)
	{
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			PlayerMove val = (PlayerMove)((instance is PlayerMove) ? instance : null);
			if ((Object)(object)val != (Object)null)
			{
				val.inputIn = Vector3.zero;
				val._worldSpaceInput = Vector3.zero;
				return;
			}
			PlayerCombat val2 = (PlayerCombat)((instance is PlayerCombat) ? instance : null);
			if ((Object)(object)val2 != (Object)null)
			{
				val2._localBlockingInput = false;
			}
		}
		catch
		{
		}
	}
}
internal static class EmoteDeckPlayerLocalParamsPatch
{
	private static void Postfix(Player __instance)
	{
		if (!EmoteDeckInputBlocker.ShouldBlockGameplayInput())
		{
			return;
		}
		try
		{
			if ((Object)(object)__instance != (Object)null && (Object)(object)__instance == (Object)(object)Player._mainPlayer)
			{
				__instance._inUI = true;
			}
		}
		catch
		{
		}
	}
}
internal sealed class EmoteDeckWindow
{
	private struct GridMetrics
	{
		public int Columns;

		public int Rows;

		public float CellW;

		public float CellH;

		public float LabelH;

		public float Spacing;

		public float RowH;

		public float TotalContentH;

		public bool NamesOnly;

		public bool ShowIcon;

		public bool ShowLabel;
	}

	private const int MainWindowId = 1162104113;

	private const int GridWindowId = 1162102577;

	private const float MinMainW = 520f;

	private const float MinMainH = 380f;

	private const float MinGridW = 260f;

	private const float MinGridH = 160f;

	private readonly EmoteDeckPlugin _plugin;

	private Rect _mainRect;

	private Rect _gridRect;

	private bool _mainOpen;

	private bool _gridOpen;

	private bool _mainResizing;

	private bool _gridResizing;

	private Vector2 _resizeStart;

	private Rect _resizeOrig;

	private CursorLockMode _savedCursorLock;

	private bool _savedCursorVisible;

	private bool _hasSavedCursor;

	private bool _playerInUiForced;

	private bool _savedCameraUnlocked;

	private bool _hasSavedCamera;

	private int _tab;

	private Vector2 _slotsScroll;

	private Vector2 _pickerScroll;

	private Vector2 _pickerSlotScroll;

	private Vector2 _filterScroll;

	private Vector2 _settingsScroll;

	private Vector2 _gridScroll;

	private string _slotCountText;

	private string _searchText = string.Empty;

	private int _editingSlot = -1;

	private string _statusText = string.Empty;

	private float _statusUntil;

	private readonly List<EmoteEntry> _pickerCache = new List<EmoteEntry>();

	private readonly List<EmoteEntry> _specialGridEntries = new List<EmoteEntry>();

	private GridMode _gridMode = GridMode.Deck;

	private bool _gridViewDropdownOpen;

	private bool _gridMouseModeDropdownOpen;

	private bool _settingsGridViewDropdownOpen;

	private bool _settingsGridMouseModeDropdownOpen;

	private string _pickerCacheSearch = null;

	private int _pickerCacheRegistryRevision = -1;

	private int _pickerCacheFilterRevision = -1;

	private bool _pickerCacheHideAssigned;

	private int _pickerCachePage = -1;

	private BindTarget _bindTarget = BindTarget.None;

	private int _bindStartedFrame = -1;

	private string _bindStatus = string.Empty;

	private GUIStyle _transparentWindowStyle;

	private GUIStyle _headerStyle;

	private GUIStyle _smallLabelStyle;

	private GUIStyle _centerLabelStyle;

	private GUIStyle _miniButtonStyle;

	internal bool IsCapturingKeyBind => _bindTarget != BindTarget.None;

	internal bool IsMainOpen => _mainOpen;

	internal bool IsGridOpen => _gridOpen;

	internal EmoteDeckWindow(EmoteDeckPlugin plugin)
	{
		//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_00da: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		_plugin = plugin;
		_mainRect = new Rect(EmoteDeckPlugin.CfgMainX.Value, EmoteDeckPlugin.CfgMainY.Value, EmoteDeckPlugin.CfgMainW.Value, EmoteDeckPlugin.CfgMainH.Value);
		_gridRect = new Rect(EmoteDeckPlugin.CfgGridX.Value, EmoteDeckPlugin.CfgGridY.Value, EmoteDeckPlugin.CfgGridW.Value, EmoteDeckPlugin.CfgGridH.Value);
		_slotCountText = EmoteDeckPlugin.CfgActiveSlotCount.Value.ToString(CultureInfo.InvariantCulture);
	}

	internal void ToggleMainWindow()
	{
		if (_mainOpen)
		{
			CloseMainWindow();
		}
		else
		{
			OpenMainWindow();
		}
	}

	internal void ToggleGridWindow()
	{
		if (_gridOpen)
		{
			CloseGridWindow();
		}
		else
		{
			OpenGridWindow();
		}
	}

	internal void OpenMainWindow()
	{
		if (!_mainOpen)
		{
			_mainOpen = true;
			SaveCursorIfNeeded();
			Cursor.lockState = (CursorLockMode)0;
			Cursor.visible = true;
			ApplyPlayerInUIIfNeeded();
			UpdateInputBlockerState();
			_plugin.ScheduleAutoRescan(0.25f, force: true);
			ClampToScreen(ref _mainRect, 520f, 380f);
		}
	}

	internal void CloseMainWindow()
	{
		if (_mainOpen)
		{
			_mainOpen = false;
			_bindTarget = BindTarget.None;
			_editingSlot = -1;
			SaveMainRect();
			UpdateInputBlockerState();
			_plugin.SavePluginConfig();
			ReleaseInputStateIfUnused();
		}
	}

	internal void OpenGridWindow()
	{
		if (!_gridOpen)
		{
			_gridOpen = true;
			ApplyPlayerInUIIfNeeded();
			if (ShouldUnlockMouseForGridWindow())
			{
				ApplyGridMouseUnlockIfNeeded();
			}
			UpdateInputBlockerState();
			_plugin.ScheduleAutoRescan(0.25f, force: true);
			ClampToScreen(ref _gridRect, 260f, 160f);
		}
	}

	internal void CloseGridWindow()
	{
		if (_gridOpen)
		{
			_gridOpen = false;
			_gridViewDropdownOpen = false;
			_gridMouseModeDropdownOpen = false;
			SaveGridRect();
			UpdateInputBlockerState();
			_plugin.SavePluginConfig();
			ReleaseInputStateIfUnused();
		}
	}

	internal void SaveOpenWindowRects()
	{
		if (_mainOpen)
		{
			SaveMainRect();
		}
		if (_gridOpen)
		{
			SaveGridRect();
		}
	}

	internal void MaintainInputState()
	{
		UpdateInputBlockerState();
		if (_mainOpen || _gridOpen)
		{
			if (ShouldBlockGameplayInputForOpenWindows())
			{
				ApplyPlayerInUIIfNeeded();
			}
			else
			{
				ReleasePlayerInUIState();
			}
			if (_gridOpen && ShouldUnlockMouseForGridWindow())
			{
				ApplyGridMouseUnlockIfNeeded();
			}
			else
			{
				ReleaseGridMouseUnlockIfSafe();
			}
		}
		else
		{
			ReleaseInputStateIfUnused();
		}
	}

	private void SaveCursorIfNeeded()
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		if (!_hasSavedCursor)
		{
			_savedCursorLock = Cursor.lockState;
			_savedCursorVisible = Cursor.visible;
			_hasSavedCursor = true;
		}
	}

	private void ApplyPlayerInUIIfNeeded()
	{
		if (!ShouldBlockGameplayInputForOpenWindows())
		{
			return;
		}
		try
		{
			Player mainPlayer = Player._mainPlayer;
			if (!((Object)(object)mainPlayer == (Object)null))
			{
				mainPlayer._inUI = true;
				_playerInUiForced = true;
			}
		}
		catch
		{
		}
	}

	private bool ShouldUnlockMouseForGridWindow()
	{
		if (!_gridOpen)
		{
			return false;
		}
		string gridMouseMode = GetGridMouseMode();
		if (gridMouseMode == "Always")
		{
			return true;
		}
		if (gridMouseMode == "Off")
		{
			return false;
		}
		return EmoteDeckPlugin.CfgCloseGridAfterEmote.Value;
	}

	private void ApplyGridMouseUnlockIfNeeded()
	{
		if (ShouldUnlockMouseForGridWindow())
		{
			SaveCursorIfNeeded();
			try
			{
				Cursor.lockState = (CursorLockMode)0;
				Cursor.visible = true;
			}
			catch
			{
			}
			ApplyCameraUnlockIfNeeded();
		}
	}

	private void ApplyCameraUnlockIfNeeded()
	{
		try
		{
			if (!((Object)(object)CameraFunction._current == (Object)null))
			{
				if (!_hasSavedCamera)
				{
					_savedCameraUnlocked = CameraFunction._current._unlockedCamera;
					_hasSavedCamera = true;
				}
				CameraFunction._current._unlockedCamera = true;
			}
		}
		catch
		{
		}
	}

	private void ReleaseGridMouseUnlockIfSafe()
	{
		if (_hasSavedCamera)
		{
			try
			{
				if ((Object)(object)CameraFunction._current != (Object)null)
				{
					CameraFunction._current._unlockedCamera = _savedCameraUnlocked;
				}
			}
			catch
			{
			}
			_hasSavedCamera = false;
		}
		ReleaseCursorStateIfSafe();
	}

	private void ReleasePlayerInUIState()
	{
		if (!_playerInUiForced || IsGameUiOrChatActive())
		{
			return;
		}
		try
		{
			Player mainPlayer = Player._mainPlayer;
			if ((Object)(object)mainPlayer != (Object)null)
			{
				mainPlayer._inUI = false;
			}
		}
		catch
		{
		}
		_playerInUiForced = false;
	}

	private bool IsGameUiOrChatActive()
	{
		try
		{
			Player mainPlayer = Player._mainPlayer;
			if ((Object)(object)mainPlayer != (Object)null)
			{
				if (mainPlayer._inChat)
				{
					return true;
				}
				if ((Object)(object)mainPlayer._chatBehaviour != (Object)null && mainPlayer._chatBehaviour._focusedInChat)
				{
					return true;
				}
			}
		}
		catch
		{
		}
		try
		{
			ChatBehaviour current = ChatBehaviour._current;
			if ((Object)(object)current != (Object)null && current._focusedInChat)
			{
				return true;
			}
		}
		catch
		{
		}
		try
		{
			if ((Object)(object)TabMenu._current != (Object)null && TabMenu._current._isOpen)
			{
				return true;
			}
		}
		catch
		{
		}
		try
		{
			if ((Object)(object)SettingsManager._current != (Object)null && SettingsManager._current._isOpen)
			{
				return true;
			}
		}
		catch
		{
		}
		try
		{
			if ((Object)(object)DialogManager._current != (Object)null && DialogManager._current._isDialogEnabled)
			{
				return true;
			}
		}
		catch
		{
		}
		return false;
	}

	private void ReleaseInputStateIfUnused()
	{
		if (_mainOpen || _gridOpen)
		{
			return;
		}
		if (_hasSavedCamera)
		{
			try
			{
				if ((Object)(object)CameraFunction._current != (Object)null)
				{
					CameraFunction._current._unlockedCamera = _savedCameraUnlocked;
				}
			}
			catch
			{
			}
			_hasSavedCamera = false;
		}
		ReleasePlayerInUIState();
		ReleaseCursorStateIfSafe();
	}

	private void ReleaseCursorStateIfSafe()
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		if (_hasSavedCursor && !_mainOpen && (!_gridOpen || !ShouldUnlockMouseForGridWindow()) && !IsGameUiOrChatActive())
		{
			try
			{
				Cursor.lockState = _savedCursorLock;
				Cursor.visible = _savedCursorVisible;
			}
			catch
			{
			}
			_hasSavedCursor = false;
		}
	}

	internal void OnGUI()
	{
		EnsureStyles();
		Event current = Event.current;
		UpdateInputBlockerState();
		if (IsCapturingKeyBind && HandleKeyBindCapture(current))
		{
			UpdateInputBlockerState();
			return;
		}
		if (_mainOpen)
		{
			DrawMainOnGUI();
		}
		if (_gridOpen)
		{
			DrawGridOnGUI();
		}
		UpdateInputBlockerState();
	}

	private void DrawMainOnGUI()
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Expected O, but got Unknown
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		Event current = Event.current;
		if (_mainResizing)
		{
			HandleResizeEvent(current, main: true);
		}
		_mainRect = GUI.Window(1162104113, _mainRect, new WindowFunction(DrawMainWindow), GUIContent.none, GetTransparentWindowStyle());
		ClampToScreen(ref _mainRect, 520f, 380f);
	}

	private void DrawGridOnGUI()
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Expected O, but got Unknown
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		Event current = Event.current;
		if (_gridResizing)
		{
			HandleResizeEvent(current, main: false);
		}
		_gridRect = GUI.Window(1162102577, _gridRect, new WindowFunction(DrawGridWindow), GUIContent.none, GetTransparentWindowStyle());
		ClampToScreen(ref _gridRect, 260f, 160f);
	}

	private void HandleResizeEvent(Event e, bool main)
	{
		//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_001e: Invalid comparison between Unknown and I4
		//IL_0077: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Invalid comparison between Unknown and I4
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0086: Invalid comparison between Unknown and I4
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_009f: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Unknown result type (might be due to invalid IL or missing references)
		//IL_015c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
		if (e == null)
		{
			return;
		}
		if ((int)e.rawType == 1 || (int)e.type == 1 || !Input.GetMouseButton(0))
		{
			if (main)
			{
				_mainResizing = false;
				SaveMainRect();
			}
			else
			{
				_gridResizing = false;
				SaveGridRect();
			}
			_plugin.SavePluginConfig();
			UseEventIfSafe(e);
		}
		else if ((int)e.type == 3 || (int)e.type == 2)
		{
			Vector2 guiMouseScreenPos = GetGuiMouseScreenPos();
			Vector2 val = guiMouseScreenPos - _resizeStart;
			if (main)
			{
				((Rect)(ref _mainRect)).width = Mathf.Max(520f, ((Rect)(ref _resizeOrig)).width + val.x);
				((Rect)(ref _mainRect)).height = Mathf.Max(380f, ((Rect)(ref _resizeOrig)).height + val.y);
				ClampToScreen(ref _mainRect, 520f, 380f);
			}
			else
			{
				((Rect)(ref _gridRect)).width = Mathf.Max(260f, ((Rect)(ref _resizeOrig)).width + val.x);
				((Rect)(ref _gridRect)).height = Mathf.Max(160f, ((Rect)(ref _resizeOrig)).height + val.y);
				ClampToScreen(ref _gridRect, 260f, 160f);
			}
			GUI.changed = true;
			UseEventIfSafe(e);
		}
	}

	private void DrawMainWindow(int id)
	{
		//IL_0076: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0096: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b6: 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_0196: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_0204: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_0269: Unknown result type (might be due to invalid IL or missing references)
		//IL_028e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0299: Unknown result type (might be due to invalid IL or missing references)
		//IL_029e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0310: Unknown result type (might be due to invalid IL or missing references)
		//IL_0315: Unknown result type (might be due to invalid IL or missing references)
		//IL_0318: Unknown result type (might be due to invalid IL or missing references)
		//IL_0323: Unknown result type (might be due to invalid IL or missing references)
		//IL_032a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0331: Unknown result type (might be due to invalid IL or missing references)
		//IL_0347: Unknown result type (might be due to invalid IL or missing references)
		//IL_03cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_03d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0405: Unknown result type (might be due to invalid IL or missing references)
		//IL_0449: Unknown result type (might be due to invalid IL or missing references)
		Rect val = default(Rect);
		((Rect)(ref val))..ctor(0f, 0f, ((Rect)(ref _mainRect)).width, ((Rect)(ref _mainRect)).height);
		Rect rect = default(Rect);
		((Rect)(ref rect))..ctor(0f, 0f, ((Rect)(ref _mainRect)).width, 26f);
		Rect rect2 = default(Rect);
		((Rect)(ref rect2))..ctor(0f, 26f, ((Rect)(ref _mainRect)).width, ((Rect)(ref _mainRect)).height - 26f);
		DrawSolid(val, new Color(0f, 0f, 0f, 0.02f));
		DrawSolid(rect, new Color(0.05f, 0.05f, 0.05f, 0.98f));
		DrawSolid(rect2, new Color(0f, 0f, 0f, Mathf.Clamp01(EmoteDeckPlugin.CfgMainOpacity.Value)));
		Rect val2 = default(Rect);
		((Rect)(ref val2))..ctor(((Rect)(ref _mainRect)).width - 26f, 3f, 22f, 20f);
		Rect val3 = default(Rect);
		((Rect)(ref val3))..ctor(((Rect)(ref val2)).x - 38f, 5f, 34f, 18f);
		Rect val4 = default(Rect);
		((Rect)(ref val4))..ctor(((Rect)(ref val3)).x - 92f, 7f, 88f, 14f);
		Rect val5 = default(Rect);
		((Rect)(ref val5))..ctor(((Rect)(ref val4)).x - 56f, 4f, 54f, 18f);
		Rect val6 = new Rect(8f, 4f, Mathf.Max(0f, ((Rect)(ref val5)).x - 10f), 18f);
		KeyCode mainWindowKey = _plugin.MainWindowKey;
		GUI.Label(val6, "ATLYSS Emote Deck  [" + ((object)(KeyCode)(ref mainWindowKey)).ToString() + "]", _headerStyle);
		GUI.Label(val5, "Opacity", _smallLabelStyle);
		float value = EmoteDeckPlugin.CfgMainOpacity.Value;
		float num = GUI.HorizontalSlider(val4, value, 0f, 1f);
		GUI.Label(val3, Mathf.RoundToInt(num * 100f).ToString(CultureInfo.InvariantCulture) + "%", _smallLabelStyle);
		if (Mathf.Abs(num - value) > 0.001f)
		{
			EmoteDeckPlugin.CfgMainOpacity.Value = num;
			_plugin.QueueConfigSave();
		}
		if (GUI.Button(val2, "X", _miniButtonStyle))
		{
			CloseMainWindow();
			return;
		}
		Rect windowContentRect = GetWindowContentRect(_mainRect, 26f, reserveResizeCorner: true);
		Rect rect3 = default(Rect);
		((Rect)(ref rect3))..ctor(((Rect)(ref windowContentRect)).x, Mathf.Max(((Rect)(ref windowContentRect)).y, ((Rect)(ref windowContentRect)).yMax - 28f), ((Rect)(ref windowContentRect)).width, 28f);
		((Rect)(ref windowContentRect)).height = Mathf.Max(40f, ((Rect)(ref windowContentRect)).height - 28f - 5f);
		((Rect)(ref rect3)).y = ((Rect)(ref windowContentRect)).yMax + 5f;
		bool flag = false;
		Color color = GUI.color;
		try
		{
			GUILayout.BeginArea(windowContentRect);
			flag = true;
			GUI.color = new Color(color.r, color.g, color.b, Mathf.Clamp01(EmoteDeckPlugin.CfgMainOpacity.Value));
			DrawTabs();
			DrawBindBannerIfNeeded();
			switch (_tab)
			{
			case 0:
				DrawSlotsTab();
				break;
			case 1:
				DrawPickerTab();
				break;
			case 2:
				DrawFiltersTab();
				break;
			case 3:
				DrawSettingsTab();
				break;
			default:
				DrawHelpTab();
				break;
			}
		}
		finally
		{
			GUI.color = color;
			if (flag)
			{
				GUILayout.EndArea();
			}
		}
		DrawMainFooter(rect3);
		ConsumeScrollWheelInsideLocalWindow(val);
		GUI.DragWindow(new Rect(0f, 0f, Mathf.Max(0f, ((Rect)(ref val5)).x - 8f), 26f));
		DrawResizeHandle(new Rect(((Rect)(ref _mainRect)).width - 16f - 3f, ((Rect)(ref _mainRect)).height - 16f - 3f, 16f, 16f), main: true);
	}

	private void DrawGridWindow(int id)
	{
		//IL_075a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
		//IL_0130: Unknown result type (might be due to invalid IL or missing references)
		//IL_0150: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0125: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_029c: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0345: Unknown result type (might be due to invalid IL or missing references)
		//IL_034a: Unknown result type (might be due to invalid IL or missing references)
		//IL_038d: Unknown result type (might be due to invalid IL or missing references)
		//IL_03ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_0465: Unknown result type (might be due to invalid IL or missing references)
		//IL_047a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0446: Unknown result type (might be due to invalid IL or missing references)
		//IL_04df: Unknown result type (might be due to invalid IL or missing references)
		//IL_0506: Unknown result type (might be due to invalid IL or missing references)
		//IL_050e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0516: Unknown result type (might be due to invalid IL or missing references)
		//IL_051e: Unknown result type (might be due to invalid IL or missing references)
		//IL_06c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_06cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_06d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_06f2: Unknown result type (might be due to invalid IL or missing references)
		//IL_06f7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0706: Unknown result type (might be due to invalid IL or missing references)
		//IL_0711: Unknown result type (might be due to invalid IL or missing references)
		//IL_0718: Unknown result type (might be due to invalid IL or missing references)
		//IL_071f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0735: Unknown result type (might be due to invalid IL or missing references)
		//IL_077a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0790: Unknown result type (might be due to invalid IL or missing references)
		//IL_07bc: Unknown result type (might be due to invalid IL or missing references)
		//IL_07e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0828: Unknown result type (might be due to invalid IL or missing references)
		//IL_07a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_07b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_069f: Unknown result type (might be due to invalid IL or missing references)
		//IL_06b2: Unknown result type (might be due to invalid IL or missing references)
		bool flag = EmoteDeckPlugin.CfgGridShowHeaderControls.Value;
		float num = (flag ? 50f : 25f);
		Rect val = default(Rect);
		((Rect)(ref val))..ctor(0f, 0f, ((Rect)(ref _gridRect)).width, ((Rect)(ref _gridRect)).height);
		Rect val2 = default(Rect);
		((Rect)(ref val2))..ctor(0f, 0f, ((Rect)(ref _gridRect)).width, num);
		Rect rect = default(Rect);
		((Rect)(ref rect))..ctor(0f, 0f, ((Rect)(ref _gridRect)).width, 25f);
		Rect rect2 = default(Rect);
		((Rect)(ref rect2))..ctor(0f, 25f, ((Rect)(ref _gridRect)).width, 25f);
		Rect rect3 = default(Rect);
		((Rect)(ref rect3))..ctor(0f, num, ((Rect)(ref _gridRect)).width, ((Rect)(ref _gridRect)).height - num);
		DrawSolid(val, new Color(0f, 0f, 0f, 0.02f));
		DrawSolid(rect, new Color(0.05f, 0.05f, 0.05f, 0.98f));
		if (flag)
		{
			DrawSolid(rect2, new Color(0.035f, 0.035f, 0.035f, 0.98f));
		}
		DrawSolid(rect3, new Color(0f, 0f, 0f, Mathf.Clamp01(EmoteDeckPlugin.CfgGridOpacity.Value)));
		Rect val3 = default(Rect);
		((Rect)(ref val3))..ctor(((Rect)(ref _gridRect)).width - 26f, 3f, 22f, 19f);
		bool flag2 = ((Rect)(ref _gridRect)).width >= 520f;
		bool flag3 = ((Rect)(ref _gridRect)).width < 440f;
		bool flag4 = ((Rect)(ref _gridRect)).width < 350f;
		float num2 = ((((Rect)(ref _gridRect)).width < 340f) ? 60f : ((((Rect)(ref _gridRect)).width < 400f) ? 70f : 84f));
		float num3 = ((((Rect)(ref _gridRect)).width < 340f) ? 30f : 34f);
		float num4 = (flag3 ? 38f : 76f);
		string text = (flag3 ? "Ctrl" : "Controls");
		Rect val4 = default(Rect);
		((Rect)(ref val4))..ctor(((Rect)(ref val3)).x - num3 - 4f, 5f, num3, 16f);
		Rect val5 = default(Rect);
		((Rect)(ref val5))..ctor(((Rect)(ref val4)).x - num2 - 4f, 7f, num2, 14f);
		Rect val6 = (flag2 ? new Rect(((Rect)(ref val5)).x - 54f, 4f, 50f, 16f) : new Rect(0f, 0f, 0f, 0f));
		float num5 = (flag2 ? (((Rect)(ref val6)).x - 10f) : (((Rect)(ref val5)).x - 10f));
		Rect val7 = default(Rect);
		((Rect)(ref val7))..ctor(num5 - num4, 3f, num4, 19f);
		bool flag5 = ((Rect)(ref val7)).x >= 82f;
		float num6 = (flag5 ? ((Rect)(ref val7)).x : (flag2 ? ((Rect)(ref val6)).x : ((Rect)(ref val5)).x));
		object obj;
		if (!flag4)
		{
			KeyCode gridWindowKey = _plugin.GridWindowKey;
			obj = "Emote Grid [" + ((object)(KeyCode)(ref gridWindowKey)).ToString() + "]";
		}
		else
		{
			obj = "Emote Grid";
		}
		string text2 = (string)obj;
		GUI.Label(new Rect(8f, 4f, Mathf.Max(0f, num6 - 10f), 18f), text2, _headerStyle);
		if (flag5)
		{
			bool flag6 = GUI.Toggle(val7, flag, text, GUI.skin.button);
			if (flag6 != flag)
			{
				EmoteDeckPlugin.CfgGridShowHeaderControls.Value = flag6;
				_plugin.SavePluginConfig();
				flag = flag6;
				if (!flag)
				{
					_gridViewDropdownOpen = false;
					_gridMouseModeDropdownOpen = false;
				}
				num = (flag ? 50f : 25f);
				((Rect)(ref rect3))..ctor(0f, num, ((Rect)(ref _gridRect)).width, ((Rect)(ref _gridRect)).height - num);
			}
		}
		if (flag2)
		{
			GUI.Label(val6, "Opacity", _smallLabelStyle);
		}
		float value = EmoteDeckPlugin.CfgGridOpacity.Value;
		float num7 = GUI.HorizontalSlider(val5, value, 0f, 1f);
		GUI.Label(val4, Mathf.RoundToInt(num7 * 100f).ToString(CultureInfo.InvariantCulture) + "%", _smallLabelStyle);
		if (Mathf.Abs(num7 - value) > 0.001f)
		{
			EmoteDeckPlugin.CfgGridOpacity.Value = num7;
			_plugin.QueueConfigSave();
		}
		if (GUI.Button(val3, "X", _miniButtonStyle))
		{
			CloseGridWindow();
			return;
		}
		Rect val8 = default(Rect);
		Rect rect4 = default(Rect);
		Rect val9 = default(Rect);
		Rect rect5 = default(Rect);
		bool flag7 = false;
		if (flag)
		{
			float num8 = 8f;
			float num9 = 29f;
			bool flag8 = ((Rect)(ref _gridRect)).width < 340f;
			float num10 = (flag8 ? 28f : 32f);
			float num11 = ((((Rect)(ref _gridRect)).width < 300f) ? 82f : ((((Rect)(ref _gridRect)).width < 360f) ? 96f : 112f));
			float num12 = (flag8 ? 44f : 74f);
			float num13 = ((((Rect)(ref _gridRect)).width < 300f) ? 68f : ((((Rect)(ref _