Decompiled source of Pack Management API v1.2.2

Infiniscryption.PackManager.dll

Decompiled 3 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using DiskCardGame;
using GBC;
using HarmonyLib;
using Infiniscryption.PackManagement.Patchers;
using Infiniscryption.PackManagement.UserInterface;
using InscryptionAPI.Ascension;
using InscryptionAPI.Card;
using InscryptionAPI.Encounters;
using InscryptionAPI.Guid;
using InscryptionAPI.Helpers;
using InscryptionAPI.Regions;
using InscryptionAPI.Saves;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("Infiniscryption.PackManager")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Infinite Inscryption - Pack Manager")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Infiniscryption.PackManager")]
[assembly: AssemblyTitle("Infiniscryption.PackManager")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Infiniscryption.PackManagement
{
	[HarmonyPatch]
	public class EncounterPackInfo : PackInfoBase
	{
		private static Dictionary<Color, Color> ReplacementColors = new Dictionary<Color, Color>
		{
			{
				new Color(0.26171875f, 35f / 128f, 0.19921875f),
				new Color(0.57421875f, 0f, 0f)
			},
			{
				new Color(0.41796875f, 0.44140625f, 0.31640625f),
				new Color(0.78515625f, 0f, 0f)
			},
			{
				new Color(0.83984375f, 113f / 128f, 0.63671875f),
				new Color(51f / 64f, 51f / 64f, 51f / 64f)
			}
		};

		private Sprite _packArt;

		private static readonly Dictionary<string, string> EncounterMap = new Dictionary<string, string>();

		public override Sprite PackArt
		{
			get
			{
				//IL_0085: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)_packArt != (Object)null)
				{
					return _packArt;
				}
				if (!string.IsNullOrEmpty(base.ModPrefix))
				{
					PackInfo packInfo = PackManager.GetPackInfo(base.ModPrefix);
					if ((Object)(object)packInfo.PackArt != (Object)null)
					{
						SetTexture(MakeEncounterSpriteFromPackSprite(packInfo.PackArt));
					}
				}
				else if (base.DefaultPackTemple.HasValue)
				{
					PackInfo defaultPackInfo = PackManager.GetDefaultPackInfo(base.DefaultPackTemple.Value);
					if ((Object)(object)defaultPackInfo.PackArt != (Object)null)
					{
						SetTexture(MakeEncounterSpriteFromPackSprite(defaultPackInfo.PackArt));
					}
				}
				return _packArt;
			}
			protected set
			{
				_packArt = value;
			}
		}

		public IEnumerable<RegionData> Regions
		{
			get
			{
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0020: Invalid comparison between Unknown and I4
				if (base.DefaultPackTemple.HasValue && (int)base.DefaultPackTemple.Value == 0)
				{
					return RegionManager.AllRegionsCopy.Where((RegionData r) => r.IsBaseGameRegion());
				}
				if (!string.IsNullOrEmpty(base.ModPrefix))
				{
					return RegionManager.AllRegionsCopy.Where((RegionData r) => !r.IsBaseGameRegion()).Where(RegionIsValid);
				}
				if (base.IsLeftoversPack)
				{
					List<string> allKnownRegions = (from r in (from pi in PackManager.AllPacks<EncounterPackInfo>()
							where !pi.IsLeftoversPack
							select pi).SelectMany((EncounterPackInfo pi) => pi.Regions)
						select ((Object)r).name).ToList();
					return from r in RegionManager.AllRegionsCopy
						where !r.IsBaseGameRegion()
						where !allKnownRegions.Contains(((Object)r).name)
						select r;
				}
				return new List<RegionData>();
			}
		}

		public IEnumerable<EncounterBlueprintData> Encounters
		{
			get
			{
				//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f2: Invalid comparison between Unknown and I4
				if (base.IsLeftoversPack)
				{
					List<string> allPacked = (from e in (from pi in PackManager.AllPacks<EncounterPackInfo>()
							where !pi.IsLeftoversPack
							select pi).SelectMany((EncounterPackInfo pi) => pi.Encounters)
						select ((Object)e).name).ToList();
					return from r in EncounterManager.AllEncountersCopy
						where !r.IsBaseGameEncounter()
						select r into ebd
						where !allPacked.Contains(((Object)ebd).name)
						select ebd;
				}
				if (base.DefaultPackTemple.HasValue && (int)base.DefaultPackTemple.Value == 0)
				{
					return from ebd in EncounterManager.AllEncountersCopy
						where ebd.IsBaseGameEncounter()
						where GetTemplesFromEncounter(ebd).FirstOrDefault() == base.DefaultPackTemple.Value
						select ebd;
				}
				if (!string.IsNullOrEmpty(base.ModPrefix))
				{
					return EncounterManager.AllEncountersCopy.Where((EncounterBlueprintData ebd) => !ebd.IsBaseGameEncounter()).Where(EncounterIsValid);
				}
				return new List<EncounterBlueprintData>();
			}
		}

		public override IEnumerable<string> ScreenFilteredContents => base.IsBaseGameCardPack ? PackContents : (from e in Encounters
			where GetTemplesFromEncounter(e).Contains(PackManager.ScreenState)
			select ((Object)e).name);

		public override IEnumerable<string> PackContents => Encounters.Select((EncounterBlueprintData e) => ((Object)e).name).Concat(Regions.Select((RegionData r) => ((Object)r).name));

		public override string Key
		{
			get
			{
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				if (base.IsBaseGameCardPack)
				{
					CardTemple value = base.DefaultPackTemple.Value;
					return "Encounter.DiskCardGame.CardTemple." + ((object)(CardTemple)(ref value)).ToString();
				}
				if (base.IsLeftoversPack)
				{
					return "Encounter.PackManager.Leftovers";
				}
				return "Encounter.M=" + base.ModPrefix + ".C=" + base.ModPrefix;
			}
		}

		public override CardInfo IconCard
		{
			get
			{
				List<string> contents = PackContents.ToList();
				List<EncounterBlueprintData> source = EncounterManager.AllEncountersCopy.Where((EncounterBlueprintData ebd) => contents.Contains(((Object)ebd).name)).ToList();
				int num = 0;
				CardInfo result = null;
				foreach (CardInfo item in source.SelectMany((EncounterBlueprintData ebd) => ebd.turns.SelectMany((List<CardBlueprint> cbl) => from cb in cbl
					where (Object)(object)cb.card != (Object)null
					select cb.card)))
				{
					if (item.PowerLevel > num)
					{
						num = item.PowerLevel;
						result = item;
					}
				}
				return result;
			}
		}

		public override float PowerLevel
		{
			get
			{
				List<string> names = ScreenFilteredContents.ToList();
				try
				{
					return (from p in (from ci in EncounterManager.AllEncountersCopy
							where names.Contains(((Object)ci).name)
							where (Object)(object)ci != (Object)null
							select ci).Select(CalcPowerLevel)
						where p > 0f
						select p).Average();
				}
				catch
				{
					return 0f;
				}
			}
		}

		internal EncounterPackInfo(bool isLeftovers)
			: base(isLeftovers)
		{
		}

		internal EncounterPackInfo(CardTemple temple)
			: base(temple)
		{
			//IL_0001: 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_000b: Invalid comparison between Unknown and I4
			if ((int)temple == 2)
			{
				base.ModPrefix = "P03KCM";
			}
		}

		internal EncounterPackInfo(string cardPrefix, PackInfo.PackMetacategory category)
		{
			base.ModPrefix = cardPrefix;
			base.ValidFor = new List<PackInfo.PackMetacategory> { category };
		}

		internal EncounterPackInfo(string cardPrefix)
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			base.ModPrefix = cardPrefix;
			string firstKey = PackContents.FirstOrDefault();
			if (string.IsNullOrEmpty(firstKey))
			{
				base.ValidFor = new List<PackInfo.PackMetacategory> { PackInfo.PackMetacategory.LeshyPack };
				return;
			}
			EncounterBlueprintData val = ((IEnumerable<EncounterBlueprintData>)EncounterManager.AllEncountersCopy).FirstOrDefault((Func<EncounterBlueprintData, bool>)((EncounterBlueprintData e) => ((Object)e).name.Equals(firstKey, StringComparison.InvariantCultureIgnoreCase)));
			if ((Object)(object)val == (Object)null)
			{
				base.ValidFor = new List<PackInfo.PackMetacategory> { PackInfo.PackMetacategory.LeshyPack };
			}
			else
			{
				base.ValidFor = new List<PackInfo.PackMetacategory> { PackInfo.GetTempleDefaultMetacategory(GetTemplesFromEncounter(val).First()) };
			}
		}

		protected override void TryInitializeImpl()
		{
			List<string> list = Encounters.Select((EncounterBlueprintData e) => ((Object)e).name).ToList();
			List<string> list2 = Regions.Select((RegionData e) => ((Object)e).name).ToList();
			if (list == null || list.Count <= 0)
			{
				return;
			}
			AutoGeneratedDescription = $"Contains {list.Count} encounters.";
			if (!string.IsNullOrEmpty(base.ModPrefix))
			{
				try
				{
					PackInfo packInfo = PackManager.GetPackInfo(base.ModPrefix);
					AutoGeneratedDescription = $"Contains {list.Count} encounters from {packInfo.Title}.";
					AutoGeneratedTitle = "Encounters Pack: " + packInfo.Title;
					return;
				}
				catch
				{
				}
			}
			AutoGeneratedTitle = "Encounters Pack: " + base.ModPrefix;
		}

		private static Color ReplaceColor(Color color)
		{
			//IL_0018: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			foreach (KeyValuePair<Color, Color> replacementColor in ReplacementColors)
			{
				if (Mathf.Abs(color.r - replacementColor.Key.r) < 0.05f && Mathf.Abs(color.g - replacementColor.Key.g) < 0.05f && Mathf.Abs(color.b - replacementColor.Key.b) < 0.05f)
				{
					return replacementColor.Value;
				}
			}
			return color;
		}

		private static Texture2D MakeEncounterSpriteFromPackSprite(Sprite target)
		{
			//IL_0039: 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)
			Texture2D val = TextureHelper.DuplicateTexture(target.texture);
			Texture2D imageAsTexture = TextureHelper.GetImageAsTexture("default_encounter.png", typeof(EncounterPackInfo).Assembly, (FilterMode)0);
			for (int i = 1; i < ((Texture)val).width - 1; i++)
			{
				for (int j = 9; j < ((Texture)val).height - 7; j++)
				{
					imageAsTexture.SetPixel(i, j - 1, ReplaceColor(val.GetPixel(i, j)));
				}
			}
			imageAsTexture.Apply();
			return imageAsTexture;
		}

		public static CardTemple GetMostUniqueTempleFromEncounter(EncounterBlueprintData data)
		{
			//IL_001e: 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_0045: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			List<CardTemple> list = GetTemplesFromEncounter(data).Distinct().ToList();
			if (list.Contains((CardTemple)2))
			{
				return (CardTemple)2;
			}
			if (list.Contains((CardTemple)1))
			{
				return (CardTemple)1;
			}
			if (list.Contains((CardTemple)3))
			{
				return (CardTemple)3;
			}
			return (CardTemple)0;
		}

		public static List<CardTemple> GetTemplesFromEncounter(EncounterBlueprintData data)
		{
			return data.turns.SelectMany((List<CardBlueprint> li) => from cb in li
				where (Object)(object)cb.card != (Object)null
				select cb.card.temple).ToList();
		}

		public static Tuple<CardTemple, string> GetModPrefixesFromEncounter(EncounterBlueprintData data)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			CardTemple item = (CardTemple)0;
			string text = string.Empty;
			foreach (CardInfo item2 in data.turns.SelectMany((List<CardBlueprint> li) => from db in li
				where (Object)(object)db.card != (Object)null
				select db.card))
			{
				item = item2.temple;
				if (!CardExtensions.IsBaseGameCard(item2))
				{
					text = CardExtensions.GetModPrefix(item2);
					break;
				}
			}
			if (string.IsNullOrEmpty(text))
			{
				foreach (CardInfo item3 in data.turns.SelectMany((List<CardBlueprint> li) => from db in li
					where (Object)(object)db.replacement != (Object)null
					select db.replacement))
				{
					item = item3.temple;
					if (!CardExtensions.IsBaseGameCard(item3))
					{
						text = CardExtensions.GetModPrefix(item3);
						break;
					}
				}
			}
			return new Tuple<CardTemple, string>(item, text);
		}

		private bool RegionIsValid(RegionData data)
		{
			if (!string.IsNullOrEmpty(base.ModPrefix))
			{
				if (((Object)data).name.StartsWith(base.ModPrefix + "_"))
				{
					return true;
				}
				Part1RegionData val = ((IEnumerable<Part1RegionData>)RegionManager.NewRegions).FirstOrDefault((Func<Part1RegionData, bool>)((Part1RegionData p1r) => ((Object)p1r.Region).name.Equals(((Object)data).name)));
				if (val != null && val.GUID.Equals(base.ModPrefix, StringComparison.InvariantCultureIgnoreCase))
				{
					return true;
				}
			}
			return false;
		}

		private bool EncounterIsValid(EncounterBlueprintData data)
		{
			if (!string.IsNullOrEmpty(base.ModPrefix))
			{
				if (((Object)data).name.StartsWith(base.ModPrefix + "_"))
				{
					return true;
				}
				if (EncounterMap.ContainsKey(((Object)data).name) && EncounterMap[((Object)data).name].Equals(base.ModPrefix, StringComparison.InvariantCultureIgnoreCase))
				{
					return true;
				}
			}
			string prefix = ((Object)data).name.Split(new char[1] { '_' })[0];
			if (PackManager.AllPacks<EncounterPackInfo>().Any((EncounterPackInfo epi) => !string.IsNullOrEmpty(epi.ModPrefix) && epi.ModPrefix.Equals(prefix, StringComparison.InvariantCultureIgnoreCase)))
			{
				return false;
			}
			if (!string.IsNullOrEmpty(base.ModPrefix) && GetModPrefixesFromEncounter(data).Item2.Equals(base.ModPrefix, StringComparison.InvariantCultureIgnoreCase))
			{
				return true;
			}
			return false;
		}

		private static float CalcPowerLevel(EncounterBlueprintData data)
		{
			if ((float)Mathf.Abs(data.PowerLevel) > 0.01f)
			{
				return data.PowerLevel;
			}
			try
			{
				return (float)data.turns.SelectMany((List<CardBlueprint> l) => from cb in l
					where (Object)(object)cb.card != (Object)null
					select cb.card.PowerLevel).Concat(data.turns.SelectMany((List<CardBlueprint> l) => from cb in l
					where (Object)(object)cb.replacement != (Object)null
					select cb.replacement.PowerLevel)).Average();
			}
			catch
			{
				return 0f;
			}
		}

		internal override bool SetOfPacksIsValid(List<PackInfoBase> packs, PackContentCache cache)
		{
			List<string> encounterNames = packs.Cast<EncounterPackInfo>().SelectMany((EncounterPackInfo p) => p.Encounters.Select((EncounterBlueprintData e) => ((Object)e).name)).ToList();
			List<string> regionNames = packs.Cast<EncounterPackInfo>().SelectMany((EncounterPackInfo p) => p.Regions.Select((RegionData e) => ((Object)e).name)).ToList();
			return (from r in RegionManager.AllRegionsCopy
				where regionNames.Contains(((Object)r).name)
				select r.encounters.Where((EncounterBlueprintData e) => encounterNames.Contains(((Object)e).name)).Count() into count
				where count > 0
				select count).Count() >= 3;
		}

		internal override string ReplaceMarkers(string inString, PackContentCache cache)
		{
			int num = Encounters.Count();
			int num2 = Regions.Count();
			string text = ((num == 1) ? "1 encounter" : $"{num} encounters");
			string text2 = ((num2 == 1) ? "1 region" : $"{num2} regions");
			string newValue = text2 + " and " + text;
			if (num == 0 && num2 > 0)
			{
				newValue = text2;
			}
			if (num2 == 0 && num > 0)
			{
				newValue = text;
			}
			return base.ReplaceMarkers(inString, cache).Replace("[encountercount]", text).Replace("[regioncount]", text2)
				.Replace("[summary]", newValue);
		}

		[HarmonyPatch(typeof(EncounterManager), "Add")]
		[HarmonyPrefix]
		private static void CaptureEncounterModGuid(EncounterBlueprintData newEncounter)
		{
			Assembly callingAssembly = Assembly.GetCallingAssembly();
			string modIdFromCallstack = Extensions.GetModIdFromCallstack(callingAssembly);
			if (!string.IsNullOrEmpty(modIdFromCallstack))
			{
				EncounterMap[((Object)newEncounter).name] = modIdFromCallstack;
			}
		}
	}
	public static class Extensions
	{
		private static readonly Dictionary<string, string> ModIds = new Dictionary<string, string>();

		public static bool IsBaseGameEncounter(this EncounterBlueprintData data)
		{
			return EncounterManager.BaseGameEncounters.Any((EncounterBlueprintData bge) => ((Object)bge).name.Equals(((Object)data).name));
		}

		public static bool IsBaseGameRegion(this RegionData data)
		{
			return RegionManager.BaseGameRegions.Any((RegionData bge) => ((Object)bge).name.Equals(((Object)data).name));
		}

		private static string GetModIdFromAssembly(Assembly assembly)
		{
			if (ModIds.ContainsKey(assembly.FullName))
			{
				return ModIds[assembly.FullName];
			}
			Type[] types = assembly.GetTypes();
			foreach (Type element in types)
			{
				foreach (BepInPlugin customAttribute in ((MemberInfo)element).GetCustomAttributes<BepInPlugin>())
				{
					if (customAttribute.GUID == "cyantist.inscryption.api" || customAttribute.GUID == "zorro.inscryption.infiniscryption.packmanager")
					{
						continue;
					}
					ModIds.Add(assembly.FullName, customAttribute.GUID);
					return customAttribute.GUID;
				}
			}
			ModIds.Add(assembly.FullName, null);
			return null;
		}

		internal static string GetModIdFromCallstack(Assembly callingAssembly)
		{
			string modIdFromAssembly = GetModIdFromAssembly(callingAssembly);
			if (!string.IsNullOrEmpty(modIdFromAssembly))
			{
				return modIdFromAssembly;
			}
			StackTrace stackTrace = new StackTrace();
			StackFrame[] frames = stackTrace.GetFrames();
			foreach (StackFrame stackFrame in frames)
			{
				string modIdFromAssembly2 = GetModIdFromAssembly(stackFrame.GetMethod().DeclaringType.Assembly);
				if (!string.IsNullOrEmpty(modIdFromAssembly2))
				{
					return modIdFromAssembly2;
				}
			}
			return null;
		}
	}
	public class PackInfo : PackInfoBase
	{
		public enum PackMetacategory
		{
			LeshyPack,
			P03Pack,
			GrimoraPack,
			MagnificusPack
		}

		public const string JSONLOADER = "MADH.inscryption.JSONLoader";

		public const string TEMPLEINDICATOR = "DiskCardGame.CardTemple.";

		public const string LEFTOVERSINDICATOR = "PackManager.Leftovers";

		public IEnumerable<CardInfo> Cards
		{
			get
			{
				if (base.IsBaseGameCardPack)
				{
					return CardManager.AllCardsCopy.Where((CardInfo ci) => CardExtensions.IsBaseGameCard(ci) && (CardTemple?)ci.temple == base.DefaultPackTemple);
				}
				if (base.IsStandardCardPack)
				{
					return CardManager.AllCardsCopy.Where((CardInfo ci) => base.ModPrefix.Equals(CardExtensions.GetModPrefix(ci)));
				}
				List<string> allKnownPrefixes = (from pi in PackManager.AllPacks<PackInfo>()
					where pi.IsStandardCardPack
					select pi.ModPrefix).ToList();
				return CardManager.AllCardsCopy.Where((CardInfo ci) => !CardExtensions.IsBaseGameCard(ci) && !allKnownPrefixes.Contains(CardExtensions.GetModPrefix(ci)));
			}
		}

		public override IEnumerable<string> PackContents => Cards.Select((CardInfo c) => ((Object)c).name);

		public override IEnumerable<string> ScreenFilteredContents => from ci in Cards
			where ci.CardIsValidForScreenState()
			select ((Object)ci).name;

		public override string Key
		{
			get
			{
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				if (base.IsBaseGameCardPack)
				{
					CardTemple value = base.DefaultPackTemple.Value;
					return "DiskCardGame.CardTemple." + ((object)(CardTemple)(ref value)).ToString();
				}
				if (base.IsLeftoversPack)
				{
					return "PackManager.Leftovers";
				}
				return base.ModPrefix;
			}
		}

		public override CardInfo IconCard
		{
			get
			{
				int num = 0;
				CardInfo result = null;
				List<string> contentCache = PackContents.ToList();
				foreach (CardInfo item in CardManager.AllCardsCopy.Where((CardInfo ci) => contentCache.Contains(((Object)ci).name)))
				{
					if (item.PowerLevel > num)
					{
						num = item.PowerLevel;
						result = item;
					}
				}
				return result;
			}
		}

		public override float PowerLevel
		{
			get
			{
				List<string> names = ScreenFilteredContents.ToList();
				try
				{
					return (float)(from ci in CardManager.AllCardsCopy
						where names.Contains(((Object)ci).name)
						where (Object)(object)ci != (Object)null
						select ci.PowerLevel).Average();
				}
				catch
				{
					return 0f;
				}
			}
		}

		public static PackMetacategory GetTempleDefaultMetacategory(CardTemple temple)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: 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_001b: Expected I4, but got Unknown
			return (int)temple switch
			{
				0 => PackMetacategory.LeshyPack, 
				2 => PackMetacategory.P03Pack, 
				1 => PackMetacategory.GrimoraPack, 
				3 => PackMetacategory.MagnificusPack, 
				_ => PackMetacategory.LeshyPack, 
			};
		}

		internal PackInfo(bool leftovers)
			: base(leftovers)
		{
		}

		internal PackInfo(CardTemple temple)
			: base(temple)
		{
		}//IL_0001: Unknown result type (might be due to invalid IL or missing references)


		internal PackInfo(string modPrefix)
			: base(modPrefix)
		{
		}

		internal PackInfo(string modPrefix, PackMetacategory category)
			: base(modPrefix)
		{
			base.ValidFor = new List<PackMetacategory> { category };
		}

		protected override void TryInitializeImpl()
		{
			List<CardInfo> list = Cards.ToList();
			if (list != null && list.Count > 0)
			{
				string modTag = CardExtensions.GetModTag(list[0]);
				if (!string.IsNullOrEmpty(modTag) && !modTag.Equals("MADH.inscryption.JSONLoader", StringComparison.OrdinalIgnoreCase) && Chainloader.PluginInfos.ContainsKey(modTag))
				{
					PluginInfo val = Chainloader.PluginInfos[modTag];
					AutoGeneratedTitle = val.Metadata.Name;
				}
				else
				{
					AutoGeneratedTitle = "Card Pack: " + base.ModPrefix;
				}
				int count = Math.Min(7, list.Count);
				AutoGeneratedDescription = string.Format("Cards in this pack: {0} and {1} other{2}.", string.Join(", ", from ci in list.Take(count)
					select ci.DisplayedNameLocalized), list.Count - 7, (list.Count - 7 > 1) ? "s" : string.Empty);
			}
		}

		internal override bool SetOfPacksIsValid(List<PackInfoBase> packs, PackContentCache cache)
		{
			return packs.Where((PackInfoBase p) => cache.GetContentsOfPack(p).Count() > 0).Count() > 0;
		}

		private string RandomCardName(List<string> cards)
		{
			CardInfo obj = CardExtensions.CardByName((IEnumerable<CardInfo>)CardManager.AllCardsCopy, cards[Random.Range(0, cards.Count)]);
			return ((obj != null) ? obj.DisplayedNameLocalized : null) ?? "";
		}

		private string ReplaceRandom(string text, PackContentCache cache)
		{
			List<string> contentsOfPack = cache.GetContentsOfPack(this);
			while (true)
			{
				int num = text.IndexOf("[randomcard]");
				if (num < 0)
				{
					break;
				}
				text = text.Substring(0, num) + RandomCardName(contentsOfPack) + text.Substring(num + 12);
			}
			return text;
		}

		internal override string ReplaceMarkers(string inString, PackContentCache cache)
		{
			return ReplaceRandom(base.ReplaceMarkers(inString, cache), cache);
		}
	}
	public abstract class PackInfoBase
	{
		private string _title;

		protected string AutoGeneratedTitle;

		private string _description;

		protected string AutoGeneratedDescription;

		public CardTemple? DefaultPackTemple { get; protected set; }

		public string ModPrefix { get; protected set; }

		public bool SplitPackByCardTemple { get; set; } = false;


		public bool IsLeftoversPack { get; protected set; }

		public bool IsBaseGameCardPack => DefaultPackTemple.HasValue;

		public bool IsStandardCardPack => !DefaultPackTemple.HasValue && !IsLeftoversPack;

		protected bool initialized { get; private set; } = false;


		public virtual string Title
		{
			get
			{
				if (!string.IsNullOrEmpty(_title))
				{
					return Localization.Translate(_title);
				}
				if (!initialized)
				{
					TryInitialize();
				}
				return Localization.Translate(AutoGeneratedTitle);
			}
			set
			{
				_title = value;
			}
		}

		public string Description
		{
			get
			{
				if (!string.IsNullOrEmpty(_description))
				{
					return Localization.Translate(_description);
				}
				if (!initialized)
				{
					TryInitialize();
				}
				return Localization.Translate(AutoGeneratedDescription);
			}
			set
			{
				_description = value;
			}
		}

		public virtual Sprite PackArt { get; protected set; }

		public List<PackInfo.PackMetacategory> ValidFor { get; set; }

		public abstract IEnumerable<string> PackContents { get; }

		public virtual IEnumerable<string> ScreenFilteredContents => PackContents;

		public abstract string Key { get; }

		public abstract CardInfo IconCard { get; }

		public abstract float PowerLevel { get; }

		protected PackInfoBase()
		{
		}

		internal PackInfoBase(CardTemple temple)
		{
			//IL_0017: 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)
			DefaultPackTemple = temple;
			ValidFor = new List<PackInfo.PackMetacategory> { PackInfo.GetTempleDefaultMetacategory(temple) };
		}

		internal PackInfoBase(string modPrefix)
		{
			ModPrefix = modPrefix;
			ValidFor = new List<PackInfo.PackMetacategory>
			{
				PackInfo.PackMetacategory.P03Pack,
				PackInfo.PackMetacategory.LeshyPack,
				PackInfo.PackMetacategory.MagnificusPack,
				PackInfo.PackMetacategory.GrimoraPack
			};
		}

		internal PackInfoBase(bool leftovers)
		{
			if (!leftovers)
			{
				throw new InvalidOperationException("Can only use bool constructor if bool is true.");
			}
			IsLeftoversPack = leftovers;
			ValidFor = new List<PackInfo.PackMetacategory>
			{
				PackInfo.PackMetacategory.GrimoraPack,
				PackInfo.PackMetacategory.MagnificusPack,
				PackInfo.PackMetacategory.P03Pack,
				PackInfo.PackMetacategory.LeshyPack
			};
		}

		protected void TryInitialize()
		{
			if (!initialized)
			{
				TryInitializeImpl();
			}
		}

		protected abstract void TryInitializeImpl();

		public void SetTexture(Texture2D t)
		{
			//IL_001f: 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)
			((Texture)t).filterMode = (FilterMode)0;
			PackArt = Sprite.Create(t, new Rect(0f, 0f, 46f, 74f), new Vector2(0.5f, 0.5f));
			((Object)PackArt).name = ((Object)t).name + "_sprite";
		}

		internal abstract bool SetOfPacksIsValid(List<PackInfoBase> packs, PackContentCache cache);

		internal virtual string ReplaceMarkers(string inString, PackContentCache cache)
		{
			return (inString ?? "").Replace("[count]", cache.GetContentsOfPack(this).Count.ToString()).Replace("[name]", Title).Replace("[powerlevel]", Math.Round(cache.GetPowerLevel(this), 2).ToString());
		}
	}
	[HarmonyPatch]
	public static class PackManager
	{
		private static List<CardMetaCategory> protectedMetacategories;

		private static List<AbilityMetaCategory> protectedAbilityMetacategories;

		private const string GRIMORA_MOD = "arackulele.inscryption.grimoramod";

		private const string P03_MOD = "zorro.inscryption.infiniscryption.p03kayceerun";

		private const string MAGNIFICUS_MOD = "silenceman.inscryption.magnificusmod";

		private static readonly CardMetaCategory GRIMORA_CHOICE_NODE;

		public static Dictionary<CardTemple, List<CardMetaCategory>> TempleMetacategories;

		internal static Dictionary<string, List<PackInfoBase>> AllPacksOfType;

		private static HashSet<string> ActiveCards;

		private static HashSet<Ability> ActiveAbilities;

		internal static Dictionary<string, string> AcceptedScreenStates;

		private static bool HasAddedFiltersToEvent;

		private static bool ShouldFilterCards;

		public static IEnumerable<PackInfo> AllRegisteredPacks => AllPacks<PackInfo>().InScreenOrder();

		internal static CardTemple ScreenState
		{
			get
			{
				//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_0038: 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_0125: Unknown result type (might be due to invalid IL or missing references)
				//IL_006a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0121: Unknown result type (might be due to invalid IL or missing references)
				//IL_0083: Unknown result type (might be due to invalid IL or missing references)
				//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
				//IL_0102: Unknown result type (might be due to invalid IL or missing references)
				Scene activeScene = SceneManager.GetActiveScene();
				if (!string.IsNullOrEmpty(((Scene)(ref activeScene)).name))
				{
					string text = ((Scene)(ref activeScene)).name.ToLowerInvariant();
					if (text.Contains("magnificus"))
					{
						return (CardTemple)3;
					}
					if (text.Contains("part3"))
					{
						return (CardTemple)2;
					}
					if (text.Contains("grimora"))
					{
						return (CardTemple)1;
					}
					if (text.Contains("part1"))
					{
						return (CardTemple)0;
					}
				}
				foreach (string key in AcceptedScreenStates.Keys)
				{
					if (Chainloader.PluginInfos.ContainsKey(key))
					{
						string value = ModdedSaveManager.SaveData.GetValue(AcceptedScreenStates[key], "ScreenState");
						if (!string.IsNullOrEmpty(value))
						{
							return (CardTemple)Enum.Parse(typeof(CardTemple), value);
						}
					}
				}
				return (CardTemple)0;
			}
		}

		public static void AddProtectedMetacategory(CardMetaCategory category)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			protectedMetacategories.Add(category);
		}

		public static void AddProtectedMetacategory(AbilityMetaCategory category)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			protectedAbilityMetacategories.Add(category);
		}

		static PackManager()
		{
			//IL_0046: 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_034f: Unknown result type (might be due to invalid IL or missing references)
			protectedMetacategories = new List<CardMetaCategory>();
			protectedAbilityMetacategories = new List<AbilityMetaCategory>
			{
				(AbilityMetaCategory)0,
				(AbilityMetaCategory)2,
				(AbilityMetaCategory)5,
				(AbilityMetaCategory)6,
				(AbilityMetaCategory)4
			};
			GRIMORA_CHOICE_NODE = GuidManager.GetEnumValue<CardMetaCategory>("arackulele.inscryption.grimoramod", "GrimoraModChoiceNode");
			AllPacksOfType = new Dictionary<string, List<PackInfoBase>>();
			ActiveCards = new HashSet<string>();
			ActiveAbilities = new HashSet<Ability>();
			AcceptedScreenStates = new Dictionary<string, string>
			{
				{ "zorro.inscryption.infiniscryption.p03kayceerun", "zorro.inscryption.infiniscryption.p03kayceerun" },
				{ "arackulele.inscryption.grimoramod", "arackulele.inscryption.grimoramod" },
				{ "silenceman.inscryption.magnificusmod", "silenceman.inscryption.magnificusmodstarterdecks" }
			};
			HasAddedFiltersToEvent = false;
			ShouldFilterCards = false;
			PackInfo packInfo = new PackInfo((CardTemple)0);
			packInfo.Title = "Inscryption: Beastly Card Expansion Pack";
			packInfo.Description = "The original set of cards featured in Leshy's cabin. Featuring wolves, mantises, and the occasional cockroach.";
			packInfo.SetTexture(TextureHelper.GetImageAsTexture("beastly.png", typeof(PackManager).Assembly, (FilterMode)0));
			AddPack(packInfo);
			PackInfo packInfo2 = new PackInfo((CardTemple)2);
			packInfo2.Title = "Inscryption: Techno Card Expansion Pack";
			packInfo2.Description = "The original set of robotic cards, exclusively using the energy mechanic.";
			packInfo2.SetTexture(TextureHelper.GetImageAsTexture("tech.png", typeof(PackManager).Assembly, (FilterMode)0));
			AddPack(packInfo2);
			PackInfo packInfo3 = new PackInfo((CardTemple)1);
			packInfo3.Title = "Inscryption: Undead Card Expansion Pack";
			packInfo3.Description = "Powered by the bones of the dead, these cards have come back from the grave to fight for you.";
			packInfo3.SetTexture(TextureHelper.GetImageAsTexture("undead.png", typeof(PackManager).Assembly, (FilterMode)0));
			AddPack(packInfo3);
			PackInfo packInfo4 = new PackInfo((CardTemple)3);
			packInfo4.Title = "Inscryption: Magickal Card Expansion Pack";
			packInfo4.Description = "Harness the might of the moxen to summon forth apprentices and fight in the most honorable of duels.";
			packInfo4.SetTexture(TextureHelper.GetImageAsTexture("wizard.png", typeof(PackManager).Assembly, (FilterMode)0));
			AddPack(packInfo4);
			PackInfo packInfo5 = new PackInfo(leftovers: true);
			packInfo5.Title = "Miscellaneous Community Cards";
			packInfo5.Description = "The unusual, unsorted, and unruly cards that have been added by mods but not properly sorted into packs.";
			packInfo5.SetTexture(TextureHelper.GetImageAsTexture("leftovers.png", typeof(PackManager).Assembly, (FilterMode)0));
			AddPack(packInfo5);
			AddPack(new EncounterPackInfo((CardTemple)0)
			{
				Title = "Inscryption: Beastly Encounters",
				Description = "The original set of [summary] that Leshy has carefully curated for the ideal gaming experience."
			});
			EncounterPackInfo encounterPackInfo = new EncounterPackInfo(isLeftovers: true);
			encounterPackInfo.Title = "Unsorted Regions and Encounters";
			encounterPackInfo.Description = "These [summary] have been added by mods but not properly sorted into packs.";
			encounterPackInfo.SetTexture(TextureHelper.GetImageAsTexture("leftovers_encounters.png", typeof(PackManager).Assembly, (FilterMode)0));
			AddPack(encounterPackInfo);
			AddPack(new EncounterPackInfo((CardTemple)2)
			{
				ValidFor = new List<PackInfo.PackMetacategory> { PackInfo.PackMetacategory.P03Pack }
			});
			TempleMetacategories = new Dictionary<CardTemple, List<CardMetaCategory>>();
			TempleMetacategories.Add((CardTemple)0, new List<CardMetaCategory>
			{
				(CardMetaCategory)0,
				(CardMetaCategory)1,
				(CardMetaCategory)3
			});
			TempleMetacategories.Add((CardTemple)2, new List<CardMetaCategory>
			{
				(CardMetaCategory)0,
				(CardMetaCategory)2,
				(CardMetaCategory)3
			});
			TempleMetacategories.Add((CardTemple)3, new List<CardMetaCategory>
			{
				(CardMetaCategory)0,
				(CardMetaCategory)3
			});
			TempleMetacategories.Add((CardTemple)1, new List<CardMetaCategory>
			{
				(CardMetaCategory)0,
				(CardMetaCategory)3,
				GRIMORA_CHOICE_NODE
			});
		}

		public static IEnumerable<T> InScreenOrder<T>(this IEnumerable<T> packs) where T : PackInfoBase
		{
			return packs.Where((T pi) => pi.IsBaseGameCardPack).Concat(packs.Where((T pi) => pi.IsStandardCardPack)).Concat(packs.Where((T pi) => pi.IsLeftoversPack));
		}

		internal static IEnumerable<PackInfoBase> AllPacks(Type type)
		{
			string name = type.Name;
			if (!AllPacksOfType.ContainsKey(name))
			{
				AllPacksOfType.Add(name, new List<PackInfoBase>());
			}
			return AllPacksOfType[name];
		}

		internal static IEnumerable<T> AllPacks<T>() where T : PackInfoBase
		{
			return AllPacks(typeof(T)).Cast<T>();
		}

		internal static void AddPackByType(Type type, PackInfoBase pack)
		{
			string name = type.Name;
			if (!AllPacksOfType.ContainsKey(name))
			{
				AllPacksOfType.Add(name, new List<PackInfoBase>());
			}
			AllPacksOfType[name].Add(pack);
		}

		internal static void AddPack<T>(T pack) where T : PackInfoBase
		{
			AddPackByType(typeof(T), pack);
		}

		public static PackInfo GetDefaultPackInfo(CardTemple temple)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			return AllPacks<PackInfo>().FirstOrDefault((PackInfo pi) => pi.DefaultPackTemple == (CardTemple?)temple);
		}

		public static T GetDefaultPackInfo<T>(CardTemple temple) where T : PackInfoBase
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			return AllPacks<T>().FirstOrDefault((T pi) => pi.DefaultPackTemple == (CardTemple?)temple);
		}

		[Obsolete]
		public static PackInfo GetPackInfo(string modPrefix)
		{
			PackInfo packInfo = AllPacks<PackInfo>().FirstOrDefault((PackInfo pi) => pi.IsStandardCardPack && modPrefix.Equals(pi.ModPrefix));
			if (packInfo == null)
			{
				packInfo = new PackInfo(modPrefix, PackInfo.PackMetacategory.LeshyPack);
				AddPack(packInfo);
			}
			return packInfo;
		}

		internal static PackInfoBase GetPackInfo(Type type, string modPrefix)
		{
			PackInfoBase packInfoBase = AllPacks(type).FirstOrDefault((PackInfoBase pi) => pi.IsStandardCardPack && modPrefix.Equals(pi.ModPrefix));
			if (packInfoBase == null)
			{
				packInfoBase = (PackInfoBase)Activator.CreateInstance(type, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new object[1] { modPrefix }, CultureInfo.InvariantCulture);
				AddPack(packInfoBase);
			}
			return packInfoBase;
		}

		public static T GetPackInfo<T>(string modPrefix) where T : PackInfoBase
		{
			T val = AllPacks<T>().FirstOrDefault((T pi) => pi.IsStandardCardPack && modPrefix.Equals(pi.ModPrefix));
			if (val == null)
			{
				val = (T)Activator.CreateInstance(typeof(T), BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new object[1] { modPrefix }, CultureInfo.InvariantCulture);
				AddPack(val);
			}
			return val;
		}

		internal static T GetEstablishedPackInfo<T>(string modPrefix, PackInfo.PackMetacategory category) where T : PackInfoBase
		{
			T val = AllPacks<T>().FirstOrDefault((T pi) => !string.IsNullOrEmpty(pi.ModPrefix) && pi.ModPrefix.Equals(modPrefix, StringComparison.InvariantCultureIgnoreCase));
			if (val == null)
			{
				val = (T)Activator.CreateInstance(typeof(T), BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new object[1] { modPrefix }, CultureInfo.InvariantCulture);
				val.ValidFor = new List<PackInfo.PackMetacategory> { category };
				AddPack(val);
			}
			return val;
		}

		internal static PackInfo GetEstablishedPackInfo(string modPrefix)
		{
			PackInfo packInfo = AllPacks<PackInfo>().FirstOrDefault((PackInfo pi) => pi.IsStandardCardPack && modPrefix.Equals(pi.ModPrefix));
			if (packInfo == null)
			{
				packInfo = new PackInfo(modPrefix, PackInfo.PackMetacategory.LeshyPack);
				packInfo.ValidFor.Add(PackInfo.PackMetacategory.P03Pack);
				packInfo.ValidFor.Add(PackInfo.PackMetacategory.MagnificusPack);
				packInfo.ValidFor.Add(PackInfo.PackMetacategory.GrimoraPack);
				packInfo.SplitPackByCardTemple = true;
				AddPack(packInfo);
			}
			return packInfo;
		}

		[Obsolete]
		public static PackInfo GetLeftoversPack()
		{
			return AllPacks<PackInfo>().FirstOrDefault((PackInfo pi) => pi.IsLeftoversPack);
		}

		public static T GetLeftoversPack<T>() where T : PackInfoBase
		{
			return AllPacks<T>().FirstOrDefault((T pi) => pi.IsLeftoversPack);
		}

		internal static void ForceSyncOfAllPacks()
		{
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			foreach (IGrouping<string, CardInfo> item in from ci in CardManager.AllCardsCopy
				where !CardExtensions.IsBaseGameCard(ci)
				group ci by CardExtensions.GetModPrefix(ci))
			{
				if (!string.IsNullOrEmpty(item.Key) && item.Count() > 5)
				{
					GetEstablishedPackInfo(item.Key);
				}
			}
			PackPlugin.Log.LogInfo((object)"Looking for encounters");
			foreach (EncounterBlueprintData item2 in EncounterManager.NewEncounters.Where((EncounterBlueprintData e) => (from epi in AllPacks<EncounterPackInfo>()
				where !epi.IsLeftoversPack
				select epi).FirstOrDefault((EncounterPackInfo epi) => epi.PackContents.Contains(((Object)e).name)) == null).ToList())
			{
				PackPlugin.Log.LogInfo((object)("Found unpacked encounter " + ((Object)item2).name));
				Tuple<CardTemple, string> modPrefixesFromEncounter = EncounterPackInfo.GetModPrefixesFromEncounter(item2);
				if (!string.IsNullOrEmpty(modPrefixesFromEncounter.Item2))
				{
					EncounterPackInfo establishedPackInfo = GetEstablishedPackInfo<EncounterPackInfo>(modPrefixesFromEncounter.Item2, PackInfo.GetTempleDefaultMetacategory(modPrefixesFromEncounter.Item1));
					PackPlugin.Log.LogInfo((object)("Established pack " + establishedPackInfo.Title));
				}
			}
		}

		internal static bool CardIsValidForScreenState(this CardInfo info)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//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)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				int powerLevel = info.PowerLevel;
				foreach (CardMetaCategory item in TempleMetacategories[ScreenState])
				{
					if (info.metaCategories.Contains(item))
					{
						return true;
					}
				}
				return false;
			}
			catch (Exception ex)
			{
				PackPlugin.Log.LogError((object)("Error checking " + ((Object)info).name));
				PackPlugin.Log.LogError((object)ex);
				return false;
			}
		}

		internal static void SavePackList(Type type, IEnumerable<PackInfoBase> packs, bool activeList, CardTemple state = 0)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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_0044: Invalid comparison between Unknown and I4
			//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)
			if (activeList)
			{
				SavePackList(type, InvertPackList(type, packs.ToList(), state), activeList: false, state);
				return;
			}
			string text = ((type == typeof(PackInfo)) ? "" : type.Name);
			if ((int)state == 0)
			{
				state = ScreenState;
			}
			string text2 = string.Join("|", packs.Select((PackInfoBase pi) => pi.Key));
			string text3 = (activeList ? (text + ((object)(CardTemple)(ref state)).ToString() + "_ActivePackList") : (text + ((object)(CardTemple)(ref state)).ToString() + "_InactivePackList"));
			ModdedSaveManager.SaveData.SetValue("zorro.inscryption.infiniscryption.packmanager", text3, (object)text2);
		}

		internal static void SavePackList<T>(List<T> packs, bool activeList, CardTemple state = 0) where T : PackInfoBase
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			SavePackList(typeof(T), packs.Cast<PackInfoBase>(), activeList, state);
		}

		internal static List<PackInfoBase> InvertPackList(Type type, List<PackInfoBase> packList, CardTemple state)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Invalid comparison between Unknown and I4
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: 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)
			if ((int)state == 0)
			{
				state = ScreenState;
			}
			PackInfo.PackMetacategory valid = PackInfo.GetTempleDefaultMetacategory(state);
			return (from p in AllPacks(type)
				where p.ValidFor.Contains(valid)
				select p into p1
				where !packList.Any((PackInfoBase p2) => p1.Key.Equals(p2.Key))
				select p1).ToList();
		}

		internal static List<PackInfoBase> RetrievePackList(Type type, bool activeList, CardTemple state = 0)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Invalid comparison between Unknown and I4
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			if (activeList)
			{
				return InvertPackList(type, RetrievePackList(type, activeList: false, state), state);
			}
			string text = ((type == typeof(PackInfo)) ? "" : type.Name);
			if ((int)state == 0)
			{
				state = ScreenState;
			}
			string text2 = (activeList ? (text + ((object)(CardTemple)(ref state)).ToString() + "_ActivePackList") : (text + ((object)(CardTemple)(ref state)).ToString() + "_InactivePackList"));
			string value = ModdedSaveManager.SaveData.GetValue("zorro.inscryption.infiniscryption.packmanager", text2);
			if (value == null)
			{
				if (activeList)
				{
					return (from pi in AllPacks(type)
						where pi.ValidFor.Contains(PackInfo.GetTempleDefaultMetacategory(state))
						select pi).ToList();
				}
				return new List<PackInfoBase>();
			}
			return (from k in value.Split(new char[1] { '|' })
				select AllPacks(type).FirstOrDefault((PackInfoBase pi) => pi.Key == k) into pi
				where pi != null
				select pi).ToList();
		}

		internal static List<T> RetrievePackList<T>(bool activeList, CardTemple state = 0) where T : PackInfoBase
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			return RetrievePackList(typeof(T), activeList, state).Cast<T>().ToList();
		}

		[Obsolete]
		public static List<PackInfo> GetActivePacks()
		{
			return RetrievePackList<PackInfo>(activeList: true, (CardTemple)0);
		}

		public static List<T> GetActivePacks<T>() where T : PackInfoBase
		{
			return RetrievePackList<T>(activeList: true, (CardTemple)0);
		}

		internal static List<CardInfo> FilterCardsInPacks(List<CardInfo> cards)
		{
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: 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_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)
			//IL_02a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02af: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0327: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0333: 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_03ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cc: Unknown result type (might be due to invalid IL or missing references)
			if (!ShouldFilterCards)
			{
				return cards;
			}
			List<PackInfo> list = RetrievePackList<PackInfo>(activeList: true, (CardTemple)0);
			string text = string.Join(", ", list.Select((PackInfo ap) => ap.Title));
			PackPlugin.Log.LogDebug((object)("Active packs are " + text));
			ActiveCards = new HashSet<string>();
			ActiveAbilities = new HashSet<Ability>();
			foreach (PackInfo item in list)
			{
				List<CardInfo> list2 = item.Cards.ToList();
				PackPlugin.Log.LogDebug((object)$"Evaluating pack {item.Title} with {list2.Count}; split by temple {item.SplitPackByCardTemple}. Temple is {ScreenState}");
				if (item.SplitPackByCardTemple)
				{
					list2 = list2.Where((CardInfo ci) => ci.temple == ScreenState).ToList();
				}
				foreach (string item2 in list2.Select((CardInfo ci) => ((Object)ci).name))
				{
					ActiveCards.Add(item2);
				}
			}
			foreach (CardInfo card in cards)
			{
				if (ActiveCards.Contains(((Object)card).name))
				{
					PackPlugin.Log.LogDebug((object)$"{((Object)card).name} is in an active pack; setting temple to {ScreenState}");
					CardExtensions.SetExtendedProperty(card, "PackManager.OriginalTemple", (object)card.temple);
					card.temple = ScreenState;
				}
				else
				{
					PackPlugin.Log.LogDebug((object)(((Object)card).name + " is NOT in an active pack; clearing metacategories"));
					card.metaCategories = new List<CardMetaCategory>(card.metaCategories.Where((CardMetaCategory c) => protectedMetacategories.Contains(c)));
				}
				if (!ActiveCards.Contains(((Object)card).name))
				{
					continue;
				}
				foreach (Ability ability in card.Abilities)
				{
					if (!ActiveAbilities.Contains(ability))
					{
						ActiveAbilities.Add(ability);
					}
				}
				if (card.iceCubeParams != null && (Object)(object)card.iceCubeParams.creatureWithin != (Object)null)
				{
					foreach (Ability ability2 in card.iceCubeParams.creatureWithin.Abilities)
					{
						if (!ActiveAbilities.Contains(ability2))
						{
							ActiveAbilities.Add(ability2);
						}
					}
				}
				if (card.evolveParams == null || !((Object)(object)card.evolveParams.evolution != (Object)null))
				{
					continue;
				}
				foreach (Ability ability3 in card.evolveParams.evolution.Abilities)
				{
					if (!ActiveAbilities.Contains(ability3))
					{
						ActiveAbilities.Add(ability3);
					}
				}
			}
			PackPlugin.Log.LogInfo((object)$"The final card pool has {ActiveCards.Count} cards and {ActiveAbilities.Count} abilities");
			return cards;
		}

		private static AbilityMetaCategory GetRulebookMetacategory(this CardTemple temple)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Invalid comparison between Unknown and I4
			//IL_000a: 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_001b: Invalid comparison between Unknown and I4
			//IL_0016: 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_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Invalid comparison between Unknown and I4
			//IL_0022: 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_0030: Unknown result type (might be due to invalid IL or missing references)
			if ((int)temple == 0)
			{
				return (AbilityMetaCategory)0;
			}
			if ((int)temple == 2)
			{
				return (AbilityMetaCategory)2;
			}
			if ((int)temple == 3)
			{
				return (AbilityMetaCategory)6;
			}
			if ((int)temple == 1)
			{
				return (AbilityMetaCategory)5;
			}
			return (AbilityMetaCategory)0;
		}

		internal static List<FullAbility> FilterAbilitiesInPacks(List<FullAbility> abilities)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Expected I4, but got Unknown
			if (!ShouldFilterCards)
			{
				return abilities;
			}
			foreach (FullAbility ability in abilities)
			{
				if (!ActiveAbilities.Contains(ability.Id))
				{
					ability.Info.metaCategories = new List<AbilityMetaCategory>(ability.Info.metaCategories.Where((AbilityMetaCategory c) => protectedAbilityMetacategories.Contains(c)));
				}
				else
				{
					ability.Info.metaCategories = new List<AbilityMetaCategory>(ability.Info.metaCategories);
					AbilityExtensions.AddMetaCategories(ability.Info, (AbilityMetaCategory[])(object)new AbilityMetaCategory[1] { (AbilityMetaCategory)(int)ScreenState.GetRulebookMetacategory() });
				}
			}
			return abilities;
		}

		private static bool EncounterValid(EncounterBlueprintData data, List<EncounterPackInfo> packs)
		{
			if (!PackPlugin.Instance.ToggleEncounters)
			{
				return true;
			}
			if (PackPlugin.Instance.EncounterPackManagementBeta)
			{
				return packs.Any((EncounterPackInfo epi) => epi.PackContents.Contains(((Object)data).name));
			}
			foreach (CardInfo item in from ci in (from cb in data.turns.SelectMany((List<CardBlueprint> l) => l)
					select cb.card).Concat(from cb in data.turns.SelectMany((List<CardBlueprint> l) => l)
					select cb.replacement).Concat(data.randomReplacementCards)
				where (Object)(object)ci != (Object)null
				select ci)
			{
				if (!ActiveCards.Contains(((Object)item).name) && (PackPlugin.Instance.RemoveDefaultEncounters || !CardExtensions.IsBaseGameCard(item)))
				{
					return false;
				}
			}
			return true;
		}

		private static bool EncounterAllDefault(EncounterBlueprintData data)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			if (PackPlugin.Instance.EncounterPackManagementBeta)
			{
				EncounterPackInfo defaultPackInfo = GetDefaultPackInfo<EncounterPackInfo>(EncounterPackInfo.GetMostUniqueTempleFromEncounter(data));
				int num = 0;
				foreach (string packContent in defaultPackInfo.PackContents)
				{
					num++;
					if (packContent.Equals(((Object)data).name, StringComparison.InvariantCultureIgnoreCase))
					{
						return true;
					}
				}
				if (num > 0)
				{
					return false;
				}
			}
			foreach (CardInfo item in from ci in (from cb in data.turns.SelectMany((List<CardBlueprint> l) => l)
					select cb.card).Concat(from cb in data.turns.SelectMany((List<CardBlueprint> l) => l)
					select cb.replacement).Concat(data.randomReplacementCards)
				where (Object)(object)ci != (Object)null
				select ci)
			{
				if (!CardExtensions.IsBaseGameCard(item))
				{
					return false;
				}
			}
			return true;
		}

		internal static bool RegionIsValid(RegionData data, List<EncounterPackInfo> packs)
		{
			if (((Object)data).name.StartsWith("Midnight") || ((Object)data).name.Equals("Pirateville"))
			{
				return true;
			}
			return packs.Any((EncounterPackInfo p) => p.Regions.Any((RegionData r) => ((Object)r).name.Equals(((Object)data).name)));
		}

		internal static List<RegionData> FilterEncountersInRegions(List<RegionData> regions)
		{
			if (ShouldFilterCards)
			{
				List<EncounterPackInfo> ActiveEncounterPacks = GetActivePacks<EncounterPackInfo>();
				string text = string.Join(", ", ActiveEncounterPacks.Select((EncounterPackInfo p) => p.Title));
				PackPlugin.Log.LogInfo((object)("Filtering regions with packs " + text));
				regions.RemoveAll((RegionData r) => !RegionIsValid(r, ActiveEncounterPacks));
				foreach (RegionData region in regions)
				{
					int count = region.encounters.Count;
					List<EncounterBlueprintData> list = region.encounters.Where((EncounterBlueprintData bp) => EncounterValid(bp, ActiveEncounterPacks)).ToList();
					if (list.Count == 0 && !PackPlugin.Instance.EncounterPackManagementBeta)
					{
						list = region.encounters.Where((EncounterBlueprintData bp) => EncounterAllDefault(bp)).ToList();
						PackPlugin.Log.LogInfo((object)$"Region {((Object)region).name} started with {count} encounters. Filtered to zero by active packs; resetting to default encounters. There are now {list.Count} encounters.");
					}
					else
					{
						PackPlugin.Log.LogInfo((object)$"Region {((Object)region).name} started with {count} encounters. Filtered to {list.Count} by active packs.");
					}
					string text2 = string.Join(", ", list.Select((EncounterBlueprintData bp) => ((Object)bp).name));
					PackPlugin.Log.LogInfo((object)("Region " + ((Object)region).name + " has these encounters: " + text2));
					region.encounters = list;
				}
			}
			return regions;
		}

		[HarmonyPatch(typeof(AscensionMenuScreens), "TransitionToGame")]
		[HarmonyPrefix]
		internal static void FilterCardAndAbilityList()
		{
			PackPlugin.Log.LogInfo((object)"Filtering card list");
			if (!HasAddedFiltersToEvent)
			{
				CardManager.ModifyCardList += FilterCardsInPacks;
				AbilityManager.ModifyAbilityList += FilterAbilitiesInPacks;
				RegionManager.ModifyRegionsList += FilterEncountersInRegions;
				HasAddedFiltersToEvent = true;
			}
			ShouldFilterCards = true;
			CardManager.SyncCardList();
			AbilityManager.SyncAbilityList();
			RegionManager.SyncRegionList();
		}

		[HarmonyPatch(typeof(AscensionMenuScreens), "Start")]
		[HarmonyPrefix]
		internal static void UnfilterCardAndAbilityList()
		{
			PackPlugin.Log.LogInfo((object)"Unfiltering card list");
			JSONLoader.LoadFromJSON();
			ForceSyncOfAllPacks();
			ShouldFilterCards = false;
			CardManager.SyncCardList();
			AbilityManager.SyncAbilityList();
			RegionManager.SyncRegionList();
		}
	}
	[BepInPlugin("zorro.inscryption.infiniscryption.packmanager", "Infiniscryption Pack Manager", "1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class PackPlugin : BaseUnityPlugin
	{
		public static readonly CardMetaCategory NeutralRegion = GuidManager.GetEnumValue<CardMetaCategory>("zorro.inscryption.infiniscryption.p03kayceerun", "NeutralRegionCards");

		public static readonly CardMetaCategory WizardRegion = GuidManager.GetEnumValue<CardMetaCategory>("zorro.inscryption.infiniscryption.p03kayceerun", "WizardRegionCards");

		public static readonly CardMetaCategory TechRegion = GuidManager.GetEnumValue<CardMetaCategory>("zorro.inscryption.infiniscryption.p03kayceerun", "TechRegionCards");

		public static readonly CardMetaCategory NatureRegion = GuidManager.GetEnumValue<CardMetaCategory>("zorro.inscryption.infiniscryption.p03kayceerun", "NatureRegionCards");

		public static readonly CardMetaCategory UndeadRegion = GuidManager.GetEnumValue<CardMetaCategory>("zorro.inscryption.infiniscryption.p03kayceerun", "UndeadRegionCards");

		public const string PluginGuid = "zorro.inscryption.infiniscryption.packmanager";

		public const string PluginName = "Infiniscryption Pack Manager";

		public const string PluginVersion = "1.0";

		internal static ManualLogSource Log;

		internal static PackPlugin Instance;

		internal bool ToggleEncounters => ((BaseUnityPlugin)this).Config.Bind<bool>("EncounterManagement", "ToggleEncounters", true, new ConfigDescription("If true, toggling off a card pack will also remove all encounters from the encounter pool that use cards in that pack.", (AcceptableValueBase)null, Array.Empty<object>())).Value;

		internal bool EncounterPackManagementBeta => ((BaseUnityPlugin)this).Config.Bind<bool>("EncounterManagement", "EncounterPackManagementBeta", true, new ConfigDescription("If true, activates the beta version of the Encounter Pack screen", (AcceptableValueBase)null, Array.Empty<object>())).Value;

		internal bool RemoveDefaultEncounters => ((BaseUnityPlugin)this).Config.Bind<bool>("EncounterManagement", "RemoveDefaultEncounters", false, new ConfigDescription("If true, toggling off the 'default' card pack will remove default encounters from the pool.", (AcceptableValueBase)null, Array.Empty<object>())).Value;

		internal bool CrossOverAllPacks => ((BaseUnityPlugin)this).Config.Bind<bool>("DefaultSettings", "CrossOverAllPacks", false, new ConfigDescription("If true, all of the game's default packs will be made available for all types of runs.", (AcceptableValueBase)null, Array.Empty<object>())).Value;

		private void Awake()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			Harmony val = new Harmony("zorro.inscryption.infiniscryption.packmanager");
			val.PatchAll();
			JSONLoader.LoadFromJSON();
			CreatePacks.CreatePacksForOtherMods();
			AscensionScreenManager.RegisterScreen<CardPackScreen>();
			if (EncounterPackManagementBeta)
			{
				AscensionScreenManager.RegisterScreen<EncounterPackScreen>();
			}
			if (CrossOverAllPacks)
			{
				PackInfo defaultPackInfo = PackManager.GetDefaultPackInfo((CardTemple)2);
				defaultPackInfo.ValidFor.Add(PackInfo.PackMetacategory.LeshyPack);
				defaultPackInfo.ValidFor.Add(PackInfo.PackMetacategory.MagnificusPack);
				defaultPackInfo.ValidFor.Add(PackInfo.PackMetacategory.GrimoraPack);
				PackInfo defaultPackInfo2 = PackManager.GetDefaultPackInfo((CardTemple)3);
				defaultPackInfo2.ValidFor.Add(PackInfo.PackMetacategory.LeshyPack);
				defaultPackInfo2.ValidFor.Add(PackInfo.PackMetacategory.P03Pack);
				defaultPackInfo2.ValidFor.Add(PackInfo.PackMetacategory.GrimoraPack);
				PackInfo defaultPackInfo3 = PackManager.GetDefaultPackInfo((CardTemple)1);
				defaultPackInfo3.ValidFor.Add(PackInfo.PackMetacategory.LeshyPack);
				defaultPackInfo3.ValidFor.Add(PackInfo.PackMetacategory.MagnificusPack);
				defaultPackInfo3.ValidFor.Add(PackInfo.PackMetacategory.P03Pack);
				PackInfo defaultPackInfo4 = PackManager.GetDefaultPackInfo((CardTemple)0);
				defaultPackInfo4.ValidFor.Add(PackInfo.PackMetacategory.GrimoraPack);
				defaultPackInfo4.ValidFor.Add(PackInfo.PackMetacategory.MagnificusPack);
				defaultPackInfo4.ValidFor.Add(PackInfo.PackMetacategory.P03Pack);
				CardManager.ModifyCardList += delegate(List<CardInfo> cards)
				{
					//IL_0018: Unknown result type (might be due to invalid IL or missing references)
					//IL_001e: Invalid comparison between Unknown and I4
					//IL_005b: Unknown result type (might be due to invalid IL or missing references)
					//IL_0061: Invalid comparison between Unknown and I4
					//IL_008b: Unknown result type (might be due to invalid IL or missing references)
					//IL_0091: Invalid comparison between Unknown and I4
					//IL_00af: Unknown result type (might be due to invalid IL or missing references)
					//IL_00b5: Invalid comparison between Unknown and I4
					//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
					//IL_00a8: Expected I4, but got Unknown
					//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
					//IL_00d9: Invalid comparison between Unknown and I4
					//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
					//IL_00cc: Expected I4, but got Unknown
					//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
					//IL_00f0: Expected I4, but got Unknown
					foreach (CardInfo card in cards)
					{
						if ((int)card.temple > 0 && CardExtensions.HasCardMetaCategory(card, (CardMetaCategory)0) && !CardExtensions.HasCardMetaCategory(card, (CardMetaCategory)3) && !CardExtensions.HasCardMetaCategory(card, (CardMetaCategory)1))
						{
							CardExtensions.AddMetaCategories(card, (CardMetaCategory[])(object)new CardMetaCategory[1] { (CardMetaCategory)1 });
						}
						if ((int)card.temple != 2 && (CardExtensions.HasCardMetaCategory(card, (CardMetaCategory)0) || CardExtensions.HasCardMetaCategory(card, (CardMetaCategory)3)))
						{
							if ((int)card.temple == 3)
							{
								CardExtensions.AddMetaCategories(card, (CardMetaCategory[])(object)new CardMetaCategory[1] { (CardMetaCategory)(int)WizardRegion });
							}
							if ((int)card.temple == 0)
							{
								CardExtensions.AddMetaCategories(card, (CardMetaCategory[])(object)new CardMetaCategory[1] { (CardMetaCategory)(int)NatureRegion });
							}
							if ((int)card.temple == 1)
							{
								CardExtensions.AddMetaCategories(card, (CardMetaCategory[])(object)new CardMetaCategory[1] { (CardMetaCategory)(int)UndeadRegion });
							}
						}
					}
					return cards;
				};
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin Infiniscryption Pack Manager is loaded!");
		}

		private void Start()
		{
			PackManager.ForceSyncOfAllPacks();
		}
	}
}
namespace Infiniscryption.PackManagement.UserInterface
{
	public class PackContentCache
	{
		private Dictionary<string, List<string>> PackMapper;

		private Dictionary<string, float> PowerLevelMapper;

		public List<PackInfoBase> OrderedPacks { get; private set; }

		public PackContentCache(Type packType)
		{
			OrderedPacks = (from pi in PackManager.AllPacks(packType).InScreenOrder()
				where pi.ValidFor.Contains(PackInfo.GetTempleDefaultMetacategory(PackManager.ScreenState))
				select pi).ToList();
			PackMapper = OrderedPacks.ToDictionary((PackInfoBase pi) => pi.Key, (PackInfoBase pi) => new List<string>(pi.ScreenFilteredContents));
			PowerLevelMapper = OrderedPacks.ToDictionary((PackInfoBase pi) => pi.Key, (PackInfoBase pi) => pi.PowerLevel);
			foreach (KeyValuePair<string, List<string>> item in PackMapper)
			{
				string text = string.Join(", ", item.Value);
				PackPlugin.Log.LogInfo((object)("Pack " + item.Key + " has " + text + " in it"));
			}
			OrderedPacks.RemoveAll((PackInfoBase pi) => PackMapper[pi.Key].Count == 0);
		}

		public float GetPowerLevel(PackInfoBase pack)
		{
			if (!PowerLevelMapper.ContainsKey(pack.Key))
			{
				throw new KeyNotFoundException("I do not recognize pack " + pack.Title);
			}
			return PowerLevelMapper[pack.Key];
		}

		public List<string> GetContentsOfPack(PackInfoBase pack)
		{
			if (!PackMapper.ContainsKey(pack.Key))
			{
				throw new KeyNotFoundException("I do not recognize pack " + pack.Title);
			}
			return PackMapper[pack.Key];
		}
	}
	public class PackIcon : MainInputInteractable
	{
		private static Dictionary<string, Sprite> _defaultPackSprites = new Dictionary<string, Sprite>();

		internal SpriteRenderer IconRenderer;

		internal SpriteRenderer CoveredRenderer;

		internal SpriteRenderer LockedRenderer;

		internal PixelText Text;

		internal SpriteRenderer SampleCardRenderer;

		internal Action IconSelectedCallback = null;

		private PackContentCache Cache { get; set; }

		public bool Selected { get; private set; }

		public bool Locked { get; private set; }

		public PackInfoBase Info { get; private set; }

		private AscensionRunSetupScreenBase ScreenParent => ((Component)this).GetComponentInParent<AscensionRunSetupScreenBase>();

		public override bool CollisionIs2D => true;

		internal static Sprite GetDefaultPackSprite(Type type)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			if (!_defaultPackSprites.ContainsKey(type.Name))
			{
				_defaultPackSprites[type.Name] = Sprite.Create(TextureHelper.GetImageAsTexture("default_window_" + type.Name + ".png", typeof(PackPlugin).Assembly, (FilterMode)0), new Rect(0f, 0f, 46f, 74f), new Vector2(0.5f, 0.5f));
			}
			return _defaultPackSprites[type.Name];
		}

		public void AssignPackInfo(PackInfoBase info, PackContentCache cache)
		{
			Info = info;
			Cache = cache;
			List<PackInfoBase> list = PackManager.RetrievePackList(info.GetType(), activeList: true, (CardTemple)0);
			Selected = list.Contains(info);
			if (!Selected)
			{
				Locked = false;
			}
			else
			{
				list.Remove(info);
				Locked = !info.SetOfPacksIsValid(list, cache);
			}
			((Component)CoveredRenderer).gameObject.SetActive(!Selected);
			((Component)LockedRenderer).gameObject.SetActive(Locked);
			if ((Object)(object)info.PackArt != (Object)null)
			{
				((Component)IconRenderer).gameObject.SetActive(true);
				IconRenderer.sprite = info.PackArt;
				((Component)Text).gameObject.SetActive(false);
				((Component)SampleCardRenderer).gameObject.SetActive(false);
			}
			else
			{
				((Component)IconRenderer).gameObject.SetActive(true);
				IconRenderer.sprite = GetDefaultPackSprite(info.GetType());
				((Component)Text).gameObject.SetActive(true);
				Text.SetText((info.ModPrefix.Length > 6) ? info.ModPrefix.Substring(0, 6) : info.ModPrefix, false);
				((Component)SampleCardRenderer).gameObject.SetActive(true);
				SampleCardRenderer.sprite = Info.IconCard.portraitTex;
			}
		}

		public override void OnCursorSelectEnd()
		{
			((MainInputInteractable)this).OnCursorSelectEnd();
			if (Locked)
			{
				return;
			}
			List<PackInfoBase> list = PackManager.RetrievePackList(Info.GetType(), activeList: true, (CardTemple)0);
			if (Selected)
			{
				while (list.Contains(Info))
				{
					list.Remove(Info);
				}
			}
			else
			{
				list.Add(Info);
			}
			PackManager.SavePackList(Info.GetType(), list, activeList: true, (CardTemple)0);
			Selected = !Selected;
			((Component)CoveredRenderer).gameObject.SetActive(!Selected);
			IconSelectedCallback?.Invoke();
		}

		private string FormatString(string description)
		{
			return Localization.Translate(Info.ReplaceMarkers(description, Cache));
		}

		public override void OnCursorEnter()
		{
			ScreenParent.DisplayCardInfo((CardInfo)null, Localization.Translate(Info.Title), FormatString(Info.Description + "\nAverage Power Level: [powerlevel]"), false);
		}

		public override void OnCursorExit()
		{
			ScreenParent.ClearMessage();
		}
	}
	public abstract class PackSelectorScreenBase<T> : AscensionRunSetupScreenBase where T : PackInfoBase
	{
		public static PackSelectorScreenBase<T> Instance;

		private static GameObject _textPseudoPrefab;

		private static Sprite _coveredSprite;

		private static Sprite _lockedSprite;

		private static Vector2 FIRST_CARD_OFFSET = new Vector2(-1.5f, 0f);

		private static Vector2 BETWEEN_CARD_OFFSET = new Vector2(0.5f, 0f);

		private List<PackIcon> PackIcons;

		private int scrollIndex = 0;

		public bool resetSelection = true;

		private PackContentCache cache;

		public override string headerText => "Choose Active Packs";

		public override bool showCardDisplayer => true;

		public override bool showCardPanel => false;

		private static GameObject TextPseudoPrefab
		{
			get
			{
				if ((Object)(object)_textPseudoPrefab == (Object)null)
				{
					_textPseudoPrefab = ((Component)Singleton<AscensionMenuScreens>.Instance.startScreen.transform.Find("Center/Subtitle/PixelTextLine_DIV")).gameObject;
				}
				return _textPseudoPrefab;
			}
		}

		private static Sprite CoveredSprite
		{
			get
			{
				//IL_003f: 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)
				if ((Object)(object)_coveredSprite == (Object)null)
				{
					_coveredSprite = Sprite.Create(TextureHelper.GetImageAsTexture("deselected.png", typeof(PackPlugin).Assembly, (FilterMode)0), new Rect(0f, 0f, 46f, 74f), new Vector2(0.5f, 0.5f));
					((Object)_coveredSprite).name = "CoveredSprite";
				}
				return _coveredSprite;
			}
		}

		private static Sprite LockedSprite
		{
			get
			{
				//IL_003f: 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)
				if ((Object)(object)_lockedSprite == (Object)null)
				{
					_lockedSprite = Sprite.Create(TextureHelper.GetImageAsTexture("locked.png", typeof(PackPlugin).Assembly, (FilterMode)0), new Rect(0f, 0f, 46f, 74f), new Vector2(0.5f, 0.5f));
					((Object)_lockedSprite).name = "LockedSprite";
				}
				return _lockedSprite;
			}
		}

		private PackIcon GeneratePackIcon(Transform parent)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Expected O, but got Unknown
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Expected O, but got Unknown
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Expected O, but got Unknown
			//IL_02c2: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Pack");
			val.transform.SetParent(parent);
			val.layer = LayerMask.NameToLayer("GBCUI");
			PackIcon packIcon = val.AddComponent<PackIcon>();
			GameObject val2 = new GameObject("PackSprite");
			val2.transform.SetParent(val.transform);
			val2.layer = LayerMask.NameToLayer("GBCUI");
			packIcon.IconRenderer = val2.AddComponent<SpriteRenderer>();
			packIcon.IconRenderer.sprite = PackIcon.GetDefaultPackSprite(typeof(T));
			((Renderer)packIcon.IconRenderer).enabled = true;
			((Renderer)packIcon.IconRenderer).sortingOrder = 200;
			GameObject val3 = Object.Instantiate<GameObject>(TextPseudoPrefab, val.transform);
			packIcon.Text = val3.GetComponentInChildren<PixelText>();
			packIcon.Text.SetColor(Color.black);
			((Component)packIcon.Text).GetComponentInChildren<Canvas>().sortingLayerName = ((Renderer)packIcon.IconRenderer).sortingLayerName;
			packIcon.Text.SetSortingOrder(225);
			val3.transform.localPosition = new Vector3(0f, 0.2f, 0f);
			GameObject val4 = new GameObject("PackCardIcon");
			val4.transform.SetParent(val.transform);
			val4.layer = LayerMask.NameToLayer("GBCUI");
			packIcon.SampleCardRenderer = val4.AddComponent<SpriteRenderer>();
			packIcon.SampleCardRenderer.sprite = CardLoader.GetCardByName("Grizzly").portraitTex;
			((Renderer)packIcon.SampleCardRenderer).enabled = true;
			((Renderer)packIcon.SampleCardRenderer).sortingOrder = 230;
			val4.transform.localPosition = new Vector3(0f, -0.07f, 0f);
			val4.transform.localScale = new Vector3(0.36f, 0.36f, 0.36f);
			GameObject val5 = new GameObject("Covered");
			val5.transform.SetParent(val.transform);
			val5.layer = LayerMask.NameToLayer("GBCUI");
			packIcon.CoveredRenderer = val5.AddComponent<SpriteRenderer>();
			packIcon.CoveredRenderer.sprite = CoveredSprite;
			((Renderer)packIcon.CoveredRenderer).enabled = true;
			((Renderer)packIcon.CoveredRenderer).sortingOrder = 250;
			GameObject val6 = new GameObject("Locked");
			val6.transform.SetParent(val.transform);
			val6.layer = LayerMask.NameToLayer("GBCUI");
			packIcon.LockedRenderer = val6.AddComponent<SpriteRenderer>();
			packIcon.LockedRenderer.sprite = LockedSprite;
			((Renderer)packIcon.LockedRenderer).enabled = true;
			((Renderer)packIcon.LockedRenderer).sortingOrder = 250;
			BoxCollider2D val7 = val.AddComponent<BoxCollider2D>();
			val7.size = packIcon.IconRenderer.size;
			packIcon.IconSelectedCallback = ShowPage;
			return packIcon;
		}

		public override void InitializeScreen(GameObject partialScreen)
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_00cb: 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)
			//IL_00d8: 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_00e2: Unknown result type (might be due to invalid IL or missing references)
			GameObject gameObject = ((Component)partialScreen.transform.Find("Header/Mid")).gameObject;
			AnchorToScreenEdge val = gameObject.AddComponent<AnchorToScreenEdge>();
			val.anchorToBottom = false;
			val.anchorToMidpoint = false;
			val.anchorYOffset = 0.47f;
			val.worldAnchor = partialScreen.transform.Find("Header");
			GameObject val2 = new GameObject("GameIcons");
			val2.transform.SetParent(partialScreen.transform);
			AnchorToScreenEdge val3 = val2.AddComponent<AnchorToScreenEdge>();
			val3.anchorToMidpoint = true;
			val3.anchorToBottom = false;
			val3.anchorYOffset = -0.42f;
			val3.worldAnchor = partialScreen.transform.Find("Footer");
			PackIcons = new List<PackIcon>();
			for (int j = 0; j < 7; j++)
			{
				PackIcon packIcon = GeneratePackIcon(val2.transform);
				((Component)packIcon).gameObject.transform.localPosition = Vector2.op_Implicit(FIRST_CARD_OFFSET + (float)j * BETWEEN_CARD_OFFSET);
				PackIcons.Add(packIcon);
			}
			(AscensionMenuInteractable, AscensionMenuInteractable) tuple = AscensionRunSetupScreenBase.BuildPaginators(val2.transform, false);
			AscensionMenuInteractable item = tuple.Item1;
			AscensionMenuInteractable item2 = tuple.Item2;
			Action<MainInputInteractable> b = delegate(MainInputInteractable i)
			{
				((AscensionRunSetupScreenBase)this).LeftButtonClicked(i);
			};
			Action<MainInputInteractable> b2 = delegate(MainInputInteractable i)
			{
				((AscensionRunSetupScreenBase)this).RightButtonClicked(i);
			};
			((MainInputInteractable)item).CursorSelectStarted = (Action<MainInputInteractable>)Delegate.Combine(((MainInputInteractable)item).CursorSelectStarted, b);
			((MainInputInteractable)item2).CursorSelectStarted = (Action<MainInputInteractable>)Delegate.Combine(((MainInputInteractable)item2).CursorSelectStarted, b2);
			base.leftButton = (MainInputInteractable)(object)item;
			base.rightButton = (MainInputInteractable)(object)item2;
			Instance = this;
		}

		public override void LeftButtonClicked(MainInputInteractable button)
		{
			if (scrollIndex > 0)
			{
				scrollIndex--;
				ShowPage();
			}
		}

		public override void RightButtonClicked(MainInputInteractable button)
		{
			if ((scrollIndex + 1) * PackIcons.Count < cache.OrderedPacks.Count)
			{
				scrollIndex++;
				ShowPage();
			}
		}

		public void ShowPage()
		{
			int num = PackIcons.Count * scrollIndex;
			int count = Math.Min(PackIcons.Count, cache.OrderedPacks.Count - num);
			ShowPacks(cache.OrderedPacks.GetRange(num, count).Cast<T>().ToList());
		}

		public void InitializeCardSelection()
		{
			base.challengeHeaderDisplay.UpdateText();
			((Component)base.leftButton).gameObject.SetActive(PackIcons.Count < cache.OrderedPacks.Count);
			((Component)base.rightButton).gameObject.SetActive(PackIcons.Count < cache.OrderedPacks.Count);
		}

		public void ShowPacks(List<T> packsToDisplay)
		{
			//IL_006d: 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_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			foreach (PackIcon packIcon in PackIcons)
			{
				((Component)packIcon).gameObject.SetActive(false);
			}
			int num = Math.Min(PackIcons.Count, packsToDisplay.Count);
			float num2 = (float)(PackIcons.Count - num) / 2f;
			Vector2 val = FIRST_CARD_OFFSET + BETWEEN_CARD_OFFSET * num2;
			for (int i = 0; i < num; i++)
			{
				PackIcons[i].AssignPackInfo(packsToDisplay[i], cache);
				((Component)PackIcons[i]).gameObject.transform.localPosition = Vector2.op_Implicit(val + (float)i * BETWEEN_CARD_OFFSET);
				((Component)PackIcons[i]).gameObject.SetActive(true);
			}
		}

		public override void OnEnable()
		{
			((AscensionRunSetupScreenBase)this).OnEnable();
			cache = new PackContentCache(typeof(T));
			List<T> inactivePacks = PackManager.RetrievePackList<T>(activeList: false, (CardTemple)0);
			PackManager.SavePackList(cache.OrderedPacks.Where((PackInfoBase pi) => !inactivePacks.Contains(pi)).ToList(), activeList: true, (CardTemple)0);
			if (cache.OrderedPacks.Count <= 1)
			{
				Singleton<InteractionCursor>.Instance.UpdateMainInput();
				if ((Object)(object)Singleton<InteractionCursor>.Instance.currentMainInputInteractable == (Object)(object)base.continueButton)
				{
					((MainInputInteractable)base.continueButton).CursorSelectStart();
				}
				if ((Object)(object)Singleton<InteractionCursor>.Instance.currentMainInputInteractable == (Object)(object)base.backButton)
				{
					((MainInputInteractable)base.backButton).CursorSelectStart();
				}
			}
			scrollIndex = 0;
			InitializeCardSelection();
			ShowPage();
		}
	}
	[AscensionScreenSort(/*Could not decode attribute arguments.*/)]
	public class CardPackScreen : PackSelectorScreenBase<PackInfo>
	{
		public override string headerText => "Select Card Packs";
	}
	[AscensionScreenSort(/*Could not decode attribute arguments.*/)]
	public class EncounterPackScreen : PackSelectorScreenBase<EncounterPackInfo>
	{
		public override string headerText => "Select Encounter Packs";
	}
}
namespace Infiniscryption.PackManagement.Patchers
{
	public static class CreatePacks
	{
		public static void CreatePacksForOtherMods()
		{
			PackInfo packInfo = PackManager.GetPackInfo<PackInfo>("eri");
			packInfo.Title = "Eri Card Expansion";
			packInfo.SetTexture(TextureHelper.GetImageAsTexture("eris_pack.png", typeof(CreatePacks).Assembly, (FilterMode)0));
			packInfo.Description = "From the [randomcard] to the [randomcard], this pack contains [count] wild animals that feel right at home in the wild world of Inscryption.";
			PackInfo packInfo2 = PackManager.GetPackInfo<PackInfo>("aracardexpansion");
			packInfo2.Title = "Ara's Card Expansion";
			packInfo2.SetTexture(TextureHelper.GetImageAsTexture("aras_packs.png", typeof(CreatePacks).Assembly, (FilterMode)0));
			packInfo2.Description = "This expansion contains [count] cards that offer a unique twist on Inscryption's core gameplay. Cards like [randomcard] and [randomcard] will give a little additional spice to your next run.";
			PackInfo packInfo3 = PackManager.GetPackInfo<PackInfo>("HE");
			packInfo3.Title = "Hallownest Expansion";
			packInfo3.SetTexture(TextureHelper.GetImageAsTexture("he_pack.png", typeof(CreatePacks).Assembly, (FilterMode)0));
			packInfo3.Description = "A large expansion containing [count] creatures from Hollow Knight. Up from peaceful Crossroads, down into the Abyss.";
			EncounterPackInfo packInfo4 = PackManager.GetPackInfo<EncounterPackInfo>("bitty45.inscryption.regions");
			packInfo4.Title = "Bitty's Regions";
			packInfo4.SetTexture(TextureHelper.GetImageAsTexture("bitty_expansion_pack.png", typeof(CreatePacks).Assembly, (FilterMode)0));
			packInfo4.Description = "Bitty's Regions adds [summary].";
			EncounterPackInfo packInfo5 = PackManager.GetPackInfo<EncounterPackInfo>("extraVoid.inscryption.RegionExpansions");
			packInfo5.Title = "Void Region Expansion";
			packInfo5.SetTexture(TextureHelper.GetImageAsTexture("void_expansion_pack.png", typeof(CreatePacks).Assembly, (FilterMode)0));
			packInfo5.Description = "This region expansion from Void adds [summary].";
			EncounterPackInfo packInfo6 = PackManager.GetPackInfo<EncounterPackInfo>("extraVoid.inscryption.ExtraEncounters");
			packInfo6.Title = "Eri's Card Pack Encounters";
			packInfo6.SetTexture(TextureHelper.GetImageAsTexture("eris_encounter_pack.png", typeof(CreatePacks).Assembly, (FilterMode)0));
			packInfo6.Description = "This expansion adds [summary] featuring cards from Eri's Card Expansion.";
		}
	}
	public static class JSONLoader
	{
		public static void LoadFromJSON()
		{
			foreach (string item in Directory.EnumerateFiles(Paths.PluginPath, "*.jlpk", SearchOption.AllDirectories))
			{
				try
				{
					string json = File.ReadAllText(item);
					PackInfoJSON packInfoJSON = json.FromJson<PackInfoJSON>();
					packInfoJSON.PackType = typeof(PackInfo);
					packInfoJSON.Convert();
				}
				catch (Exception ex)
				{
					PackPlugin.Log.LogError((object)("Error deserializing pack " + item + ": " + ex.Message));
					PackPlugin.Log.LogError((object)ex);
				}
			}
			foreach (string item2 in Directory.EnumerateFiles(Paths.PluginPath, "*.jlenc", SearchOption.AllDirectories))
			{
				try
				{
					string json2 = File.ReadAllText(item2);
					PackInfoJSON packInfoJSON2 = json2.FromJson<PackInfoJSON>();
					packInfoJSON2.PackType = typeof(EncounterPackInfo);
					packInfoJSON2.Convert();
				}
				catch (Exception ex2)
				{
					PackPlugin.Log.LogError((object)("Error deserializing pack " + item2 + ": " + ex2.Message));
					PackPlugin.Log.LogError((object)ex2);
				}
			}
		}
	}
	public static class JSONParser
	{
		[ThreadStatic]
		private static Stack<List<string>> splitArrayPool;

		[ThreadStatic]
		private static StringBuilder stringBuilder;

		[ThreadStatic]
		private static Dictionary<Type, Dictionary<string, FieldInfo>> fieldInfoCache;

		[ThreadStatic]
		private static Dictionary<Type, Dictionary<string, PropertyInfo>> propertyInfoCache;

		public static T FromJson<T>(this string json)
		{
			if (propertyInfoCache == null)
			{
				propertyInfoCache = new Dictionary<Type, Dictionary<string, PropertyInfo>>();
			}
			if (fieldInfoCache == null)
			{
				fieldInfoCache = new Dictionary<Type, Dictionary<string, FieldInfo>>();
			}
			if (stringBuilder == null)
			{
				stringBuilder = new StringBuilder();
			}
			if (splitArrayPool == null)
			{
				splitArrayPool = new Stack<List<string>>();
			}
			stringBuilder.Length = 0;
			for (int i = 0; i < json.Length; i++)
			{
				char c = json[i];
				if (c == '"')
				{
					i = AppendUntilStringEnd(appendEscapeCharacter: true, i, json);
				}
				else if (!char.IsWhiteSpace(c))
				{
					stringBuilder.Append(c);
				}
			}
			return (T)ParseValue(typeof(T), stringBuilder.ToString());
		}

		private static int AppendUntilStringEnd(bool appendEscapeCharacter, int startIdx, string json)
		{
			stringBuilder.Append(json[startIdx]);
			for (int i = startIdx + 1; i < json.Length; i++)
			{
				if (json[i] == '\\')
				{
					if (appendEscapeCharacter)
					{
						stringBuilder.Append(json[i]);
					}
					stringBuilder.Append(json[i + 1]);
					i++;
				}
				else
				{
					if (json[i] == '"')
					{
						stringBuilder.Append(json[i]);
						return i;
					}
					stringBuilder.Append(json[i]);
				}
			}
			return json.Length - 1;
		}

		private static List<string> Split(string json)
		{
			List<string> list = ((splitArrayPool.Count > 0) ? splitArrayPool.Pop() : new List<string>());
			list.Clear();
			if (json.Length == 2)
			{
				return list;
			}
			int num = 0;
			stringBuilder.Length = 0;
			for (int i = 1; i < json.Length - 1; i++)
			{
				switch (json[i])
				{
				case '[':
				case '{':
					num++;
					break;
				case ']':
				case '}':
					num--;
					break;
				case '"':
					i = AppendUntilStringEnd(appendEscapeCharacter: true, i, json);
					continue;
				case ',':
				case ':':
					if (num == 0)
					{
						list.Add(stringBuilder.ToString());
						stringBuilder.Length = 0;
						continue;
					}
					break;
				}
				stringBuilder.Append(json[i]);
			}
			list.Add(stringBuilder.ToString());
			return list;
		}

		internal static object ParseValue(Type type, string json)
		{
			if (type == typeof(string))
			{
				if (json.Length <= 2)
				{
					return string.Empty;
				}
				StringBuilder stringBuilder = new StringBuilder(json.Length);
				for (int i = 1; i < json.Length - 1; i++)
				{
					if (json[i] == '\\' && i + 1 < json.Length - 1)
					{
						int num = "\"\\nrtbf/".IndexOf(json[i + 1]);
						if (num >= 0)
						{
							stringBuilder.Append("\"\\\n\r\t\b\f/"[num]);
							i++;
							continue;
						}
						if (json[i + 1] == 'u' && i + 5 < json.Length - 1)
						{
							uint result = 0u;
							if (uint.TryParse(json.Substring(i + 2, 4), NumberStyles.AllowHexSpecifier, null, out result))
							{
								stringBuilder.Append((char)result);
								i += 5;
								continue;
							}
						}
					}
					stringBuilder.Append(json[i]);
				}
				return stringBuilder.ToString();
			}
			if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
			{
				return Convert.ChangeType(json, type.GetGenericArguments().First(), CultureInfo.InvariantCulture);
			}
			if (type.IsPrimitive)
			{
				return Convert.ChangeType(json, type, CultureInfo.InvariantCulture);
			}
			if (type == typeof(decimal))
			{
				decimal.TryParse(json, NumberStyles.Float, CultureInfo.InvariantCulture, out var result2);
				return result2;
			}
			if (type == typeof(DateTime))
			{
				DateTime.TryParse(json.Replace("\"", ""), CultureInfo.InvariantCulture, DateTimeStyles.None, out var result3);
				return result3;
			}
			if (json == "null")
			{
				return null;
			}
			if (type.IsEnum)
			{
				if (json[0] == '"')
				{
					json = json.Substring(1, json.Length - 2);
				}
				try
				{
					return Enum.Parse(type, json, ignoreCase: false);
				}
				catch
				{
					return 0;
				}
			}
			if (type.IsArray)
			{
				Type elementType = type.GetElementType();
				if (json[0] != '[' || json[json.Length - 1] != ']')
				{
					return null;
				}
				List<string> list = Split(json);
				Array array = Array.CreateInstance(elementType, list.Count);
				for (int j = 0; j < list.Count; j++)
				{
					array.SetValue(ParseValue(elementType, list[j]), j);
				}
				splitArrayPool.Push(list);
				return array;
			}
			if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>))
			{
				Type type2 = type.GetGenericArguments()[0];
				if (json[0] != '[' || json[json.Length - 1] != ']')
				{
					return null;
				}
				List<string> list2 = Split(json);
				IList list3 = (IList)type.GetConstructor(new Type[1] { typeof(int) }).Invoke(new object[1] { list2.Count });
				for (int k = 0; k < list2.Count; k++)
				{
					list3.Add(ParseValue(type2, list2[k]));
				}
				splitArrayPool.Push(list2);
				return list3;
			}
			if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<, >))
			{
				Type[] genericArguments = type.GetGenericArguments();
				Type type3 = genericArguments[0];
				Type type4 = genericArguments[1];
				if (type3 != typeof(string))
				{
					return null;
				}
				if (json[0] != '{' || json[json.Length - 1] != '}')
				{
					return null;
				}
				List<string> list4 = Split(json);
				if (list4.Count % 2 != 0)
				{
					return null;
				}
				IDictionary dictionary = (IDictionary)type.GetConstructor(new Type[1] { typeof(int) }).Invoke(new object[1] { list4.Count / 2 });
				for (int l = 0; l < list4.Count; l += 2)
				{
					if (list4[l].Length > 2)
					{
						string key = list4[l].Substring(1, list4[l].Length - 2);
						object value = ParseValue(type4, list4[l + 1]);
						dictionary[key] = value;
					}
				}
				return dictionary;
			}
			if (type == typeof(object))
			{
				return ParseAnonymousValue(json);
			}
			if (json[0] == '{' && json[json.Length - 1] == '}')
			{
				return ParseObject(type, json);
			}
			return null;
		}

		private static object ParseAnonymousValue(string json)
		{
			if (json.Length == 0)
			{
				return null;
			}
			if (json[0] == '{' && json[json.Length - 1] == '}')
			{
				List<string> list = Split(json);
				if (list.Count % 2 != 0)
				{
					return null;
				}
				Dictionary<string, object> dictionary = new Dictionary<string, object>(list.Count / 2);
				for (int i = 0; i < list.Count; i += 2)
				{
					dictionary[list[i].Substring(1, list[i].Length - 2)] = ParseAnonymousValue(list[i + 1]);
				}
				return dictionary;
			}
			if (json[0] == '[' && json[json.Length - 1] == ']')
			{
				List<string> list2 = Split(json);
				List<object> list3 = new List<object>(list2.Count);
				for (int j = 0; j < list2.Count; j++)
				{
					list3.Add(ParseAnonymousValue(list2[j]));
				}
				return list3;
			}
			if (json[0] == '"' && json[json.Length - 1] == '"')
			{
				string text = json.Substring(1, json.Length - 2);
				return text.Replace("\\", string.Empty);
			}
			if (char.IsDigit(json[0]) || json[0] == '-')
			{
				if (json.Contains("."))
				{
					double.TryParse(json, NumberStyles.Float, CultureInfo.InvariantCulture, out var result);
					return result;
				}
				int.TryParse(json, out var result2);
				return result2;
			}
			if (json == "true")
			{
				return true;
			}
			if (json == "false")
			{
				return false;
			}
			return null;
		}

		private static Dictionary<string, T> CreateMemberNameDictionary<T>(T[] members) where T : MemberInfo
		{
			Dictionary<string, T> dictionary = new Dictionary<string, T>(StringComparer.OrdinalIgnoreCase);
			foreach (T val in members)
			{
				if (val.IsDefined(typeof(IgnoreDataMemberAttribute), inherit: true))
				{
					continue;
				}
				string name = val.Name;
				if (val.IsDefined(typeof(DataMemberAttribute), inherit: true))
				{
					DataMemberAttribute dataMemberAttribute = (DataMemberAttribute)Attribute.GetCustomAttribute(val, typeof(DataMemberAttribute), inherit: true);
					if (!string.IsNullOrEmpty(dataMemberAttribute.Name))
					{
						name = dataMemberAttribute.Name;
					}
				}
				dictionary.Add(name, val);
			}
			return dictionary;
		}

		private static object ParseObject(Type type, string json)
		{
			object uninitializedObject = FormatterServices.GetUninitializedObject(type);
			List<string> list = Split(json);
			if (list.Count % 2 != 0)
			{
				return uninitializedObject;
			}
			if (!fieldInfoCache.TryGetValue(type, out var value))
			{
				value = CreateMemberNameDictionary(type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy));
				fieldInfoCache.Add(type, value);
			}
			if (!propertyInfoCache.TryGetValue(type, out var value2))
			{
				value2 = CreateMemberNameDictionary(type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy));
				propertyInfoCache.Add(type, value2);
			}
			for (int i = 0; i < list.Count; i += 2)
			{
				if (list[i].Length > 2)
				{
					string key = list[i].Substring(1, list[i].Length - 2);
					string json2 = list[i + 1];
					PropertyInfo value4;
					if (value.TryGetValue(key, out var value3))
					{
						value3.SetValue(uninitializedObject, ParseValue(value3.FieldType, json2));
					}
					else if (value2.TryGetValue(key, out value4))
					{
						value4.SetValue(uninitializedObject, ParseValue(value4.PropertyType, json2), null);
					}
				}
			}
			return uninitializedObject;
		}
	}
	public class PackInfoJSON
	{
		internal Type PackType = typeof(PackInfo);

		public string Title;

		public string Description;

		public string ModPrefix;

		public string PackArt;

		public string[] ValidFor;

		public bool SplitPackByCardTemple;

		public void Convert()
		{
			PackInfoBase packInfo = PackManager.GetPackInfo(PackType, ModPrefix);
			packInfo.Title = Title;
			packInfo.Description = Description;
			packInfo.SetTexture(TextureHelper.GetImageAsTexture(PackArt, (FilterMode)0));
			packInfo.SplitPackByCardTemple = SplitPackByCardTemple;
			if (ValidFor != null && ValidFor.Length != 0)
			{
				packInfo.ValidFor.Clear();
				packInfo.ValidFor.AddRange(ValidFor.Select((string s) => (PackInfo.PackMetacategory)Enum.Parse(typeof(PackInfo.PackMetacategory), s)));
			}
		}
	}
}