Decompiled source of Emote Deck v1.1.0
plugins/Emote_Deck/Emote_Deck.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
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 _