Decompiled source of UpgradeQueue v0.1.8

plugins/UpgradeQueue.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mirror;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.UIElements;

[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("UpgradeQueue")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.1.8.0")]
[assembly: AssemblyInformationalVersion("0.1.8+e4bcdca95f41c8d3048c237f2255f661e5b1fdf6")]
[assembly: AssemblyProduct("UpgradeQueue")]
[assembly: AssemblyTitle("UpgradeQueue")]
[assembly: AssemblyVersion("0.1.8.0")]
[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 UpgradeQueue
{
	internal sealed class ConfigurationManagerAttributes
	{
		public string DispName;

		public int? Order;
	}
	internal static class Hotkey
	{
		private static bool? _legacyAvailable;

		private static readonly Dictionary<KeyCode, Key> Renamed = new Dictionary<KeyCode, Key>
		{
			[(KeyCode)13] = (Key)2,
			[(KeyCode)271] = (Key)77,
			[(KeyCode)306] = (Key)55,
			[(KeyCode)305] = (Key)56,
			[(KeyCode)310] = (Key)57,
			[(KeyCode)309] = (Key)58,
			[(KeyCode)96] = (Key)4,
			[(KeyCode)270] = (Key)80,
			[(KeyCode)269] = (Key)81,
			[(KeyCode)268] = (Key)79,
			[(KeyCode)267] = (Key)78,
			[(KeyCode)266] = (Key)82
		};

		private static bool LegacyAvailable
		{
			get
			{
				if (!_legacyAvailable.HasValue)
				{
					try
					{
						Input.GetKey((KeyCode)0);
						_legacyAvailable = true;
					}
					catch (InvalidOperationException)
					{
						_legacyAvailable = false;
					}
					Plugin.Log.LogInfo((object)(_legacyAvailable.Value ? "Reading hotkeys through the legacy Input manager" : "Legacy Input manager is disabled; reading hotkeys through the Input System package"));
				}
				return _legacyAvailable.Value;
			}
		}

		public static bool WasPressed(KeyboardShortcut shortcut)
		{
			//IL_0002: 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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			if ((int)((KeyboardShortcut)(ref shortcut)).MainKey == 0)
			{
				return false;
			}
			if (LegacyAvailable)
			{
				return ((KeyboardShortcut)(ref shortcut)).IsDown();
			}
			Keyboard current = Keyboard.current;
			if (current == null || !TryGetKey(((KeyboardShortcut)(ref shortcut)).MainKey, out var key) || !((ButtonControl)current[key]).wasPressedThisFrame)
			{
				return false;
			}
			foreach (KeyCode modifier in ((KeyboardShortcut)(ref shortcut)).Modifiers)
			{
				if (!TryGetKey(modifier, out var key2) || !((ButtonControl)current[key2]).isPressed)
				{
					return false;
				}
			}
			return true;
		}

		private unsafe static bool TryGetKey(KeyCode code, out Key key)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (Renamed.TryGetValue(code, out key))
			{
				return true;
			}
			string text = ((object)(*(KeyCode*)(&code))/*cast due to .constrained prefix*/).ToString();
			if (text.StartsWith("Alpha"))
			{
				text = "Digit" + text.Substring("Alpha".Length);
			}
			else if (text.StartsWith("Keypad"))
			{
				text = "Numpad" + text.Substring("Keypad".Length);
			}
			if (Enum.TryParse<Key>(text, ignoreCase: true, out key))
			{
				return (int)key != 0;
			}
			return false;
		}
	}
	public enum CounterCorner
	{
		TopLeft,
		TopRight,
		BottomLeft,
		BottomRight
	}
	internal static class HudCounter
	{
		private const float Margin = 24f;

		private const float EdgeMargin = 6f;

		private const float IconSize = 28f;

		private const string IconResource = "UpgradeQueue.counter-icon.png";

		private const int PingRings = 2;

		private const float PingRingDelay = 0.35f;

		private const float PingRingDuration = 1.1f;

		private const float PingSpread = 26f;

		private const float PingStartAlpha = 0.85f;

		private const float PingRingWidth = 2f;

		private const float IdlePingInterval = 1.5f;

		private const float IdlePingAlpha = 0.45f;

		private const float IdlePingSpread = 0.6f;

		private const float CornerRadius = 8f;

		private static readonly Color Gold = new Color(1f, 0.82f, 0.45f);

		private static Button _button;

		private static Label _label;

		private static readonly VisualElement[] _rings = (VisualElement[])(object)new VisualElement[2];

		private static float _pingStart = float.NegativeInfinity;

		private static Hud _attachedHud;

		private static Texture2D _icon;

		private static bool _iconLoadAttempted;

		public static void Update()
		{
			//IL_0059: 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_00d0: Unknown result type (might be due to invalid IL or missing references)
			Hud instance = Hud.Instance;
			if ((Object)(object)instance == (Object)null || (Object)(object)instance.hudDocument == (Object)null)
			{
				return;
			}
			if (_button == null || (Object)(object)_attachedHud != (Object)(object)instance || ((VisualElement)_button).panel == null)
			{
				Attach(instance);
			}
			int num = (((Object)(object)InputManager.Instance != (Object)null) ? ((int)InputManager.Instance.CurrentInputState) : 0);
			bool flag = num == 2;
			bool flag2 = num == 3;
			bool flag3 = Plugin.Enabled.Value && Plugin.ShowCounter.Value && QueueState.PendingCount > 0 && !QueuedUpgradeSession.IsOpen && (flag || flag2);
			((VisualElement)_button).style.display = StyleEnum<DisplayStyle>.op_Implicit((DisplayStyle)(!flag3));
			if (flag3)
			{
				UpdatePing();
				string text = (flag2 ? $"Open upgrade ({QueueState.PendingCount})" : $"Upgrades: {QueueState.PendingCount}  [{Plugin.OpenQueueKey.Value}]");
				if (((TextElement)_label).text != text)
				{
					((TextElement)_label).text = text;
				}
				ApplyCorner(Plugin.CounterPosition.Value);
			}
		}

		private static void Attach(Hud hud)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: 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_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_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: 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: 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_00c2: 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_00c9: 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_00d0: 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_00e8: 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_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: 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)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: Expected O, but got Unknown
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Expected O, but got Unknown
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_021c: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_0320: Unknown result type (might be due to invalid IL or missing references)
			//IL_0325: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: Unknown result type (might be due to invalid IL or missing references)
			//IL_0339: Expected O, but got Unknown
			//IL_0342: Unknown result type (might be due to invalid IL or missing references)
			//IL_034d: Unknown result type (might be due to invalid IL or missing references)
			Button button = _button;
			if (button != null)
			{
				((VisualElement)button).RemoveFromHierarchy();
			}
			_button = new Button((Action)delegate
			{
				QueuedUpgradeSession.RequestOpen();
			})
			{
				name = "UpgradeQueueCounter"
			};
			IStyle style = ((VisualElement)_button).style;
			style.position = StyleEnum<Position>.op_Implicit((Position)1);
			style.flexDirection = StyleEnum<FlexDirection>.op_Implicit((FlexDirection)2);
			style.alignItems = StyleEnum<Align>.op_Implicit((Align)2);
			style.paddingLeft = StyleLength.op_Implicit(8f);
			style.paddingRight = StyleLength.op_Implicit(12f);
			StyleLength paddingTop = (style.paddingBottom = StyleLength.op_Implicit(6f));
			style.paddingTop = paddingTop;
			StyleLength val2 = (style.marginBottom = StyleLength.op_Implicit(0f));
			StyleLength val4 = (style.marginTop = val2);
			paddingTop = (style.marginRight = val4);
			style.marginLeft = paddingTop;
			style.fontSize = StyleLength.op_Implicit(18f);
			style.unityFontStyleAndWeight = StyleEnum<FontStyle>.op_Implicit((FontStyle)1);
			style.color = StyleColor.op_Implicit(new Color(1f, 0.87f, 0.55f));
			style.backgroundColor = StyleColor.op_Implicit(new Color(0.08f, 0.06f, 0.05f, 0.75f));
			StyleFloat val7 = (style.borderRightWidth = StyleFloat.op_Implicit(2f));
			StyleFloat val9 = (style.borderLeftWidth = val7);
			StyleFloat borderTopWidth = (style.borderBottomWidth = val9);
			style.borderTopWidth = borderTopWidth;
			StyleColor val12 = (style.borderRightColor = StyleColor.op_Implicit(new Color(0.78f, 0.58f, 0.24f)));
			StyleColor val14 = (style.borderLeftColor = val12);
			StyleColor borderTopColor = (style.borderBottomColor = val14);
			style.borderTopColor = borderTopColor;
			val2 = (style.borderBottomRightRadius = StyleLength.op_Implicit(8f));
			val4 = (style.borderBottomLeftRadius = val2);
			paddingTop = (style.borderTopRightRadius = val4);
			style.borderTopLeftRadius = paddingTop;
			style.display = StyleEnum<DisplayStyle>.op_Implicit((DisplayStyle)1);
			Texture2D val20 = LoadIcon();
			if ((Object)(object)val20 != (Object)null)
			{
				VisualElement val21 = new VisualElement
				{
					name = "UpgradeQueueCounterIcon",
					pickingMode = (PickingMode)1
				};
				IStyle style2 = val21.style;
				paddingTop = (val21.style.height = StyleLength.op_Implicit(28f));
				style2.width = paddingTop;
				val21.style.marginRight = StyleLength.op_Implicit(8f);
				val21.style.backgroundImage = StyleBackground.op_Implicit(val20);
				((VisualElement)_button).Add(val21);
			}
			_label = new Label
			{
				pickingMode = (PickingMode)1
			};
			IStyle style3 = ((VisualElement)_label).style;
			IStyle style4 = ((VisualElement)_label).style;
			IStyle style5 = ((VisualElement)_label).style;
			val2 = (((VisualElement)_label).style.marginBottom = StyleLength.op_Implicit(0f));
			val4 = (style5.marginTop = val2);
			paddingTop = (style4.marginRight = val4);
			style3.marginLeft = paddingTop;
			IStyle style6 = ((VisualElement)_label).style;
			IStyle style7 = ((VisualElement)_label).style;
			IStyle style8 = ((VisualElement)_label).style;
			val2 = (((VisualElement)_label).style.paddingBottom = StyleLength.op_Implicit(0f));
			val4 = (style8.paddingTop = val2);
			paddingTop = (style7.paddingRight = val4);
			style6.paddingLeft = paddingTop;
			((VisualElement)_button).Add((VisualElement)(object)_label);
			for (int num = 0; num < 2; num++)
			{
				VisualElement val29 = new VisualElement
				{
					name = "UpgradeQueuePingRing",
					pickingMode = (PickingMode)1
				};
				IStyle style9 = val29.style;
				style9.position = StyleEnum<Position>.op_Implicit((Position)1);
				style9.display = StyleEnum<DisplayStyle>.op_Implicit((DisplayStyle)1);
				((VisualElement)_button).Add(val29);
				_rings[num] = val29;
			}
			hud.hudDocument.rootVisualElement.Add((VisualElement)(object)_button);
			((VisualElement)_button).BringToFront();
			_attachedHud = hud;
		}

		public static void Ping()
		{
			if (Plugin.PingOnLevelUp.Value)
			{
				_pingStart = Time.unscaledTime;
			}
		}

		private static void UpdatePing()
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			float unscaledTime = Time.unscaledTime;
			float num = 1.45f;
			float intensity = Mathf.Clamp(Plugin.PingIntensity.Value, 0.25f, 2f);
			float num2 = unscaledTime - _pingStart;
			if (num2 < num)
			{
				for (int i = 0; i < 2; i++)
				{
					DrawRing(_rings[i], (num2 - (float)i * 0.35f) / 1.1f, intensity, 1f, 1f);
				}
				return;
			}
			for (int j = 1; j < 2; j++)
			{
				_rings[j].style.display = StyleEnum<DisplayStyle>.op_Implicit((DisplayStyle)1);
			}
			if (!Plugin.IdlePing.Value)
			{
				_rings[0].style.display = StyleEnum<DisplayStyle>.op_Implicit((DisplayStyle)1);
				return;
			}
			float t = ((float.IsInfinity(num2) ? unscaledTime : (num2 - num)) % 1.5f - 0.39999998f) / 1.1f;
			DrawRing(_rings[0], t, intensity, 0.45f, 0.6f);
		}

		private static void DrawRing(VisualElement ring, float t, float intensity, float alphaScale, float spreadScale)
		{
			//IL_0017: 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_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: 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)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: 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_00fe: 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_0101: 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)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: 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_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: 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_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Unknown result type (might be due to invalid IL or missing references)
			if (t < 0f || t >= 1f)
			{
				ring.style.display = StyleEnum<DisplayStyle>.op_Implicit((DisplayStyle)1);
				return;
			}
			float num = 1f - (1f - t) * (1f - t) * (1f - t);
			float num2 = 26f * intensity * spreadScale * num;
			float num3 = Mathf.Min(1f, 0.85f * intensity) * alphaScale;
			Color val = default(Color);
			((Color)(ref val))..ctor(Gold.r, Gold.g, Gold.b, num3 * (1f - t) * (1f - t));
			IStyle style = ring.style;
			style.display = StyleEnum<DisplayStyle>.op_Implicit((DisplayStyle)0);
			StyleFloat val2 = (style.borderRightWidth = StyleFloat.op_Implicit(Mathf.Max(1f, 2f * intensity)));
			StyleFloat val4 = (style.borderLeftWidth = val2);
			StyleFloat borderTopWidth = (style.borderBottomWidth = val4);
			style.borderTopWidth = borderTopWidth;
			StyleLength val7 = (style.bottom = StyleLength.op_Implicit(-2f - num2));
			StyleLength val9 = (style.top = val7);
			StyleLength left = (style.right = val9);
			style.left = left;
			val7 = (style.borderBottomRightRadius = StyleLength.op_Implicit(8f + num2));
			val9 = (style.borderBottomLeftRadius = val7);
			left = (style.borderTopRightRadius = val9);
			style.borderTopLeftRadius = left;
			StyleColor val15 = (style.borderRightColor = StyleColor.op_Implicit(val));
			StyleColor val17 = (style.borderLeftColor = val15);
			StyleColor borderTopColor = (style.borderBottomColor = val17);
			style.borderTopColor = borderTopColor;
		}

		private static Texture2D LoadIcon()
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			if (_iconLoadAttempted)
			{
				return _icon;
			}
			_iconLoadAttempted = true;
			using (Stream stream = typeof(HudCounter).Assembly.GetManifestResourceStream("UpgradeQueue.counter-icon.png"))
			{
				if (stream == null)
				{
					Plugin.Log.LogWarning((object)"Missing embedded resource UpgradeQueue.counter-icon.png");
					return null;
				}
				byte[] array = new byte[stream.Length];
				stream.Read(array, 0, array.Length);
				Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false)
				{
					name = "UpgradeQueueCounterIcon",
					filterMode = (FilterMode)1,
					wrapMode = (TextureWrapMode)1,
					hideFlags = (HideFlags)61
				};
				if (!ImageConversion.LoadImage(val, array))
				{
					Plugin.Log.LogWarning((object)"Could not decode the counter icon");
					Object.Destroy((Object)(object)val);
					return null;
				}
				_icon = val;
			}
			return _icon;
		}

		private static void ApplyCorner(CounterCorner corner)
		{
			//IL_0051: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			IStyle style = ((VisualElement)_button).style;
			bool flag = corner == CounterCorner.TopLeft || corner == CounterCorner.TopRight;
			bool flag2 = corner == CounterCorner.TopLeft || corner == CounterCorner.BottomLeft;
			float num = 24f + (float)Plugin.CounterOffsetX.Value;
			float num2 = 6f + (float)Plugin.CounterOffsetY.Value;
			style.top = (flag ? StyleLength.op_Implicit(num2) : StyleLength.op_Implicit((StyleKeyword)2));
			style.bottom = (flag ? StyleLength.op_Implicit((StyleKeyword)2) : StyleLength.op_Implicit(num2));
			style.left = (flag2 ? StyleLength.op_Implicit(num) : StyleLength.op_Implicit((StyleKeyword)2));
			style.right = (flag2 ? StyleLength.op_Implicit((StyleKeyword)2) : StyleLength.op_Implicit(num));
		}
	}
	[BepInPlugin("com.darkharasho.stonewards.upgradequeue", "UpgradeQueue", "0.1.8")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.darkharasho.stonewards.upgradequeue";

		public const string PluginName = "UpgradeQueue";

		public const string PluginVersion = "0.1.8";

		internal static ManualLogSource Log;

		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<KeyboardShortcut> OpenQueueKey;

		internal static ConfigEntry<bool> PauseInSolo;

		internal static ConfigEntry<bool> PickAllInARow;

		internal static ConfigEntry<bool> ShowCounter;

		internal static ConfigEntry<bool> PingOnLevelUp;

		internal static ConfigEntry<bool> IdlePing;

		internal static ConfigEntry<float> PingIntensity;

		internal static ConfigEntry<CounterCorner> CounterPosition;

		internal static ConfigEntry<int> CounterOffsetX;

		internal static ConfigEntry<int> CounterOffsetY;

		internal static Plugin Instance;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected O, but got Unknown
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Expected O, but got Unknown
			//IL_010c: 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_013a: Expected O, but got Unknown
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Expected O, but got Unknown
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Expected O, but got Unknown
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_021e: Expected O, but got Unknown
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_027c: Expected O, but got Unknown
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c8: Expected O, but got Unknown
			//IL_0318: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Expected O, but got Unknown
			//IL_0372: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: Expected O, but got Unknown
			//IL_038c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, new ConfigDescription("Queue level-up upgrade popups instead of opening them immediately.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					DispName = "Queue upgrades",
					Order = 20
				}
			}));
			PickAllInARow = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "PickAllInARow", true, new ConfigDescription("After picking a queued upgrade, open the next one right away until the queue is empty. Press the open key again to stop and keep the rest queued.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					DispName = "Pick all queued upgrades in a row",
					Order = 15
				}
			}));
			PauseInSolo = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "PauseInSolo", true, new ConfigDescription("Pause the game while picking a queued upgrade in single player. Never pauses in multiplayer.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					DispName = "Pause while picking (single player)",
					Order = 10
				}
			}));
			OpenQueueKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Controls", "OpenQueueKey", new KeyboardShortcut((KeyCode)117, Array.Empty<KeyCode>()), new ConfigDescription("Key that opens the next queued upgrade. Press it again before picking to close the screen and keep the upgrade queued.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					DispName = "Open / close queued upgrade"
				}
			}));
			ShowCounter = ((BaseUnityPlugin)this).Config.Bind<bool>("HUD", "ShowCounter", true, new ConfigDescription("Show the queued upgrade counter. In the inventory it becomes a button that opens the next upgrade.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					DispName = "Show counter",
					Order = 40
				}
			}));
			PingOnLevelUp = ((BaseUnityPlugin)this).Config.Bind<bool>("HUD", "PingOnLevelUp", true, new ConfigDescription("Play a sonar ping animation around the counter when a level-up is queued.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					DispName = "Ping on new level-up",
					Order = 35
				}
			}));
			IdlePing = ((BaseUnityPlugin)this).Config.Bind<bool>("HUD", "IdlePing", true, new ConfigDescription("Keep a faint ping repeating around the counter every 1.5 seconds while upgrades are queued.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					DispName = "Ping while upgrades wait",
					Order = 34
				}
			}));
			PingIntensity = ((BaseUnityPlugin)this).Config.Bind<float>("HUD", "PingIntensity", 1f, new ConfigDescription("Strength of the ping. Scales how far the rings spread, how bright they are and how thick they are. 1 is the default.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 2f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					DispName = "Ping intensity",
					Order = 33
				}
			}));
			CounterPosition = ((BaseUnityPlugin)this).Config.Bind<CounterCorner>("HUD", "CounterPosition", CounterCorner.TopRight, new ConfigDescription("Screen corner for the queued upgrade counter.", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					DispName = "Counter corner",
					Order = 30
				}
			}));
			CounterOffsetX = ((BaseUnityPlugin)this).Config.Bind<int>("HUD", "CounterOffsetX", 0, new ConfigDescription("Extra horizontal distance, in UI pixels, from the counter's corner. Negative moves it toward the edge.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-500, 500), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					DispName = "Counter offset X",
					Order = 20
				}
			}));
			CounterOffsetY = ((BaseUnityPlugin)this).Config.Bind<int>("HUD", "CounterOffsetY", 0, new ConfigDescription("Extra vertical distance, in UI pixels, from the counter's corner. Increase to move it clear of other HUD elements.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-500, 500), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					DispName = "Counter offset Y",
					Order = 10
				}
			}));
			QueueSnapshot.Init();
			_harmony = new Harmony("com.darkharasho.stonewards.upgradequeue");
			_harmony.PatchAll(typeof(Plugin).Assembly);
			Log.LogInfo((object)"UpgradeQueue 0.1.8 loaded");
		}

		private void Update()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (Hotkey.WasPressed(OpenQueueKey.Value))
			{
				QueuedUpgradeSession.Toggle();
			}
			QueuedUpgradeSession.RefreshCardText();
			HudCounter.Update();
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	internal static class QueuedUpgradeSession
	{
		[HarmonyPatch(typeof(RogueLikeUpgradeMenu), "OnUpgradeClicked")]
		private static class CloseOnPickPatch
		{
			private static bool Prefix()
			{
				return !_puttingBack;
			}

			private static void Postfix(RogueLikeUpgradeMenu __instance)
			{
				if (IsOpen && __instance.IsUpgradeSelected)
				{
					OnScreenClosed.Invoke(__instance, null);
				}
			}
		}

		[HarmonyPatch(typeof(UpgradePopupController), "Setup", new Type[] { typeof(List<UpgradeDraftChoice>) })]
		private static class TrackShownChoicesPatch
		{
			private static void Postfix(List<UpgradeDraftChoice> upgradeDraftChoices)
			{
				if (IsOpen && !_puttingBack)
				{
					_shownChoices = new List<UpgradeDraftChoice>(upgradeDraftChoices);
					QueueSnapshot.Save();
				}
			}
		}

		[HarmonyPatch(typeof(BaseMenu), "Close")]
		private static class EndSessionOnClosePatch
		{
			private static void Postfix(BaseMenu __instance)
			{
				if (IsOpen && __instance is RogueLikeUpgradeMenu)
				{
					bool num = !_puttingBack && Plugin.PickAllInARow.Value && QueueState.PendingCount > 0;
					IsOpen = false;
					_puttingBack = false;
					_menu = null;
					_shownChoices = null;
					QueueSnapshot.Save();
					if (num)
					{
						((MonoBehaviour)Plugin.Instance).StartCoroutine(OpenNextFrame());
					}
				}
			}
		}

		private static readonly FieldRef<RogueLikeUpgradeMenu, Coroutine> AutoChooseCoroutine = AccessTools.FieldRefAccess<RogueLikeUpgradeMenu, Coroutine>("autoChooseCoroutine");

		private static readonly MethodInfo OnUpgradeDraftGenerated = AccessTools.Method(typeof(RogueLikeUpgradeMenu), "OnUpgradeDraftGenerated", (Type[])null, (Type[])null);

		private static readonly FieldRef<RogueLikeUpgradeMenu, Coroutine> HideCoroutine = AccessTools.FieldRefAccess<RogueLikeUpgradeMenu, Coroutine>("hideCoroutine");

		private static readonly FieldRef<RogueLikeUpgradeMenu, Coroutine> RerollCoroutine = AccessTools.FieldRefAccess<RogueLikeUpgradeMenu, Coroutine>("_rerollCoroutine");

		private static readonly MethodInfo OnScreenClosed = AccessTools.Method(typeof(RogueLikeUpgradeMenu), "OnScreenClosed", (Type[])null, (Type[])null);

		private static readonly MethodInfo HideUpgradeScreen = AccessTools.Method(typeof(RogueLikeUpgradeMenu), "HideUpgradeScreen", (Type[])null, (Type[])null);

		private static readonly MethodInfo EnableOptions = AccessTools.Method(typeof(RogueLikeUpgradeMenu), "EnableOptions", (Type[])null, (Type[])null);

		private static readonly MethodInfo ShowControllers = AccessTools.Method(typeof(RogueLikeUpgradeMenu), "ShowControllers", (Type[])null, (Type[])null);

		private static readonly MethodInfo HandleInput = AccessTools.Method(typeof(BaseMenu), "HandleInput", (Type[])null, (Type[])null);

		private static readonly FieldRef<RogueLikeUpgradeMenu, UpgradeDraftChoice> SelectedUpgrade = AccessTools.FieldRefAccess<RogueLikeUpgradeMenu, UpgradeDraftChoice>("selectedUpgrade");

		private static readonly FieldRef<RogueLikeUpgradeMenu, UpgradePopupController> PopupController = AccessTools.FieldRefAccess<RogueLikeUpgradeMenu, UpgradePopupController>("upgradePopupController");

		private static readonly FieldRef<RogueLikeUpgradeMenu, StatsPopupController> StatsController = AccessTools.FieldRefAccess<RogueLikeUpgradeMenu, StatsPopupController>("statsController");

		private static readonly FieldRef<UpgradeButton, Label> DescriptionLabel = AccessTools.FieldRefAccess<UpgradeButton, Label>("descriptionLabel");

		private const float CardRefreshInterval = 0.2f;

		private static float _nextCardRefresh;

		private static RogueLikeUpgradeMenu _menu;

		private static bool _puttingBack;

		private static List<UpgradeDraftChoice> _shownChoices;

		private static List<UpgradeDraftChoice> _savedChoices;

		public static bool IsOpen { get; private set; }

		public static bool IsOpening { get; private set; }

		public static int PendingIncludingOpen => QueueState.PendingCount + ((IsOpen && !_puttingBack) ? 1 : 0);

		public static List<UpgradeDraftChoice> FrontChoices
		{
			get
			{
				List<UpgradeDraftChoice> list = _savedChoices;
				if (list == null)
				{
					if (!IsOpen || _puttingBack)
					{
						return null;
					}
					list = _shownChoices;
				}
				return list;
			}
		}

		public static void RestoreFrontChoices(List<UpgradeDraftChoice> choices)
		{
			_savedChoices = choices;
		}

		public static void Toggle()
		{
			if (IsOpen)
			{
				PutBack();
			}
			else
			{
				RequestOpen();
			}
		}

		public static void PutBack()
		{
			if (IsOpen && !_puttingBack && !((Object)(object)_menu == (Object)null) && !_menu.IsUpgradeSelected)
			{
				_puttingBack = true;
				EnableOptions.Invoke(_menu, new object[1] { false });
				Coroutine val = RerollCoroutine.Invoke(_menu);
				if (val != null)
				{
					((MonoBehaviour)_menu).StopCoroutine(val);
					RerollCoroutine.Invoke(_menu) = null;
				}
				Coroutine val2 = HideCoroutine.Invoke(_menu);
				if (val2 != null)
				{
					((MonoBehaviour)_menu).StopCoroutine(val2);
				}
				HideCoroutine.Invoke(_menu) = ((MonoBehaviour)_menu).StartCoroutine((IEnumerator)HideUpgradeScreen.Invoke(_menu, null));
				_savedChoices = _shownChoices;
				QueueState.Enqueue();
				Plugin.Log.LogInfo((object)$"Closed queued upgrade without picking ({QueueState.PendingCount} pending)");
			}
		}

		public static void CloseNow(string reason)
		{
			//IL_0062: 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)
			if (IsOpen && !((Object)(object)_menu == (Object)null))
			{
				RogueLikeUpgradeMenu menu = _menu;
				StopCoroutine(menu, HideCoroutine);
				StopCoroutine(menu, RerollCoroutine);
				StopCoroutine(menu, AutoChooseCoroutine);
				bool isUpgradeSelected = menu.IsUpgradeSelected;
				bool puttingBack = _puttingBack;
				_puttingBack = true;
				if (isUpgradeSelected)
				{
					RogueLikeUpgradeManager.Instance.ApplyUpgrade(SelectedUpgrade.Invoke(menu));
				}
				else if (!puttingBack)
				{
					EnableOptions.Invoke(menu, new object[1] { false });
					_savedChoices = _shownChoices;
					QueueState.Enqueue();
				}
				ShowControllers.Invoke(menu, new object[3] { false, 0f, 0f });
				menu.rogueLikeUpgradeScreen.style.display = StyleEnum<DisplayStyle>.op_Implicit((DisplayStyle)1);
				Time.timeScale = 1f;
				HandleInput.Invoke(menu, new object[1] { false });
				((BaseMenu)menu).Close();
				Plugin.Log.LogInfo((object)(isUpgradeSelected ? (reason + "; applied the queued pick early") : $"{reason}; put the queued upgrade back ({QueueState.PendingCount} pending)"));
			}
		}

		private static void StopCoroutine(RogueLikeUpgradeMenu menu, FieldRef<RogueLikeUpgradeMenu, Coroutine> field)
		{
			Coroutine val = field.Invoke(menu);
			if (val != null)
			{
				((MonoBehaviour)menu).StopCoroutine(val);
				field.Invoke(menu) = null;
			}
		}

		public static void RequestOpen()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Invalid comparison between Unknown and I4
			if (!IsOpen && QueueState.PendingCount != 0 && !((Object)(object)InputManager.Instance == (Object)null))
			{
				if ((int)InputManager.Instance.CurrentInputState == 3 && (Object)(object)InventoryScreen.Instance != (Object)null)
				{
					InventoryScreen.Instance.CloseInventoryScreen(true);
					((MonoBehaviour)Plugin.Instance).StartCoroutine(OpenNextFrame());
				}
				else
				{
					TryOpen();
				}
			}
		}

		private static IEnumerator OpenNextFrame()
		{
			yield return null;
			TryOpen();
		}

		public static bool TryOpen()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Invalid comparison between Unknown and I4
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			if (IsOpen || QueueState.PendingCount == 0)
			{
				return false;
			}
			if ((Object)(object)InputManager.Instance == (Object)null || (int)InputManager.Instance.CurrentInputState != 2)
			{
				return false;
			}
			if ((Object)(object)NetworkHelper.Instance == (Object)null || (int)NetworkHelper.Instance.NetworkblockingState != 0)
			{
				return false;
			}
			RogueLikeUpgradeManager instance = RogueLikeUpgradeManager.Instance;
			RogueLikeUpgradeMenu val = Object.FindAnyObjectByType<RogueLikeUpgradeMenu>();
			if ((Object)(object)instance == (Object)null || (Object)(object)val == (Object)null || (Object)(object)GameManager.Instance.LocalPlayer == (Object)null)
			{
				return false;
			}
			if (!QueueState.TryDequeue())
			{
				return false;
			}
			IsOpen = true;
			IsOpening = true;
			_menu = val;
			_puttingBack = false;
			try
			{
				List<UpgradeDraftChoice> list = _savedChoices ?? instance.GenerateThreeChoices();
				_savedChoices = null;
				OnUpgradeDraftGenerated.Invoke(val, new object[1] { list });
			}
			finally
			{
				IsOpening = false;
			}
			Coroutine val2 = AutoChooseCoroutine.Invoke(val);
			if (val2 != null)
			{
				((MonoBehaviour)val).StopCoroutine(val2);
				AutoChooseCoroutine.Invoke(val) = null;
			}
			if (!Plugin.PauseInSolo.Value || !IsSolo())
			{
				Time.timeScale = 1f;
			}
			Plugin.Log.LogInfo((object)$"Opened queued upgrade ({QueueState.PendingCount} still pending)");
			return true;
		}

		public static void Reset()
		{
			IsOpen = false;
			IsOpening = false;
			_puttingBack = false;
			_menu = null;
			_shownChoices = null;
			_savedChoices = null;
		}

		public static void RefreshCardText()
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			if (!IsOpen || _puttingBack || (Object)(object)_menu == (Object)null || _menu.IsUpgradeSelected || Time.unscaledTime < _nextCardRefresh)
			{
				return;
			}
			_nextCardRefresh = Time.unscaledTime + 0.2f;
			UpgradePopupController val = PopupController.Invoke(_menu);
			if (val == null)
			{
				return;
			}
			foreach (UpgradeButton upgradeButton in val.UpgradeButtons)
			{
				UpgradeDraftChoice draftChoice = upgradeButton.DraftChoice;
				Label val2 = DescriptionLabel.Invoke(upgradeButton);
				if (!((Object)(object)draftChoice.Upgrade == (Object)null) && val2 != null)
				{
					string text = "<line-height=70%>" + draftChoice.Upgrade.GetLocalizedDescriptionWithRarity(draftChoice.Rarity);
					if (((TextElement)val2).text != text)
					{
						((TextElement)val2).text = text;
					}
				}
			}
			StatsPopupController obj = StatsController.Invoke(_menu);
			if (obj != null)
			{
				obj.RefreshStatsUI();
			}
		}

		private static bool IsSolo()
		{
			return FirstPersonController.LocalPlayers.Count <= 1;
		}
	}
	internal static class QueueSnapshot
	{
		private sealed class Data
		{
			public ulong LobbyId;

			public long Ticks;

			public int Wave;

			public int TomeLevels;

			public int Count;

			public List<UpgradeDraftChoice> Choices;
		}

		[HarmonyPatch(typeof(NetworkHelper), "UserCode_TargetNotifyJoinedClass__NetworkConnectionToClient__PlayerClass__Boolean")]
		private static class RestoreOnJoinPatch
		{
			private static void Postfix(bool restoredFromSession)
			{
				TryRestore(restoredFromSession);
			}
		}

		[HarmonyPatch(typeof(RogueLikeUpgradeManager), "ApplyUpgrade")]
		private static class SaveOnUpgradeAppliedPatch
		{
			private static void Postfix()
			{
				Save();
			}
		}

		[HarmonyPatch(typeof(StoneWardsNetworkManager), "OnClientChangeScene")]
		private static class DeleteOnHubPatch
		{
			private static void Prefix(StoneWardsNetworkManager __instance, string newSceneName)
			{
				//IL_0012: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Invalid comparison between Unknown and I4
				if ((Object)(object)GameManager.Instance != (Object)null && (int)GameManager.Instance.SceneType == 1 && newSceneName == HubScene.Invoke(__instance))
				{
					Delete();
				}
			}
		}

		private static readonly TimeSpan MaxAge = TimeSpan.FromMinutes(30.0);

		private const int FormatVersion = 1;

		private static readonly FieldRef<StoneWardsNetworkManager, string> HubScene = AccessTools.FieldRefAccess<StoneWardsNetworkManager, string>("hubScene");

		private static string FilePath => Path.Combine(Paths.ConfigPath, "UpgradeQueue.rejoin.txt");

		public static bool Paused { get; set; }

		public static void Init()
		{
			QueueState.Changed += delegate
			{
				Save();
			};
		}

		public static void Save()
		{
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: 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_0114: Expected I4, but got Unknown
			if (Paused || !InClientLevel(out var lobbyId))
			{
				return;
			}
			int pendingIncludingOpen = QueuedUpgradeSession.PendingIncludingOpen;
			List<string> list = new List<string>
			{
				1.ToString(CultureInfo.InvariantCulture),
				lobbyId.ToString(CultureInfo.InvariantCulture),
				DateTime.UtcNow.Ticks.ToString(CultureInfo.InvariantCulture),
				NetworkHelper.Instance.currentWaveIndex.ToString(CultureInfo.InvariantCulture),
				TomeLevels().ToString(CultureInfo.InvariantCulture),
				pendingIncludingOpen.ToString(CultureInfo.InvariantCulture)
			};
			List<UpgradeDraftChoice> list2 = ((pendingIncludingOpen > 0) ? QueuedUpgradeSession.FrontChoices : null);
			if (list2 != null)
			{
				foreach (UpgradeDraftChoice item in list2)
				{
					UpgradeDraftChoice current = item;
					if (((UpgradeDraftChoice)(ref current)).IsValid)
					{
						list.Add(string.Join("\t", ((BaseUpgradeSO)current.Upgrade).ID, current.Level.ToString(CultureInfo.InvariantCulture), ((int)current.Rarity).ToString(CultureInfo.InvariantCulture)));
					}
				}
			}
			try
			{
				string text = FilePath + ".tmp";
				File.WriteAllLines(text, list);
				if (File.Exists(FilePath))
				{
					File.Delete(FilePath);
				}
				File.Move(text, FilePath);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Could not save the queue for rejoining: " + ex.Message));
			}
		}

		public static void Delete()
		{
			try
			{
				if (File.Exists(FilePath))
				{
					File.Delete(FilePath);
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Could not delete the rejoin snapshot: " + ex.Message));
			}
		}

		private static void TryRestore(bool restoredFromSession)
		{
			Data data = Read();
			Delete();
			if (data == null || !restoredFromSession || !InClientLevel(out var lobbyId))
			{
				return;
			}
			string text = null;
			if (data.LobbyId != lobbyId)
			{
				text = "different lobby";
			}
			else if (DateTime.UtcNow - new DateTime(data.Ticks, DateTimeKind.Utc) > MaxAge)
			{
				text = "too old";
			}
			else if (NetworkHelper.Instance.currentWaveIndex < data.Wave)
			{
				text = "earlier wave";
			}
			else if (TomeLevels() != data.TomeLevels)
			{
				text = "upgrades don't match";
			}
			else if (QueueState.PendingCount > 0 || QueuedUpgradeSession.IsOpen)
			{
				text = "queue already in use";
			}
			if (text != null)
			{
				if (data.Count > 0)
				{
					Plugin.Log.LogInfo((object)$"Not restoring {data.Count} queued upgrade(s) from before rejoining: {text}");
				}
				Save();
				return;
			}
			if (data.Count > 0)
			{
				QueuedUpgradeSession.RestoreFrontChoices(data.Choices);
				QueueState.Restore(data.Count);
				HudCounter.Ping();
				Plugin.Log.LogInfo((object)$"Rejoined the run; restored {data.Count} queued upgrade(s)");
			}
			Save();
		}

		private static bool InClientLevel(out ulong lobbyId)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Invalid comparison between Unknown and I4
			lobbyId = (((Object)(object)SteamLobby.Instance != (Object)null) ? SteamLobby.Instance.currentLobbyID : 0);
			if (lobbyId != 0L && NetworkClient.active && !NetworkServer.active && (Object)(object)GameManager.Instance != (Object)null && (int)GameManager.Instance.SceneType == 1 && (Object)(object)NetworkHelper.Instance != (Object)null)
			{
				return (Object)(object)RogueLikeUpgradeManager.Instance != (Object)null;
			}
			return false;
		}

		private static int TomeLevels()
		{
			int num = 0;
			foreach (ActiveRunUpgrade tome in RogueLikeUpgradeManager.Instance.GetTomes())
			{
				num += tome.Level;
			}
			return num;
		}

		private static Data Read()
		{
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: 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)
			try
			{
				if (!File.Exists(FilePath))
				{
					return null;
				}
				string[] array = File.ReadAllLines(FilePath);
				if (array.Length < 6 || array[0] != 1.ToString(CultureInfo.InvariantCulture))
				{
					return null;
				}
				CultureInfo invariantCulture = CultureInfo.InvariantCulture;
				Data data = new Data
				{
					LobbyId = ulong.Parse(array[1], invariantCulture),
					Ticks = long.Parse(array[2], invariantCulture),
					Wave = int.Parse(array[3], invariantCulture),
					TomeLevels = int.Parse(array[4], invariantCulture),
					Count = int.Parse(array[5], invariantCulture)
				};
				List<UpgradeDraftChoice> list = new List<UpgradeDraftChoice>();
				for (int i = 6; i < array.Length; i++)
				{
					string[] array2 = array[i].Split('\t');
					object obj;
					if (array2.Length != 3)
					{
						obj = null;
					}
					else
					{
						RogueLikeUpgradeManager instance = RogueLikeUpgradeManager.Instance;
						obj = ((instance != null) ? instance.GetUpgradeSOByID(array2[0]) : null);
					}
					RogueLikeUpgradeSO val = (RogueLikeUpgradeSO)obj;
					if ((Object)(object)val == (Object)null)
					{
						list = null;
						break;
					}
					list.Add(new UpgradeDraftChoice
					{
						Upgrade = val,
						Level = int.Parse(array2[1], invariantCulture),
						Rarity = (Rarity)int.Parse(array2[2], invariantCulture)
					});
				}
				data.Choices = ((list != null && list.Count > 0) ? list : null);
				return data;
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Could not read the rejoin snapshot: " + ex.Message));
				return null;
			}
		}
	}
	internal static class QueueState
	{
		public static int PendingCount { get; private set; }

		public static event Action<int> Changed;

		public static void Enqueue()
		{
			PendingCount++;
			QueueState.Changed?.Invoke(PendingCount);
		}

		public static bool TryDequeue()
		{
			if (PendingCount == 0)
			{
				return false;
			}
			PendingCount--;
			QueueState.Changed?.Invoke(PendingCount);
			return true;
		}

		public static void Restore(int count)
		{
			PendingCount = Math.Max(0, count);
			QueueState.Changed?.Invoke(PendingCount);
		}

		public static void Clear()
		{
			if (PendingCount != 0)
			{
				PendingCount = 0;
				QueueState.Changed?.Invoke(PendingCount);
			}
		}
	}
}
namespace UpgradeQueue.Patches
{
	internal static class ClearQueueOnRunEndPatch
	{
		[HarmonyPatch(typeof(MetaProgressManager), "StartRun")]
		private static class StartRunPatch
		{
			private static void Prefix()
			{
				Clear("Run started");
			}
		}

		[HarmonyPatch(typeof(MetaProgressManager), "EndRun")]
		private static class EndRunPatch
		{
			private static void Postfix()
			{
				Clear("Run ended");
			}
		}

		private static void Clear(string reason)
		{
			int pendingCount = QueueState.PendingCount;
			QueueSnapshot.Paused = true;
			try
			{
				QueueState.Clear();
				QueuedUpgradeSession.Reset();
			}
			finally
			{
				QueueSnapshot.Paused = false;
			}
			if (pendingCount > 0)
			{
				Plugin.Log.LogInfo((object)$"{reason}; dropped {pendingCount} queued upgrade(s)");
			}
		}
	}
	[HarmonyPatch(typeof(EndWaveUpgradeScreen), "OnEndOfWaveUpgradeDraftGenerated")]
	internal static class CloseForEndOfWavePatch
	{
		private static void Prefix()
		{
			QueuedUpgradeSession.CloseNow("End-of-wave upgrade opened");
		}
	}
	[HarmonyPatch(typeof(RogueLikeUpgradeMenu), "OnUpgradeDraftGenerated")]
	internal static class InterceptLevelUpPatch
	{
		private static readonly FieldRef<RogueLikeUpgradeMenu, UpgradeDraftChoice> SelectedUpgrade = AccessTools.FieldRefAccess<RogueLikeUpgradeMenu, UpgradeDraftChoice>("selectedUpgrade");

		private static readonly FieldRef<RogueLikeUpgradeMenu, bool> HasSkip = AccessTools.FieldRefAccess<RogueLikeUpgradeMenu, bool>("hasSkip");

		private static bool Prefix(RogueLikeUpgradeMenu __instance, List<UpgradeDraftChoice> upgradeDraftChoices)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			if (QueuedUpgradeSession.IsOpening)
			{
				return true;
			}
			if (!Plugin.Enabled.Value && !QueuedUpgradeSession.IsOpen)
			{
				return true;
			}
			if (!QueuedUpgradeSession.IsOpen)
			{
				SelectedUpgrade.Invoke(__instance) = default(UpgradeDraftChoice);
				HasSkip.Invoke(__instance) = false;
			}
			QueueState.Enqueue();
			HudCounter.Ping();
			Plugin.Log.LogInfo((object)$"Queued level-up upgrade ({QueueState.PendingCount} pending)");
			((MonoBehaviour)__instance).StartCoroutine(ReportChosenNextFrame());
			return false;
		}

		private static IEnumerator ReportChosenNextFrame()
		{
			yield return null;
			FirstPersonController val = (((Object)(object)GameManager.Instance != (Object)null) ? GameManager.Instance.LocalPlayer : null);
			if ((Object)(object)val == (Object)null || (Object)(object)NetworkHelper.Instance == (Object)null)
			{
				Plugin.Log.LogWarning((object)"No local player or NetworkHelper; could not end the upgrade phase");
			}
			else
			{
				NetworkHelper.Instance.CmdOnUpgradeChosen(val);
			}
		}
	}
}