Decompiled source of EnhancedUpgradeMenu v1.3.0

BepInEx/plugins/EnhancedUpgradeMenu.dll

Decompiled 10 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Pigeon;
using Pigeon.Movement;
using Pigeon.UI;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("EnhancedUpgradeMenu")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.0.0.0")]
[assembly: AssemblyInformationalVersion("0.0.0-alpha.0.11+098e0cb453ec1e5fd7f1ab509befcfe51eba0673")]
[assembly: AssemblyProduct("EnhancedUpgradeMenu")]
[assembly: AssemblyTitle("EnhancedUpgradeMenu")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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 class EquippedUpgrades
{
	public int GearID;

	public List<EquippedUpgrade> Upgrades;

	public EquippedUpgrades(int gearID)
	{
		GearID = gearID;
		Upgrades = new List<EquippedUpgrade>();
	}

	public EquippedUpgrades(int gearID, List<EquippedUpgrade> upgrades)
	{
		GearID = gearID;
		Upgrades = upgrades;
	}

	public EquippedUpgrades(string code)
	{
		if (string.IsNullOrEmpty(code))
		{
			throw new ArgumentException("Code cannot be null or empty", "code");
		}
		using MemoryStream memoryStream = new MemoryStream(Convert.FromBase64String(code));
		using BinaryReader binaryReader = new BinaryReader(memoryStream);
		GearID = 0;
		Upgrades = new List<EquippedUpgrade>();
		while (memoryStream.Position < memoryStream.Length)
		{
			byte[] array = binaryReader.ReadBytes(2);
			Array.Reverse((Array)array);
			short num = BitConverter.ToInt16(array, 0);
			byte[] array2 = binaryReader.ReadBytes(4);
			Array.Reverse((Array)array2);
			int id = BitConverter.ToInt32(array2, 0);
			int x = (num >> 6) & 7;
			int y = (num >> 3) & 7;
			byte rotation = (byte)((uint)num & 7u);
			Upgrades.Add(new EquippedUpgrade(x, y, rotation, id));
		}
	}

	public void Add(EquippedUpgrade upgrade)
	{
		Upgrades.Add(upgrade);
	}

	public override string ToString()
	{
		List<byte> list = new List<byte>();
		foreach (EquippedUpgrade upgrade in Upgrades)
		{
			short value = IPAddress.HostToNetworkOrder((short)((upgrade.X << 6) | (upgrade.Y << 3) | upgrade.Rotation));
			list.AddRange(BitConverter.GetBytes(value));
			int value2 = IPAddress.HostToNetworkOrder(upgrade.ID);
			list.AddRange(BitConverter.GetBytes(value2));
		}
		return Convert.ToBase64String(list.ToArray()).TrimEnd(new char[1] { '=' });
	}
}
public class EquippedUpgrade
{
	public int X;

	public int Y;

	public byte Rotation;

	public int ID;

	public EquippedUpgrade(int x, int y, byte rotation, int id)
	{
		X = x;
		Y = y;
		Rotation = rotation;
		ID = id;
	}
}
public static class CompareHandling
{
	public static ConfigEntry<Key> CompareKey;

	public static void Initialize()
	{
	}

	public static void ApplyPatches(Harmony harmony)
	{
		try
		{
			CompareHoverPatches.ApplyPatches(harmony);
		}
		catch (Exception ex)
		{
			SparrohPlugin.Logger.LogError((object)("Failed to apply CompareHandling patches: " + ex.Message));
		}
	}
}
public class CompareHoverManager : MonoBehaviour
{
	public static HoverInfo currentComparisonInfo;

	public static HoverInfo currentHoverUpgrade;

	private static GameObject comparisonDisplayContainer;

	private static HoverInfoDisplay comparisonDisplay;

	private static HoverInfoDisplay mainDisplay;

	private static FileSystemWatcher configWatcher;

	private static ManualLogSource Logger => SparrohPlugin.Logger;

	public static CompareHoverManager Instance { get; private set; }

	private void Awake()
	{
		Instance = this;
		Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
		SetupConfigWatcher();
	}

	private void SetupConfigWatcher()
	{
		try
		{
			string configPath = Paths.ConfigPath;
			string filter = "sparroh.enhancedupgrademenu.cfg";
			if (!string.IsNullOrEmpty(configPath) && Directory.Exists(configPath))
			{
				configWatcher = new FileSystemWatcher(configPath, filter);
				configWatcher.NotifyFilter = NotifyFilters.LastWrite;
				configWatcher.Created += OnConfigChanged;
				configWatcher.Changed += OnConfigChanged;
				configWatcher.EnableRaisingEvents = true;
			}
		}
		catch (Exception ex)
		{
			Logger.LogError((object)("Failed to setup config watcher: " + ex.Message));
		}
	}

	private void OnConfigChanged(object sender, FileSystemEventArgs e)
	{
	}

	public static bool IsCompareKeyPressed()
	{
		//IL_0010: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		Keyboard current = Keyboard.current;
		if (current == null)
		{
			return false;
		}
		Key value = CompareHandling.CompareKey.Value;
		return ((ButtonControl)current[value]).wasPressedThisFrame;
	}

	public static void SetComparisonUpgrade(HoverInfo info)
	{
		if (!((Object)(object)currentComparisonInfo == (Object)(object)info))
		{
			ClearComparisonUpgrade();
			currentComparisonInfo = info;
			if ((Object)(object)info != (Object)null)
			{
				CreateComparisonDisplay(info);
			}
		}
	}

	public static void ClearComparisonUpgrade()
	{
		if (!((Object)(object)currentComparisonInfo == (Object)null))
		{
			currentComparisonInfo = null;
			if ((Object)(object)comparisonDisplayContainer != (Object)null)
			{
				Object.Destroy((Object)(object)comparisonDisplayContainer);
				comparisonDisplayContainer = null;
				comparisonDisplay = null;
			}
		}
	}

	private static void CreateComparisonDisplay(HoverInfo info)
	{
		//IL_00ad: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)comparisonDisplayContainer != (Object)null))
		{
			if ((Object)(object)mainDisplay == (Object)null)
			{
				mainDisplay = HoverInfoDisplay.Instance;
			}
			if (!((Object)(object)(mainDisplay ?? HoverInfoDisplay.Instance) == (Object)null))
			{
				comparisonDisplayContainer = Object.Instantiate<GameObject>(((Component)mainDisplay).gameObject);
				((Object)comparisonDisplayContainer).name = "CompareHoverDisplay";
				comparisonDisplay = comparisonDisplayContainer.GetComponent<HoverInfoDisplay>();
				comparisonDisplayContainer.AddComponent<ComparisonDisplayMarker>();
				comparisonDisplayContainer.transform.SetParent(((Component)mainDisplay).transform.parent, false);
				RectTransform component = comparisonDisplayContainer.GetComponent<RectTransform>();
				component.anchorMin = new Vector2(0.15f, 0.5f);
				component.anchorMax = new Vector2(0.15f, 0.5f);
				component.pivot = new Vector2(0f, 0.5f);
				component.anchoredPosition = Vector2.zero;
				comparisonDisplay.ShowInfo(info);
			}
		}
	}

	private void Update()
	{
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: 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)
		if ((Object)(object)currentHoverUpgrade != (Object)null && IsCompareKeyPressed() && currentHoverUpgrade is HoverInfoUpgrade)
		{
			if ((Object)(object)currentComparisonInfo == (Object)(object)currentHoverUpgrade)
			{
				ClearComparisonUpgrade();
			}
			else
			{
				SetComparisonUpgrade(currentHoverUpgrade);
			}
		}
		if ((Object)(object)comparisonDisplayContainer != (Object)null)
		{
			if (!comparisonDisplayContainer.gameObject.activeSelf)
			{
				comparisonDisplayContainer.gameObject.SetActive(true);
			}
			RectTransform component = comparisonDisplayContainer.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0.15f, 0.5f);
			component.anchorMax = new Vector2(0.15f, 0.5f);
			component.pivot = new Vector2(0f, 0.5f);
			component.anchoredPosition = Vector2.zero;
		}
	}

	private void OnDestroy()
	{
		if (configWatcher != null)
		{
			configWatcher.Dispose();
		}
		ClearComparisonUpgrade();
	}
}
[HarmonyPatch]
public class CompareHoverPatches
{
	public static void ApplyPatches(Harmony harmony)
	{
		harmony.PatchAll();
	}

	[HarmonyPatch(typeof(HoverInfoDisplay), "OnHoverEnter")]
	[HarmonyPostfix]
	public static void OnHoverEnter_Postfix(HoverInfo info)
	{
		//IL_0012: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Expected O, but got Unknown
		if ((Object)(object)CompareHoverManager.Instance == (Object)null)
		{
			GameObject val = new GameObject("CompareHoverManager");
			Object.DontDestroyOnLoad((Object)val);
			val.AddComponent<CompareHoverManager>();
		}
		if (!((Object)(object)CompareHoverManager.Instance == (Object)null))
		{
			if (info is HoverInfoUpgrade)
			{
				CompareHoverManager.currentHoverUpgrade = info;
			}
			else
			{
				CompareHoverManager.currentHoverUpgrade = null;
			}
		}
	}

	[HarmonyPatch(typeof(HoverInfoDisplay), "OnHoverExit")]
	[HarmonyPostfix]
	public static void OnHoverExit_Postfix(HoverInfo info)
	{
		CompareHoverManager.currentHoverUpgrade = null;
	}

	[HarmonyPatch(typeof(HoverInfoDisplay), "Update")]
	[HarmonyPrefix]
	public static bool Update_Prefix(HoverInfoDisplay __instance)
	{
		if ((Object)(object)((Component)__instance).gameObject.GetComponent<ComparisonDisplayMarker>() != (Object)null)
		{
			return false;
		}
		return true;
	}

	[HarmonyPatch(typeof(HoverInfoDisplay), "ShowInfo")]
	[HarmonyPrefix]
	public static bool ShowInfo_Prefix(HoverInfoDisplay __instance, HoverInfo info)
	{
		if ((Object)(object)((Component)__instance).gameObject.GetComponent<ComparisonDisplayMarker>() != (Object)null && (Object)(object)CompareHoverManager.currentComparisonInfo != (Object)null)
		{
			_ = (Object)(object)info != (Object)(object)CompareHoverManager.currentComparisonInfo;
		}
		return true;
	}

	[HarmonyPatch(typeof(HoverInfoDisplay), "Activate")]
	[HarmonyPrefix]
	public static bool Activate_Prefix(HoverInfoDisplay __instance, HoverInfo info, bool resetPosition)
	{
		if ((Object)(object)((Component)__instance).gameObject.GetComponent<ComparisonDisplayMarker>() != (Object)null)
		{
			if ((Object)(object)info == (Object)(object)CompareHoverManager.currentComparisonInfo)
			{
				return true;
			}
			return false;
		}
		return true;
	}

	[HarmonyPatch(typeof(HoverInfoDisplay), "Deactivate")]
	[HarmonyPrefix]
	public static bool Deactivate_Prefix(HoverInfoDisplay __instance)
	{
		if ((Object)(object)((Component)__instance).gameObject.GetComponent<ComparisonDisplayMarker>() != (Object)null)
		{
			return false;
		}
		return true;
	}
}
public class ComparisonDisplayMarker : MonoBehaviour
{
}
public class DisplayGunDataMod
{
	private bool enableGearDetailsStatsWindow;

	private IWeapon currentWeapon;

	private GearDetailsWindow currentWindow;

	private bool showStatsWindow;

	private Rect windowRect = new Rect(20f, 20f, 350f, 400f);

	private Vector2 scrollPosition = Vector2.zero;

	private bool statsWindowVisible = true;

	private readonly Color sky = new Color(0.529f, 0.808f, 0.922f);

	private readonly Color orchid = new Color(0.855f, 0.439f, 0.839f);

	private readonly Color rose = new Color(0.8901961f, 12f / 85f, 0.16862746f);

	private readonly Color macaroon = new Color(83f / 85f, 0.8784314f, 0.4627451f);

	private readonly Color shamrock = new Color(1f / 85f, 0.6745098f, 0.07450981f);

	private const int NUM_STAT_LINES = 25;

	private const float UpdateInterval = 0.5f;

	private float updateTimer;

	private List<string> statLines = new List<string>();

	public DisplayGunDataMod(bool enable)
	{
		//IL_0015: 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_0025: 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_0046: 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)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: 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_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
		enableGearDetailsStatsWindow = enable;
	}

	public void SetEnable(bool enable)
	{
		enableGearDetailsStatsWindow = enable;
	}

	public void Update()
	{
		if (!enableGearDetailsStatsWindow)
		{
			return;
		}
		if ((Object)(object)Menu.Instance != (Object)null && LevelData.CanModifyGear)
		{
			Window top = Menu.Instance.WindowSystem.GetTop();
			GearDetailsWindow val = (GearDetailsWindow)(object)((top is GearDetailsWindow) ? top : null);
			if (val != null && !val.InSkinMode)
			{
				IUpgradable upgradablePrefab = val.UpgradablePrefab;
				IWeapon val2 = (IWeapon)(object)((upgradablePrefab is IWeapon) ? upgradablePrefab : null);
				if (val2 != null)
				{
					if (currentWeapon != val2)
					{
						currentWeapon = val2;
						currentWindow = val;
						showStatsWindow = true;
						updateTimer = 0f;
						UpdateGearDetailsStats();
					}
				}
				else
				{
					currentWeapon = null;
					currentWindow = null;
					showStatsWindow = false;
				}
			}
			else
			{
				currentWeapon = null;
				currentWindow = null;
				showStatsWindow = false;
			}
		}
		else
		{
			currentWeapon = null;
			showStatsWindow = false;
		}
		if (showStatsWindow && currentWeapon != null)
		{
			updateTimer += Time.deltaTime;
			if (updateTimer >= 0.5f)
			{
				updateTimer = 0f;
				UpdateGearDetailsStats();
			}
		}
	}

	private void UpdateGearDetailsStats()
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: 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: Expected O, but got Unknown
		//IL_0659: Unknown result type (might be due to invalid IL or missing references)
		//IL_065a: 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_018b: 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_01c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0348: Unknown result type (might be due to invalid IL or missing references)
		//IL_0399: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0479: Unknown result type (might be due to invalid IL or missing references)
		//IL_04d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0234: Unknown result type (might be due to invalid IL or missing references)
		//IL_0246: Unknown result type (might be due to invalid IL or missing references)
		//IL_0248: 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_0517: 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_00a4: 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_051d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0522: Unknown result type (might be due to invalid IL or missing references)
		//IL_0524: Unknown result type (might be due to invalid IL or missing references)
		//IL_0529: Unknown result type (might be due to invalid IL or missing references)
		//IL_0530: Unknown result type (might be due to invalid IL or missing references)
		//IL_0535: Unknown result type (might be due to invalid IL or missing references)
		//IL_0542: Unknown result type (might be due to invalid IL or missing references)
		//IL_0563: Unknown result type (might be due to invalid IL or missing references)
		//IL_0584: Unknown result type (might be due to invalid IL or missing references)
		//IL_05a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_05a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_05cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_05e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_05e3: Unknown result type (might be due to invalid IL or missing references)
		//IL_05e9: Invalid comparison between Unknown and I4
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_05eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_05ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_0606: Unknown result type (might be due to invalid IL or missing references)
		//IL_0617: 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_00ca: Unknown result type (might be due to invalid IL or missing references)
		if (currentWeapon == null)
		{
			return;
		}
		GunData gunData = currentWeapon.GunData;
		UpgradeStatChanges val = new UpgradeStatChanges();
		if ((Object)(object)currentWindow != (Object)null)
		{
			FieldInfo field = typeof(GearDetailsWindow).GetField("equipSlots", BindingFlags.Instance | BindingFlags.NonPublic);
			if (field != null)
			{
				object? value = field.GetValue(currentWindow);
				ModuleEquipSlots val2 = (ModuleEquipSlots)((value is ModuleEquipSlots) ? value : null);
				if (val2 != null)
				{
					HexMap hexMap = val2.HexMap;
					if (hexMap != null)
					{
						List<UpgradeInstance> list = new List<UpgradeInstance>();
						for (int i = 0; i < hexMap.Width; i++)
						{
							for (int j = 0; j < hexMap.Height; j++)
							{
								Node val3 = hexMap[i, j];
								if (val3.enabled && val3.upgrade != null && !list.Contains(val3.upgrade))
								{
									list.Add(val3.upgrade);
								}
							}
						}
						foreach (UpgradeInstance item in list)
						{
							try
							{
								((GearUpgrade)item.Upgrade).Apply((IGear)(object)currentWeapon, item);
							}
							catch (Exception arg)
							{
								SparrohPlugin.Logger.LogWarning((object)$"Error applying upgrade {item.Upgrade.Name}: {arg}");
							}
						}
					}
				}
			}
		}
		ref GunData gunData2 = ref currentWeapon.GunData;
		Dictionary<string, StatInfo> dictionary = new Dictionary<string, StatInfo>();
		IEnumerator<StatInfo> enumerator2 = ((IGear)currentWeapon).EnumeratePrimaryStats(val);
		while (enumerator2.MoveNext())
		{
			dictionary[enumerator2.Current.name] = enumerator2.Current;
		}
		Dictionary<string, StatInfo> dictionary2 = new Dictionary<string, StatInfo>();
		IEnumerator<StatInfo> enumerator3 = ((IGear)currentWeapon).EnumerateSecondaryStats(val);
		while (enumerator3.MoveNext())
		{
			if (enumerator3.Current.name != "Aim Zoom")
			{
				dictionary2[enumerator3.Current.name] = enumerator3.Current;
			}
		}
		statLines.Clear();
		statLines.Add("Weapon Stats Preview:");
		if (dictionary.TryGetValue("Damage Type", out var value2))
		{
			statLines.Add(value2.name + ": <color=#" + ColorUtility.ToHtmlStringRGB(value2.color) + ">" + value2.value + "</color>");
		}
		AddStatFromDict(ref statLines, dictionary2, "Damage");
		AddStatFromDict(ref statLines, dictionary, "Damage Type");
		AddStatFromDict(ref statLines, dictionary2, "Fire Rate");
		statLines.Add($"Burst Size: <color=#{ColorUtility.ToHtmlStringRGB(macaroon)}>{gunData2.burstSize}</color>");
		statLines.Add("Burst Interval: <color=#" + ColorUtility.ToHtmlStringRGB(macaroon) + ">" + gunData2.burstFireInterval.ToString("F2") + "</color>");
		AddStatFromDict(ref statLines, dictionary2, "Ammo Capacity");
		statLines.Add($"Ammo Capacity: <color=#{ColorUtility.ToHtmlStringRGB(sky)}>{gunData2.ammoCapacity}</color>");
		AddStatFromDict(ref statLines, dictionary2, "Reload Duration");
		AddStatFromDict(ref statLines, dictionary2, "Charge Duration");
		statLines.Add($"Explosion Size: <color=#{ColorUtility.ToHtmlStringRGB(orchid)}>{Mathf.Round(gunData2.hitForce)}</color>");
		AddStatFromDict(ref statLines, dictionary2, "Range");
		statLines.Add($"Recoil: <color=#{ColorUtility.ToHtmlStringRGB(shamrock)}>X({Mathf.Round(gunData2.recoilData.recoilX.x)}, {Mathf.Round(gunData2.recoilData.recoilX.y)}) Y({Mathf.Round(gunData2.recoilData.recoilY.x)}, {Mathf.Round(gunData2.recoilData.recoilY.y)})</color>");
		statLines.Add($"Spread: <color=#{ColorUtility.ToHtmlStringRGB(shamrock)}>Size({Mathf.Round(gunData2.spreadData.spreadSize.x)}, {Mathf.Round(gunData2.spreadData.spreadSize.y)})</color>");
		statLines.Add("Fire Mode: <color=#" + ColorUtility.ToHtmlStringRGB(macaroon) + ">" + ((gunData2.automatic == 1) ? "Automatic" : "Semi Automatic") + "</color>");
		BulletData val4 = default(BulletData);
		try
		{
			Vector3 zero = Vector3.zero;
			Quaternion identity = Quaternion.identity;
			val4 = ((GunData)(ref gunData2)).GetBulletData(ref zero, ref identity);
			statLines.Add($"Bullet Speed: <color=#FFFFFF>{val4.speed:F1}</color>");
			statLines.Add($"Bullet Force: <color=#FFFFFF>{val4.force:F1}</color>");
			statLines.Add($"Bullet Damage: <color=#FFFFFF>{val4.damage:F1}</color>");
			statLines.Add($"Bullet Range: <color=#FFFFFF>{val4.range.falloffEndDistance:F0}</color>");
			statLines.Add($"Bullet Gravity: <color=#FFFFFF>{val4.gravity:F2}</color>");
			if ((int)val4.damageEffect > 0)
			{
				StatusEffectData effect = Global.GetEffect(val4.damageEffect);
				statLines.Add($"Bullet Effect: <color=#{ColorUtility.ToHtmlStringRGB(effect.iconColor)}>{effect.EffectName} x{val4.damageEffectAmount}</color>");
			}
		}
		catch (Exception ex)
		{
			SparrohPlugin.Logger.LogWarning((object)("Error getting BulletData: " + ex.Message));
		}
		currentWeapon.GunData = gunData;
	}

	private void AddStatFromDict(ref List<string> lines, Dictionary<string, StatInfo> stats, string statName)
	{
		//IL_000e: 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_0033: 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_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: 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_0096: Unknown result type (might be due to invalid IL or missing references)
		if (stats.TryGetValue(statName, out var value))
		{
			string text = value.name + ":";
			string text2 = value.value;
			if (statName == "Fire Rate" && float.TryParse(value.value, out var result))
			{
				text2 = (result / 60f).ToString("F1") + " /s";
			}
			Color val = ((statName == "Damage Type") ? value.color : GetStatValueColor(statName));
			lines.Add(text + " <color=#" + ColorUtility.ToHtmlStringRGB(val) + ">" + text2 + "</color>");
		}
	}

	private Color GetStatValueColor(string statName)
	{
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: 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_005a: 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_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_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0071: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: 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_007e: 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_0086: Unknown result type (might be due to invalid IL or missing references)
		//IL_008b: Unknown result type (might be due to invalid IL or missing references)
		return (Color)(statName switch
		{
			"Damage" => rose, 
			"Fire Rate" => macaroon, 
			"Ammo Capacity" => sky, 
			"Reload Duration" => sky, 
			"Charge Duration" => sky, 
			"Range" => shamrock, 
			_ => Color.white, 
		});
	}

	public void OnGUI()
	{
		//IL_0043: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_0098: Expected O, but got Unknown
		//IL_0093: 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)
		if (enableGearDetailsStatsWindow && showStatsWindow && currentWeapon != null)
		{
			float num = 150f;
			float num2 = 30f;
			if (GUI.Button(new Rect((float)Screen.width - num - 20f, (float)Screen.height - num2 - 20f, num, num2), statsWindowVisible ? "Hide Gun Stats" : "Show Gun Stats"))
			{
				statsWindowVisible = !statsWindowVisible;
			}
			if (statsWindowVisible)
			{
				windowRect = GUI.Window(0, windowRect, new WindowFunction(DoStatsWindow), "Gun Stats Preview");
			}
		}
	}

	private void DoStatsWindow(int windowID)
	{
		//IL_0002: 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_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_003a: 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_0052: Expected O, but got Unknown
		//IL_0084: Unknown result type (might be due to invalid IL or missing references)
		scrollPosition = GUILayout.BeginScrollView(scrollPosition, Array.Empty<GUILayoutOption>());
		foreach (string statLine in statLines)
		{
			GUILayout.Label(statLine, new GUIStyle(GUI.skin.label)
			{
				richText = true,
				wordWrap = true
			}, Array.Empty<GUILayoutOption>());
		}
		GUILayout.EndScrollView();
		GUI.DragWindow(new Rect(0f, 0f, 10000f, 20f));
	}
}
public static class SortHandlingMod
{
	public struct FilterSettings
	{
		public List<Rarity> HiddenRarities;

		public bool FilterStats;

		public List<string> StatIncludeList;

		public FavoriteFilter FavoriteSetting;
	}

	public enum FavoriteFilter
	{
		ShowAll,
		ShowOnlyFavorited,
		HideFavorited
	}
}
public static class UpgradeSortingPlugin
{
	public class FilterPanelUI
	{
		private GameObject filterPanel;

		private bool isExpanded;

		private bool isInitialized;

		public bool IsExpanded => isExpanded;

		private void CreateFilterPanel()
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Expected O, but got Unknown
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			if (isInitialized)
			{
				return;
			}
			GameObject val = GameObject.Find("Gear Details/UpgradeList");
			Transform val2 = null;
			if ((Object)(object)val != (Object)null)
			{
				val2 = val.transform;
			}
			else
			{
				GameObject val3 = GameObject.Find("Gear Details");
				if (!((Object)(object)val3 != (Object)null))
				{
					return;
				}
				val2 = val3.transform;
			}
			filterPanel = new GameObject("UpgradeFilterPanel");
			filterPanel.transform.SetParent(val2, false);
			((Graphic)filterPanel.AddComponent<Image>()).color = new Color(0.1f, 0.1f, 0.1f, 0.9f);
			VerticalLayoutGroup obj = filterPanel.AddComponent<VerticalLayoutGroup>();
			((LayoutGroup)obj).padding = new RectOffset(5, 5, 5, 5);
			((HorizontalOrVerticalLayoutGroup)obj).spacing = 3f;
			((LayoutGroup)obj).childAlignment = (TextAnchor)0;
			((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = false;
			((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = false;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = false;
			RectTransform component = filterPanel.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 1f);
			component.anchorMax = new Vector2(0f, 1f);
			component.pivot = new Vector2(0f, 1f);
			component.sizeDelta = new Vector2(200f, 300f);
			component.anchoredPosition = new Vector2(-200f, -80f);
			if (!((Object)(object)filterPanel == (Object)null) && !((Object)(object)filterPanel.transform == (Object)null))
			{
				try
				{
					CreateClearAllFiltersButton();
					CreateRarityFilter();
					CreateFavoriteFilter();
					CreateStatFilters();
				}
				catch (Exception)
				{
					return;
				}
				filterPanel.SetActive(false);
				isInitialized = true;
			}
		}

		private void CreateRarityFilter()
		{
			//IL_002f: 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)
			CreateUITextObject("RarityFilterLabel", "Hide Rarities:", 12f, filterPanel.transform).GetComponent<RectTransform>().sizeDelta = new Vector2(180f, 20f);
			var obj = new[]
			{
				new
				{
					Name = "Standard",
					Rarity = (Rarity)0
				},
				new
				{
					Name = "Rare",
					Rarity = (Rarity)1
				},
				new
				{
					Name = "Epic",
					Rarity = (Rarity)2
				},
				new
				{
					Name = "Exotic",
					Rarity = (Rarity)3
				},
				new
				{
					Name = "Oddity",
					Rarity = (Rarity)4
				}
			};
			CurrentFilters.HiddenRarities.Clear();
			var array = obj;
			foreach (var anon in array)
			{
				CreateRarityToggleButton(anon.Name, anon.Rarity);
			}
			FixRarityButtonTextPosition();
		}

		private GameObject CreateRarityToggleButton(string text, Rarity rarity)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Expected O, but got Unknown
			//IL_0107: 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_0133: Expected O, but got Unknown
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)filterPanel == (Object)null)
				{
					return null;
				}
				GameObject val = new GameObject("FilterButton_" + text.Replace(" ", "_"));
				if ((Object)(object)val == (Object)null)
				{
					return null;
				}
				val.AddComponent<RectTransform>();
				val.transform.SetParent(filterPanel.transform, false);
				Image buttonImage = val.AddComponent<Image>();
				((Graphic)buttonImage).color = new Color(0.3f, 0.3f, 0.3f, 1f);
				Button val2 = val.AddComponent<Button>();
				if ((Object)(object)val2 == (Object)null)
				{
					return null;
				}
				GameObject val3 = new GameObject("Text");
				if ((Object)(object)val3 == (Object)null)
				{
					return null;
				}
				val3.transform.SetParent(val.transform, false);
				TextMeshProUGUI obj = val3.AddComponent<TextMeshProUGUI>();
				((TMP_Text)obj).text = text;
				((TMP_Text)obj).fontSize = 10f;
				((Graphic)obj).color = Color.white;
				((UnityEventBase)val2.onClick).RemoveAllListeners();
				((UnityEvent)val2.onClick).AddListener((UnityAction)delegate
				{
					//IL_000b: Unknown result type (might be due to invalid IL or missing references)
					//IL_005e: Unknown result type (might be due to invalid IL or missing references)
					//IL_0082: Unknown result type (might be due to invalid IL or missing references)
					//IL_0022: 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)
					if (CurrentFilters.HiddenRarities.Contains(rarity))
					{
						CurrentFilters.HiddenRarities.Remove(rarity);
						((Graphic)buttonImage).color = new Color(0.3f, 0.3f, 0.3f, 1f);
					}
					else
					{
						CurrentFilters.HiddenRarities.Add(rarity);
						((Graphic)buttonImage).color = new Color(0.6f, 0.3f, 0.3f, 1f);
					}
					RefreshUpgrades();
				});
				RectTransform component = val.GetComponent<RectTransform>();
				if ((Object)(object)component == (Object)null)
				{
					return null;
				}
				component.sizeDelta = new Vector2(170f, 20f);
				return val;
			}
			catch (Exception)
			{
				return null;
			}
		}

		private void CreateFavoriteFilter()
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Expected O, but got Unknown
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Expected O, but got Unknown
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Expected O, but got Unknown
			CreateUITextObject("FavoriteFilterLabel", "Favorites:", 12f, filterPanel.transform).GetComponent<RectTransform>().sizeDelta = new Vector2(180f, 20f);
			GameObject showAllBtn = null;
			GameObject onlyFavBtn = null;
			GameObject hideFavBtn = null;
			showAllBtn = CreateFilterButton("Show All", (UnityAction)delegate
			{
				CurrentFilters.FavoriteSetting = SortHandlingMod.FavoriteFilter.ShowAll;
				UpdateFavoriteButtonHighlights(showAllBtn, onlyFavBtn, hideFavBtn, SortHandlingMod.FavoriteFilter.ShowAll);
				RefreshUpgrades();
			});
			onlyFavBtn = CreateFilterButton("Only Favorite", (UnityAction)delegate
			{
				CurrentFilters.FavoriteSetting = SortHandlingMod.FavoriteFilter.ShowOnlyFavorited;
				UpdateFavoriteButtonHighlights(showAllBtn, onlyFavBtn, hideFavBtn, SortHandlingMod.FavoriteFilter.ShowOnlyFavorited);
				RefreshUpgrades();
			});
			hideFavBtn = CreateFilterButton("Hide Favorite", (UnityAction)delegate
			{
				CurrentFilters.FavoriteSetting = SortHandlingMod.FavoriteFilter.HideFavorited;
				UpdateFavoriteButtonHighlights(showAllBtn, onlyFavBtn, hideFavBtn, SortHandlingMod.FavoriteFilter.HideFavorited);
				RefreshUpgrades();
			});
			if ((Object)(object)showAllBtn != (Object)null)
			{
				((Selectable)showAllBtn.GetComponent<Button>()).interactable = true;
			}
			if ((Object)(object)onlyFavBtn != (Object)null)
			{
				((Selectable)onlyFavBtn.GetComponent<Button>()).interactable = true;
			}
			if ((Object)(object)hideFavBtn != (Object)null)
			{
				((Selectable)hideFavBtn.GetComponent<Button>()).interactable = true;
			}
			UpdateFavoriteButtonHighlights(showAllBtn, onlyFavBtn, hideFavBtn, SortHandlingMod.FavoriteFilter.ShowAll);
			FixFavoriteButtonTextPosition(showAllBtn);
			FixFavoriteButtonTextPosition(onlyFavBtn);
			FixFavoriteButtonTextPosition(hideFavBtn);
		}

		private void UpdateFavoriteButtonHighlights(GameObject showAllBtn, GameObject onlyFavBtn, GameObject hideFavBtn, SortHandlingMod.FavoriteFilter selectedFilter)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)filterPanel == (Object)null)
			{
				return;
			}
			Color color = default(Color);
			((Color)(ref color))..ctor(0.3f, 0.3f, 0.3f, 1f);
			Color color2 = default(Color);
			((Color)(ref color2))..ctor(0.5f, 0.7f, 0.5f, 1f);
			if ((Object)(object)showAllBtn != (Object)null)
			{
				((Graphic)showAllBtn.GetComponent<Image>()).color = color;
			}
			if ((Object)(object)onlyFavBtn != (Object)null)
			{
				((Graphic)onlyFavBtn.GetComponent<Image>()).color = color;
			}
			if ((Object)(object)hideFavBtn != (Object)null)
			{
				((Graphic)hideFavBtn.GetComponent<Image>()).color = color;
			}
			switch (selectedFilter)
			{
			case SortHandlingMod.FavoriteFilter.ShowAll:
				if ((Object)(object)showAllBtn != (Object)null)
				{
					((Graphic)showAllBtn.GetComponent<Image>()).color = color2;
				}
				break;
			case SortHandlingMod.FavoriteFilter.ShowOnlyFavorited:
				if ((Object)(object)onlyFavBtn != (Object)null)
				{
					((Graphic)onlyFavBtn.GetComponent<Image>()).color = color2;
				}
				break;
			case SortHandlingMod.FavoriteFilter.HideFavorited:
				if ((Object)(object)hideFavBtn != (Object)null)
				{
					((Graphic)hideFavBtn.GetComponent<Image>()).color = color2;
				}
				break;
			}
		}

		private void CreateStatFilters()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Expected O, but got Unknown
			//IL_00b4: 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_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Expected O, but got Unknown
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Expected O, but got Unknown
			//IL_0141: 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_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: 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_022a: Expected O, but got Unknown
			//IL_0360: Unknown result type (might be due to invalid IL or missing references)
			CreateUITextObject("StatFilterLabel", "Show Only Upgrades With:", 12f, filterPanel.transform).GetComponent<RectTransform>().sizeDelta = new Vector2(180f, 20f);
			GameObject val = new GameObject("StatPropertyScrollView");
			val.transform.SetParent(filterPanel.transform, false);
			ScrollRect obj = val.AddComponent<ScrollRect>();
			RectTransform component = val.GetComponent<RectTransform>();
			component.sizeDelta = new Vector2(180f, 120f);
			GameObject val2 = new GameObject("Viewport");
			val2.transform.SetParent(val.transform, false);
			((Graphic)val2.AddComponent<Image>()).color = new Color(0.2f, 0.2f, 0.2f, 0.8f);
			RectTransform component2 = val2.GetComponent<RectTransform>();
			component2.sizeDelta = component.sizeDelta;
			GameObject val3 = new GameObject("Content");
			val3.transform.SetParent(val2.transform, false);
			VerticalLayoutGroup obj2 = val3.AddComponent<VerticalLayoutGroup>();
			((LayoutGroup)obj2).padding = new RectOffset(2, 2, 2, 2);
			((HorizontalOrVerticalLayoutGroup)obj2).spacing = 2f;
			((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = false;
			((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = false;
			((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = false;
			RectTransform component3 = val3.GetComponent<RectTransform>();
			component3.anchorMin = new Vector2(0f, 1f);
			component3.anchorMax = new Vector2(0f, 1f);
			component3.pivot = new Vector2(0f, 1f);
			component3.sizeDelta = new Vector2(component.sizeDelta.x - 4f, 0f);
			ContentSizeFitter obj3 = val3.AddComponent<ContentSizeFitter>();
			obj3.horizontalFit = (FitMode)0;
			obj3.verticalFit = (FitMode)2;
			val2.AddComponent<Mask>().showMaskGraphic = false;
			obj.viewport = component2;
			obj.content = component3;
			obj.horizontal = false;
			obj.vertical = true;
			obj.scrollSensitivity = 1f;
			obj.elasticity = 0.01f;
			obj.inertia = false;
			obj.decelerationRate = 0.01f;
			List<string> contextAwareProperties = GetContextAwareProperties();
			List<GameObject> list = new List<GameObject>();
			foreach (Transform item in val3.transform)
			{
				Transform val4 = item;
				if (((Object)((Component)val4).gameObject).name.StartsWith("StatToggle_") || ((Object)((Component)val4).gameObject).name == "Toggle")
				{
					list.Add(((Component)val4).gameObject);
				}
			}
			foreach (GameObject item2 in list)
			{
				Object.DestroyImmediate((Object)(object)item2);
			}
			foreach (string propertyName in contextAwareProperties.OrderBy((string p) => p))
			{
				string text = propertyName.Replace("_", " ");
				CreateUIToggleObject("StatToggle_" + propertyName, text, 8f, val3.transform, delegate(bool value)
				{
					if (value)
					{
						CurrentFilters.FilterStats = true;
						if (!CurrentFilters.StatIncludeList.Contains(propertyName))
						{
							CurrentFilters.StatIncludeList.Add(propertyName);
						}
					}
					else
					{
						CurrentFilters.StatIncludeList.Remove(propertyName);
						if (CurrentFilters.StatIncludeList.Count == 0)
						{
							CurrentFilters.FilterStats = false;
						}
					}
					RefreshUpgrades();
				}).GetComponent<RectTransform>().sizeDelta = new Vector2(170f, 16f);
			}
		}

		private List<string> GetContextAwareProperties()
		{
			try
			{
				GameObject obj = GameObject.Find("Gear Details");
				GearDetailsWindow val = ((obj != null) ? obj.GetComponent<GearDetailsWindow>() : null);
				bool flag = false;
				if ((Object)(object)val != (Object)null)
				{
					FieldInfo fieldInfo = AccessTools.Field(typeof(GearDetailsWindow), "inSkinMode");
					if (fieldInfo != null)
					{
						try
						{
							flag = (bool)fieldInfo.GetValue(val);
						}
						catch (Exception)
						{
						}
					}
				}
				if (flag)
				{
					return DiscoverSkinProperties();
				}
				return GetCuratedUpgradeProperties();
			}
			catch (Exception)
			{
				return GetCuratedUpgradeProperties();
			}
		}

		private List<string> GetCuratedUpgradeProperties()
		{
			return new List<string>
			{
				"AmmoCapacity", "AutomaticFire", "BatteryCapacity", "BulletsPerShot", "BurstFire", "Carver_Blood", "Charge", "Damage", "FireInterval", "Globbler_Globblometer",
				"Health", "HealthRegenDelay", "HitForce", "MagazineSize", "MaxBounces", "MeleeDamage", "Range", "Recoil", "Reload", "Speed"
			};
		}

		private List<string> DiscoverSkinProperties()
		{
			List<string> list = new List<string>();
			try
			{
				Type skinUpgradePropertyType = typeof(GearUpgradeUI).Assembly.GetType("SkinUpgradeProperty");
				if (skinUpgradePropertyType == null)
				{
					return list;
				}
				foreach (Type item in (from t in skinUpgradePropertyType.Assembly.GetTypes()
					where t.IsClass && !t.IsAbstract && skinUpgradePropertyType.IsAssignableFrom(t) && t.FullName != null && t.FullName.StartsWith("SkinUpgradeProperty_")
					select t).ToList())
				{
					string text = item.Name;
					if (text.StartsWith("SkinUpgradeProperty_"))
					{
						text = text.Substring("SkinUpgradeProperty_".Length);
					}
					list.Add(text);
				}
				list = (from p in list.Distinct()
					orderby p
					select p).ToList();
				return list;
			}
			catch (Exception)
			{
				return list;
			}
		}

		private List<string> DiscoverUpgradeProperties()
		{
			List<string> list = new List<string>();
			try
			{
				Type upgradePropertyType = typeof(GearUpgradeUI).Assembly.GetType("UpgradeProperty");
				if (upgradePropertyType == null)
				{
					return GetFallbackProperties();
				}
				Type skinUpgradePropertyType = typeof(GearUpgradeUI).Assembly.GetType("SkinUpgradeProperty");
				List<Type> list2 = (from t in upgradePropertyType.Assembly.GetTypes()
					where t.IsClass && !t.IsAbstract && (t == upgradePropertyType || upgradePropertyType.IsAssignableFrom(t)) && t.FullName != null && t.FullName.StartsWith("UpgradeProperty_")
					select t).ToList();
				if (skinUpgradePropertyType != null)
				{
					list2 = list2.Where((Type t) => !skinUpgradePropertyType.IsAssignableFrom(t)).ToList();
				}
				foreach (Type item in list2)
				{
					string text = item.Name;
					if (text.StartsWith("UpgradeProperty_"))
					{
						text = text.Substring("UpgradeProperty_".Length);
					}
					list.Add(text);
				}
				list = (from p in list.Distinct()
					orderby p
					select p).ToList();
				if (list.Count == 0)
				{
					return GetFallbackProperties();
				}
				return list;
			}
			catch (Exception)
			{
				return GetFallbackProperties();
			}
		}

		private List<string> GetFallbackProperties()
		{
			return new List<string>
			{
				"Damage", "AmmoCapacity", "FireInterval", "AutomaticFire", "BurstFire", "BulletsPerShot", "Aim", "AmmoOnFire", "Recoil", "Reload",
				"Range", "Health", "Speed"
			};
		}

		private GameObject CreateFilterButton(string text, UnityAction action)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_007f: 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_00ac: Expected O, but got Unknown
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)filterPanel == (Object)null)
				{
					return null;
				}
				GameObject val = new GameObject("FilterButton_" + text.Replace(" ", "_"));
				if ((Object)(object)val == (Object)null)
				{
					return null;
				}
				val.AddComponent<RectTransform>();
				val.transform.SetParent(filterPanel.transform, false);
				((Graphic)val.AddComponent<Image>()).color = new Color(0.3f, 0.3f, 0.3f, 1f);
				Button val2 = val.AddComponent<Button>();
				if ((Object)(object)val2 == (Object)null)
				{
					return null;
				}
				GameObject val3 = new GameObject("Text");
				if ((Object)(object)val3 == (Object)null)
				{
					return null;
				}
				val3.transform.SetParent(val.transform, false);
				TextMeshProUGUI obj = val3.AddComponent<TextMeshProUGUI>();
				((TMP_Text)obj).text = text;
				((TMP_Text)obj).fontSize = 10f;
				((Graphic)obj).color = Color.white;
				((UnityEvent)val2.onClick).AddListener(action);
				RectTransform component = val.GetComponent<RectTransform>();
				if ((Object)(object)component == (Object)null)
				{
					return null;
				}
				component.sizeDelta = new Vector2(170f, 20f);
				return val;
			}
			catch (Exception)
			{
				return null;
			}
		}

		private void RefreshUpgrades()
		{
			//IL_034a: 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_0090: 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_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj = GameObject.Find("Gear Details");
			GearDetailsWindow val = ((obj != null) ? obj.GetComponent<GearDetailsWindow>() : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			try
			{
				FieldInfo fieldInfo = AccessTools.Field(typeof(GearDetailsWindow), "inSkinMode");
				bool flag = false;
				if (fieldInfo != null)
				{
					flag = (bool)fieldInfo.GetValue(val);
				}
				FieldInfo fieldInfo2 = (flag ? AccessTools.Field(typeof(GearDetailsWindow), "currentSortingMethodSkins") : AccessTools.Field(typeof(GearDetailsWindow), "currentSortingMethodUpgrades"));
				SortingMethod val2 = (SortingMethod)0;
				if (fieldInfo2 != null)
				{
					try
					{
						val2 = (SortingMethod)fieldInfo2.GetValue(val);
					}
					catch (Exception)
					{
					}
				}
				FieldInfo fieldInfo3 = AccessTools.Field(typeof(GearDetailsWindow), "upgradeUIs") ?? AccessTools.Field(typeof(GearDetailsWindow), "<upgradeUIs>k__BackingField") ?? AccessTools.Field(typeof(GearDetailsWindow), "upgrades");
				if (fieldInfo3 != null)
				{
					List<GearUpgradeUI> list = (List<GearUpgradeUI>)fieldInfo3.GetValue(val);
					if (list != null)
					{
						int num = 0;
						foreach (GearUpgradeUI item in list)
						{
							bool flag2 = true;
							if (CurrentFilters.HiddenRarities.Any())
							{
								flag2 &= !CurrentFilters.HiddenRarities.Contains(((HoverInfoUpgrade)item).Upgrade.Upgrade.Rarity);
							}
							switch (CurrentFilters.FavoriteSetting)
							{
							case SortHandlingMod.FavoriteFilter.ShowOnlyFavorited:
								flag2 &= ((HoverInfoUpgrade)item).Upgrade.Favorite;
								break;
							case SortHandlingMod.FavoriteFilter.HideFavorited:
								flag2 &= !((HoverInfoUpgrade)item).Upgrade.Favorite;
								break;
							}
							if (CurrentFilters.FilterStats && CurrentFilters.StatIncludeList.Any())
							{
								bool flag3 = true;
								foreach (string statInclude in CurrentFilters.StatIncludeList)
								{
									bool flag4 = false;
									Enumerator properties = ((HoverInfoUpgrade)item).Upgrade.Upgrade.GetProperties();
									while (((Enumerator)(ref properties)).MoveNext())
									{
										string text = ((object)((Enumerator)(ref properties)).Current).GetType().Name;
										if (text.StartsWith("UpgradeProperty_"))
										{
											text = text.Substring("UpgradeProperty_".Length);
										}
										else if (text.StartsWith("SkinUpgradeProperty_"))
										{
											text = text.Substring("SkinUpgradeProperty_".Length);
										}
										if (text == statInclude)
										{
											flag4 = true;
											break;
										}
									}
									if (!flag4)
									{
										flag3 = false;
										break;
									}
								}
								flag2 = flag2 && flag3;
							}
							((Component)item).gameObject.SetActive(flag2);
							if (flag2)
							{
								num++;
								((Component)item).transform.SetSiblingIndex(num - 1);
							}
						}
						FieldInfo fieldInfo4 = AccessTools.Field(typeof(GearDetailsWindow), "upgradeUICount");
						if (fieldInfo4 != null)
						{
							fieldInfo4.SetValue(val, num);
						}
					}
				}
				AccessTools.Method(typeof(GearDetailsWindow), "SortUpgrades", new Type[2]
				{
					typeof(SortingMethod),
					typeof(bool)
				}, (Type[])null)?.Invoke(val, new object[2] { val2, false });
				try
				{
					AccessTools.Method(typeof(GearDetailsWindow), "SwitchUpgradeView", (Type[])null, (Type[])null)?.Invoke(val, new object[0]);
					AccessTools.Method(typeof(GearDetailsWindow), "SwitchUpgradeView", (Type[])null, (Type[])null)?.Invoke(val, new object[0]);
				}
				catch (Exception)
				{
				}
			}
			catch (Exception)
			{
			}
		}

		public void Toggle()
		{
			//IL_0073: 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 (!isInitialized)
			{
				CreateFilterPanel();
				if (!isInitialized)
				{
					return;
				}
			}
			isExpanded = !isExpanded;
			if (isExpanded)
			{
				RegenerateStatFilters();
			}
			filterPanel.SetActive(isExpanded);
			filterPanel.GetComponent<RectTransform>().anchoredPosition = (isExpanded ? new Vector2(-190f, -80f) : new Vector2(-200f, -80f));
		}

		public void RegenerateStatFilters()
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected O, but got Unknown
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)filterPanel == (Object)null || !isInitialized)
				{
					return;
				}
				Transform val = filterPanel.transform.Find("StatPropertyScrollView/Content");
				if (!((Object)(object)val != (Object)null))
				{
					return;
				}
				GameObject gameObject = ((Component)val).gameObject;
				List<GameObject> list = new List<GameObject>();
				foreach (Transform item in gameObject.transform)
				{
					Transform val2 = item;
					if (((Object)((Component)val2).gameObject).name.StartsWith("StatToggle_") || ((Object)((Component)val2).gameObject).name == "Toggle")
					{
						list.Add(((Component)val2).gameObject);
					}
				}
				foreach (GameObject item2 in list)
				{
					Object.DestroyImmediate((Object)(object)item2);
				}
				CurrentFilters.StatIncludeList.Clear();
				CurrentFilters.FilterStats = false;
				foreach (string propertyName in from p in GetContextAwareProperties()
					orderby p
					select p)
				{
					string text = propertyName.Replace("_", " ");
					CreateUIToggleObject("StatToggle_" + propertyName, text, 8f, gameObject.transform, delegate(bool value)
					{
						if (value)
						{
							CurrentFilters.FilterStats = true;
							if (!CurrentFilters.StatIncludeList.Contains(propertyName))
							{
								CurrentFilters.StatIncludeList.Add(propertyName);
							}
						}
						else
						{
							CurrentFilters.StatIncludeList.Remove(propertyName);
							if (CurrentFilters.StatIncludeList.Count == 0)
							{
								CurrentFilters.FilterStats = false;
							}
						}
						RefreshUpgrades();
					}).GetComponent<RectTransform>().sizeDelta = new Vector2(170f, 16f);
				}
			}
			catch (Exception)
			{
			}
		}

		public void RebuildFilterPanel()
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				bool num = isExpanded && (Object)(object)filterPanel != (Object)null && filterPanel.activeSelf;
				if ((Object)(object)filterPanel != (Object)null)
				{
					Object.DestroyImmediate((Object)(object)filterPanel);
				}
				isInitialized = false;
				isExpanded = false;
				CreateFilterPanel();
				if (num)
				{
					filterPanel.SetActive(true);
					filterPanel.GetComponent<RectTransform>().anchoredPosition = new Vector2(10f, -80f);
				}
			}
			catch (Exception)
			{
			}
		}

		private GameObject CreateUITextObject(string objName, string text, float fontSize, Transform parent)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			GameObject val = new GameObject(objName);
			val.transform.SetParent(parent, false);
			TextMeshProUGUI obj = val.AddComponent<TextMeshProUGUI>();
			((TMP_Text)obj).text = text;
			((TMP_Text)obj).fontSize = fontSize;
			((Graphic)obj).color = Color.white;
			return val;
		}

		private GameObject CreateUIToggleObject(string objName, string text, float fontSize, Transform parent, UnityAction<bool> onValueChanged)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: 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_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: 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_0100: 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_0130: 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_0145: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(objName);
			val.transform.SetParent(parent, false);
			Toggle val2 = val.AddComponent<Toggle>();
			((UnityEvent<bool>)(object)val2.onValueChanged).AddListener(onValueChanged);
			((Graphic)val.AddComponent<Image>()).color = new Color(0.4f, 0.4f, 0.4f, 1f);
			GameObject val3 = new GameObject("Text");
			val3.transform.SetParent(val.transform, false);
			TextMeshProUGUI obj = val3.AddComponent<TextMeshProUGUI>();
			((TMP_Text)obj).text = text;
			((TMP_Text)obj).fontSize = fontSize;
			((Graphic)obj).color = Color.white;
			((TMP_Text)obj).alignment = (TextAlignmentOptions)513;
			GameObject val4 = new GameObject("Checkmark");
			val4.transform.SetParent(val.transform, false);
			Image val5 = val4.AddComponent<Image>();
			((Graphic)val5).color = Color.green;
			val2.graphic = (Graphic)(object)val5;
			RectTransform component = ((Component)obj).GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0.3f, 0.1f);
			component.anchorMax = new Vector2(1f, 0.9f);
			component.offsetMin = Vector2.zero;
			component.offsetMax = Vector2.zero;
			RectTransform component2 = ((Component)val5).GetComponent<RectTransform>();
			component2.anchorMin = new Vector2(0.05f, 0.2f);
			component2.anchorMax = new Vector2(0.25f, 0.8f);
			component2.offsetMin = Vector2.zero;
			component2.offsetMax = Vector2.zero;
			return val;
		}

		private void FixFavoriteButtonTextPosition(GameObject buttonGo)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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_0068: 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)
			try
			{
				if (!((Object)(object)buttonGo == (Object)null))
				{
					TextMeshProUGUI[] componentsInChildren = buttonGo.GetComponentsInChildren<TextMeshProUGUI>();
					if (componentsInChildren.Length != 0)
					{
						RectTransform component = ((Component)componentsInChildren[0]).GetComponent<RectTransform>();
						component.anchorMin = new Vector2(0f, 0f);
						component.anchorMax = new Vector2(1f, 1f);
						component.offsetMin = new Vector2(5f, 2f);
						component.offsetMax = new Vector2(-5f, -2f);
						((Transform)component).localPosition = Vector3.zero;
					}
				}
			}
			catch (Exception)
			{
			}
		}

		private void CreateClearAllFiltersButton()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: 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_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Expected O, but got Unknown
			try
			{
				if ((Object)(object)filterPanel == (Object)null)
				{
					return;
				}
				GameObject val = new GameObject("ClearAllFiltersButton");
				if ((Object)(object)val == (Object)null)
				{
					return;
				}
				val.transform.SetParent(filterPanel.transform, false);
				((Graphic)val.AddComponent<Image>()).color = new Color(0.8f, 0.4f, 0.4f, 1f);
				Button val2 = val.AddComponent<Button>();
				if ((Object)(object)val2 == (Object)null)
				{
					return;
				}
				GameObject val3 = new GameObject("Text");
				if ((Object)(object)val3 == (Object)null)
				{
					return;
				}
				val3.transform.SetParent(val.transform, false);
				TextMeshProUGUI val4 = val3.AddComponent<TextMeshProUGUI>();
				((TMP_Text)val4).text = "Clear All Filters";
				((TMP_Text)val4).fontSize = 12f;
				((Graphic)val4).color = Color.white;
				((TMP_Text)val4).alignment = (TextAlignmentOptions)514;
				RectTransform component = val.GetComponent<RectTransform>();
				if ((Object)(object)component == (Object)null)
				{
					return;
				}
				component.sizeDelta = new Vector2(180f, 30f);
				RectTransform component2 = ((Component)val4).GetComponent<RectTransform>();
				component2.anchorMin = Vector2.zero;
				component2.anchorMax = Vector2.one;
				component2.offsetMin = new Vector2(5f, 2f);
				component2.offsetMax = new Vector2(-5f, -2f);
				((UnityEventBase)val2.onClick).RemoveAllListeners();
				((UnityEvent)val2.onClick).AddListener((UnityAction)delegate
				{
					//IL_005e: Unknown result type (might be due to invalid IL or missing references)
					//IL_0064: Expected O, but got Unknown
					//IL_010a: Unknown result type (might be due to invalid IL or missing references)
					//IL_0111: Expected O, but got Unknown
					//IL_01cc: 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_022a: Unknown result type (might be due to invalid IL or missing references)
					//IL_00af: Unknown result type (might be due to invalid IL or missing references)
					CurrentFilters.HiddenRarities.Clear();
					CurrentFilters.FavoriteSetting = SortHandlingMod.FavoriteFilter.ShowAll;
					CurrentFilters.FilterStats = false;
					CurrentFilters.StatIncludeList.Clear();
					if ((Object)(object)filterPanel != (Object)null)
					{
						foreach (Transform item in filterPanel.transform)
						{
							Transform val5 = item;
							if (((Object)val5).name.StartsWith("FilterButton_"))
							{
								Image component3 = ((Component)val5).GetComponent<Image>();
								if ((Object)(object)component3 != (Object)null)
								{
									TextMeshProUGUI componentInChildren = ((Component)val5).GetComponentInChildren<TextMeshProUGUI>();
									if (((componentInChildren != null) ? ((TMP_Text)componentInChildren).text : null) != null)
									{
										((Graphic)component3).color = new Color(0.3f, 0.3f, 0.3f, 1f);
									}
								}
							}
						}
					}
					if ((Object)(object)filterPanel != (Object)null)
					{
						GameObject val6 = null;
						GameObject val7 = null;
						GameObject val8 = null;
						foreach (Transform item2 in filterPanel.transform)
						{
							Transform val9 = item2;
							if (((Object)val9).name.StartsWith("FilterButton_"))
							{
								TextMeshProUGUI componentInChildren2 = ((Component)val9).GetComponentInChildren<TextMeshProUGUI>();
								if ((Object)(object)componentInChildren2 != (Object)null)
								{
									switch (((TMP_Text)componentInChildren2).text)
									{
									case "Show All":
										val6 = ((Component)val9).gameObject;
										break;
									case "Only Favorite":
										val7 = ((Component)val9).gameObject;
										break;
									case "Hide Favorite":
										val8 = ((Component)val9).gameObject;
										break;
									}
								}
							}
						}
						if ((Object)(object)val6 != (Object)null)
						{
							((Graphic)val6.GetComponent<Image>()).color = new Color(0.5f, 0.7f, 0.5f, 1f);
						}
						if ((Object)(object)val7 != (Object)null)
						{
							((Graphic)val7.GetComponent<Image>()).color = new Color(0.3f, 0.3f, 0.3f, 1f);
						}
						if ((Object)(object)val8 != (Object)null)
						{
							((Graphic)val8.GetComponent<Image>()).color = new Color(0.3f, 0.3f, 0.3f, 1f);
						}
					}
					RefreshUpgrades();
					RegenerateStatFilters();
				});
				val.SetActive(true);
				((Selectable)val2).interactable = true;
			}
			catch (Exception)
			{
			}
		}

		private void FixRarityButtonTextPosition()
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				foreach (Button item in filterPanel.GetComponentsInChildren<Button>().Where(delegate(Button b)
				{
					if (((Object)b).name.StartsWith("FilterButton_"))
					{
						TextMeshProUGUI componentInChildren = ((Component)b).GetComponentInChildren<TextMeshProUGUI>();
						if (componentInChildren == null || !((TMP_Text)componentInChildren).text.Contains("Standard"))
						{
							TextMeshProUGUI componentInChildren2 = ((Component)b).GetComponentInChildren<TextMeshProUGUI>();
							if (componentInChildren2 == null || !((TMP_Text)componentInChildren2).text.Contains("Rare"))
							{
								TextMeshProUGUI componentInChildren3 = ((Component)b).GetComponentInChildren<TextMeshProUGUI>();
								if (componentInChildren3 == null || !((TMP_Text)componentInChildren3).text.Contains("Epic"))
								{
									TextMeshProUGUI componentInChildren4 = ((Component)b).GetComponentInChildren<TextMeshProUGUI>();
									if (componentInChildren4 == null || !((TMP_Text)componentInChildren4).text.Contains("Exotic"))
									{
										TextMeshProUGUI componentInChildren5 = ((Component)b).GetComponentInChildren<TextMeshProUGUI>();
										if (componentInChildren5 == null)
										{
											return false;
										}
										return ((TMP_Text)componentInChildren5).text.Contains("Oddity");
									}
								}
							}
						}
						return true;
					}
					return false;
				}).ToList())
				{
					TextMeshProUGUI[] componentsInChildren = ((Component)item).GetComponentsInChildren<TextMeshProUGUI>();
					if (componentsInChildren.Length != 0)
					{
						RectTransform component = ((Component)componentsInChildren[0]).GetComponent<RectTransform>();
						component.anchorMin = new Vector2(0f, 0f);
						component.anchorMax = new Vector2(1f, 1f);
						component.offsetMin = new Vector2(5f, 2f);
						component.offsetMax = new Vector2(-5f, -2f);
						((Transform)component).localPosition = Vector3.zero;
					}
				}
			}
			catch (Exception)
			{
			}
		}
	}

	internal static FilterPanelUI FilterPanel;

	internal static readonly Dictionary<Rarity, int> RarityOrder = new Dictionary<Rarity, int>
	{
		{
			(Rarity)4,
			5
		},
		{
			(Rarity)3,
			4
		},
		{
			(Rarity)2,
			3
		},
		{
			(Rarity)1,
			2
		},
		{
			(Rarity)0,
			1
		},
		{
			(Rarity)(-1),
			0
		}
	};

	internal static SortHandlingMod.FilterSettings CurrentFilters = new SortHandlingMod.FilterSettings
	{
		HiddenRarities = new List<Rarity>(),
		FilterStats = false,
		StatIncludeList = new List<string>(),
		FavoriteSetting = SortHandlingMod.FavoriteFilter.ShowAll
	};

	internal static bool? PreviousSkinMode = null;
}
public enum CustomSortingMethod
{
	Name,
	Rarity,
	DamageType,
	RecentlyCollected,
	RecentlyUnequipped,
	Stat,
	Favorite,
	Modifier
}
public struct FilterSettings
{
	public List<Rarity> HiddenRarities;

	public bool FilterStats;

	public List<string> StatIncludeList;

	public SortHandlingMod.FavoriteFilter FavoriteSetting;
}
public enum FavoriteFilter
{
	ShowAll,
	ShowOnlyFavorited,
	HideFavorited
}
[HarmonyPatch(typeof(GearDetailsWindow))]
public static class GearDetailsWindowpatches
{
	[Serializable]
	[CompilerGenerated]
	private sealed class <>c
	{
		public static readonly <>c <>9 = new <>c();

		public static UnityAction <>9__8_0;

		internal void <CreateFilterButton>b__8_0()
		{
			UpgradeSortingPlugin.FilterPanel.Toggle();
		}

		internal int <.cctor>b__9_0(GearUpgradeUI a, GearUpgradeUI b)
		{
			if (((Component)a).gameObject.activeSelf && !((Component)b).gameObject.activeSelf)
			{
				return -1;
			}
			if (!((Component)a).gameObject.activeSelf && ((Component)b).gameObject.activeSelf)
			{
				return 1;
			}
			return ((HoverInfoUpgrade)a).Upgrade.Upgrade.Name.CompareTo(((HoverInfoUpgrade)b).Upgrade.Upgrade.Name);
		}

		internal int <.cctor>b__9_1(GearUpgradeUI a, GearUpgradeUI b)
		{
			//IL_0048: 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)
			if (((Component)a).gameObject.activeSelf && !((Component)b).gameObject.activeSelf)
			{
				return -1;
			}
			if (!((Component)a).gameObject.activeSelf && ((Component)b).gameObject.activeSelf)
			{
				return 1;
			}
			UpgradeSortingPlugin.RarityOrder.TryGetValue(((HoverInfoUpgrade)a).Upgrade.Upgrade.Rarity, out var value);
			UpgradeSortingPlugin.RarityOrder.TryGetValue(((HoverInfoUpgrade)b).Upgrade.Upgrade.Rarity, out var value2);
			int num = value2.CompareTo(value);
			if (num == 0)
			{
				return CompareUpgradesByFullName(a, b);
			}
			return num;
		}

		internal int <.cctor>b__9_2(GearUpgradeUI a, GearUpgradeUI b)
		{
			if (((Component)a).gameObject.activeSelf && !((Component)b).gameObject.activeSelf)
			{
				return -1;
			}
			if (!((Component)a).gameObject.activeSelf && ((Component)b).gameObject.activeSelf)
			{
				return 1;
			}
			return -((HoverInfoUpgrade)a).Upgrade.TimeUnlocked.CompareTo(((HoverInfoUpgrade)b).Upgrade.TimeUnlocked);
		}
	}

	private static readonly Comparison<GearUpgradeUI> CompareUpgradesByFullName = delegate(GearUpgradeUI a, GearUpgradeUI b)
	{
		if (((Component)a).gameObject.activeSelf && !((Component)b).gameObject.activeSelf)
		{
			return -1;
		}
		return (!((Component)a).gameObject.activeSelf && ((Component)b).gameObject.activeSelf) ? 1 : ((HoverInfoUpgrade)a).Upgrade.Upgrade.Name.CompareTo(((HoverInfoUpgrade)b).Upgrade.Upgrade.Name);
	};

	private static readonly Comparison<GearUpgradeUI> CompareUpgradesByCustomRarity = delegate(GearUpgradeUI a, GearUpgradeUI b)
	{
		//IL_0048: 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)
		if (((Component)a).gameObject.activeSelf && !((Component)b).gameObject.activeSelf)
		{
			return -1;
		}
		if (!((Component)a).gameObject.activeSelf && ((Component)b).gameObject.activeSelf)
		{
			return 1;
		}
		UpgradeSortingPlugin.RarityOrder.TryGetValue(((HoverInfoUpgrade)a).Upgrade.Upgrade.Rarity, out var value);
		UpgradeSortingPlugin.RarityOrder.TryGetValue(((HoverInfoUpgrade)b).Upgrade.Upgrade.Rarity, out var value2);
		int num = value2.CompareTo(value);
		return (num == 0) ? CompareUpgradesByFullName(a, b) : num;
	};

	private static readonly Comparison<GearUpgradeUI> CompareUpgradesByRecentlyAcquired = delegate(GearUpgradeUI a, GearUpgradeUI b)
	{
		if (((Component)a).gameObject.activeSelf && !((Component)b).gameObject.activeSelf)
		{
			return -1;
		}
		return (!((Component)a).gameObject.activeSelf && ((Component)b).gameObject.activeSelf) ? 1 : (-((HoverInfoUpgrade)a).Upgrade.TimeUnlocked.CompareTo(((HoverInfoUpgrade)b).Upgrade.TimeUnlocked));
	};

	public static Comparison<GearUpgradeUI> GetCustomComparison(CustomSortingMethod method)
	{
		return method switch
		{
			CustomSortingMethod.Name => CompareUpgradesByFullName, 
			CustomSortingMethod.Rarity => CompareUpgradesByCustomRarity, 
			CustomSortingMethod.RecentlyCollected => CompareUpgradesByRecentlyAcquired, 
			_ => CompareUpgradesByFullName, 
		};
	}

	public static Comparison<GearUpgradeUI> CreateChainedComparison(List<CustomSortingMethod> priorities)
	{
		return delegate(GearUpgradeUI a, GearUpgradeUI b)
		{
			foreach (CustomSortingMethod priority in priorities)
			{
				int num = GetCustomComparison(priority)(a, b);
				if (num != 0)
				{
					return num;
				}
			}
			return 0;
		};
	}

	public static List<CustomSortingMethod> GetDynamicPrioritiesForMethod(SortingMethod method)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0016: Expected I4, but got Unknown
		return (int)method switch
		{
			0 => new List<CustomSortingMethod>
			{
				CustomSortingMethod.Name,
				CustomSortingMethod.Rarity
			}, 
			1 => new List<CustomSortingMethod>
			{
				CustomSortingMethod.Rarity,
				CustomSortingMethod.Name
			}, 
			3 => new List<CustomSortingMethod>
			{
				CustomSortingMethod.RecentlyCollected,
				CustomSortingMethod.Rarity,
				CustomSortingMethod.Name
			}, 
			_ => new List<CustomSortingMethod>
			{
				CustomSortingMethod.Rarity,
				CustomSortingMethod.Name
			}, 
		};
	}

	public static List<GearUpgradeUI> ApplyFilters(List<GearUpgradeUI> upgradeUIs, FilterSettings filters)
	{
		List<GearUpgradeUI> list = new List<GearUpgradeUI>(upgradeUIs.Count);
		foreach (GearUpgradeUI upgradeUI in upgradeUIs)
		{
			if ((filters.FavoriteSetting != SortHandlingMod.FavoriteFilter.ShowOnlyFavorited || ((HoverInfoUpgrade)upgradeUI).Upgrade.Favorite) && (filters.FavoriteSetting != SortHandlingMod.FavoriteFilter.HideFavorited || !((HoverInfoUpgrade)upgradeUI).Upgrade.Favorite))
			{
				list.Add(upgradeUI);
			}
		}
		return list;
	}

	[HarmonyPostfix]
	[HarmonyPatch("OnOpen")]
	private static void OnOpen(GearDetailsWindow __instance)
	{
		try
		{
			FieldInfo fieldInfo = AccessTools.Field(typeof(GearDetailsWindow), "inSkinMode");
			bool flag = false;
			if (fieldInfo != null)
			{
				flag = (bool)fieldInfo.GetValue(__instance);
				if (UpgradeSortingPlugin.PreviousSkinMode.HasValue && UpgradeSortingPlugin.PreviousSkinMode.Value != flag && UpgradeSortingPlugin.FilterPanel != null)
				{
					UpgradeSortingPlugin.FilterPanel.RegenerateStatFilters();
				}
				UpgradeSortingPlugin.PreviousSkinMode = flag;
			}
		}
		catch (Exception)
		{
		}
		UpgradeSortingPlugin.FilterPanel = new UpgradeSortingPlugin.FilterPanelUI();
	}

	private static void CreateFilterButton(GearDetailsWindow window)
	{
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Expected O, but got Unknown
		//IL_0050: 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_0098: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: 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_00e9: 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_0113: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_012e: 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_0143: Unknown result type (might be due to invalid IL or missing references)
		//IL_0163: Unknown result type (might be due to invalid IL or missing references)
		//IL_0191: Unknown result type (might be due to invalid IL or missing references)
		//IL_0196: Unknown result type (might be due to invalid IL or missing references)
		//IL_019c: Expected O, but got Unknown
		try
		{
			GameObject val = GameObject.Find("Gear Details");
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			GameObject val2 = new GameObject("Mycopunk_FilterButton");
			val2.transform.SetParent(val.transform, false);
			((Graphic)val2.AddComponent<Image>()).color = new Color(0.8f, 0.2f, 0.9f, 1f);
			Button obj = val2.AddComponent<Button>();
			TextMeshProUGUI obj2 = new GameObject("Text").AddComponent<TextMeshProUGUI>();
			((TMP_Text)obj2).transform.SetParent(val2.transform, false);
			((TMP_Text)obj2).text = "FILTER";
			((TMP_Text)obj2).fontSize = 18f;
			((Graphic)obj2).color = Color.white;
			((TMP_Text)obj2).alignment = (TextAlignmentOptions)514;
			RectTransform component = val2.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0.5f, 1f);
			component.anchorMax = new Vector2(0.5f, 1f);
			component.pivot = new Vector2(0.5f, 1f);
			component.anchoredPosition = new Vector2(50f, -300f);
			component.sizeDelta = new Vector2(150f, 45f);
			RectTransform component2 = ((Component)obj2).GetComponent<RectTransform>();
			component2.anchorMin = Vector2.zero;
			component2.anchorMax = Vector2.one;
			component2.offsetMin = Vector2.zero;
			component2.offsetMax = Vector2.zero;
			val2.SetActive(true);
			((Selectable)obj).interactable = true;
			((Selectable)obj).transition = (Transition)1;
			((Selectable)obj).colors = ColorBlock.defaultColorBlock;
			((UnityEventBase)obj.onClick).RemoveAllListeners();
			ButtonClickedEvent onClick = obj.onClick;
			object obj3 = <>c.<>9__8_0;
			if (obj3 == null)
			{
				UnityAction val3 = delegate
				{
					UpgradeSortingPlugin.FilterPanel.Toggle();
				};
				<>c.<>9__8_0 = val3;
				obj3 = (object)val3;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj3);
			LayoutRebuilder.ForceRebuildLayoutImmediate(component);
			Canvas.ForceUpdateCanvases();
		}
		catch (Exception)
		{
		}
	}
}
[HarmonyPatch(typeof(GearDetailsWindow), "SortUpgrades", new Type[]
{
	typeof(SortingMethod),
	typeof(bool)
})]
public static class SortUpgradesPatch
{
	private static bool? lastSkinMode;

	private static string CleanNameForSorting(string name)
	{
		return Regex.Replace(name, "<[^>]*>", string.Empty);
	}

	public static int PropertyAwareNameComparison(GearUpgradeUI a, GearUpgradeUI b)
	{
		if (((Component)a).gameObject.activeSelf && !((Component)b).gameObject.activeSelf)
		{
			return -1;
		}
		if (!((Component)a).gameObject.activeSelf && ((Component)b).gameObject.activeSelf)
		{
			return 1;
		}
		return ((HoverInfoUpgrade)a).Upgrade.Upgrade.Name.CompareTo(((HoverInfoUpgrade)b).Upgrade.Upgrade.Name);
	}

	[HarmonyPrefix]
	public static bool Prefix(GearDetailsWindow __instance, SortingMethod method, bool resetScroll)
	{
		return true;
	}

	[HarmonyPostfix]
	public static void Postfix(GearDetailsWindow __instance, SortingMethod method, bool resetScroll)
	{
		FieldInfo fieldInfo = AccessTools.Field(typeof(GearDetailsWindow), "inSkinMode");
		bool flag = false;
		if (fieldInfo != null)
		{
			try
			{
				flag = (bool)fieldInfo.GetValue(__instance);
			}
			catch
			{
			}
		}
		bool flag2 = lastSkinMode.HasValue && lastSkinMode.Value != flag;
		lastSkinMode = flag;
		if (!flag2 && HasActiveFilters())
		{
			try
			{
				ApplyFiltersToSortedList(__instance);
			}
			catch (Exception)
			{
			}
		}
	}

	private static bool HasActiveFilters()
	{
		if (!UpgradeSortingPlugin.CurrentFilters.HiddenRarities.Any() && UpgradeSortingPlugin.CurrentFilters.FavoriteSetting == SortHandlingMod.FavoriteFilter.ShowAll)
		{
			if (UpgradeSortingPlugin.CurrentFilters.FilterStats)
			{
				return UpgradeSortingPlugin.CurrentFilters.StatIncludeList.Any();
			}
			return false;
		}
		return true;
	}

	private static void ApplyFiltersToSortedList(GearDetailsWindow window)
	{
		//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_016d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0172: Unknown result type (might be due to invalid IL or missing references)
		FieldInfo fieldInfo = AccessTools.Field(typeof(GearDetailsWindow), "upgradeUIs") ?? AccessTools.Field(typeof(GearDetailsWindow), "<upgradeUIs>k__BackingField") ?? AccessTools.Field(typeof(GearDetailsWindow), "upgrades");
		FieldInfo fieldInfo2 = AccessTools.Field(typeof(GearDetailsWindow), "upgradeUICount");
		if (fieldInfo == null || fieldInfo2 == null)
		{
			return;
		}
		List<GearUpgradeUI> list = (List<GearUpgradeUI>)fieldInfo.GetValue(window);
		if (list == null || list.Count == 0)
		{
			return;
		}
		int num = 0;
		foreach (GearUpgradeUI item in list)
		{
			bool flag = true;
			if (UpgradeSortingPlugin.CurrentFilters.HiddenRarities.Any())
			{
				flag &= !UpgradeSortingPlugin.CurrentFilters.HiddenRarities.Contains(((HoverInfoUpgrade)item).Upgrade.Upgrade.Rarity);
			}
			switch (UpgradeSortingPlugin.CurrentFilters.FavoriteSetting)
			{
			case SortHandlingMod.FavoriteFilter.ShowOnlyFavorited:
				flag &= ((HoverInfoUpgrade)item).Upgrade.Favorite;
				break;
			case SortHandlingMod.FavoriteFilter.HideFavorited:
				flag &= !((HoverInfoUpgrade)item).Upgrade.Favorite;
				break;
			}
			if (UpgradeSortingPlugin.CurrentFilters.FilterStats && UpgradeSortingPlugin.CurrentFilters.StatIncludeList.Any())
			{
				bool flag2 = true;
				foreach (string statInclude in UpgradeSortingPlugin.CurrentFilters.StatIncludeList)
				{
					bool flag3 = false;
					Enumerator properties = ((HoverInfoUpgrade)item).Upgrade.Upgrade.GetProperties();
					while (((Enumerator)(ref properties)).MoveNext())
					{
						string text = ((object)((Enumerator)(ref properties)).Current).GetType().Name;
						if (text.StartsWith("UpgradeProperty_"))
						{
							text = text.Substring("UpgradeProperty_".Length);
						}
						else if (text.StartsWith("SkinUpgradeProperty_"))
						{
							text = text.Substring("SkinUpgradeProperty_".Length);
						}
						if (text == statInclude)
						{
							flag3 = true;
							break;
						}
					}
					if (!flag3)
					{
						flag2 = false;
						break;
					}
				}
				flag = flag && flag2;
			}
			((Component)item).gameObject.SetActive(flag);
			if (flag)
			{
				num++;
				((Component)item).transform.SetSiblingIndex(num - 1);
			}
		}
		try
		{
			fieldInfo2.SetValue(window, num);
		}
		catch
		{
		}
	}
}
public static class FormatHandling
{
	public static bool enableStatReformat = true;

	public static void Initialize()
	{
	}

	public static void ReformatStats(Upgrade __instance, ref string text)
	{
		if (!enableStatReformat || string.IsNullOrEmpty(text))
		{
			return;
		}
		try
		{
			string[] array = text.Split(new string[2] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
			StringBuilder stringBuilder = new StringBuilder();
			string[] array2 = array;
			foreach (string text2 in array2)
			{
				string text3 = text2.Trim();
				if (string.IsNullOrWhiteSpace(text3))
				{
					stringBuilder.AppendLine();
					continue;
				}
				string input = Regex.Replace(text3, "<[^>]*>", "");
				if (Regex.IsMatch(input, "^[-+]?\\d"))
				{
					Match match = Regex.Match(input, "^([-+]?\\d+(?:\\.\\d+)?[%s]?)\\s*(.+)$");
					if (match.Success)
					{
						string value = match.Groups[1].Value;
						string text4 = match.Groups[2].Value.Trim();
						if (!string.IsNullOrEmpty(text4))
						{
							string value2 = text4 + ": <b>" + value + "</b>";
							stringBuilder.AppendLine(value2);
							continue;
						}
					}
				}
				stringBuilder.AppendLine(text2);
			}
			text = stringBuilder.ToString().TrimEnd(Array.Empty<char>());
		}
		catch (Exception)
		{
		}
	}

	public static void ReformatUIText(TextMeshProUGUI textComponent, string fieldName = "text")
	{
		if (!enableStatReformat || (Object)(object)textComponent == (Object)null)
		{
			return;
		}
		string text = ((TMP_Text)textComponent).text;
		if (string.IsNullOrEmpty(text))
		{
			return;
		}
		try
		{
			string[] array = text.Split(new string[2] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
			StringBuilder stringBuilder = new StringBuilder();
			string[] array2 = array;
			foreach (string text2 in array2)
			{
				string text3 = text2.Trim();
				if (string.IsNullOrWhiteSpace(text3))
				{
					stringBuilder.AppendLine();
					continue;
				}
				string input = Regex.Replace(text3, "<[^>]*>", "");
				if (Regex.IsMatch(input, "^[-+]?\\d"))
				{
					Match match = Regex.Match(input, "^([-+]?\\d+(?:\\.\\d+)?[%s]?)\\s*(.+)$");
					if (match.Success)
					{
						string value = match.Groups[1].Value;
						string text4 = match.Groups[2].Value.Trim();
						if (!string.IsNullOrEmpty(text4))
						{
							string value2 = text4 + ": <b>" + value + "</b>";
							stringBuilder.AppendLine(value2);
							continue;
						}
					}
				}
				stringBuilder.AppendLine(text2);
			}
			string text5 = stringBuilder.ToString().TrimEnd(Array.Empty<char>());
			((TMP_Text)textComponent).text = text5;
			((TMP_Text)textComponent).ForceMeshUpdate(false, false);
		}
		catch (Exception)
		{
		}
	}
}
[HarmonyPatch(typeof(Upgrade), "GetStatList")]
public static class StatListReformatPatch
{
	private static void Postfix(Upgrade __instance, int seed, ref string __result)
	{
		FormatHandling.ReformatStats(__instance, ref __result);
	}
}
[HarmonyPatch(typeof(HoverInfoDisplay), "Activate")]
public static class HoverInfoDisplayReformatPatch
{
	private static void Postfix(HoverInfoDisplay __instance, HoverInfo info, bool resetPosition)
	{
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Expected O, but got Unknown
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Expected O, but got Unknown
		if (!FormatHandling.enableStatReformat || (Object)(object)info == (Object)null)
		{
			return;
		}
		try
		{
			FieldInfo fieldInfo = AccessTools.Field(typeof(HoverInfoDisplay), "text");
			if (fieldInfo != null)
			{
				FormatHandling.ReformatUIText((TextMeshProUGUI)fieldInfo.GetValue(__instance), "main text");
			}
			FieldInfo fieldInfo2 = AccessTools.Field(typeof(HoverInfoDisplay), "statsText");
			if (fieldInfo2 != null)
			{
				FormatHandling.ReformatUIText((TextMeshProUGUI)fieldInfo2.GetValue(__instance), "statsText");
			}
		}
		catch (Exception ex)
		{
			SparrohPlugin.Logger.LogWarning((object)("HoverInfoDisplayReformatPatch: Failed: " + ex.Message));
		}
	}
}
[HarmonyPatch(typeof(HoverInfoDisplay), "Refresh")]
public static class HoverInfoDisplayRefreshReformatPatch
{
	private static void Postfix(HoverInfoDisplay __instance)
	{
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Expected O, but got Unknown
		//IL_0097: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a6: Expected O, but got Unknown
		FieldInfo fieldInfo = AccessTools.Field(typeof(HoverInfoDisplay), "selectedInfo");
		if (fieldInfo == null)
		{
			return;
		}
		object? value = fieldInfo.GetValue(__instance);
		HoverInfo val = (HoverInfo)((value is HoverInfo) ? value : null);
		if (!FormatHandling.enableStatReformat || (Object)(object)val == (Object)null)
		{
			return;
		}
		try
		{
			FieldInfo fieldInfo2 = AccessTools.Field(typeof(HoverInfoDisplay), "text");
			if (fieldInfo2 != null)
			{
				FormatHandling.ReformatUIText((TextMeshProUGUI)fieldInfo2.GetValue(__instance), "main text (refresh)");
			}
			FieldInfo fieldInfo3 = AccessTools.Field(typeof(HoverInfoDisplay), "statsText");
			if (fieldInfo3 != null)
			{
				FormatHandling.ReformatUIText((TextMeshProUGUI)fieldInfo3.GetValue(__instance), "statsText (refresh)");
			}
		}
		catch (Exception ex)
		{
			SparrohPlugin.Logger.LogWarning((object)("HoverInfoDisplayRefreshReformatPatch: Failed: " + ex.Message));
		}
	}
}
public static class PriorityPatches
{
	private static List<PriorityCriteria> priorityOrder;

	private static bool performingPrioritySort;

	public static GearDetailsWindow currentWindow;

	private static bool isWindowOpen;

	private static HashSet<PriorityCriteria> usedCriteria;

	public static bool IsWindowOpen => isWindowOpen;

	static PriorityPatches()
	{
		isWindowOpen = false;
		usedCriteria = new HashSet<PriorityCriteria>();
		priorityOrder = LoadPriorityOrder();
	}

	[HarmonyPostfix]
	[HarmonyPatch(typeof(GearDetailsWindow), "OnOpen")]
	public static void OnOpen_Postfix(GearDetailsWindow __instance)
	{
		isWindowOpen = true;
		currentWindow = __instance;
	}

	[HarmonyPostfix]
	[HarmonyPatch(typeof(GearDetailsWindow), "OnCloseCallback")]
	public static void OnCloseCallback_Postfix()
	{
		performingPrioritySort = false;
		isWindowOpen = false;
	}

	public static bool SortUpgrades_Prefix(GearDetailsWindow __instance, int i)
	{
		try
		{
			if (performingPrioritySort)
			{
				try
				{
					priorityOrder = LoadPriorityOrder();
					performingPrioritySort = false;
					usedCriteria.Clear();
					Traverse.Create((object)__instance).Field<List<GearUpgradeUI>>("upgradeUIs").Value.Sort(GetPriorityComparison(priorityOrder));
					Traverse.Create((object)__instance).Method("UpdateUpgradeOrder", Array.Empty<object>()).GetValue();
					Traverse.Create((object)__instance).Method("SetUpgradeListScroll", new object[1] { 1f }).GetValue();
					return false;
				}
				catch (Exception ex)
				{
					SparrohPlugin.Logger.LogError((object)("Failed to perform priority sort: " + ex.Message));
					performingPrioritySort = false;
					return true;
				}
			}
			return true;
		}
		catch (Exception ex2)
		{
			SparrohPlugin.Logger.LogError((object)("Critical error in SortUpgrades_Prefix: " + ex2.Message));
			return true;
		}
	}

	public static void Patch(Harmony harmony)
	{
		//IL_0039: Unknown result type (might be due to invalid IL or missing references)
		//IL_0047: Expected O, but got Unknown
		harmony.Patch((MethodBase)AccessTools.Method(typeof(GearDetailsWindow), "SortUpgrades", new Type[1] { typeof(int) }, (Type[])null), new HarmonyMethod(typeof(PriorityPatches), "SortUpgrades_Prefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
	}

	public static void TriggerPrioritySort()
	{
		Window top = Menu.Instance.WindowSystem.GetTop();
		currentWindow = (GearDetailsWindow)(object)((top is GearDetailsWindow) ? top : null);
		if ((Object)(object)currentWindow != (Object)null)
		{
			performingPrioritySort = true;
			currentWindow.SortUpgrades(0);
		}
	}

	public static Comparison<GearUpgradeUI> GetPriorityComparison(List<PriorityCriteria> order)
	{
		return delegate(GearUpgradeUI a, GearUpgradeUI b)
		{
			if ((Object)(object)a == (Object)null)
			{
				return 1;
			}
			if ((Object)(object)b == (Object)null)
			{
				return -1;
			}
			if (((HoverInfoUpgrade)a).Upgrade == null)
			{
				return 1;
			}
			if (((HoverInfoUpgrade)b).Upgrade == null)
			{
				return -1;
			}
			int num = ((!((Component)a).gameObject.activeSelf) ? 1 : 0).CompareTo((!((Component)b).gameObject.activeSelf) ? 1 : 0);
			if (num != 0)
			{
				return num;
			}
			foreach (PriorityCriteria item in order)
			{
				int num2 = CompareByCriteria(a, b, item);
				if (num2 != 0)
				{
					usedCriteria.Add(item);
					return num2;
				}
			}
			string instanceName = ((HoverInfoUpgrade)a).Upgrade.Upgrade.GetInstanceName(((HoverInfoUpgrade)a).Upgrade.Seed);
			string instanceName2 = ((HoverInfoUpgrade)b).Upgrade.Upgrade.GetInstanceName(((HoverInfoUpgrade)b).Upgrade.Seed);
			return instanceName.CompareTo(instanceName2);
		};
	}

	public static int CompareByCriteria(GearUpgradeUI a, GearUpgradeUI b, PriorityCriteria criteria)
	{
		//IL_0367: Unknown result type (might be due to invalid IL or missing references)
		//IL_036d: Invalid comparison between Unknown and I4
		//IL_037e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0384: Invalid comparison between Unknown and I4
		//IL_0398: Unknown result type (might be due to invalid IL or missing references)
		//IL_039e: Invalid comparison between Unknown and I4
		//IL_03af: Unknown result type (might be due to invalid IL or missing references)
		//IL_03b5: Invalid comparison between Unknown and I4
		//IL_03c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_03cf: Invalid comparison between Unknown and I4
		//IL_03e0: Unknown result type (might be due to invalid IL or missing references)
		//IL_03e6: Invalid comparison between Unknown and I4
		//IL_03fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_0400: Invalid comparison between Unknown and I4
		//IL_0411: Unknown result type (might be due to invalid IL or missing references)
		//IL_0417: Invalid comparison between Unknown and I4
		//IL_042b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0431: Invalid comparison between Unknown and I4
		//IL_0442: Unknown result type (might be due to invalid IL or missing references)
		//IL_0448: Invalid comparison between Unknown and I4
		switch (criteria)
		{
		case PriorityCriteria.Favorited:
			return -(((HoverInfoUpgrade)a).Upgrade.Favorite ? 1 : 0).CompareTo(((HoverInfoUpgrade)b).Upgrade.Favorite ? 1 : 0);
		case PriorityCriteria.NotFavorited:
			return -((!((HoverInfoUpgrade)a).Upgrade.Favorite) ? 1 : 0).CompareTo((!((HoverInfoUpgrade)b).Upgrade.Favorite) ? 1 : 0);
		case PriorityCriteria.Unlocked:
			return -((HoverInfoUpgrade)a).Upgrade.IsUnlocked.CompareTo(((HoverInfoUpgrade)b).Upgrade.IsUnlocked);
		case PriorityCriteria.Locked:
			return -((!((HoverInfoUpgrade)a).Upgrade.IsUnlocked) ? 1 : 0).CompareTo((!((HoverInfoUpgrade)b).Upgrade.IsUnlocked) ? 1 : 0);
		case PriorityCriteria.Turbocharged:
		{
			bool value3 = Traverse.Create((object)((HoverInfoUpgrade)a).Upgrade).Property<bool>("IsTurbocharged", (object[])null).Value;
			bool value4 = Traverse.Create((object)((HoverInfoUpgrade)b).Upgrade).Property<bool>("IsTurbocharged", (object[])null).Value;
			return -(value3 ? 1 : 0).CompareTo(value4 ? 1 : 0);
		}
		case PriorityCriteria.Trashed:
			try
			{
				bool value = Traverse.Create((object)((HoverInfoUpgrade)a).Upgrade).Property<bool>("IsTrashed", (object[])null).Value;
				bool value2 = Traverse.Create((object)((HoverInfoUpgrade)b).Upgrade).Property<bool>("IsTrashed", (object[])null).Value;
				return (value ? 1 : 0).CompareTo(value2 ? 1 : 0);
			}
			catch
			{
				SparrohPlugin.Logger.LogInfo((object)$"Checked {criteria} for {((HoverInfoUpgrade)a).Upgrade.Upgrade.Name} vs {((HoverInfoUpgrade)b).Upgrade.Upgrade.Name}: cmp=0 (Property not found)");
				return 0;
			}
		case PriorityCriteria.NotTurbocharged:
		{
			bool num2 = !Traverse.Create((object)((HoverInfoUpgrade)a).Upgrade).Property<bool>("IsTurbocharged", (object[])null).Value;
			bool flag2 = !Traverse.Create((object)((HoverInfoUpgrade)b).Upgrade).Property<bool>("IsTurbocharged", (object[])null).Value;
			return -(num2 ? 1 : 0).CompareTo(flag2 ? 1 : 0);
		}
		case PriorityCriteria.NotTrashed:
			try
			{
				bool num = !Traverse.Create((object)((HoverInfoUpgrade)a).Upgrade).Property<bool>("IsTrashed", (object[])null).Value;
				bool flag = !Traverse.Create((object)((HoverInfoUpgrade)b).Upgrade).Property<bool>("IsTrashed", (object[])null).Value;
				return -(num ? 1 : 0).CompareTo(flag ? 1 : 0);
			}
			catch
			{
				SparrohPlugin.Logger.LogInfo((object)$"Checked {criteria} for {((HoverInfoUpgrade)a).Upgrade.Upgrade.Name} vs {((HoverInfoUpgrade)b).Upgrade.Upgrade.Name}: cmp=0 (Property not found)");
				return 0;
			}
		case PriorityCriteria.RecentlyAcquired:
			return -((HoverInfoUpgrade)a).Upgrade.TimeUnlocked.CompareTo(((HoverInfoUpgrade)b).Upgrade.TimeUnlocked);
		case PriorityCriteria.RecentlyUsed:
			return -((HoverInfoUpgrade)a).Upgrade.TimeUnequipped.CompareTo(((HoverInfoUpgrade)b).Upgrade.TimeUnequipped);
		case PriorityCriteria.InstanceName:
		{
			string text = ((HoverInfoUpgrade)a).Upgrade.Upgrade.GetInstanceName(((HoverInfoUpgrade)a).Upgrade.Seed);
			if (string.IsNullOrEmpty(text))
			{
				text = ((HoverInfoUpgrade)a).Upgrade.Upgrade.Name;
			}
			string text2 = ((HoverInfoUpgrade)b).Upgrade.Upgrade.GetInstanceName(((HoverInfoUpgrade)b).Upgrade.Seed);
			if (string.IsNullOrEmpty(text2))
			{
				text2 = ((HoverInfoUpgrade)b).Upgrade.Upgrade.Name;
			}
			return text.CompareTo(text2);
		}
		case PriorityCriteria.Oddity:
			return -(((int)((HoverInfoUpgrade)a).Upgrade.Upgrade.Rarity == 4) ? 1 : 0).CompareTo(((int)((HoverInfoUpgrade)b).Upgrade.Upgrade.Rarity == 4) ? 1 : 0);
		case PriorityCriteria.Exotic:
			return -(((int)((HoverInfoUpgrade)a).Upgrade.Upgrade.Rarity == 3) ? 1 : 0).CompareTo(((int)((HoverInfoUpgrade)b).Upgrade.Upgrade.Rarity == 3) ? 1 : 0);
		case PriorityCriteria.Epic:
			return -(((int)((HoverInfoUpgrade)a).Upgrade.Upgrade.Rarity == 2) ? 1 : 0).CompareTo(((int)((HoverInfoUpgrade)b).Upgrade.Upgrade.Rarity == 2) ? 1 : 0);
		case PriorityCriteria.Rare:
			return -(((int)((HoverInfoUpgrade)a).Upgrade.Upgrade.Rarity == 1) ? 1 : 0).CompareTo(((int)((HoverInfoUpgrade)b).Upgrade.Upgrade.Rarity == 1) ? 1 : 0);
		case PriorityCriteria.Standard:
			return -(((int)((HoverInfoUpgrade)a).Upgrade.Upgrade.Rarity == 0) ? 1 : 0).CompareTo(((int)((HoverInfoUpgrade)b).Upgrade.Upgrade.Rarity == 0) ? 1 : 0);
		default:
			return 0;
		}
	}

	public static List<PriorityCriteria> LoadPriorityOrder()
	{
		try
		{
			string json = default(string);
			if (PlayerOptions.TryGetConfig<string>("SortPrio