Decompiled source of Adaptive Chest Picker v1.0.0

AdaptiveChestPicker.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using EntityStates;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using RiskOfOptions;
using RiskOfOptions.Components.Options;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RoR2;
using RoR2.UI;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.UI;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace AdaptiveChestPicker
{
	internal static class AdaptiveChestHook
	{
		private sealed class ChestState
		{
			public LocalUser owner;

			public EntityState cycle;

			public int[] ranks;

			public int ranksVersion;

			public bool predictionChecked;

			public bool autoSent;

			public float autoSentAt;

			public bool manuallyStopped;

			public bool duplicateLogged;

			public int lastLoggedEntry = -1;

			public int lastSkipLoggedEntry = -1;
		}

		private const float DuplicateGuardSeconds = 1.5f;

		private const float MinSecondsBeforeEntryEnd = 0.1f;

		private static readonly ConditionalWeakTable<RouletteChestController, ChestState> chestStates = new ConditionalWeakTable<RouletteChestController, ChestState>();

		private static bool sendingAutoInteraction;

		internal static bool Install(Harmony harmony)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Expected O, but got Unknown
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected O, but got Unknown
			bool ok = true;
			MethodInfo methodInfo = RouletteChestAccess.Require(AccessTools.Method(typeof(RouletteChestController), "FixedUpdate", Type.EmptyTypes, (Type[])null), "RouletteChestController.FixedUpdate()", ref ok);
			MethodInfo methodInfo2 = RouletteChestAccess.Require(AccessTools.Method(typeof(Interactor), "AttemptInteraction", new Type[1] { typeof(GameObject) }, (Type[])null), "Interactor.AttemptInteraction(GameObject)", ref ok);
			if (!ok)
			{
				return false;
			}
			harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(AdaptiveChestHook), "FixedUpdatePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(AdaptiveChestHook), "AttemptInteractionPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			return true;
		}

		private static void FixedUpdatePostfix(RouletteChestController __instance)
		{
			if (!ModConfig.Enabled.Value || !chestStates.TryGetValue(__instance, out var value) || value.owner == null)
			{
				return;
			}
			try
			{
				Evaluate(__instance, value);
			}
			catch (Exception arg)
			{
				value.owner = null;
				Plugin.Log.LogError((object)$"Stopped tracking an Adaptive Chest after an unexpected error; vanilla behaviour is unaffected.\n{arg}");
			}
		}

		private static void Evaluate(RouletteChestController chest, ChestState state)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: 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)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Invalid comparison between Unknown and I4
			//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0350: Unknown result type (might be due to invalid IL or missing references)
			//IL_0365: Unknown result type (might be due to invalid IL or missing references)
			//IL_0371: Unknown result type (might be due to invalid IL or missing references)
			EntityState state2 = RouletteChestAccess.GetState(chest);
			if (state2 == null || ((object)state2).GetType() != RouletteChestAccess.CyclingStateType)
			{
				return;
			}
			FixedTimeStamp val = RouletteChestAccess.ActivationTimeRef.Invoke(chest);
			Entry[] array = RouletteChestAccess.EntriesRef.Invoke(chest);
			if (((FixedTimeStamp)(ref val)).isInfinity || array == null || array.Length == 0 || !SyncCycle(chest, state, state2))
			{
				return;
			}
			if (state.ranks == null || state.ranks.Length != array.Length || state.ranksVersion != PriorityRules.Version)
			{
				state.ranks = new int[array.Length];
				for (int i = 0; i < array.Length; i++)
				{
					state.ranks[i] = PriorityRules.GetRank(array[i].pickup.pickupIndex);
				}
				state.ranksVersion = PriorityRules.Version;
				if (ModConfig.DebugLogging.Value)
				{
					LogCyclePlan(chest, array, state.ranks);
				}
			}
			if (!state.predictionChecked)
			{
				state.predictionChecked = true;
				if (NetworkServer.active)
				{
					ChestPreview.VerifyPrediction(chest, array);
				}
			}
			if (state.autoSent || state.manuallyStopped)
			{
				return;
			}
			FixedTimeStamp val2 = FixedTimeStamp.now - RouletteChestAccess.RewindTime;
			int num = RouletteChestAccess.GetEntryIndexForTime(chest, val2);
			if (num < 0)
			{
				return;
			}
			int num2 = array.Length - 1;
			int num3 = FindTarget(array, state.ranks, num, val2);
			if (num != state.lastLoggedEntry)
			{
				state.lastLoggedEntry = num;
				if (ModConfig.DebugLogging.Value)
				{
					Plugin.DebugLog($"{DescribeChest(chest)} entry {num + 1}/{array.Length}: {DescribePickup(array[num].pickup)} " + "-> " + Verdict(num, num3, num2, state.ranks[num]));
				}
			}
			if (num3 != num || num3 == num2)
			{
				return;
			}
			FixedTimeStamp val3 = ((num == 0) ? val : array[num - 1].endTime);
			FixedTimeStamp endTime = array[num].endTime;
			if (val2 < val3 + (endTime - val3) * 0.5f)
			{
				return;
			}
			CharacterBody val4 = (LocalUserManager.readOnlyLocalUsersList.Contains(state.owner) ? state.owner.cachedBody : null);
			Interactor val5 = (Object.op_Implicit((Object)(object)val4) ? ((Component)val4).GetComponent<Interactor>() : null);
			if (!Object.op_Implicit((Object)(object)val5))
			{
				LogSkipOnce(chest, state, num, "the owner has no living body");
				return;
			}
			PurchaseInteraction val6 = RouletteChestAccess.PurchaseInteractionRef.Invoke(chest);
			if (!Object.op_Implicit((Object)(object)val6) || (int)val6.GetInteractability(val5) != 2)
			{
				LogSkipOnce(chest, state, num, "the chest is not interactable right now (locked?)");
				return;
			}
			state.autoSent = true;
			state.autoSentAt = Time.unscaledTime;
			sendingAutoInteraction = true;
			try
			{
				val5.AttemptInteraction(((Component)chest).gameObject);
			}
			finally
			{
				sendingAutoInteraction = false;
			}
			Plugin.Log.LogInfo((object)("Adaptive Chest stopped on " + DisplayName(array[num].pickup.pickupIndex) + ", " + PriorityRules.DescribeRank(state.ranks[num]) + " (" + (NetworkServer.active ? "host: handled locally" : "client: vanilla interact request sent to the host") + ")."));
			Plugin.DebugLog($"{DescribeChest(chest)}: pressed at selection time {val2.t:F3}s, " + $"entry window [{val3.t:F3}s, {endTime.t:F3}s), rewindTime {RouletteChestAccess.RewindTime:F3}s.");
		}

		private static int FindTarget(Entry[] entries, int[] ranks, int currentIndex, FixedTimeStamp selectionTime)
		{
			//IL_0023: 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)
			int num = entries.Length - 1;
			int result = -1;
			int num2 = int.MaxValue;
			for (int i = currentIndex; i <= num; i++)
			{
				if (ranks[i] < num2 && (i >= num || !(entries[i].endTime - selectionTime < 0.1f)))
				{
					result = i;
					num2 = ranks[i];
				}
			}
			return result;
		}

		private static string Verdict(int index, int target, int lastIndex, int rank)
		{
			if (rank == int.MaxValue)
			{
				return "not wanted";
			}
			string text = PriorityRules.DescribeRank(rank);
			if (index == target)
			{
				if (index != lastIndex)
				{
					return text + ", stopping in the middle of this entry";
				}
				return text + ", final entry: the vanilla auto-drop ejects it";
			}
			if (target >= 0)
			{
				return $"{text}, waiting for entry {target + 1}";
			}
			return text + ", too late to stop on it";
		}

		private static bool AttemptInteractionPrefix(Interactor __instance, GameObject interactableObject)
		{
			RouletteChestController chest = default(RouletteChestController);
			if (sendingAutoInteraction || !ModConfig.Enabled.Value || !Object.op_Implicit((Object)(object)__instance) || !Object.op_Implicit((Object)(object)interactableObject) || !interactableObject.TryGetComponent<RouletteChestController>(ref chest))
			{
				return true;
			}
			try
			{
				return OnLocalInteraction(__instance, chest);
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Error while inspecting an Adaptive Chest interaction; letting it through.\n{arg}");
				return true;
			}
		}

		private static bool OnLocalInteraction(Interactor interactor, RouletteChestController chest)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Invalid comparison between Unknown and I4
			LocalUser val = FindLocalUser(interactor);
			if (val == null)
			{
				return true;
			}
			EntityState state = RouletteChestAccess.GetState(chest);
			if (state == null)
			{
				return true;
			}
			PurchaseInteraction val2 = RouletteChestAccess.PurchaseInteractionRef.Invoke(chest);
			bool flag = Object.op_Implicit((Object)(object)val2) && (int)val2.GetInteractability(interactor) == 2;
			Type type = ((object)state).GetType();
			if (type == RouletteChestAccess.IdleStateType)
			{
				if (flag)
				{
					ChestState value = chestStates.GetValue(chest, (RouletteChestController _) => new ChestState());
					value.owner = val;
					value.cycle = null;
					Plugin.DebugLog(DescribeChest(chest) + " opened by local player '" + val.userProfile?.name + "', watching its cycle.");
				}
				return true;
			}
			if (type != RouletteChestAccess.CyclingStateType || !chestStates.TryGetValue(chest, out var value2) || value2.owner == null || !SyncCycle(chest, value2, state))
			{
				return true;
			}
			if (value2.autoSent)
			{
				if (Time.unscaledTime - value2.autoSentAt < 1.5f)
				{
					if (!value2.duplicateLogged)
					{
						value2.duplicateLogged = true;
						Plugin.DebugLog(DescribeChest(chest) + ": ignored a manual press, the auto-stop request is already on its way.");
					}
					return false;
				}
				return true;
			}
			if (flag && !value2.manuallyStopped)
			{
				value2.manuallyStopped = true;
				Plugin.DebugLog(DescribeChest(chest) + " stopped manually by the player, auto-stop is off for this cycle.");
			}
			return true;
		}

		private static bool SyncCycle(RouletteChestController chest, ChestState state, EntityState cyclingState)
		{
			if (state.cycle == cyclingState)
			{
				return state.owner != null;
			}
			state.cycle = cyclingState;
			state.ranks = null;
			state.predictionChecked = false;
			state.autoSent = false;
			state.manuallyStopped = false;
			state.duplicateLogged = false;
			state.lastLoggedEntry = -1;
			state.lastSkipLoggedEntry = -1;
			if (NetworkServer.active)
			{
				PurchaseInteraction val = RouletteChestAccess.PurchaseInteractionRef.Invoke(chest);
				Interactor val2 = (Object.op_Implicit((Object)(object)val) ? val.lastActivator : null);
				if (Object.op_Implicit((Object)(object)val2) && (Object)(object)((Component)val2).gameObject != (Object)(object)state.owner.cachedBodyObject)
				{
					Plugin.DebugLog(DescribeChest(chest) + " was opened by another player, not tracking it.");
					state.owner = null;
					return false;
				}
			}
			return true;
		}

		private static LocalUser FindLocalUser(Interactor interactor)
		{
			GameObject gameObject = ((Component)interactor).gameObject;
			ReadOnlyCollection<LocalUser> readOnlyLocalUsersList = LocalUserManager.readOnlyLocalUsersList;
			for (int i = 0; i < readOnlyLocalUsersList.Count; i++)
			{
				LocalUser val = readOnlyLocalUsersList[i];
				if (val != null && Object.op_Implicit((Object)(object)val.cachedBodyObject) && (Object)(object)val.cachedBodyObject == (Object)(object)gameObject)
				{
					return val;
				}
			}
			return null;
		}

		private static void LogCyclePlan(RouletteChestController chest, Entry[] entries, int[] ranks)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			StringBuilder stringBuilder = new StringBuilder();
			int num = -1;
			for (int i = 0; i < entries.Length; i++)
			{
				if (ranks[i] != int.MaxValue)
				{
					stringBuilder.Append((stringBuilder.Length == 0) ? "#" : ", #").Append(i + 1).Append(' ')
						.Append(DisplayName(entries[i].pickup.pickupIndex))
						.Append(" [priority ")
						.Append(ranks[i] + 1)
						.Append(']');
					if (num < 0 || ranks[i] < ranks[num])
					{
						num = i;
					}
				}
			}
			Plugin.DebugLog((num < 0) ? $"{DescribeChest(chest)}: cycle of {entries.Length} entries has nothing from the priority list, leaving it to vanilla." : $"{DescribeChest(chest)}: cycle of {entries.Length} entries, wanted: {stringBuilder}. Best: entry {num + 1}.");
		}

		private static void LogSkipOnce(RouletteChestController chest, ChestState state, int index, string reason)
		{
			if (state.lastSkipLoggedEntry != index)
			{
				state.lastSkipLoggedEntry = index;
				Plugin.DebugLog($"{DescribeChest(chest)}: not stopping on entry {index + 1}: {reason}.");
			}
		}

		private static string DescribeChest(RouletteChestController chest)
		{
			//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_0024: Unknown result type (might be due to invalid IL or missing references)
			string name = ((Object)chest).name;
			NetworkInstanceId netId = ((NetworkBehaviour)chest).netId;
			return $"Adaptive Chest '{name}' (netId {((NetworkInstanceId)(ref netId)).Value}, at {((Component)chest).transform.position})";
		}

		private static string DescribePickup(UniquePickup pickup)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: 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_0015: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			PickupDef pickupDef = PickupCatalog.GetPickupDef(pickup.pickupIndex);
			if (pickupDef == null)
			{
				return $"PickupIndex {pickup.pickupIndex.value} (no such pickup)";
			}
			Rarity rarity;
			string text = (PriorityRules.TryGetRarity(pickupDef, out rarity) ? rarity.ToString() : "no rarity");
			return $"PickupIndex {pickup.pickupIndex.value} {pickupDef.internalName} \"{Language.GetString(pickupDef.nameToken)}\" [{text}]";
		}

		private static string DisplayName(PickupIndex pickupIndex)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			PickupDef pickupDef = PickupCatalog.GetPickupDef(pickupIndex);
			if (pickupDef == null)
			{
				return $"PickupIndex {pickupIndex.value}";
			}
			return "\"" + Language.GetString(pickupDef.nameToken) + "\" (" + pickupDef.internalName + ")";
		}
	}
	internal static class ChestPreview
	{
		private sealed class Prediction
		{
			public UniquePickup[] entries;

			public float computedAt;

			public int rulesVersion = -1;

			public string suffix;
		}

		private const float RefreshSeconds = 1f;

		private const int MaxNamesShown = 3;

		private static readonly ConditionalWeakTable<RouletteChestController, Prediction> predictions = new ConditionalWeakTable<RouletteChestController, Prediction>();

		private static bool errorLogged;

		internal static void Install(Harmony harmony)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Expected O, but got Unknown
			if (RouletteChestAccess.RngRef != null)
			{
				MethodInfo methodInfo = AccessTools.Method(typeof(PurchaseInteraction), "GetContextString", new Type[1] { typeof(Interactor) }, (Type[])null);
				if (methodInfo == null)
				{
					Plugin.Log.LogWarning((object)"PurchaseInteraction.GetContextString(Interactor) not found; the host preview is unavailable.");
				}
				else
				{
					harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(ChestPreview), "GetContextStringPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
		}

		internal static void VerifyPrediction(RouletteChestController chest, Entry[] realEntries)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: 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)
			if (!predictions.TryGetValue(chest, out var value) || value.entries == null)
			{
				return;
			}
			predictions.Remove(chest);
			UniquePickup[] entries = value.entries;
			for (int i = 0; i < realEntries.Length; i++)
			{
				if (i >= entries.Length || !((UniquePickup)(ref entries[i])).Equals(realEntries[i].pickup))
				{
					string arg = ((i < entries.Length) ? PickupName(entries[i].pickupIndex) : "nothing");
					Plugin.Log.LogWarning((object)($"Preview mismatch at entry {i + 1}: predicted {arg}, actual {PickupName(realEntries[i].pickup.pickupIndex)} " + "(the item pool probably changed after the preview)."));
					return;
				}
			}
			Plugin.DebugLog($"Preview check passed: all {realEntries.Length} predicted entries match the real cycle.");
		}

		private static void GetContextStringPostfix(PurchaseInteraction __instance, ref string __result)
		{
			RouletteChestController chest = default(RouletteChestController);
			if (__result == null || !ModConfig.Enabled.Value || !ModConfig.PreviewOnHover.Value || !NetworkServer.active || !((Component)__instance).TryGetComponent<RouletteChestController>(ref chest))
			{
				return;
			}
			try
			{
				EntityState state = RouletteChestAccess.GetState(chest);
				if (state != null && ((object)state).GetType() == RouletteChestAccess.IdleStateType)
				{
					__result += GetSuffix(chest);
				}
			}
			catch (Exception arg)
			{
				if (!errorLogged)
				{
					errorLogged = true;
					Plugin.Log.LogError((object)$"Adaptive Chest preview failed; the prompt is shown without it.\n{arg}");
				}
			}
		}

		private static string GetSuffix(RouletteChestController chest)
		{
			Prediction value = predictions.GetValue(chest, (RouletteChestController _) => new Prediction());
			float unscaledTime = Time.unscaledTime;
			if (value.entries == null || unscaledTime - value.computedAt > 1f)
			{
				value.entries = Predict(chest);
				value.computedAt = unscaledTime;
				value.suffix = null;
			}
			if (value.entries == null)
			{
				return "";
			}
			if (value.suffix == null || value.rulesVersion != PriorityRules.Version)
			{
				value.suffix = BuildSuffix(value.entries);
				value.rulesVersion = PriorityRules.Version;
			}
			return value.suffix;
		}

		private static UniquePickup[] Predict(RouletteChestController chest)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			Xoroshiro128Plus val = RouletteChestAccess.RngRef.Invoke(chest);
			PickupDropTable dropTable = chest.dropTable;
			if (val == null || !Object.op_Implicit((Object)(object)dropTable) || chest.maxEntries <= 0)
			{
				return null;
			}
			Xoroshiro128Plus val2 = new Xoroshiro128Plus(val);
			UniquePickup[] array = (UniquePickup[])(object)new UniquePickup[chest.maxEntries];
			UniquePickup val3 = UniquePickup.none;
			for (int i = 0; i < array.Length; i++)
			{
				UniquePickup val4 = dropTable.GeneratePickup(val2);
				if (((UniquePickup)(ref val4)).Equals(val3))
				{
					val4 = dropTable.GeneratePickup(val2);
				}
				array[i] = val4;
				val3 = val4;
			}
			return array;
		}

		private static string BuildSuffix(UniquePickup[] entries)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			List<KeyValuePair<int, PickupIndex>> list = new List<KeyValuePair<int, PickupIndex>>();
			HashSet<PickupIndex> hashSet = new HashSet<PickupIndex>();
			foreach (UniquePickup val in entries)
			{
				int rank = PriorityRules.GetRank(val.pickupIndex);
				if (rank != int.MaxValue && hashSet.Add(val.pickupIndex))
				{
					list.Add(new KeyValuePair<int, PickupIndex>(rank, val.pickupIndex));
				}
			}
			if (list.Count == 0)
			{
				return " <color=#8C8C8C>| no priority items</color>";
			}
			List<KeyValuePair<int, PickupIndex>> list2 = list.OrderBy((KeyValuePair<int, PickupIndex> pair) => pair.Key).ToList();
			StringBuilder stringBuilder = new StringBuilder(" | ");
			for (int num = 0; num < list2.Count && num < 3; num++)
			{
				PickupDef pickupDef = PickupCatalog.GetPickupDef(list2[num].Value);
				stringBuilder.Append((num == 0) ? "" : ", ").Append("<color=#").Append(ColorUtility.ToHtmlStringRGB(pickupDef.baseColor))
					.Append('>')
					.Append(Language.GetString(pickupDef.nameToken))
					.Append("</color>");
			}
			if (list2.Count > 3)
			{
				stringBuilder.Append(" +").Append(list2.Count - 3);
			}
			return stringBuilder.ToString();
		}

		private static string PickupName(PickupIndex pickupIndex)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			PickupDef pickupDef = PickupCatalog.GetPickupDef(pickupIndex);
			if (pickupDef == null)
			{
				return $"PickupIndex {pickupIndex.value}";
			}
			return "\"" + Language.GetString(pickupDef.nameToken) + "\" (" + pickupDef.internalName + ")";
		}
	}
	internal static class ModConfig
	{
		internal const string PriorityListNameToken = "ADAPTIVECHESTPICKER_PRIORITY_LIST_NAME";

		internal const string PriorityListDescriptionToken = "ADAPTIVECHESTPICKER_PRIORITY_LIST_DESC";

		internal const string NeverPickNameToken = "ADAPTIVECHESTPICKER_NEVER_PICK_NAME";

		internal const string NeverPickDescriptionToken = "ADAPTIVECHESTPICKER_NEVER_PICK_DESC";

		internal static ConfigEntry<bool> Enabled { get; private set; }

		internal static ConfigEntry<string> PriorityList { get; private set; }

		internal static ConfigEntry<string> NeverPick { get; private set; }

		internal static ConfigEntry<bool> PreviewOnHover { get; private set; }

		internal static ConfigEntry<bool> DebugLogging { get; private set; }

		internal static ConfigEntry<KeyboardShortcut> EditorKey { get; private set; }

		internal static void Bind(ConfigFile config)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			Enabled = config.Bind<bool>("General", "Enabled", true, "Master switch for the whole mod (auto-stop and preview). Can be toggled while the game runs.");
			EditorKey = config.Bind<KeyboardShortcut>("General", "Priority editor key", new KeyboardShortcut((KeyCode)288, Array.Empty<KeyCode>()), "Opens and closes the visual priority editor (also available as a button in Settings -> Mods).");
			PriorityList = config.Bind<string>("Priority", "Priority list", "Red", "Click the box and TYPE (it is a text field, not a list of choices), entries separated by commas, highest priority first; press Enter to apply. An entry is a rarity - White, Green, Red, Yellow, Lunar, Void, Equipment (Russian names work too) - or an item/equipment name: English, your game language, internal (Clover) or just a unique part of it (clover, behemoth). When YOUR OWN Adaptive Chest starts cycling, the mod stops it on the highest-priority item among its 30; items that match nothing here are never auto-picked. Example: clover, Red, feather, Green");
			NeverPick = config.Bind<string>("Priority", "Never pick", "", "Click the box and TYPE: comma-separated items, equipment or rarities the mod must never stop on, even if the priority list matches them; press Enter to apply. Example: behemoth");
			PreviewOnHover = config.Bind<bool>("Preview", "Show contents on hover", true, "Host only: when you aim at an unopened Adaptive Chest, its prompt lists the priority items it will contain. Clients cannot know the contents before a chest is opened.");
			DebugLogging = config.Bind<bool>("General", "DebugLogging", false, "Write details to the BepInEx log: which chest is tracked, every cycled entry (PickupIndex, item name, rarity, priority) and why the mod did or did not stop the chest. At most one line per entry, never one per frame.");
		}

		internal static void UpdateListTexts(string priorityFeedback, string neverFeedback)
		{
			SetString("ADAPTIVECHESTPICKER_PRIORITY_LIST_NAME", ((ConfigEntryBase)PriorityList).Definition.Key);
			SetString("ADAPTIVECHESTPICKER_PRIORITY_LIST_DESC", ((ConfigEntryBase)PriorityList).Description.Description + "\n\n" + priorityFeedback);
			SetString("ADAPTIVECHESTPICKER_NEVER_PICK_NAME", ((ConfigEntryBase)NeverPick).Definition.Key);
			SetString("ADAPTIVECHESTPICKER_NEVER_PICK_DESC", ((ConfigEntryBase)NeverPick).Description.Description + "\n\n" + neverFeedback);
		}

		private static void SetString(string token, string text)
		{
			Language english = Language.english;
			if (english != null)
			{
				english.SetStringByToken(token, text);
			}
			if (Language.currentLanguage != null && Language.currentLanguage != Language.english)
			{
				Language.currentLanguage.SetStringByToken(token, text);
			}
		}
	}
	internal sealed class CatalogEntry
	{
		public ListEntry entry;

		public Rarity rarity;

		public string name;

		public string searchKey;

		public Sprite icon;

		public Color color;

		public string tooltip;
	}
	internal static class EditorCatalog
	{
		internal static readonly Rarity[] Categories = new Rarity[4]
		{
			Rarity.White,
			Rarity.Green,
			Rarity.Red,
			Rarity.Equipment
		};

		private static readonly List<CatalogEntry> Empty = new List<CatalogEntry>();

		private static readonly Dictionary<Rarity, List<CatalogEntry>> byRarity = new Dictionary<Rarity, List<CatalogEntry>>();

		private static readonly List<CatalogEntry> rarityEntries = new List<CatalogEntry>();

		private static readonly List<CatalogEntry> all = new List<CatalogEntry>();

		private static string builtForLanguage;

		internal static IReadOnlyList<CatalogEntry> Rarities
		{
			get
			{
				EnsureBuilt();
				return rarityEntries;
			}
		}

		internal static IReadOnlyList<CatalogEntry> Get(Rarity rarity)
		{
			EnsureBuilt();
			if (!byRarity.TryGetValue(rarity, out var value))
			{
				return Empty;
			}
			return value;
		}

		internal static List<CatalogEntry> Search(string text)
		{
			EnsureBuilt();
			string text2 = PriorityRules.Normalize(text);
			List<CatalogEntry> list = new List<CatalogEntry>();
			if (text2.Length == 0)
			{
				return list;
			}
			foreach (CatalogEntry item in all)
			{
				if (item.searchKey.Contains(text2))
				{
					list.Add(item);
				}
			}
			return list;
		}

		internal static Color RarityColor(Rarity rarity)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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_005b: 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)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//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)
			//IL_009d: 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)
			switch (rarity)
			{
			case Rarity.White:
				return Color32.op_Implicit(ColorCatalog.GetColor((ColorIndex)1));
			case Rarity.Green:
				return Color32.op_Implicit(ColorCatalog.GetColor((ColorIndex)2));
			case Rarity.Red:
				return Color32.op_Implicit(ColorCatalog.GetColor((ColorIndex)3));
			case Rarity.Yellow:
				return Color32.op_Implicit(ColorCatalog.GetColor((ColorIndex)13));
			case Rarity.Lunar:
				return Color32.op_Implicit(ColorCatalog.GetColor((ColorIndex)4));
			case Rarity.Equipment:
				return Color32.op_Implicit(ColorCatalog.GetColor((ColorIndex)5));
			default:
			{
				ItemTierDef itemTierDef = ItemTierCatalog.GetItemTierDef((ItemTier)6);
				if (!((Object)(object)itemTierDef != (Object)null))
				{
					return new Color(0.93f, 0.5f, 0.8f);
				}
				return Color32.op_Implicit(ColorCatalog.GetColor(itemTierDef.colorIndex));
			}
			}
		}

		internal static string RarityTitle(Rarity rarity)
		{
			return rarity switch
			{
				Rarity.White => "White", 
				Rarity.Green => "Green", 
				Rarity.Red => "Red", 
				Rarity.Yellow => "Boss", 
				Rarity.Lunar => "Lunar", 
				Rarity.Void => "Void", 
				_ => "Equipment", 
			};
		}

		internal static Color ColorOf(ListEntry entry)
		{
			//IL_0021: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			switch (entry.kind)
			{
			case EntryKind.Rarity:
				return RarityColor(entry.rarity);
			case EntryKind.Item:
			{
				Rarity? rarity2 = PriorityRules.RarityOf(ItemCatalog.GetItemDef(entry.itemIndex));
				if (!rarity2.HasValue)
				{
					return Color.white;
				}
				return RarityColor(rarity2.Value);
			}
			case EntryKind.Equipment:
			{
				Rarity? rarity = PriorityRules.RarityOf(EquipmentCatalog.GetEquipmentDef(entry.equipmentIndex));
				if (!rarity.HasValue)
				{
					return Color.white;
				}
				return RarityColor(rarity.Value);
			}
			default:
				return EditorSkin.Danger;
			}
		}

		internal static Sprite IconOf(ListEntry entry)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			return (Sprite)(entry.kind switch
			{
				EntryKind.Item => ItemCatalog.GetItemDef(entry.itemIndex)?.pickupIconSprite, 
				EntryKind.Equipment => EquipmentCatalog.GetEquipmentDef(entry.equipmentIndex)?.pickupIconSprite, 
				_ => null, 
			});
		}

		internal static string TooltipOf(ListEntry entry)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			switch (entry.kind)
			{
			case EntryKind.Rarity:
				return Colored("Any " + RarityTitle(entry.rarity).ToLowerInvariant() + " item", RarityColor(entry.rarity)) + "\nMatches every item of this rarity that is not listed higher up.";
			case EntryKind.Item:
			{
				ItemDef itemDef = ItemCatalog.GetItemDef(entry.itemIndex);
				if (!((Object)(object)itemDef == (Object)null))
				{
					return Describe(itemDef.nameToken, itemDef.pickupToken, ColorOf(entry));
				}
				return "";
			}
			case EntryKind.Equipment:
			{
				EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef(entry.equipmentIndex);
				if (!((Object)(object)equipmentDef == (Object)null))
				{
					return Describe(equipmentDef.nameToken, equipmentDef.pickupToken, ColorOf(entry));
				}
				return "";
			}
			default:
				return Colored("Not recognised: \"" + entry.text + "\"", EditorSkin.Danger) + "\nRemove it, or fix the text in Settings -> Mods.";
			}
		}

		internal static string Colored(string text, Color color)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			return "<color=#" + ColorUtility.ToHtmlStringRGB(color) + ">" + text + "</color>";
		}

		private static void EnsureBuilt()
		{
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			if (builtForLanguage == Language.currentLanguageName && all.Count > 0)
			{
				return;
			}
			builtForLanguage = Language.currentLanguageName;
			byRarity.Clear();
			rarityEntries.Clear();
			all.Clear();
			Rarity[] categories = Categories;
			for (int i = 0; i < categories.Length; i++)
			{
				Rarity rarity = categories[i];
				byRarity[rarity] = new List<CatalogEntry>();
				rarityEntries.Add(Create(ListEntry.OfRarity(rarity), rarity, "Any " + RarityTitle(rarity).ToLowerInvariant(), "", rarity.ToString()));
			}
			for (int j = 0; j < ItemCatalog.itemCount; j++)
			{
				ItemDef itemDef = ItemCatalog.GetItemDef((ItemIndex)j);
				Rarity? rarity2 = PriorityRules.RarityOf(itemDef);
				if (PriorityRules.CanDropFromChest(itemDef) && rarity2.HasValue && byRarity.ContainsKey(rarity2.Value))
				{
					Add(Create(ListEntry.OfItem(itemDef.itemIndex), rarity2.Value, PriorityRules.DisplayName(ListEntry.OfItem(itemDef.itemIndex)), itemDef.nameToken, ((Object)itemDef).name));
				}
			}
			for (int k = 0; k < EquipmentCatalog.equipmentCount; k++)
			{
				EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef((EquipmentIndex)k);
				Rarity? rarity3 = PriorityRules.RarityOf(equipmentDef);
				if ((Object)(object)equipmentDef != (Object)null && equipmentDef.canDrop && rarity3.HasValue && byRarity.ContainsKey(rarity3.Value))
				{
					Add(Create(ListEntry.OfEquipment(equipmentDef.equipmentIndex), rarity3.Value, PriorityRules.DisplayName(ListEntry.OfEquipment(equipmentDef.equipmentIndex)), equipmentDef.nameToken, ((Object)equipmentDef).name));
				}
			}
			foreach (List<CatalogEntry> value in byRarity.Values)
			{
				value.Sort((CatalogEntry a, CatalogEntry b) => string.Compare(a.name, b.name, StringComparison.CurrentCultureIgnoreCase));
			}
		}

		private static CatalogEntry Create(ListEntry entry, Rarity rarity, string name, string nameToken, string internalName)
		{
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			string text = ((string.IsNullOrEmpty(nameToken) || Language.english == null) ? "" : Language.english.GetLocalizedStringByToken(nameToken));
			CatalogEntry catalogEntry = new CatalogEntry();
			catalogEntry.entry = entry;
			catalogEntry.rarity = rarity;
			catalogEntry.name = name;
			catalogEntry.searchKey = PriorityRules.Normalize(name) + "|" + PriorityRules.Normalize(text) + "|" + PriorityRules.Normalize(internalName);
			catalogEntry.icon = IconOf(entry);
			catalogEntry.color = RarityColor(rarity);
			catalogEntry.tooltip = TooltipOf(entry);
			return catalogEntry;
		}

		private static void Add(CatalogEntry entry)
		{
			byRarity[entry.rarity].Add(entry);
			all.Add(entry);
		}

		private static string Describe(string nameToken, string pickupToken, Color color)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			string text = PriorityRules.StripTags(Language.GetString(nameToken));
			string text2 = (string.IsNullOrEmpty(pickupToken) ? "" : PriorityRules.StripTags(Language.GetString(pickupToken)));
			if (text2.Length != 0)
			{
				return Colored(text, color) + "\n" + text2;
			}
			return Colored(text, color);
		}
	}
	internal sealed class EditorSkin
	{
		internal static readonly Color Text = new Color(0.92f, 0.94f, 0.97f);

		internal static readonly Color Muted = new Color(0.6f, 0.64f, 0.72f);

		internal static readonly Color Accent = new Color(0.33f, 0.62f, 1f);

		internal static readonly Color Danger = new Color(1f, 0.4f, 0.36f);

		private static readonly RectOffset SliceBorder = new RectOffset(7, 7, 7, 7);

		internal readonly GUISkin guiSkin;

		internal readonly GUIStyle window;

		internal readonly GUIStyle title;

		internal readonly GUIStyle sectionLabel;

		internal readonly GUIStyle panel;

		internal readonly GUIStyle row;

		internal readonly GUIStyle rowIndex;

		internal readonly GUIStyle rowName;

		internal readonly GUIStyle hint;

		internal readonly GUIStyle emptyNote;

		internal readonly GUIStyle button;

		internal readonly GUIStyle dangerButton;

		internal readonly GUIStyle iconButton;

		internal readonly GUIStyle removeButton;

		internal readonly GUIStyle closeButton;

		internal readonly GUIStyle tab;

		internal readonly GUIStyle tabActive;

		internal readonly GUIStyle textField;

		internal readonly GUIStyle placeholder;

		internal readonly GUIStyle toggleOn;

		internal readonly GUIStyle toggleOff;

		internal readonly GUIStyle tooltip;

		internal readonly GUIStyle ghost;

		internal readonly GUIStyle badge;

		internal readonly GUIStyle badgeNever;

		internal readonly GUIStyle tileText;

		internal readonly GUIStyle iconText;

		internal readonly Texture2D arrowUp;

		internal readonly Texture2D arrowDown;

		internal readonly Texture2D cross;

		internal readonly Texture2D grip;

		internal readonly Texture2D dropLine;

		internal readonly Texture2D cursorFallback;

		private readonly Dictionary<Color, GUIStyle> tileStyles = new Dictionary<Color, GUIStyle>();

		private readonly Dictionary<Color, GUIStyle> hoverTileStyles = new Dictionary<Color, GUIStyle>();

		internal EditorSkin()
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Expected O, but got Unknown
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Expected O, but got Unknown
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Expected O, but got Unknown
			//IL_02e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f0: Expected O, but got Unknown
			//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0309: Unknown result type (might be due to invalid IL or missing references)
			//IL_032a: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0360: Unknown result type (might be due to invalid IL or missing references)
			//IL_0374: Unknown result type (might be due to invalid IL or missing references)
			//IL_0388: Unknown result type (might be due to invalid IL or missing references)
			//IL_03aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_03be: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0408: Unknown result type (might be due to invalid IL or missing references)
			//IL_041c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0443: Unknown result type (might be due to invalid IL or missing references)
			//IL_0457: Unknown result type (might be due to invalid IL or missing references)
			//IL_046b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0492: Unknown result type (might be due to invalid IL or missing references)
			//IL_04a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_04db: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e5: Expected O, but got Unknown
			//IL_04fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0513: Unknown result type (might be due to invalid IL or missing references)
			//IL_052c: Unknown result type (might be due to invalid IL or missing references)
			//IL_054a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0554: Expected O, but got Unknown
			//IL_0585: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_060d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0617: Expected O, but got Unknown
			//IL_0627: Unknown result type (might be due to invalid IL or missing references)
			//IL_063b: Unknown result type (might be due to invalid IL or missing references)
			//IL_064f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0671: Unknown result type (might be due to invalid IL or missing references)
			//IL_0685: Unknown result type (might be due to invalid IL or missing references)
			//IL_0699: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_06cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_06eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_06f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_06fc: Expected O, but got Unknown
			//IL_06fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0701: Unknown result type (might be due to invalid IL or missing references)
			//IL_070b: Expected O, but got Unknown
			//IL_0710: Expected O, but got Unknown
			//IL_0724: Unknown result type (might be due to invalid IL or missing references)
			//IL_073d: Unknown result type (might be due to invalid IL or missing references)
			//IL_075c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0761: Unknown result type (might be due to invalid IL or missing references)
			//IL_083a: Unknown result type (might be due to invalid IL or missing references)
			//IL_083f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0840: Unknown result type (might be due to invalid IL or missing references)
			//IL_0847: Unknown result type (might be due to invalid IL or missing references)
			//IL_0849: Unknown result type (might be due to invalid IL or missing references)
			//IL_084a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0851: Unknown result type (might be due to invalid IL or missing references)
			//IL_0853: Unknown result type (might be due to invalid IL or missing references)
			//IL_0854: Unknown result type (might be due to invalid IL or missing references)
			//IL_085b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0889: Unknown result type (might be due to invalid IL or missing references)
			//IL_08a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_08b0: Expected O, but got Unknown
			//IL_08c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_08d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_08eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_08f5: Expected O, but got Unknown
			//IL_092a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0949: Unknown result type (might be due to invalid IL or missing references)
			//IL_094e: Unknown result type (might be due to invalid IL or missing references)
			//IL_095e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0968: Expected O, but got Unknown
			//IL_099d: Unknown result type (might be due to invalid IL or missing references)
			//IL_09dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_09eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_09f5: Expected O, but got Unknown
			//IL_0a2a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a49: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a57: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a61: Expected O, but got Unknown
			//IL_0a6a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a7f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b41: Unknown result type (might be due to invalid IL or missing references)
			guiSkin = Object.Instantiate<GUISkin>(GUI.skin);
			((Object)guiSkin).hideFlags = (HideFlags)61;
			guiSkin.settings.cursorColor = Text;
			guiSkin.settings.selectionColor = new Color(Accent.r, Accent.g, Accent.b, 0.45f);
			Texture2D background = Rounded(new Color(1f, 1f, 1f, 0.04f));
			Texture2D background2 = Rounded(new Color(1f, 1f, 1f, 0.22f));
			Texture2D hover = Rounded(new Color(1f, 1f, 1f, 0.34f));
			guiSkin.verticalScrollbar = Scrollbar(guiSkin.verticalScrollbar, background, vertical: true);
			guiSkin.verticalScrollbarThumb = Scrollbar(guiSkin.verticalScrollbarThumb, background2, vertical: true, hover);
			guiSkin.verticalScrollbarUpButton = Hidden(guiSkin.verticalScrollbarUpButton);
			guiSkin.verticalScrollbarDownButton = Hidden(guiSkin.verticalScrollbarDownButton);
			guiSkin.horizontalScrollbar = Scrollbar(guiSkin.horizontalScrollbar, background, vertical: false);
			guiSkin.horizontalScrollbarThumb = Scrollbar(guiSkin.horizontalScrollbarThumb, background2, vertical: false, hover);
			guiSkin.horizontalScrollbarLeftButton = Hidden(guiSkin.horizontalScrollbarLeftButton);
			guiSkin.horizontalScrollbarRightButton = Hidden(guiSkin.horizontalScrollbarRightButton);
			window = Box(Rounded(new Color(0.055f, 0.063f, 0.082f, 0.985f), new Color(0.3f, 0.34f, 0.42f)), new RectOffset(18, 18, 12, 16));
			window.onNormal.background = window.normal.background;
			title = Label(21, (FontStyle)1, Text, (TextAnchor)3);
			sectionLabel = Label(14, (FontStyle)1, Muted, (TextAnchor)3);
			panel = Box(Rounded(new Color(1f, 1f, 1f, 0.035f), new Color(1f, 1f, 1f, 0.08f)), new RectOffset(12, 12, 12, 12));
			row = Box(Rounded(new Color(1f, 1f, 1f, 0.045f)), new RectOffset(4, 6, 2, 2));
			row.margin = new RectOffset(0, 4, 0, 5);
			rowIndex = Label(15, (FontStyle)1, Muted, (TextAnchor)4);
			rowName = Label(15, (FontStyle)0, Text, (TextAnchor)3);
			rowName.clipping = (TextClipping)1;
			hint = Label(12, (FontStyle)2, Muted, (TextAnchor)0, wrap: true);
			emptyNote = Label(14, (FontStyle)2, Muted, (TextAnchor)4, wrap: true);
			button = Button(new Color(0.17f, 0.19f, 0.24f), new Color(0.23f, 0.26f, 0.33f), new Color(0.3f, 0.35f, 0.45f), 14, (FontStyle)0);
			dangerButton = Button(new Color(0.24f, 0.13f, 0.13f), new Color(0.4f, 0.17f, 0.16f), new Color(0.55f, 0.2f, 0.18f), 14, (FontStyle)0);
			iconButton = IconButton(Button(new Color(0.17f, 0.19f, 0.24f), new Color(0.25f, 0.29f, 0.37f), new Color(0.32f, 0.38f, 0.5f), 13, (FontStyle)0));
			removeButton = IconButton(Button(new Color(0.24f, 0.13f, 0.13f), new Color(0.45f, 0.17f, 0.16f), new Color(0.6f, 0.2f, 0.18f), 13, (FontStyle)0));
			closeButton = IconButton(Button(new Color(0.17f, 0.19f, 0.24f), new Color(0.55f, 0.18f, 0.17f), new Color(0.7f, 0.22f, 0.2f), 13, (FontStyle)0));
			closeButton.margin = new RectOffset(3, 3, 3, 3);
			tab = Button(new Color(1f, 1f, 1f, 0.03f), new Color(1f, 1f, 1f, 0.09f), new Color(1f, 1f, 1f, 0.14f), 13, (FontStyle)0);
			tab.padding = new RectOffset(10, 10, 4, 4);
			tabActive = Button(new Color(Accent.r * 0.45f, Accent.g * 0.45f, Accent.b * 0.55f), new Color(Accent.r * 0.55f, Accent.g * 0.55f, Accent.b * 0.65f), new Color(Accent.r * 0.6f, Accent.g * 0.6f, Accent.b * 0.7f), 13, (FontStyle)1);
			tabActive.padding = new RectOffset(10, 10, 4, 4);
			toggleOn = Button(new Color(0.16f, 0.4f, 0.25f), new Color(0.2f, 0.5f, 0.31f), new Color(0.24f, 0.58f, 0.36f), 14, (FontStyle)1);
			toggleOff = Button(new Color(0.2f, 0.21f, 0.25f), new Color(0.27f, 0.28f, 0.33f), new Color(0.32f, 0.34f, 0.4f), 14, (FontStyle)0);
			toggleOff.normal.textColor = Muted;
			textField = new GUIStyle(guiSkin.textField)
			{
				fontSize = 15,
				alignment = (TextAnchor)3,
				border = SliceBorder,
				padding = new RectOffset(12, 12, 6, 6),
				margin = new RectOffset(3, 3, 3, 3)
			};
			Texture2D val = Rounded(new Color(0f, 0f, 0f, 0.35f), new Color(1f, 1f, 1f, 0.14f));
			Texture2D val2 = Rounded(new Color(0f, 0f, 0f, 0.45f), Accent);
			textField.normal.background = (textField.hover.background = (textField.onNormal.background = (textField.onHover.background = val)));
			textField.focused.background = (textField.active.background = (textField.onFocused.background = (textField.onActive.background = val2)));
			textField.normal.textColor = (textField.hover.textColor = (textField.focused.textColor = (textField.active.textColor = Text)));
			placeholder = Label(14, (FontStyle)2, new Color(Muted.r, Muted.g, Muted.b, 0.8f), (TextAnchor)3);
			placeholder.padding = new RectOffset(14, 12, 6, 6);
			tooltip = Box(Rounded(new Color(0.03f, 0.035f, 0.047f, 0.98f), new Color(0.45f, 0.5f, 0.6f)), new RectOffset(12, 12, 10, 10));
			tooltip.fontSize = 14;
			tooltip.wordWrap = true;
			tooltip.richText = true;
			tooltip.normal.textColor = Text;
			ghost = Box(Rounded(new Color(0.1f, 0.12f, 0.16f, 0.96f), Accent), new RectOffset(48, 14, 6, 6));
			ghost.fontSize = 15;
			ghost.richText = true;
			ghost.alignment = (TextAnchor)3;
			ghost.normal.textColor = Text;
			badge = Box(Rounded(new Color(Accent.r * 0.75f, Accent.g * 0.75f, Accent.b * 0.85f, 0.95f)), new RectOffset(0, 0, 0, 0));
			badge.fontSize = 12;
			badge.fontStyle = (FontStyle)1;
			badge.alignment = (TextAnchor)4;
			badge.normal.textColor = Color.white;
			badgeNever = Box(Rounded(new Color(0.75f, 0.2f, 0.18f, 0.95f)), new RectOffset(0, 0, 0, 0));
			tileText = Label(15, (FontStyle)0, Text, (TextAnchor)3, wrap: true);
			iconText = Label(10, (FontStyle)1, Text, (TextAnchor)4);
			arrowUp = Icon(12, (float u, float v) => InTriangle(u, v, 0.5f, 0.18f, 0.06f, 0.8f, 0.94f, 0.8f));
			arrowDown = Icon(12, (float u, float v) => InTriangle(u, v, 0.5f, 0.82f, 0.06f, 0.2f, 0.94f, 0.2f));
			cross = Icon(12, (float u, float v) => SegmentDistance(u, v, 0.14f, 0.14f, 0.86f, 0.86f) < 0.12f || SegmentDistance(u, v, 0.86f, 0.14f, 0.14f, 0.86f) < 0.12f);
			grip = Icon(14, (float u, float v) => IsGripDot(u, v));
			dropLine = Solid(Accent);
			cursorFallback = Icon(24, (float u, float v) => InTriangle(u, v, 0.05f, 0.02f, 0.05f, 0.82f, 0.62f, 0.62f));
		}

		internal GUIStyle Tile(Color color, bool hover)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<Color, GUIStyle> dictionary = (hover ? hoverTileStyles : tileStyles);
			if (!dictionary.TryGetValue(color, out var value) || !Object.op_Implicit((Object)(object)value.normal.background))
			{
				value = (dictionary[color] = Box(Rounded(new Color(color.r, color.g, color.b, hover ? 0.3f : 0.13f), new Color(color.r, color.g, color.b, hover ? 1f : 0.55f)), new RectOffset(0, 0, 0, 0)));
			}
			return value;
		}

		internal static void DrawCentered(Rect rect, Texture2D icon)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			GUI.DrawTexture(new Rect(Mathf.Round(((Rect)(ref rect)).center.x - (float)((Texture)icon).width / 2f), Mathf.Round(((Rect)(ref rect)).center.y - (float)((Texture)icon).height / 2f), (float)((Texture)icon).width, (float)((Texture)icon).height), (Texture)(object)icon);
		}

		private static GUIStyle Box(Texture2D background, RectOffset padding)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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_0024: Expected O, but got Unknown
			GUIStyle val = new GUIStyle
			{
				border = SliceBorder,
				padding = padding
			};
			val.normal.background = background;
			return val;
		}

		private static GUIStyle Label(int size, FontStyle style, Color color, TextAnchor anchor = (TextAnchor)3, bool wrap = false)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: 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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_0038: 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_0045: Expected O, but got Unknown
			GUIStyle val = new GUIStyle
			{
				fontSize = size,
				fontStyle = style,
				alignment = anchor,
				wordWrap = wrap,
				richText = true,
				padding = new RectOffset(2, 2, 2, 2)
			};
			val.normal.textColor = color;
			return val;
		}

		private static GUIStyle Button(Color normal, Color hover, Color active, int fontSize, FontStyle fontStyle = (FontStyle)0)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: 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_000d: 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_001b: 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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			//IL_004e: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: 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_00be: 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_00c5: Unknown result type (might be due to invalid IL or missing references)
			GUIStyle val = new GUIStyle
			{
				fontSize = fontSize,
				fontStyle = fontStyle,
				alignment = (TextAnchor)4,
				richText = true,
				border = SliceBorder,
				padding = new RectOffset(10, 10, 5, 5),
				margin = new RectOffset(3, 3, 3, 3)
			};
			val.normal.background = Rounded(normal);
			GUIStyleState hover2 = val.hover;
			Texture2D background = (val.focused.background = Rounded(hover));
			hover2.background = background;
			val.active.background = Rounded(active);
			val.normal.textColor = Text;
			GUIStyleState hover3 = val.hover;
			GUIStyleState focused = val.focused;
			Color val3 = (val.active.textColor = Color.white);
			Color textColor = (focused.textColor = val3);
			hover3.textColor = textColor;
			return val;
		}

		private static GUIStyle IconButton(GUIStyle style)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			style.imagePosition = (ImagePosition)2;
			style.padding = new RectOffset(0, 0, 0, 0);
			style.margin = new RectOffset(2, 2, 6, 6);
			return style;
		}

		private static GUIStyle Scrollbar(GUIStyle original, Texture2D background, bool vertical, Texture2D hover = null)
		{
			//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_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//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_0024: Expected O, but got Unknown
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_0042: Expected O, but got Unknown
			GUIStyle val = new GUIStyle(original)
			{
				border = new RectOffset(5, 5, 5, 5),
				padding = new RectOffset(0, 0, 0, 0),
				margin = (vertical ? new RectOffset(6, 0, 2, 2) : new RectOffset(2, 2, 4, 0))
			};
			if (vertical)
			{
				val.fixedWidth = 10f;
			}
			else
			{
				val.fixedHeight = 8f;
			}
			GUIStyleState normal = val.normal;
			GUIStyleState onNormal = val.onNormal;
			GUIStyleState focused = val.focused;
			Texture2D val2 = (val.onFocused.background = background);
			Texture2D val4 = (focused.background = val2);
			Texture2D background2 = (onNormal.background = val4);
			normal.background = background2;
			GUIStyleState hover2 = val.hover;
			GUIStyleState onHover = val.onHover;
			GUIStyleState active = val.active;
			val2 = (val.onActive.background = hover ?? background);
			val4 = (active.background = val2);
			background2 = (onHover.background = val4);
			hover2.background = background2;
			return val;
		}

		private static GUIStyle Hidden(GUIStyle original)
		{
			//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_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			GUIStyle val = new GUIStyle(original)
			{
				fixedWidth = 0f,
				fixedHeight = 0f
			};
			GUIStyleState normal = val.normal;
			GUIStyleState hover = val.hover;
			Texture2D val2 = (val.active.background = null);
			Texture2D background = (hover.background = val2);
			normal.background = background;
			GUIStyleState onNormal = val.onNormal;
			GUIStyleState onHover = val.onHover;
			val2 = (val.onActive.background = null);
			background = (onHover.background = val2);
			onNormal.background = background;
			return val;
		}

		private static Texture2D Rounded(Color fill)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return Rounded(fill, fill);
		}

		private static Texture2D Solid(Color color)
		{
			//IL_0010: 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_0018: 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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = NewTexture(2);
			val.SetPixels((Color[])(object)new Color[4] { color, color, color, color });
			val.Apply();
			return val;
		}

		private static Texture2D Rounded(Color fill, Color border)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: 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_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: 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)
			Texture2D val = NewTexture(16);
			float num = 8f;
			for (int i = 0; i < 16; i++)
			{
				for (int j = 0; j < 16; j++)
				{
					float num2 = Mathf.Abs((float)j + 0.5f - num) - (num - 6f);
					float num3 = Mathf.Abs((float)i + 0.5f - num) - (num - 6f);
					Vector2 val2 = new Vector2(Mathf.Max(num2, 0f), Mathf.Max(num3, 0f));
					float num4 = ((Vector2)(ref val2)).magnitude + Mathf.Min(Mathf.Max(num2, num3), 0f) - 6f;
					Color val3 = ((num4 > -1.25f) ? border : fill);
					val3.a *= Mathf.Clamp01(0.5f - num4);
					val.SetPixel(j, i, val3);
				}
			}
			val.Apply();
			return val;
		}

		private static Texture2D Icon(int size, Func<float, float, bool> shape)
		{
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = NewTexture(size);
			for (int i = 0; i < size; i++)
			{
				for (int j = 0; j < size; j++)
				{
					int num = 0;
					for (int k = 0; k < 4; k++)
					{
						for (int l = 0; l < 4; l++)
						{
							float arg = ((float)j + ((float)l + 0.5f) / 4f) / (float)size;
							float arg2 = 1f - ((float)i + ((float)k + 0.5f) / 4f) / (float)size;
							if (shape(arg, arg2))
							{
								num++;
							}
						}
					}
					val.SetPixel(j, i, new Color(1f, 1f, 1f, (float)num / 16f));
				}
			}
			val.Apply();
			return val;
		}

		private static bool InTriangle(float px, float py, float ax, float ay, float bx, float by, float cx, float cy)
		{
			float num = (px - bx) * (ay - by) - (ax - bx) * (py - by);
			float num2 = (px - cx) * (by - cy) - (bx - cx) * (py - cy);
			float num3 = (px - ax) * (cy - ay) - (cx - ax) * (py - ay);
			bool flag = num < 0f || num2 < 0f || num3 < 0f;
			bool flag2 = num > 0f || num2 > 0f || num3 > 0f;
			return !(flag && flag2);
		}

		private static float SegmentDistance(float px, float py, float ax, float ay, float bx, float by)
		{
			float num = bx - ax;
			float num2 = by - ay;
			float num3 = Mathf.Clamp01(((px - ax) * num + (py - ay) * num2) / (num * num + num2 * num2));
			float num4 = ax + num3 * num - px;
			float num5 = ay + num3 * num2 - py;
			return Mathf.Sqrt(num4 * num4 + num5 * num5);
		}

		private static bool IsGripDot(float u, float v)
		{
			float[] array = new float[2] { 0.32f, 0.68f };
			foreach (float num in array)
			{
				float[] array2 = new float[3] { 0.2f, 0.5f, 0.8f };
				foreach (float num2 in array2)
				{
					float num3 = u - num;
					float num4 = v - num2;
					if (num3 * num3 + num4 * num4 < 0.012f)
					{
						return true;
					}
				}
			}
			return false;
		}

		private static Texture2D NewTexture(int size)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: 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_0020: Expected O, but got Unknown
			return new Texture2D(size, size, (TextureFormat)4, false)
			{
				wrapMode = (TextureWrapMode)1,
				filterMode = (FilterMode)1,
				hideFlags = (HideFlags)61
			};
		}
	}
	[BepInPlugin("com.adaptivechestpicker", "Adaptive Chest Picker", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.adaptivechestpicker";

		public const string PluginName = "Adaptive Chest Picker";

		public const string PluginVersion = "1.0.0";

		private const string LegacyGuid = "com.adaptivechestredauto";

		private Harmony harmony;

		internal static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			MigrateLegacyFiles();
			ModConfig.Bind(((BaseUnityPlugin)this).Config);
			PresetStore.Load();
			if (RiskOfOptionsCompat.IsInstalled)
			{
				RiskOfOptionsCompat.RegisterOptions();
				Sprite val = LoadModIcon();
				if (Object.op_Implicit((Object)(object)val))
				{
					RiskOfOptionsCompat.SetIcon(val);
				}
			}
			((Component)this).gameObject.AddComponent<PriorityEditor>();
			if (RoR2Application.loadFinished)
			{
				OnGameLoaded();
			}
			else
			{
				RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, new Action(OnGameLoaded));
			}
			Language.onCurrentLanguageChanged += PriorityRules.Rebuild;
			ModConfig.PriorityList.SettingChanged += OnPriorityChanged;
			ModConfig.NeverPick.SettingChanged += OnPriorityChanged;
			harmony = new Harmony("com.adaptivechestpicker");
			if (!RouletteChestAccess.Resolve() || !AdaptiveChestHook.Install(harmony))
			{
				Log.LogError((object)"Adaptive Chest Picker is inactive: the Adaptive Chest code of this game version differs from what the mod expects.");
				return;
			}
			ChestPreview.Install(harmony);
			Log.LogInfo((object)(string.Format("{0} {1} loaded (client-side). Enabled={2}, ", "Adaptive Chest Picker", "1.0.0", ModConfig.Enabled.Value) + $"PreviewOnHover={ModConfig.PreviewOnHover.Value}, DebugLogging={ModConfig.DebugLogging.Value}."));
		}

		private void OnDestroy()
		{
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}

		private void MigrateLegacyFiles()
		{
			try
			{
				string text = Path.Combine(Paths.ConfigPath, "com.adaptivechestredauto.cfg");
				if (!File.Exists(((BaseUnityPlugin)this).Config.ConfigFilePath) && File.Exists(text))
				{
					File.Copy(text, ((BaseUnityPlugin)this).Config.ConfigFilePath);
					((BaseUnityPlugin)this).Config.Reload();
					Log.LogInfo((object)"Settings carried over from com.adaptivechestredauto.cfg.");
				}
				PresetStore.MigrateLegacyFile("com.adaptivechestredauto");
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("Could not carry over the settings of the old version: " + ex.Message));
			}
		}

		internal static void DebugLog(string message)
		{
			if (ModConfig.DebugLogging.Value)
			{
				Log.LogInfo((object)("[debug] " + message));
			}
		}

		private static void OnGameLoaded()
		{
			PriorityRules.Initialize();
		}

		private static Sprite LoadModIcon()
		{
			//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_0046: Expected O, but got Unknown
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				using Stream stream = typeof(Plugin).Assembly.GetManifestResourceStream("AdaptiveChestPicker.icon.png");
				using MemoryStream memoryStream = new MemoryStream();
				if (stream == null)
				{
					return null;
				}
				stream.CopyTo(memoryStream);
				Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true)
				{
					name = "AdaptiveChestPickerIcon"
				};
				if (!ImageConversion.LoadImage(val, memoryStream.ToArray()))
				{
					return null;
				}
				((Texture)val).wrapMode = (TextureWrapMode)1;
				return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f));
			}
			catch (Exception ex)
			{
				Log.LogWarning((object)("Could not load the mod icon: " + ex.Message));
				return null;
			}
		}

		private static void OnPriorityChanged(object sender, EventArgs e)
		{
			PriorityRules.Rebuild();
			PresetStore.SyncActiveFromConfig();
		}
	}
	[Serializable]
	public sealed class PresetData
	{
		public string name;

		public string priority;

		public string never;
	}
	[Serializable]
	public sealed class PresetFile
	{
		public int active;

		public List<PresetData> presets = new List<PresetData>();
	}
	internal static class PresetStore
	{
		internal const int MaxNameLength = 24;

		private static readonly string FilePath = Path.Combine(Paths.ConfigPath, "com.adaptivechestpicker.presets.json");

		private static PresetFile data = new PresetFile();

		private static bool applying;

		internal static int Count => data.presets.Count;

		internal static int ActiveIndex => data.active;

		internal static string NameAt(int index)
		{
			return data.presets[index].name;
		}

		internal static void MigrateLegacyFile(string legacyGuid)
		{
			string text = Path.Combine(Paths.ConfigPath, legacyGuid + ".presets.json");
			if (!File.Exists(FilePath) && File.Exists(text))
			{
				File.Copy(text, FilePath);
				Plugin.Log.LogInfo((object)("Presets carried over from " + legacyGuid + ".presets.json."));
			}
		}

		internal static void Load()
		{
			try
			{
				if (File.Exists(FilePath))
				{
					data = JsonUtility.FromJson<PresetFile>(File.ReadAllText(FilePath)) ?? new PresetFile();
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Could not read " + FilePath + ", starting with one preset: " + ex.Message));
				data = new PresetFile();
			}
			if (data.presets == null)
			{
				data.presets = new List<PresetData>();
			}
			data.presets.RemoveAll((PresetData preset) => preset == null);
			if (data.presets.Count == 0)
			{
				data.presets.Add(new PresetData
				{
					name = "Main"
				});
			}
			for (int num = 0; num < data.presets.Count; num++)
			{
				data.presets[num].name = UniqueName(data.presets[num].name, num);
			}
			data.active = Mathf.Clamp(data.active, 0, data.presets.Count - 1);
			SyncActiveFromConfig(forceSave: true);
		}

		internal static void SyncActiveFromConfig(bool forceSave = false)
		{
			if (!applying)
			{
				PresetData presetData = data.presets[data.active];
				string text = ModConfig.PriorityList.Value ?? "";
				string text2 = ModConfig.NeverPick.Value ?? "";
				if (forceSave || !(presetData.priority == text) || !(presetData.never == text2))
				{
					presetData.priority = text;
					presetData.never = text2;
					Save();
				}
			}
		}

		internal static void Activate(int index)
		{
			if (index >= 0 && index < data.presets.Count && index != data.active)
			{
				data.active = index;
				Save();
				ApplyActive();
			}
		}

		internal static void Create(bool copyActive)
		{
			PresetData presetData = data.presets[data.active];
			PresetData item = new PresetData
			{
				name = UniqueName(copyActive ? (presetData.name + " copy") : ("Preset " + (data.presets.Count + 1)), -1),
				priority = (copyActive ? presetData.priority : ""),
				never = (copyActive ? presetData.never : "")
			};
			data.presets.Add(item);
			data.active = data.presets.Count - 1;
			Save();
			ApplyActive();
		}

		internal static void Rename(int index, string name)
		{
			if (index >= 0 && index < data.presets.Count)
			{
				data.presets[index].name = UniqueName(name, index);
				Save();
			}
		}

		internal static void Delete(int index)
		{
			if (index >= 0 && index < data.presets.Count && data.presets.Count > 1)
			{
				data.presets.RemoveAt(index);
				data.active = Mathf.Clamp((index < data.active || data.active >= data.presets.Count) ? (data.active - 1) : data.active, 0, data.presets.Count - 1);
				Save();
				ApplyActive();
			}
		}

		private static string UniqueName(string wanted, int ignoreIndex)
		{
			string text = (wanted ?? "").Trim();
			if (text.Length == 0)
			{
				text = "Preset";
			}
			if (text.Length > 24)
			{
				text = text.Substring(0, 24).TrimEnd();
			}
			string text2 = text;
			int num = 2;
			while (IsTaken(text2, ignoreIndex))
			{
				string text3 = $" ({num})";
				text2 = ((text.Length + text3.Length > 24) ? text.Substring(0, 24 - text3.Length).TrimEnd() : text) + text3;
				num++;
			}
			return text2;
		}

		private static bool IsTaken(string name, int ignoreIndex)
		{
			for (int i = 0; i < data.presets.Count; i++)
			{
				if (i != ignoreIndex && string.Equals(data.presets[i].name, name, StringComparison.OrdinalIgnoreCase))
				{
					return true;
				}
			}
			return false;
		}

		private static void ApplyActive()
		{
			PresetData presetData = data.presets[data.active];
			applying = true;
			try
			{
				ModConfig.PriorityList.Value = presetData.priority ?? "";
				ModConfig.NeverPick.Value = presetData.never ?? "";
			}
			finally
			{
				applying = false;
			}
			Plugin.Log.LogInfo((object)("Preset \"" + presetData.name + "\" is active."));
		}

		private static void Save()
		{
			try
			{
				File.WriteAllText(FilePath, JsonUtility.ToJson((object)data, true));
			}
			catch (Exception ex)
			{
				Plugin.Log.LogError((object)("Could not save presets to " + FilePath + ": " + ex.Message));
			}
		}
	}
	internal sealed class PriorityEditor : MonoBehaviour
	{
		private enum DragSource
		{
			None,
			List,
			Catalog
		}

		private const float ReferenceHeight = 1080f;

		private const float WindowWidth = 1100f;

		private const float WindowHeight = 790f;

		private const float HeaderHeight = 44f;

		private const float ListWidth = 410f;

		private const float TileSize = 64f;

		private const float TileGap = 8f;

		private const int GridColumns = 8;

		private const string SearchControl = "AdaptiveChestPicker.Search";

		private static readonly int WindowId = "AdaptiveChestPicker.PriorityEditor".GetHashCode();

		private bool isOpen;

		private bool focusPending;

		private Rect windowRect = new Rect(0f, 0f, 1100f, 790f);

		private bool positioned;

		private Vector2 windowMouse;

		private bool editingNever;

		private int category = 3;

		private string search = "";

		private bool frameNever;

		private int frameCategory = 3;

		private string frameSearch = "";

		private IReadOnlyList<ListEntry> framePriority = Array.Empty<ListEntry>();

		private IReadOnlyList<ListEntry> frameNeverList = Array.Empty<ListEntry>();

		private IReadOnlyList<CatalogEntry> frameGrid;

		private Vector2 listScroll;

		private Vector2 gridScroll;

		private Rect gridViewport;

		private string hoverTooltip;

		private Action pendingEdit;

		private GameObject backdrop;

		private EditorSkin skin;

		private Sprite cursorSprite;

		private Color cursorColor = Color.white;

		private Vector2 cursorPivot = new Vector2(0f, 1f);

		private Vector2 cursorScreenSize = new Vector2(32f, 32f);

		private float nextCursorSearch;

		private const float DragThreshold = 6f;

		private const float AutoScrollZone = 30f;

		private const float AutoScrollSpeed = 420f;

		private DragSource dragSource;

		private bool dragStarted;

		private bool dragFromNever;

		private int dragIndex;

		private int pressButton;

		private ListEntry dragEntry;

		private Vector2 pressMouse;

		private int releasedFrames;

		private Rect listViewport;

		private readonly List<Rect> rowRects = new List<Rect>();

		private const string RenameControl = "AdaptiveChestPicker.PresetName";

		private const float DeleteConfirmSeconds = 3f;

		private int renamingIndex = -1;

		private string renameText = "";

		private bool renameFocusPending;

		private float deleteArmedUntil;

		private Vector2 presetScroll;

		private int framePresetCount = 1;

		private int frameActivePreset;

		private int frameRenaming = -1;

		private bool frameDeleteArmed;

		internal static PriorityEditor Instance { get; private set; }

		private static float GuiScale => Mathf.Max(0.5f, (float)Screen.height / 1080f);

		internal static void OpenFromSettings()
		{
			if (Object.op_Implicit((Object)(object)Instance))
			{
				Instance.Open();
			}
		}

		private void Awake()
		{
			Instance = this;
		}

		private void Update()
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			if (pendingEdit != null)
			{
				Action action = pendingEdit;
				pendingEdit = null;
				try
				{
					action();
				}
				catch (Exception arg)
				{
					Plugin.Log.LogError((object)$"Priority editor: {arg}");
				}
			}
			KeyboardShortcut value = ModConfig.EditorKey.Value;
			if (((KeyboardShortcut)(ref value)).IsDown() && renamingIndex < 0)
			{
				if (isOpen)
				{
					Close();
				}
				else
				{
					Open();
				}
			}
			if (isOpen)
			{
				UpdateDrag();
				if (!Object.op_Implicit((Object)(object)cursorSprite) && Time.unscaledTime >= nextCursorSearch)
				{
					nextCursorSearch = Time.unscaledTime + 0.5f;
					FindGameCursor();
				}
			}
		}

		internal void Open()
		{
			if (!isOpen && PriorityRules.IsReady)
			{
				EnsureBackdrop();
				backdrop.SetActive(true);
				FindGameCursor();
				isOpen = true;
				focusPending = true;
			}
		}

		internal void Close()
		{
			if (isOpen)
			{
				isOpen = false;
				CancelDrag();
				CancelRename();
				if (Object.op_Implicit((Object)(object)backdrop))
				{
					backdrop.SetActive(false);
				}
				if (RiskOfOptionsCompat.IsInstalled)
				{
					RiskOfOptionsCompat.RefreshControls();
				}
			}
		}

		private void OnGUI()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: 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_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Expected O, but got Unknown
			//IL_00f8: 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)
			if (isOpen)
			{
				if (skin == null)
				{
					skin = new EditorSkin();
				}
				GUISkin obj = GUI.skin;
				Matrix4x4 matrix = GUI.matrix;
				float guiScale = GuiScale;
				float num = (float)Screen.width / guiScale;
				GUI.skin = skin.guiSkin;
				GUI.matrix = Matrix4x4.Scale(new Vector3(guiScale, guiScale, 1f));
				if (!positioned)
				{
					((Rect)(ref windowRect)).x = (num - ((Rect)(ref windowRect)).width) / 2f;
					((Rect)(ref windowRect)).y = (1080f - ((Rect)(ref windowRect)).height) / 2f;
					positioned = true;
				}
				windowMouse = Event.current.mousePosition - ((Rect)(ref windowRect)).position;
				HandleDragEvents();
				windowRect = GUI.Window(WindowId, windowRect, new WindowFunction(DrawWindow), GUIContent.none, skin.window);
				((Rect)(ref windowRect)).x = Mathf.Clamp(((Rect)(ref windowRect)).x, 0f, Mathf.Max(0f, num - ((Rect)(ref windowRect)).width));
				((Rect)(ref windowRect)).y = Mathf.Clamp(((Rect)(ref windowRect)).y, 0f, Mathf.Max(0f, 1080f - ((Rect)(ref windowRect)).height));
				if (focusPending)
				{
					GUI.FocusWindow(WindowId);
					focusPending = false;
				}
				GUI.matrix = matrix;
				GUI.skin = obj;
			}
		}

		private void DrawWindow(int id)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Invalid comparison between Unknown and I4
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Invalid comparison between Unknown and I4
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			if ((int)Event.current.type == 8)
			{
				CaptureFrameState();
			}
			hoverTooltip = null;
			DrawHeader();
			DrawPresetBar();
			GUILayout.Space(8f);
			GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) });
			DrawListColumn();
			GUILayout.Space(14f);
			DrawCatalogColumn();
			GUILayout.EndHorizontal();
			GUILayout.Space(10f);
			DrawFooter();
			if ((int)Event.current.type == 7)
			{
				if (dragStarted)
				{
					DrawGhost();
				}
				else
				{
					DrawTooltip(hoverTooltip ?? GUI.tooltip);
				}
				DrawCursor();
			}
			GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref windowRect)).width, 56f));
		}

		private void CaptureFrameState()
		{
			frameNever = editingNever;
			frameCategory = category;
			frameSearch = (search ?? "").Trim();
			framePriority = PriorityRules.PriorityEntries;
			frameNeverList = PriorityRules.NeverEntries;
			object obj;
			if (frameSearch.Length <= 0)
			{
				obj = ((frameCategory > 0) ? EditorCatalog.Get(EditorCatalog.Categories[frameCategory - 1]) : null);
			}
			else
			{
				IReadOnlyList<CatalogEntry> readOnlyList = EditorCatalog.Search(frameSearch);
				obj = readOnlyList;
			}
			frameGrid = (IReadOnlyList<CatalogEntry>)obj;
			CapturePresetState();
		}

		private void DrawHeader()
		{
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Expected O, but got Unknown
			//IL_00ef: 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_0133: Expected O, but got Unknown
			GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(44f) });
			GUILayout.Label("Adaptive Chest Picker  <color=#8FA3BF>·  Priority editor</color>", skin.title, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(44f) });
			GUILayout.FlexibleSpace();
			bool value = ModConfig.Enabled.Value;
			if (GUILayout.Button(new GUIContent(value ? "Mod enabled" : "Mod disabled", "Master switch: auto-stop and preview."), value ? skin.toggleOn : skin.toggleOff, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(150f),
				GUILayout.Height(34f)
			}))
			{
				Defer(delegate
				{
					ModConfig.Enabled.Value = !ModConfig.Enabled.Value;
				});
			}
			GUILayout.Space(8f);
			if (GUILayout.Button(new GUIContent((Texture)(object)skin.cross, $"Close ({ModConfig.EditorKey.Value})"), skin.closeButton, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(40f),
				GUILayout.Height(34f)
			}))
			{
				Defer(Close);
			}
			GUILayout.EndHorizontal();
		}

		private void DrawListColumn()
		{
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Invalid comparison between Unknown and I4
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Invalid comparison between Unknown and I4
			//IL_01e9: 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)
			GUILayout.BeginVertical(skin.panel, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(410f),
				GUILayout.ExpandHeight(true)
			});
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (GUILayout.Button($"Priority list   <b>{CountRecognised(framePriority)}</b>", frameNever ? skin.tab : skin.tabActive, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(34f) }))
			{
				editingNever = false;
			}
			if (GUILayout.Button($"Never pick   <b>{CountRecognised(frameNeverList)}</b>", frameNever ? skin.tabActive : skin.tab, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(34f) }))
			{
				editingNever = true;
			}
			GUILayout.EndHorizontal();
			GUILayout.Label(frameNever ? "The mod never stops the chest on these, even if the priority list matches them." : "Top = most wanted. Drag rows by the handle to reorder. The chest stops on the best item of its cycle; anything not listed is never picked.", skin.hint, Array.Empty<GUILayoutOption>());
			GUILayout.Space(4f);
			IReadOnlyList<ListEntry> readOnlyList = (frameNever ? frameNeverList : framePriority);
			listScroll = GUILayout.BeginScrollView(listScroll, false, false, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) });
			if (readOnlyList.Count == 0)
			{
				GUILayout.Space(30f);
				GUILayout.Label(frameNever ? "Nothing here yet.\nRight-click items on the right, or drag them here." : "The list is empty.\nClick items or rarities on the right, or drag them here.", skin.emptyNote, Array.Empty<GUILayoutOption>());
			}
			for (int i = 0; i < readOnlyList.Count; i++)
			{
				DrawRow(readOnlyList, i);
			}
			TrimRowRects(readOnlyList.Count);
			if ((int)Event.current.type == 7)
			{
				DrawDropLine();
			}
			GUILayout.EndScrollView();
			if ((int)Event.current.type != 8)
			{
				listViewport = GUILayoutUtility.GetLastRect();
			}
			GUILayout.Space(6f);
			bool never = frameNever;
			GUI.enabled = readOnlyList.Count > 0;
			if (GUILayout.Button("Clear list", skin.dangerButton, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(32f) }))
			{
				Defer(delegate
				{
					Save(never, new List<ListEntry>());
				});
			}
			GUI.enabled = true;
			GUILayout.EndVertical();
		}

		private void DrawRow(IReadOnlyList<ListEntry> list, int index)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Expected O, but got Unknown
			//IL_013c: 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)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Invalid comparison between Unknown and I4
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Expected O, but got Unknown
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Expected O, but got Unknown
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Expected O, but got Unknown
			//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0329: Expected O, but got Unknown
			//IL_0342: 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_034d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0354: Unknown result type (might be due to invalid IL or missing references)
			//IL_035a: Invalid comparison between Unknown and I4
			//IL_036b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0363: Unknown result type (might be due to invalid IL or missing references)
			ListEntry entry = list[index];
			bool never = frameNever;
			bool num = IsDraggedRow(index);
			Color color = GUI.color;
			if (num)
			{
				GUI.color = new Color(1f, 1f, 1f, 0.3f);
			}
			GUILayout.BeginHorizontal(skin.row, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(42f) });
			Rect rect = GUILayoutUtility.GetRect(18f, 38f, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(18f),
				GUILayout.Height(38f)
			});
			GUILayout.Label(new GUIContent(never ? "–" : (PriorityRules.TryGetListRank(entry, out var rank) ? (rank + 1).ToString() : "?"), "Drag the row to move it"), skin.rowIndex, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(24f),
				GUILayout.Height(38f)
			});
			Rect rect2 = GUILayoutUtility.GetRect(36f, 36f, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(36f),
				GUILayout.Height(36f)
			});
			if ((int)Event.current.type == 7)
			{
				Color color2 = GUI.color;
				GUI.color = new Color(color2.r, color2.g, color2.b, color2.a * 0.5f);
				EditorSkin.DrawCentered(rect, skin.grip);
				GUI.color = color2;
				((Rect)(ref rect2)).y = ((Rect)(ref rect2)).y + 3f;
				DrawEntryIcon(rect2, entry);
			}
			GUILayout.Space(6f);
			GUILayout.Label(new GUIContent(EditorCatalog.Colored(RowTitle(entry), EditorCatalog.ColorOf(entry)), EditorCatalog.TooltipOf(entry)), skin.rowName, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Height(38f),
				GUILayout.ExpandWidth(true)
			});
			GUI.enabled = index > 0;
			if (GUILayout.Button(new GUIContent((Texture)(object)skin.arrowUp, "Move up"), skin.iconButton, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(30f),
				GUILayout.Height(30f)
			}))
			{
				Defer(delegate
				{
					MoveTo(never, index, index - 1);
				});
			}
			GUI.enabled = index < list.Count - 1;
			if (GUILayout.Button(new GUIContent((Texture)(object)skin.arrowDown, "Move down"), skin.iconButton, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(30f),
				GUILayout.Height(30f)
			}))
			{
				Defer(delegate
				{
					MoveTo(never, index, index + 2);
				});
			}
			GUI.enabled = true;
			if (GUILayout.Button(new GUIContent((Texture)(object)skin.cross, "Remove"), skin.removeButton, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(30f),
				GUILayout.Height(30f)
			}))
			{
				Defer(delegate
				{
					RemoveAt(never, index);
				});
			}
			GUILayout.EndHorizontal();
			GUI.color = color;
			Rect lastRect = GUILayoutUtility.GetLastRect();
			if ((int)Event.current.type != 8)
			{
				SetRowRect(index, lastRect);
			}
			HandleRowPress(lastRect, entry, index, never);
		}

		private void DrawCatalogColumn()
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Invalid comparison between Unknown and I4
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Expected O, but got Unknown
			//IL_00b0: 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_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Invalid comparison between Unknown and I4
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.BeginVertical(skin.panel, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.ExpandWidth(true),
				GUILayout.ExpandHeight(true)
			});
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUI.SetNextCo