Decompiled source of ConsumableHotkeys v1.0.6

BepInEx/plugins/ConsumableHotkeys.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Pigeon;
using Pigeon.Movement;
using Sparroh.UI;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Sparroh")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.6.0")]
[assembly: AssemblyInformationalVersion("1.0.6")]
[assembly: AssemblyProduct("ConsumableHotkeys")]
[assembly: AssemblyTitle("ConsumableHotkeys")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.6.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public static class ConfigManager
{
	private const float DebounceSeconds = 0.25f;

	private static ConfigFile config;

	private static ManualLogSource logger;

	private static FileSystemWatcher configWatcher;

	private static volatile bool pendingRefresh;

	private static volatile bool reloadPending;

	private static float lastReloadTime;

	public static ConfigEntry<bool> EnableHotkeys { get; private set; }

	public static ConfigEntry<bool> EnableHUD { get; private set; }

	public static ConfigEntry<Key> PersonalAccessTokenHotkey { get; private set; }

	public static ConfigEntry<Key> PremiumLootLicenseHotkey { get; private set; }

	public static ConfigEntry<Key> BootlegReplicatorHotkey { get; private set; }

	public static ConfigEntry<Key> ClearanceCertificateHotkey { get; private set; }

	public static HudAnchors Anchors { get; private set; }

	public static ConfigColor ActiveColor { get; private set; }

	public static ConfigColor InactiveColor { get; private set; }

	public static void Initialize(ConfigFile configFile, ManualLogSource log)
	{
		//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
		//IL_011f: Unknown result type (might be due to invalid IL or missing references)
		config = configFile;
		logger = log;
		EnableHotkeys = config.Bind<bool>("Consumables", "Enable Hotkeys", true, "Enables hotkey functionality for consumables.");
		EnableHUD = config.Bind<bool>("Consumables", "Enable HUD", true, "Enables the HUD display for consumable statuses.");
		PersonalAccessTokenHotkey = config.Bind<Key>("Consumables", "PersonalAccessToken Key", (Key)22, "Hotkey for Personal Access Token.");
		PremiumLootLicenseHotkey = config.Bind<Key>("Consumables", "PremiumLootLicense Key", (Key)24, "Hotkey for Premium Loot License.");
		BootlegReplicatorHotkey = config.Bind<Key>("Consumables", "BootlegReplicator Key", (Key)25, "Hotkey for Bootleg Replicator.");
		ClearanceCertificateHotkey = config.Bind<Key>("Consumables", "ClearanceCertificate Key", (Key)26, "Hotkey for Clearance Certificate.");
		Anchors = HudAnchors.Bind(config, "HUD", 0.2561931f, 0.9362161f, "HUD Positioning");
		ActiveColor = ConfigColor.Bind(config, "Colors", "Active Color", UIColors.Shamrock, "Rich-text color for active consumables (hex RRGGBB or #RRGGBB).");
		InactiveColor = ConfigColor.Bind(config, "Colors", "Inactive Color", UIColors.Rose, "Rich-text color for inactive consumables (hex RRGGBB or #RRGGBB).");
		EnableHotkeys.SettingChanged += OnSettingChanged;
		EnableHUD.SettingChanged += OnSettingChanged;
		PersonalAccessTokenHotkey.SettingChanged += OnSettingChanged;
		PremiumLootLicenseHotkey.SettingChanged += OnSettingChanged;
		BootlegReplicatorHotkey.SettingChanged += OnSettingChanged;
		ClearanceCertificateHotkey.SettingChanged += OnSettingChanged;
		ActiveColor.Entry.SettingChanged += OnSettingChanged;
		InactiveColor.Entry.SettingChanged += OnSettingChanged;
		try
		{
			SetupFileWatcher();
		}
		catch (Exception ex)
		{
			logger.LogError((object)("Error setting up config file watcher: " + ex.Message));
		}
	}

	public static void Tick()
	{
		if (!reloadPending || Time.unscaledTime - lastReloadTime < 0.25f)
		{
			return;
		}
		reloadPending = false;
		lastReloadTime = Time.unscaledTime;
		try
		{
			config.Reload();
			pendingRefresh = true;
			logger.LogInfo((object)"Config reloaded from disk.");
		}
		catch (Exception ex)
		{
			logger.LogError((object)("Error reloading config: " + ex.Message));
		}
	}

	public static bool ConsumePendingRefresh()
	{
		if (!pendingRefresh)
		{
			return false;
		}
		pendingRefresh = false;
		return true;
	}

	public static void Dispose()
	{
		if (EnableHotkeys != null)
		{
			EnableHotkeys.SettingChanged -= OnSettingChanged;
		}
		if (EnableHUD != null)
		{
			EnableHUD.SettingChanged -= OnSettingChanged;
		}
		if (PersonalAccessTokenHotkey != null)
		{
			PersonalAccessTokenHotkey.SettingChanged -= OnSettingChanged;
		}
		if (PremiumLootLicenseHotkey != null)
		{
			PremiumLootLicenseHotkey.SettingChanged -= OnSettingChanged;
		}
		if (BootlegReplicatorHotkey != null)
		{
			BootlegReplicatorHotkey.SettingChanged -= OnSettingChanged;
		}
		if (ClearanceCertificateHotkey != null)
		{
			ClearanceCertificateHotkey.SettingChanged -= OnSettingChanged;
		}
		try
		{
			ConfigColor activeColor = ActiveColor;
			if (((activeColor != null) ? activeColor.Entry : null) != null)
			{
				ActiveColor.Entry.SettingChanged -= OnSettingChanged;
			}
			ConfigColor inactiveColor = InactiveColor;
			if (((inactiveColor != null) ? inactiveColor.Entry : null) != null)
			{
				InactiveColor.Entry.SettingChanged -= OnSettingChanged;
			}
		}
		catch
		{
		}
		if (configWatcher != null)
		{
			configWatcher.EnableRaisingEvents = false;
			configWatcher.Changed -= OnConfigFileChanged;
			configWatcher.Created -= OnConfigFileChanged;
			configWatcher.Renamed -= OnConfigFileChanged;
			configWatcher.Dispose();
			configWatcher = null;
		}
	}

	private static void SetupFileWatcher()
	{
		configWatcher = new FileSystemWatcher(Paths.ConfigPath, "sparroh.consumablehotkeys.cfg");
		configWatcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite;
		configWatcher.Changed += OnConfigFileChanged;
		configWatcher.Created += OnConfigFileChanged;
		configWatcher.Renamed += OnConfigFileChanged;
		configWatcher.EnableRaisingEvents = true;
	}

	private static void OnConfigFileChanged(object sender, FileSystemEventArgs e)
	{
		reloadPending = true;
	}

	private static void OnSettingChanged(object sender, EventArgs e)
	{
		pendingRefresh = true;
	}
}
public class ConsumableHotkeysMod
{
	private class ConsumableStatus
	{
		public bool IsActive { get; set; }

		public int UsesRemaining { get; set; } = -1;

		public int MaxUses { get; set; } = -1;
	}

	private const string PersonalAccessTokenName = "Personal Access Token";

	private const string PremiumLootLicenseName = "Premium Loot License";

	private const string BootlegReplicatorName = "Bootleg Replicator";

	private const string ClearanceCertificateName = "Clearance Certificate";

	private const int ClearanceCertificateMaxUses = 5;

	private const float HudPollIntervalSeconds = 0.25f;

	private static FieldInfo _storageSlotsField;

	private static FieldInfo _slotItemField;

	private static FieldInfo _onPrimaryActionField;

	private static bool _reflectionResolved;

	private readonly Dictionary<string, ConsumableStatus> consumableStatuses;

	private readonly Dictionary<string, PlayerResource> resourceCache = new Dictionary<string, PlayerResource>();

	private readonly string[] lastLineTexts = new string[4];

	private HudHandle hud;

	private float nextHudPollTime;

	private bool hudRefreshRequested = true;

	private bool resourceCacheBuilt;

	private int lastHudStateHash;

	private bool hasHudStateHash;

	private InputActionMap controls;

	private InputAction patAction;

	private InputAction pllAction;

	private InputAction replicatorAction;

	private InputAction clearanceAction;

	private Action<CallbackContext> patPerformed;

	private Action<CallbackContext> pllPerformed;

	private Action<CallbackContext> replicatorPerformed;

	private Action<CallbackContext> clearancePerformed;

	public static ConsumableHotkeysMod Instance { get; private set; }

	private bool IsHudAlive
	{
		get
		{
			if (HudHandle.IsValid(hud) && hud.Lines != null)
			{
				return hud.Lines.Length >= 4;
			}
			return false;
		}
	}

	public ConsumableHotkeysMod()
	{
		Instance = this;
		try
		{
			consumableStatuses = new Dictionary<string, ConsumableStatus>
			{
				{
					"Personal Access Token",
					new ConsumableStatus()
				},
				{
					"Premium Loot License",
					new ConsumableStatus()
				},
				{
					"Bootleg Replicator",
					new ConsumableStatus()
				},
				{
					"Clearance Certificate",
					new ConsumableStatus
					{
						MaxUses = 5,
						UsesRemaining = 5
					}
				}
			};
			SetupHotkeyActions();
		}
		catch (Exception ex)
		{
			SparrohPlugin.Logger.LogError((object)("Failed to initialize ConsumableHotkeys: " + ex.Message));
		}
	}

	public void OnConfigChanged()
	{
		if (!ConfigManager.EnableHUD.Value && HudHandle.IsValid(hud))
		{
			DestroyHud();
		}
		InvalidateHudTextCache();
		hudRefreshRequested = true;
		UpdateHudVisibility();
		RefreshHotkeyActions();
	}

	public void RequestHudRefresh()
	{
		hudRefreshRequested = true;
	}

	public void UpdateHudVisibility()
	{
		if (!IsHudAlive)
		{
			ClearDestroyedHud();
		}
		else
		{
			hud.SetActive(ConfigManager.EnableHUD.Value);
		}
	}

	private void InvalidateHudTextCache()
	{
		for (int i = 0; i < lastLineTexts.Length; i++)
		{
			lastLineTexts[i] = null;
		}
		hasHudStateHash = false;
	}

	private void ClearDestroyedHud()
	{
		if (hud != null)
		{
			hud = null;
			InvalidateHudTextCache();
		}
	}

	private void DestroyHud()
	{
		if (hud != null)
		{
			if (hud.IsAlive)
			{
				hud.Destroy();
			}
			hud = null;
		}
		InvalidateHudTextCache();
	}

	private void CreateHUD()
	{
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		if (IsHudAlive)
		{
			return;
		}
		ClearDestroyedHud();
		if (!((Object)(object)Player.LocalPlayer == (Object)null) && !((Object)(object)Player.LocalPlayer.PlayerLook == (Object)null) && !((Object)(object)Player.LocalPlayer.PlayerLook.Reticle == (Object)null))
		{
			hud = HudBuilder.Create("TicketStatusHUD").ParentToReticle(true).Anchor(ConfigManager.Anchors.XValue, ConfigManager.Anchors.YValue)
				.Pivot(new Vector2(0f, 1f))
				.Size(420f, 100f, true)
				.AddLines(4, 16f, (TextAlignmentOptions)257)
				.Build();
			if (IsHudAlive)
			{
				hud.EnableReposition("sparroh.consumablehotkeys", "Consumable Hotkeys", ConfigManager.Anchors);
				InvalidateHudTextCache();
				hudRefreshRequested = true;
				UpdateHudVisibility();
			}
		}
	}

	public void Update()
	{
		try
		{
			if (ConfigManager.EnableHUD == null || !ConfigManager.EnableHUD.Value)
			{
				if (IsHudAlive)
				{
					hud.SetActive(false);
				}
				return;
			}
			if (hud != null && !IsHudAlive)
			{
				ClearDestroyedHud();
			}
			if ((Object)(object)Player.LocalPlayer == (Object)null || (Object)(object)Player.LocalPlayer.PlayerLook == (Object)null || (Object)(object)Player.LocalPlayer.PlayerLook.Reticle == (Object)null)
			{
				return;
			}
			if (!IsHudAlive)
			{
				CreateHUD();
			}
			else if (consumableStatuses != null)
			{
				float unscaledTime = Time.unscaledTime;
				if (hudRefreshRequested || !(unscaledTime < nextHudPollTime))
				{
					nextHudPollTime = unscaledTime + 0.25f;
					hudRefreshRequested = false;
					RefreshHudIfNeeded();
				}
			}
		}
		catch (Exception ex)
		{
			SparrohPlugin.Logger.LogError((object)("Error in ConsumableHotkeys.Update(): " + ex.Message));
		}
	}

	private void SetupHotkeyActions()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Expected O, but got Unknown
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a9: 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_00c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e5: 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)
		controls = new InputActionMap("ConsumableHotkeys");
		patAction = InputActionSetupExtensions.AddAction(controls, "PersonalAccessToken", (InputActionType)1, (string)null, (string)null, (string)null, (string)null, (string)null);
		pllAction = InputActionSetupExtensions.AddAction(controls, "PremiumLootLicense", (InputActionType)1, (string)null, (string)null, (string)null, (string)null, (string)null);
		replicatorAction = InputActionSetupExtensions.AddAction(controls, "BootlegReplicator", (InputActionType)1, (string)null, (string)null, (string)null, (string)null, (string)null);
		clearanceAction = InputActionSetupExtensions.AddAction(controls, "ClearanceCertificate", (InputActionType)1, (string)null, (string)null, (string)null, (string)null, (string)null);
		InputActionSetupExtensions.AddBinding(patAction, KeyToBindingPath(ConfigManager.PersonalAccessTokenHotkey.Value), (string)null, (string)null, (string)null);
		InputActionSetupExtensions.AddBinding(pllAction, KeyToBindingPath(ConfigManager.PremiumLootLicenseHotkey.Value), (string)null, (string)null, (string)null);
		InputActionSetupExtensions.AddBinding(replicatorAction, KeyToBindingPath(ConfigManager.BootlegReplicatorHotkey.Value), (string)null, (string)null, (string)null);
		InputActionSetupExtensions.AddBinding(clearanceAction, KeyToBindingPath(ConfigManager.ClearanceCertificateHotkey.Value), (string)null, (string)null, (string)null);
		patPerformed = delegate
		{
			OnHotkeyPerformed("Personal Access Token");
		};
		pllPerformed = delegate
		{
			OnHotkeyPerformed("Premium Loot License");
		};
		replicatorPerformed = delegate
		{
			OnHotkeyPerformed("Bootleg Replicator");
		};
		clearancePerformed = delegate
		{
			OnHotkeyPerformed("Clearance Certificate");
		};
		patAction.performed += patPerformed;
		pllAction.performed += pllPerformed;
		replicatorAction.performed += replicatorPerformed;
		clearanceAction.performed += clearancePerformed;
		ApplyHotkeyMapEnabled();
	}

	private void RefreshHotkeyActions()
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		if (controls == null)
		{
			return;
		}
		try
		{
			ApplyBinding(patAction, ConfigManager.PersonalAccessTokenHotkey.Value);
			ApplyBinding(pllAction, ConfigManager.PremiumLootLicenseHotkey.Value);
			ApplyBinding(replicatorAction, ConfigManager.BootlegReplicatorHotkey.Value);
			ApplyBinding(clearanceAction, ConfigManager.ClearanceCertificateHotkey.Value);
			ApplyHotkeyMapEnabled();
		}
		catch (Exception ex)
		{
			SparrohPlugin.Logger.LogError((object)("Failed to refresh hotkey bindings: " + ex.Message));
		}
	}

	private void ApplyHotkeyMapEnabled()
	{
		if (controls == null)
		{
			return;
		}
		if (ConfigManager.EnableHotkeys != null && ConfigManager.EnableHotkeys.Value)
		{
			if (!controls.enabled)
			{
				controls.Enable();
			}
		}
		else if (controls.enabled)
		{
			controls.Disable();
		}
	}

	private static void ApplyBinding(InputAction action, Key key)
	{
		//IL_0004: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		if (action != null)
		{
			string text = KeyToBindingPath(key);
			if (action.bindings.Count == 0)
			{
				InputActionSetupExtensions.AddBinding(action, text, (string)null, (string)null, (string)null);
			}
			else
			{
				InputActionRebindingExtensions.ApplyBindingOverride(action, 0, text);
			}
		}
	}

	internal unsafe static string KeyToBindingPath(Key key)
	{
		//IL_0000: 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_000c: Invalid comparison between Unknown and I4
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Invalid comparison between Unknown and I4
		//IL_001a: 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_001e: Unknown result type (might be due to invalid IL or missing references)
		if ((int)key == 0)
		{
			return string.Empty;
		}
		if ((int)key >= 50 && (int)key <= 49)
		{
			return $"<Keyboard>/{(char)(48 + (key - 50))}";
		}
		string text = ((object)(*(Key*)(&key))/*cast due to .constrained prefix*/).ToString();
		if (text.Length == 0)
		{
			return string.Empty;
		}
		StringBuilder stringBuilder = new StringBuilder(text.Length + 12);
		stringBuilder.Append("<Keyboard>/");
		stringBuilder.Append(char.ToLowerInvariant(text[0]));
		if (text.Length > 1)
		{
			stringBuilder.Append(text, 1, text.Length - 1);
		}
		return stringBuilder.ToString();
	}

	private void OnHotkeyPerformed(string consumableName)
	{
		try
		{
			if (ConfigManager.EnableHotkeys != null && ConfigManager.EnableHotkeys.Value && !ShouldBlockHotkeys())
			{
				UseConsumable(consumableName);
			}
		}
		catch (Exception ex)
		{
			SparrohPlugin.Logger.LogError((object)("Error handling hotkey for " + consumableName + ": " + ex.Message));
		}
	}

	private void DisposeHotkeyActions()
	{
		if (controls == null)
		{
			return;
		}
		try
		{
			if (patAction != null && patPerformed != null)
			{
				patAction.performed -= patPerformed;
			}
			if (pllAction != null && pllPerformed != null)
			{
				pllAction.performed -= pllPerformed;
			}
			if (replicatorAction != null && replicatorPerformed != null)
			{
				replicatorAction.performed -= replicatorPerformed;
			}
			if (clearanceAction != null && clearancePerformed != null)
			{
				clearanceAction.performed -= clearancePerformed;
			}
			controls.Disable();
			controls.Dispose();
		}
		catch (Exception ex)
		{
			SparrohPlugin.Logger.LogError((object)("Error disposing hotkey actions: " + ex.Message));
		}
		finally
		{
			controls = null;
			patAction = null;
			pllAction = null;
			replicatorAction = null;
			clearanceAction = null;
			patPerformed = null;
			pllPerformed = null;
			replicatorPerformed = null;
			clearancePerformed = null;
		}
	}

	private void RefreshHudIfNeeded()
	{
		//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
		//IL_0100: Unknown result type (might be due to invalid IL or missing references)
		//IL_0116: 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_0201: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_0237: Unknown result type (might be due to invalid IL or missing references)
		//IL_022b: Unknown result type (might be due to invalid IL or missing references)
		//IL_026d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0261: Unknown result type (might be due to invalid IL or missing references)
		//IL_02b9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
		if (IsHudAlive && consumableStatuses != null && PlayerData.Instance != null)
		{
			EnsureResourceCache();
			bool flag = PlayerData.Instance.GetFlag("pa_token") == 1;
			bool flag2 = PlayerData.Instance.GetFlag("equip_loot") == 1;
			bool flag3 = PlayerData.Instance.GetFlag("r_replicator") == 1;
			int flag4 = PlayerData.Instance.GetFlag("dur_drops");
			consumableStatuses["Personal Access Token"].IsActive = flag;
			consumableStatuses["Premium Loot License"].IsActive = flag2;
			consumableStatuses["Bootleg Replicator"].IsActive = flag3;
			consumableStatuses["Clearance Certificate"].IsActive = flag4 > 0;
			int currentItemCount = GetCurrentItemCount("Personal Access Token");
			int currentItemCount2 = GetCurrentItemCount("Premium Loot License");
			int currentItemCount3 = GetCurrentItemCount("Bootleg Replicator");
			int currentItemCount4 = GetCurrentItemCount("Clearance Certificate");
			int hashCode = ((object)ConfigManager.ActiveColor.Value/*cast due to .constrained prefix*/).GetHashCode();
			int hashCode2 = ((object)ConfigManager.InactiveColor.Value/*cast due to .constrained prefix*/).GetHashCode();
			int hashCode3 = flag.GetHashCode();
			hashCode3 = (hashCode3 * 397) ^ flag2.GetHashCode();
			hashCode3 = (hashCode3 * 397) ^ flag3.GetHashCode();
			hashCode3 = (hashCode3 * 397) ^ flag4;
			hashCode3 = (hashCode3 * 397) ^ currentItemCount;
			hashCode3 = (hashCode3 * 397) ^ currentItemCount2;
			hashCode3 = (hashCode3 * 397) ^ currentItemCount3;
			hashCode3 = (hashCode3 * 397) ^ currentItemCount4;
			hashCode3 = (hashCode3 * 397) ^ hashCode;
			hashCode3 = (hashCode3 * 397) ^ hashCode2;
			if (!hasHudStateHash || hashCode3 != lastHudStateHash)
			{
				lastHudStateHash = hashCode3;
				hasHudStateHash = true;
				WriteHudLine(0, "PAT", flag ? "Active" : "Inactive", currentItemCount, flag ? ConfigManager.ActiveColor.Value : ConfigManager.InactiveColor.Value);
				WriteHudLine(1, "PLL", flag2 ? "Active" : "Inactive", currentItemCount2, flag2 ? ConfigManager.ActiveColor.Value : ConfigManager.InactiveColor.Value);
				WriteHudLine(2, "Replicator", flag3 ? "Active" : "Inactive", currentItemCount3, flag3 ? ConfigManager.ActiveColor.Value : ConfigManager.InactiveColor.Value);
				string statusText = ((flag4 == 0) ? "Inactive" : $"{flag4}/{5} Uses");
				WriteHudLine(3, "Clearance", statusText, currentItemCount4, (flag4 > 0) ? ConfigManager.ActiveColor.Value : ConfigManager.InactiveColor.Value);
			}
		}
	}

	private void WriteHudLine(int index, string shortName, string statusText, int count, Color color)
	{
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		if (index >= 0 && index < hud.Lines.Length)
		{
			string text = RichText.Labeled(shortName, $"{statusText} ({count})", color);
			if (!(lastLineTexts[index] == text))
			{
				lastLineTexts[index] = text;
				hud.Lines[index].Text = text;
			}
		}
	}

	private void EnsureResourceCache()
	{
		if (resourceCacheBuilt || (Object)(object)Global.Instance == (Object)null || Global.Instance.PlayerResources == null)
		{
			return;
		}
		resourceCache.Clear();
		bool flag = false;
		PlayerResource[] playerResources = Global.Instance.PlayerResources;
		foreach (PlayerResource val in playerResources)
		{
			flag = true;
			if (!((Object)(object)val == (Object)null) && !string.IsNullOrEmpty(val.Name) && consumableStatuses != null && consumableStatuses.ContainsKey(val.Name))
			{
				resourceCache[val.Name] = val;
			}
		}
		if (resourceCache.Count > 0 || flag)
		{
			resourceCacheBuilt = true;
		}
	}

	private int GetCurrentItemCount(string itemName)
	{
		if (PlayerData.Instance == null)
		{
			return 0;
		}
		if (resourceCache.TryGetValue(itemName, out var value) && (Object)(object)value != (Object)null)
		{
			return PlayerData.Instance.GetResource(value);
		}
		if ((Object)(object)Global.Instance == (Object)null || Global.Instance.PlayerResources == null)
		{
			return 0;
		}
		PlayerResource[] playerResources = Global.Instance.PlayerResources;
		foreach (PlayerResource val in playerResources)
		{
			if (!((Object)(object)val == (Object)null) && !(val.Name != itemName))
			{
				resourceCache[itemName] = val;
				return PlayerData.Instance.GetResource(val);
			}
		}
		return 0;
	}

	private static bool ShouldBlockHotkeys()
	{
		if ((Object)(object)Player.LocalPlayer == (Object)null)
		{
			return true;
		}
		try
		{
			if ((Object)(object)Menu.Instance != (Object)null && Menu.Instance.IsOpen)
			{
				return true;
			}
			if (PlayerInput.IsMenuEnabled)
			{
				return true;
			}
			if (!PlayerInput.IsPlayerEnabled)
			{
				return true;
			}
			if ((Object)(object)GameManager.Instance != (Object)null && (Object)(object)GameManager.Instance.WindowSystem != (Object)null && GameManager.Instance.WindowSystem.Count > 0)
			{
				return true;
			}
		}
		catch
		{
		}
		if (IsTextInputFocused())
		{
			return true;
		}
		if (ModMenuOpenDetector.IsAnyOpen())
		{
			return true;
		}
		return false;
	}

	private static bool IsTextInputFocused()
	{
		try
		{
			EventSystem current = EventSystem.current;
			if ((Object)(object)current == (Object)null)
			{
				return false;
			}
			GameObject currentSelectedGameObject = current.currentSelectedGameObject;
			if ((Object)(object)currentSelectedGameObject == (Object)null)
			{
				return false;
			}
			TMP_InputField component = currentSelectedGameObject.GetComponent<TMP_InputField>();
			if ((Object)(object)component != (Object)null && component.isFocused)
			{
				return true;
			}
			InputField component2 = currentSelectedGameObject.GetComponent<InputField>();
			if ((Object)(object)component2 != (Object)null && component2.isFocused)
			{
				return true;
			}
		}
		catch
		{
		}
		return false;
	}

	private void UseConsumable(string name)
	{
		TryActivateConsumableByName(name);
		UpdateConsumableStatus(name);
		hudRefreshRequested = true;
		nextHudPollTime = 0f;
	}

	private void TryActivateConsumableByName(string name)
	{
		EnsureActivationReflection();
		StorageWindow[] array = Object.FindObjectsOfType<StorageWindow>();
		foreach (StorageWindow storageWindow in array)
		{
			if (TryActivateFromStorageWindow(storageWindow, name))
			{
				return;
			}
		}
		TryDirectActivation(name);
	}

	private static void EnsureActivationReflection()
	{
		if (!_reflectionResolved)
		{
			_reflectionResolved = true;
			_storageSlotsField = typeof(StorageWindow).GetField("slots", BindingFlags.Instance | BindingFlags.NonPublic);
			_slotItemField = typeof(StorageSlot).GetField("item", BindingFlags.Instance | BindingFlags.NonPublic);
			_onPrimaryActionField = typeof(PlayerResource).GetField("onPrimaryAction", BindingFlags.Instance | BindingFlags.NonPublic);
		}
	}

	private bool TryActivateFromStorageWindow(StorageWindow storageWindow, string itemName)
	{
		try
		{
			if (_storageSlotsField == null || _slotItemField == null)
			{
				return false;
			}
			if (!(_storageSlotsField.GetValue(storageWindow) is StorageSlot[] array))
			{
				return false;
			}
			StorageSlot[] array2 = array;
			InputAction val3 = default(InputAction);
			string text = default(string);
			foreach (StorageSlot obj in array2)
			{
				object? value = _slotItemField.GetValue(obj);
				IInventoryItem val = (IInventoryItem)((value is IInventoryItem) ? value : null);
				if (val == null)
				{
					continue;
				}
				PlayerResource val2 = (PlayerResource)(object)((val is PlayerResource) ? val : null);
				if (val2 != null && !(val2.Name != itemName) && val.ItemCount > 0 && ((IHoverInfo)val).GetPrimaryBinding(ref val3, ref text))
				{
					object? obj2 = _onPrimaryActionField?.GetValue(val2);
					UnityEvent val4 = (UnityEvent)((obj2 is UnityEvent) ? obj2 : null);
					if (val4 != null)
					{
						val4.Invoke();
						return true;
					}
				}
			}
		}
		catch (Exception ex)
		{
			SparrohPlugin.Logger.LogError((object)("Error activating " + itemName + " from storage: " + ex.Message));
		}
		return false;
	}

	private void TryDirectActivation(string itemName)
	{
		if (PlayerData.Instance == null || IsConsumableActive(itemName))
		{
			return;
		}
		EnsureResourceCache();
		PlayerResource value = null;
		if (!resourceCache.TryGetValue(itemName, out value) || (Object)(object)value == (Object)null)
		{
			if (Global.Instance?.PlayerResources == null)
			{
				return;
			}
			PlayerResource[] playerResources = Global.Instance.PlayerResources;
			foreach (PlayerResource val in playerResources)
			{
				if (!((Object)(object)val == (Object)null) && !(val.Name != itemName))
				{
					value = val;
					resourceCache[itemName] = val;
					break;
				}
			}
		}
		if (!((Object)(object)value == (Object)null) && PlayerData.Instance.GetResource(value) > 0 && PlayerData.Instance.TryRemoveResource(value, 1))
		{
			ActivateConsumableByFlag(itemName);
		}
	}

	private bool IsConsumableActive(string name)
	{
		if (PlayerData.Instance == null)
		{
			return false;
		}
		return name switch
		{
			"Personal Access Token" => PlayerData.Instance.GetFlag("pa_token") == 1, 
			"Bootleg Replicator" => PlayerData.Instance.GetFlag("r_replicator") == 1, 
			"Premium Loot License" => PlayerData.Instance.GetFlag("equip_loot") == 1, 
			"Clearance Certificate" => PlayerData.Instance.GetFlag("dur_drops") > 0, 
			_ => false, 
		};
	}

	private void ActivateConsumableByFlag(string name)
	{
		if (PlayerData.Instance != null)
		{
			switch (name)
			{
			case "Personal Access Token":
				PlayerData.Instance.SetFlag("pa_token", 1);
				break;
			case "Bootleg Replicator":
				PlayerData.Instance.SetFlag("r_replicator", 1);
				break;
			case "Premium Loot License":
				PlayerData.Instance.SetFlag("equip_loot", 1);
				break;
			case "Clearance Certificate":
				PlayerData.Instance.SetFlag("dur_drops", 5);
				break;
			}
		}
	}

	private void UpdateConsumableStatus(string name)
	{
		if (consumableStatuses != null && consumableStatuses.TryGetValue(name, out var value))
		{
			value.IsActive = IsConsumableActive(name);
		}
	}

	public void UpdateConsumableStatuses()
	{
		if (consumableStatuses == null)
		{
			return;
		}
		foreach (KeyValuePair<string, ConsumableStatus> consumableStatus in consumableStatuses)
		{
			consumableStatus.Value.IsActive = IsConsumableActive(consumableStatus.Key);
		}
		hudRefreshRequested = true;
	}

	public void OnDestroy()
	{
		try
		{
			DisposeHotkeyActions();
		}
		catch (Exception ex)
		{
			SparrohPlugin.Logger.LogError((object)("Error disposing hotkeys: " + ex.Message));
		}
		try
		{
			DestroyHud();
		}
		catch (Exception ex2)
		{
			SparrohPlugin.Logger.LogError((object)("Error in ConsumableHotkeys.OnDestroy(): " + ex2.Message));
		}
	}
}
[HarmonyPatch]
public static class ConsumablePatches
{
	[HarmonyPostfix]
	[HarmonyPatch(typeof(PlayerData), "SetFlag", new Type[]
	{
		typeof(string),
		typeof(int)
	})]
	public static void PostfixSetFlag(string id, int value)
	{
		if (id != null && id.Length >= 7 && id.Length <= 12 && (!(id != "pa_token") || !(id != "r_replicator") || !(id != "equip_loot") || !(id != "dur_drops")))
		{
			ConsumableHotkeysMod.Instance?.RequestHudRefresh();
		}
	}

	[HarmonyPostfix]
	[HarmonyPatch(typeof(MissionManager), "OnUpgradeCollected")]
	public static void PostfixOnUpgradeCollected(UpgradeInstance upgrade)
	{
		if (((upgrade != null) ? upgrade.Gear : null) != null && PlayerData.Instance != null)
		{
			int flag = PlayerData.Instance.GetFlag("dur_drops");
			if (flag > 0)
			{
				PlayerData.Instance.SetFlag("dur_drops", flag - 1);
			}
		}
	}
}
internal static class ModMenuOpenDetector
{
	private static readonly string[] KnownTypeNames = new string[11]
	{
		"ModConfigGUI", "HudRepositionMode", "CheatMenu", "CheatMenuGUI", "CheatMenuPlus", "CheatMenuUI", "ForceModifiers", "ForceModifiersGUI", "ForceModifiersMenu", "ForceModifierMenu",
		"ForceModifiersUI"
	};

	private static readonly string[] OpenMemberNames = new string[6] { "IsVisible", "IsOpen", "IsActive", "IsHeld", "Visible", "Open" };

	private static readonly List<PropertyInfo> OpenProps = new List<PropertyInfo>();

	private static readonly List<FieldInfo> OpenFields = new List<FieldInfo>();

	private static bool resolved;

	public static bool IsAnyOpen()
	{
		EnsureResolved();
		bool flag = default(bool);
		for (int i = 0; i < OpenProps.Count; i++)
		{
			try
			{
				object value = OpenProps[i].GetValue(null);
				int num;
				if (value is bool)
				{
					flag = (bool)value;
					num = 1;
				}
				else
				{
					num = 0;
				}
				if (((uint)num & (flag ? 1u : 0u)) != 0)
				{
					return true;
				}
			}
			catch
			{
			}
		}
		bool flag2 = default(bool);
		for (int j = 0; j < OpenFields.Count; j++)
		{
			try
			{
				object value = OpenFields[j].GetValue(null);
				int num2;
				if (value is bool)
				{
					flag2 = (bool)value;
					num2 = 1;
				}
				else
				{
					num2 = 0;
				}
				if (((uint)num2 & (flag2 ? 1u : 0u)) != 0)
				{
					return true;
				}
			}
			catch
			{
			}
		}
		return false;
	}

	private static void EnsureResolved()
	{
		if (resolved)
		{
			return;
		}
		resolved = true;
		Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
		foreach (Assembly assembly in assemblies)
		{
			for (int j = 0; j < KnownTypeNames.Length; j++)
			{
				Type type;
				try
				{
					type = assembly.GetType(KnownTypeNames[j], throwOnError: false);
				}
				catch
				{
					continue;
				}
				if (!(type == null) && type.IsClass)
				{
					CollectOpenMembers(type);
				}
			}
		}
	}

	private static void CollectOpenMembers(Type type)
	{
		for (int i = 0; i < OpenMemberNames.Length; i++)
		{
			string name = OpenMemberNames[i];
			try
			{
				PropertyInfo property = type.GetProperty(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null && property.PropertyType == typeof(bool) && property.CanRead)
				{
					OpenProps.Add(property);
				}
			}
			catch
			{
			}
			try
			{
				FieldInfo field = type.GetField(name, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null && field.FieldType == typeof(bool))
				{
					OpenFields.Add(field);
				}
			}
			catch
			{
			}
		}
	}
}
[BepInPlugin("sparroh.consumablehotkeys", "ConsumableHotkeys", "1.0.6")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[MycoMod(/*Could not decode attribute arguments.*/)]
public class SparrohPlugin : BaseUnityPlugin
{
	public const string PluginGUID = "sparroh.consumablehotkeys";

	public const string PluginName = "ConsumableHotkeys";

	public const string PluginVersion = "1.0.6";

	internal static ManualLogSource Logger;

	private ConsumableHotkeysMod consumableHotkeys;

	private Harmony harmony;

	private void Awake()
	{
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_004e: Expected O, but got Unknown
		Logger = ((BaseUnityPlugin)this).Logger;
		try
		{
			ConfigManager.Initialize(((BaseUnityPlugin)this).Config, Logger);
		}
		catch (Exception ex)
		{
			Logger.LogError((object)("Failed to initialize config: " + ex.Message));
			return;
		}
		try
		{
			harmony = new Harmony("sparroh.consumablehotkeys");
		}
		catch (Exception ex2)
		{
			Logger.LogError((object)("Failed to create Harmony instance: " + ex2.Message));
			return;
		}
		try
		{
			consumableHotkeys = new ConsumableHotkeysMod();
		}
		catch (Exception ex3)
		{
			Logger.LogError((object)("Failed to initialize ConsumableHotkeys: " + ex3.Message));
		}
		try
		{
			harmony.PatchAll();
		}
		catch (Exception ex4)
		{
			Logger.LogError((object)("Failed to apply Harmony patches: " + ex4.Message));
		}
		Logger.LogInfo((object)"ConsumableHotkeys loaded successfully.");
	}

	private void Update()
	{
		try
		{
			ConfigManager.Tick();
			if (ConfigManager.ConsumePendingRefresh() && consumableHotkeys != null)
			{
				consumableHotkeys.OnConfigChanged();
			}
			if (consumableHotkeys != null)
			{
				consumableHotkeys.Update();
			}
		}
		catch (Exception ex)
		{
			Logger.LogError((object)("Error in ConsumableHotkeys.Update(): " + ex.Message));
		}
	}

	private void OnDestroy()
	{
		try
		{
			if (consumableHotkeys != null)
			{
				consumableHotkeys.OnDestroy();
			}
		}
		catch (Exception ex)
		{
			Logger.LogError((object)("Error in ConsumableHotkeys.OnDestroy(): " + ex.Message));
		}
		try
		{
			ConfigManager.Dispose();
		}
		catch (Exception ex2)
		{
			Logger.LogError((object)("Error disposing config: " + ex2.Message));
		}
		try
		{
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
		catch (Exception ex3)
		{
			Logger.LogError((object)("Error unpatching Harmony: " + ex3.Message));
		}
	}
}
namespace ConsumableHotkeys
{
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "ConsumableHotkeys";

		public const string PLUGIN_NAME = "ConsumableHotkeys";

		public const string PLUGIN_VERSION = "1.0.6";
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}