Decompiled source of CompareUpgrades v2.0.1

BepInEx/plugins/CompareUpgrades.dll

Decompiled 2 months ago
using System;
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 BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Pigeon;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
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("2.0.1.0")]
[assembly: AssemblyInformationalVersion("2.0.1")]
[assembly: AssemblyProduct("CompareUpgrades")]
[assembly: AssemblyTitle("CompareUpgrades")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.0.1.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;
		}
	}
}
namespace CompareUpgrades
{
	public static class CompareController
	{
		public static UpgradeInstance LockedUpgrade { get; private set; }

		public static bool HasLock => LockedUpgrade != null;

		public static void Tick()
		{
			if (!IsGearDetailsOpen(out var _))
			{
				if (HasLock)
				{
					ClearLock();
				}
			}
			else if (LockedUpgrade != null && (Object)(object)LockedUpgrade.Upgrade == (Object)null)
			{
				ClearLock();
			}
			else
			{
				HandleHotkey();
				UpdateComparisonView();
				CompareLockMark.Update(LockedUpgrade, GetHoveredUpgradeUi());
			}
		}

		public static void OnGearWindowReset()
		{
			ClearLock();
		}

		public static void Shutdown()
		{
			ClearLock();
			CompareDisplay.Destroy();
		}

		public static void OnMainHoverRefreshed()
		{
			if (HasLock && CompareDisplay.IsVisible)
			{
				CompareDisplay.RefreshIfVisible();
			}
		}

		private static void HandleHotkey()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			Keyboard current = Keyboard.current;
			if (current == null)
			{
				return;
			}
			Key val = (Key)((ConfigManager.CompareKey == null) ? 17 : ((int)ConfigManager.CompareKey.Value));
			if ((int)val == 0)
			{
				return;
			}
			KeyControl val2 = current[val];
			if (val2 == null || !((ButtonControl)val2).wasPressedThisFrame || IsSearchFocused())
			{
				return;
			}
			if (HasLock)
			{
				ClearLock();
				return;
			}
			GearUpgradeUI hoveredUpgradeUi = GetHoveredUpgradeUi();
			if ((Object)(object)hoveredUpgradeUi != (Object)null && ((HoverInfoUpgrade)hoveredUpgradeUi).Upgrade != null)
			{
				Lock(((HoverInfoUpgrade)hoveredUpgradeUi).Upgrade, hoveredUpgradeUi);
			}
		}

		private static void UpdateComparisonView()
		{
			if (!HasLock)
			{
				CompareDisplay.Hide();
				return;
			}
			GearUpgradeUI hoveredUpgradeUi = GetHoveredUpgradeUi();
			bool num = (Object)(object)hoveredUpgradeUi != (Object)null && ((HoverInfoUpgrade)hoveredUpgradeUi).Upgrade != null && ((HoverInfoUpgrade)hoveredUpgradeUi).Upgrade != LockedUpgrade;
			HoverInfoDisplay instance = HoverInfoDisplay.Instance;
			bool flag = (Object)(object)instance != (Object)null && ((Component)instance).gameObject.activeSelf && !CompareDisplay.IsCompareInstance(instance) && (Object)(object)instance.SelectedInfo != (Object)null;
			if (num && flag)
			{
				CompareDisplay.Show(LockedUpgrade);
				CompareDisplay.TickPosition();
			}
			else
			{
				CompareDisplay.Hide();
			}
		}

		private static void Lock(UpgradeInstance upgrade, GearUpgradeUI ui)
		{
			LockedUpgrade = upgrade;
			CompareDisplay.EnsureCreated();
			CompareLockMark.Apply(ui);
			ManualLogSource log = CompareUpgradesPlugin.Log;
			if (log != null)
			{
				log.LogInfo((object)("Locked upgrade for comparison: " + GetUpgradeName(upgrade)));
			}
		}

		private static void ClearLock()
		{
			if (LockedUpgrade != null)
			{
				ManualLogSource log = CompareUpgradesPlugin.Log;
				if (log != null)
				{
					log.LogInfo((object)"Unlocked upgrade comparison.");
				}
			}
			LockedUpgrade = null;
			CompareDisplay.Hide();
			CompareLockMark.Release();
		}

		private static GearUpgradeUI GetHoveredUpgradeUi()
		{
			GearUpgradeUI val = default(GearUpgradeUI);
			if (UIRaycaster.RaycastForComponent<GearUpgradeUI>(ref val) && (Object)(object)val != (Object)null)
			{
				return val;
			}
			return null;
		}

		private static bool IsGearDetailsOpen(out GearDetailsWindow window)
		{
			window = null;
			if ((Object)(object)Menu.Instance == (Object)null || !Menu.Instance.IsOpen)
			{
				return false;
			}
			if ((Object)(object)Menu.Instance.WindowSystem == (Object)null)
			{
				return false;
			}
			Window top = Menu.Instance.WindowSystem.GetTop();
			window = (GearDetailsWindow)(object)((top is GearDetailsWindow) ? top : null);
			return (Object)(object)window != (Object)null;
		}

		private static bool IsSearchFocused()
		{
			GameObject val = (((Object)(object)EventSystem.current != (Object)null) ? EventSystem.current.currentSelectedGameObject : null);
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			if ((Object)(object)val.GetComponent<InputField>() != (Object)null)
			{
				return true;
			}
			MonoBehaviour[] components = val.GetComponents<MonoBehaviour>();
			for (int i = 0; i < components.Length; i++)
			{
				if (!((Object)(object)components[i] == (Object)null))
				{
					string name = ((object)components[i]).GetType().Name;
					if (name == "TMP_InputField" || name == "InputField")
					{
						return true;
					}
				}
			}
			return false;
		}

		private static string GetUpgradeName(UpgradeInstance upgrade)
		{
			try
			{
				if ((Object)(object)((upgrade != null) ? upgrade.Upgrade : null) != (Object)null)
				{
					return upgrade.Upgrade.GetInstanceName(upgrade);
				}
			}
			catch
			{
			}
			return "(unknown)";
		}
	}
	public static class CompareDisplay
	{
		private static LockedUpgradeProxy proxy;

		private static GameObject proxyRoot;

		private static UpgradeInstance shownUpgrade;

		public static HoverInfoDisplay Clone { get; private set; }

		public static bool IsVisible { get; private set; }

		public static bool IsCompareInstance(HoverInfoDisplay display)
		{
			if ((Object)(object)Clone != (Object)null)
			{
				return (Object)(object)display == (Object)(object)Clone;
			}
			return false;
		}

		public static void EnsureCreated()
		{
			if ((Object)(object)Clone != (Object)null)
			{
				return;
			}
			HoverInfoDisplay instance = HoverInfoDisplay.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			Transform parent = ((Component)instance).transform.parent;
			if (!((Object)(object)parent == (Object)null))
			{
				Clone = Object.Instantiate<HoverInfoDisplay>(instance, parent);
				((Object)((Component)Clone).gameObject).name = "CompareUpgrades_HoverInfoDisplay";
				RestoreMainInstance(instance);
				DisableRaycasts(((Component)Clone).gameObject);
				try
				{
					Clone.Deactivate();
				}
				catch
				{
					((Component)Clone).gameObject.SetActive(false);
				}
				EnsureProxy();
				ManualLogSource log = CompareUpgradesPlugin.Log;
				if (log != null)
				{
					log.LogInfo((object)"Created comparison hover display.");
				}
			}
		}

		public static void Show(UpgradeInstance upgrade)
		{
			if (upgrade == null)
			{
				return;
			}
			EnsureCreated();
			if ((Object)(object)Clone == (Object)null || (Object)(object)proxy == (Object)null)
			{
				return;
			}
			bool num = !IsVisible || shownUpgrade != upgrade || !((Component)Clone).gameObject.activeSelf;
			proxy.SetLockedUpgrade(upgrade);
			shownUpgrade = upgrade;
			if (num)
			{
				try
				{
					Clone.ShowInfo((HoverInfo)(object)proxy);
				}
				catch (Exception ex)
				{
					ManualLogSource log = CompareUpgradesPlugin.Log;
					if (log != null)
					{
						log.LogWarning((object)("ShowInfo on compare display failed: " + ex.Message));
					}
					return;
				}
			}
			IsVisible = ((Component)Clone).gameObject.activeSelf;
			if (IsVisible)
			{
				CompareTooltipPositioning.PositionBesideMain(HoverInfoDisplay.Instance, Clone);
			}
		}

		public static void RefreshIfVisible()
		{
			if (!IsVisible || (Object)(object)Clone == (Object)null || (Object)(object)proxy == (Object)null || shownUpgrade == null)
			{
				return;
			}
			try
			{
				Clone.Refresh();
				CompareTooltipPositioning.PositionBesideMain(HoverInfoDisplay.Instance, Clone);
			}
			catch (Exception ex)
			{
				ManualLogSource log = CompareUpgradesPlugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("Refresh compare display failed: " + ex.Message));
				}
			}
		}

		public static void Hide()
		{
			if ((Object)(object)Clone == (Object)null)
			{
				IsVisible = false;
				shownUpgrade = null;
				return;
			}
			if (((Component)Clone).gameObject.activeSelf)
			{
				try
				{
					Clone.Deactivate();
				}
				catch
				{
					((Component)Clone).gameObject.SetActive(false);
				}
			}
			IsVisible = false;
			shownUpgrade = null;
		}

		public static void TickPosition()
		{
			if (IsVisible && !((Object)(object)Clone == (Object)null) && ((Component)Clone).gameObject.activeSelf)
			{
				CompareTooltipPositioning.PositionBesideMain(HoverInfoDisplay.Instance, Clone);
			}
		}

		public static void Destroy()
		{
			Hide();
			if ((Object)(object)Clone != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)Clone).gameObject);
				Clone = null;
			}
			if ((Object)(object)proxyRoot != (Object)null)
			{
				Object.Destroy((Object)(object)proxyRoot);
				proxyRoot = null;
				proxy = null;
			}
			shownUpgrade = null;
			IsVisible = false;
		}

		private static void EnsureProxy()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			if (!((Object)(object)proxy != (Object)null))
			{
				proxyRoot = new GameObject("CompareUpgrades_LockedProxy");
				Object.DontDestroyOnLoad((Object)(object)proxyRoot);
				((Object)proxyRoot).hideFlags = (HideFlags)61;
				proxy = proxyRoot.AddComponent<LockedUpgradeProxy>();
			}
		}

		private static void RestoreMainInstance(HoverInfoDisplay main)
		{
			try
			{
				PropertyInfo propertyInfo = AccessTools.Property(typeof(HoverInfoDisplay), "Instance");
				if (propertyInfo != null)
				{
					propertyInfo.SetValue(null, main, null);
					return;
				}
			}
			catch (Exception ex)
			{
				ManualLogSource log = CompareUpgradesPlugin.Log;
				if (log != null)
				{
					log.LogWarning((object)("Failed to restore HoverInfoDisplay.Instance via AccessTools: " + ex.Message));
				}
			}
			try
			{
				typeof(HoverInfoDisplay).GetProperty("Instance", BindingFlags.Static | BindingFlags.Public)?.SetValue(null, main, null);
			}
			catch (Exception arg)
			{
				ManualLogSource log2 = CompareUpgradesPlugin.Log;
				if (log2 != null)
				{
					log2.LogError((object)$"Failed to restore HoverInfoDisplay.Instance: {arg}");
				}
			}
		}

		private static void DisableRaycasts(GameObject root)
		{
			Graphic[] componentsInChildren = root.GetComponentsInChildren<Graphic>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				componentsInChildren[i].raycastTarget = false;
			}
			CanvasGroup[] componentsInChildren2 = root.GetComponentsInChildren<CanvasGroup>(true);
			for (int j = 0; j < componentsInChildren2.Length; j++)
			{
				componentsInChildren2[j].blocksRaycasts = false;
				componentsInChildren2[j].interactable = false;
			}
		}
	}
	public static class CompareLockMark
	{
		private static SelectionMark lockMark;

		private static GearUpgradeUI markedUi;

		public static void Update(UpgradeInstance lockedUpgrade, GearUpgradeUI hoveredUi)
		{
			if (lockedUpgrade == null)
			{
				Release();
				return;
			}
			GearUpgradeUI val = FindUiForLocked(lockedUpgrade, hoveredUi);
			if ((Object)(object)val != (Object)(object)markedUi)
			{
				Apply(val);
			}
		}

		public static void Apply(GearUpgradeUI ui)
		{
			//IL_003d: 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_004d: Expected O, but got Unknown
			Release();
			markedUi = ui;
			if ((Object)(object)ui == (Object)null || (Object)(object)Menu.Instance == (Object)null)
			{
				return;
			}
			try
			{
				lockMark = Menu.Instance.GetSelectionMark();
				lockMark.Setup((RectTransform)((Component)ui).transform, Vector2.zero, true);
			}
			catch
			{
				lockMark = null;
			}
		}

		public static void Release()
		{
			if ((Object)(object)lockMark != (Object)null)
			{
				try
				{
					lockMark.Release();
				}
				catch
				{
				}
				lockMark = null;
			}
			markedUi = null;
		}

		private static GearUpgradeUI FindUiForLocked(UpgradeInstance lockedUpgrade, GearUpgradeUI hoveredUi)
		{
			if (lockedUpgrade == null)
			{
				return null;
			}
			if ((Object)(object)hoveredUi != (Object)null && ((HoverInfoUpgrade)hoveredUi).Upgrade == lockedUpgrade)
			{
				return hoveredUi;
			}
			if ((Object)(object)markedUi != (Object)null && Object.op_Implicit((Object)(object)markedUi) && ((Component)markedUi).gameObject.activeInHierarchy && ((HoverInfoUpgrade)markedUi).Upgrade == lockedUpgrade)
			{
				return markedUi;
			}
			return null;
		}
	}
	internal static class ComparePatches
	{
		[HarmonyPatch(typeof(HoverInfoDisplay), "UpdatePosition")]
		[HarmonyPrefix]
		private static bool UpdatePositionPrefix(HoverInfoDisplay __instance)
		{
			if (CompareDisplay.IsCompareInstance(__instance))
			{
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(HoverInfoDisplay), "Refresh")]
		[HarmonyPostfix]
		private static void RefreshPostfix(HoverInfoDisplay __instance)
		{
			if (!CompareDisplay.IsCompareInstance(__instance))
			{
				CompareController.OnMainHoverRefreshed();
			}
		}

		[HarmonyPatch(typeof(GearDetailsWindow), "Setup")]
		[HarmonyPostfix]
		private static void GearDetailsSetupPostfix()
		{
			CompareController.OnGearWindowReset();
		}

		[HarmonyPatch(typeof(GearDetailsWindow), "OnCloseCallback")]
		[HarmonyPostfix]
		private static void GearDetailsClosePostfix()
		{
			CompareController.OnGearWindowReset();
		}
	}
	public static class CompareTooltipPositioning
	{
		private const float Gap = 24f;

		private const float EdgePadding = 20f;

		public static void PositionBesideMain(HoverInfoDisplay main, HoverInfoDisplay clone)
		{
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: 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_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: 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)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)main == (Object)null || (Object)(object)clone == (Object)null || (Object)(object)main == (Object)(object)clone || !((Component)main).gameObject.activeSelf)
			{
				return;
			}
			RectTransform rectTransform = main.RectTransform;
			RectTransform rectTransform2 = clone.RectTransform;
			if (!((Object)(object)rectTransform == (Object)null) && !((Object)(object)rectTransform2 == (Object)null))
			{
				Transform parent = ((Transform)rectTransform).parent;
				RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null);
				if (!((Object)(object)val == (Object)null))
				{
					Vector2 anchoredPosition = rectTransform.anchoredPosition;
					Vector2 sizeDelta = rectTransform.sizeDelta;
					Vector2 sizeDelta2 = rectTransform2.sizeDelta;
					Rect rect = val.rect;
					Vector2 size = ((Rect)(ref rect)).size;
					Vector2 val2 = default(Vector2);
					((Vector2)(ref val2))..ctor(anchoredPosition.x + (sizeDelta.x + sizeDelta2.x) * 0.5f + 24f, anchoredPosition.y);
					Vector2 val3 = default(Vector2);
					((Vector2)(ref val3))..ctor(anchoredPosition.x - (sizeDelta.x + sizeDelta2.x) * 0.5f - 24f, anchoredPosition.y);
					Vector2 val4 = (Fits(val2, sizeDelta2, size) ? val2 : (Fits(val3, sizeDelta2, size) ? val3 : Clamp(val2, sizeDelta2, size)));
					val4.y = ClampY(val4.y, sizeDelta2.y, size.y);
					rectTransform2.anchoredPosition = val4;
				}
			}
		}

		private static bool Fits(Vector2 center, Vector2 size, Vector2 bounds)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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_0020: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			float num = bounds.x * 0.5f;
			float num2 = bounds.y * 0.5f;
			float num3 = center.x - size.x * 0.5f;
			float num4 = center.x + size.x * 0.5f;
			float num5 = center.y - size.y * 0.5f;
			float num6 = center.y + size.y * 0.5f;
			if (num3 >= 0f - num + 20f && num4 <= num - 20f && num5 >= 0f - num2 + 20f)
			{
				return num6 <= num2 - 20f;
			}
			return false;
		}

		private static Vector2 Clamp(Vector2 center, Vector2 size, Vector2 bounds)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			float num = bounds.x * 0.5f;
			float num2 = bounds.y * 0.5f;
			center.x = Mathf.Clamp(center.x, 0f - num + size.x * 0.5f + 20f, num - size.x * 0.5f - 20f);
			center.y = Mathf.Clamp(center.y, 0f - num2 + size.y * 0.5f + 20f, num2 - size.y * 0.5f - 20f);
			return center;
		}

		private static float ClampY(float y, float height, float boundsY)
		{
			float num = boundsY * 0.5f;
			return Mathf.Clamp(y, 0f - num + height * 0.5f + 20f, num - height * 0.5f - 20f);
		}
	}
	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 reloadPending;

		private static float lastReloadTime;

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

		public static void Initialize(ConfigFile configFile, ManualLogSource log)
		{
			config = configFile;
			logger = log;
			CompareKey = config.Bind<Key>("Keybinds", "Compare Key", (Key)17, "Hotkey to lock/unlock an upgrade for side-by-side comparison while the gear details window is open.");
			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();
				logger.LogInfo((object)"Config reloaded from disk.");
			}
			catch (Exception ex)
			{
				logger.LogError((object)("Error reloading config: " + ex.Message));
			}
		}

		public static void Dispose()
		{
			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.compareupgrades.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;
		}
	}
	public sealed class LockedUpgradeProxy : HoverInfoUpgrade
	{
		public override bool EnableHoverInfoEvents => false;

		public override bool GetPrimaryBinding(out InputAction binding, out string label)
		{
			binding = null;
			label = null;
			return false;
		}

		public override bool GetSecondaryBinding(out InputAction binding, out string label)
		{
			binding = null;
			label = null;
			return false;
		}

		public override int GetAdditionalBindingCount()
		{
			return 0;
		}

		public override bool HasUnlockAction(out UnlockActionParams data)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			data = default(UnlockActionParams);
			return false;
		}

		public override bool HasUnlockInfo(out string text)
		{
			text = null;
			return false;
		}

		public void SetLockedUpgrade(UpgradeInstance upgrade)
		{
			((HoverInfoUpgrade)this).Upgrade = upgrade;
		}
	}
	[BepInPlugin("sparroh.compareupgrades", "CompareUpgrades", "2.0.1")]
	[MycoMod(/*Could not decode attribute arguments.*/)]
	public class CompareUpgradesPlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "sparroh.compareupgrades";

		public const string PluginName = "CompareUpgrades";

		public const string PluginVersion = "2.0.1";

		internal static ManualLogSource Log;

		internal static CompareUpgradesPlugin Instance;

		private Harmony harmony;

		private void Awake()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			ConfigManager.Initialize(((BaseUnityPlugin)this).Config, Log);
			try
			{
				harmony = new Harmony("sparroh.compareupgrades");
				harmony.PatchAll(typeof(ComparePatches));
				Log.LogInfo((object)"CompareUpgrades v2.0.1 loaded.");
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Failed to initialize: {arg}");
			}
		}

		private void Update()
		{
			try
			{
				ConfigManager.Tick();
				CompareController.Tick();
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"CompareController tick failed: {arg}");
			}
		}

		private void OnDestroy()
		{
			try
			{
				CompareController.Shutdown();
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Shutdown failed: {arg}");
			}
			try
			{
				ConfigManager.Dispose();
			}
			catch (Exception arg2)
			{
				Log.LogError((object)$"Config dispose failed: {arg2}");
			}
			try
			{
				Harmony obj = harmony;
				if (obj != null)
				{
					obj.UnpatchSelf();
				}
			}
			catch (Exception arg3)
			{
				Log.LogError((object)$"Unpatch failed: {arg3}");
			}
			Instance = null;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "CompareUpgrades";

		public const string PLUGIN_NAME = "CompareUpgrades";

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