Decompiled source of Seed Searcher v1.2.2

BepInEx/plugins/com.binbin.SeedSearcher.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Obeliskial_Essentials;
using SeedSearcher;
using TMPro;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("com.binbin.SeedSearcher")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.2.1.0")]
[assembly: AssemblyInformationalVersion("1.2.1+90a59480a5955f0298d8545d002e28e90e726953")]
[assembly: AssemblyProduct("SeedSearcher")]
[assembly: AssemblyTitle("com.binbin.SeedSearcher")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.2.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
public static class EssentialsCompatibility
{
	private static bool? _enabled;

	public static bool Enabled
	{
		get
		{
			bool valueOrDefault = _enabled.GetValueOrDefault();
			if (!_enabled.HasValue)
			{
				valueOrDefault = Chainloader.PluginInfos.ContainsKey("com.stiffmeds.obeliskialessentials");
				_enabled = valueOrDefault;
			}
			return _enabled.Value;
		}
	}

	[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
	public static void EssentialsRegister()
	{
		Essentials.RegisterMod(Plugin.PluginName, "binbin", "Seed Searcher", Plugin.PluginVersion, Plugin.ModDate, "https://github.com/binbinmods/SeedSearcher", (string[])null, "", 100, (string[])null, "", true);
		Plugin.LogInfo(Plugin.PluginGUID + " " + Plugin.PluginVersion + " has loaded with Essentials!");
	}
}
[Serializable]
public class ItemObject
{
	public string Id { get; set; }

	public string Name { get; set; }

	public bool Droponly { get; set; }

	public string CardUpgraded { get; set; }

	public string UpgradesToRareId { get; set; }

	public int PercentRetentionEndGame { get; set; }

	public int PercentDiscountShop { get; set; }

	public string CardRarity { get; set; }

	public string CardType { get; set; }

	public ItemObject(string name, CardData cardData)
	{
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0083: Unknown result type (might be due to invalid IL or missing references)
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		Id = name;
		Name = cardData.CardName;
		Droponly = cardData.Item.DropOnly;
		CardUpgraded cardUpgraded = cardData.CardUpgraded;
		CardUpgraded = ((object)(CardUpgraded)(ref cardUpgraded)).ToString();
		CardData upgradesToRare = cardData.UpgradesToRare;
		UpgradesToRareId = ((upgradesToRare != null) ? upgradesToRare.Id : null) ?? "";
		PercentRetentionEndGame = cardData.Item.PercentRetentionEndGame;
		PercentDiscountShop = cardData.Item.PercentDiscountShop;
		CardRarity cardRarity = cardData.CardRarity;
		CardRarity = ((object)(CardRarity)(ref cardRarity)).ToString();
		CardType cardType = cardData.CardType;
		CardType = ((object)(CardType)(ref cardType)).ToString();
		base..ctor();
	}
}
namespace SeedSearcher
{
	[BepInPlugin("com.binbin.SeedSearcher", "SeedSearcher", "1.2.1")]
	[BepInProcess("AcrossTheObelisk.exe")]
	public class Plugin : BaseUnityPlugin
	{
		public static string PluginName;

		public static string PluginVersion;

		public static string PluginGUID;

		internal static int ModDate = int.Parse(DateTime.Today.ToString("yyyyMMdd"));

		private readonly Harmony harmony = new Harmony("com.binbin.SeedSearcher");

		internal static ManualLogSource Log;

		public static string debugBase = "com.binbin.SeedSearcher ";

		public static ConfigEntry<bool> EnableMod { get; set; }

		public static ConfigEntry<bool> SearchForItemsOnStartup { get; set; }

		public static ConfigEntry<int> MadnessLevel { get; set; }

		public static ConfigEntry<int> CorruptorCount { get; set; }

		public static ConfigEntry<bool> PovertyEnabled { get; set; }

		public static ConfigEntry<bool> StopSearchOnSeedFound { get; set; }

		public static ConfigEntry<bool> SaveSeedToGame { get; set; }

		public static ConfigEntry<bool> BypassMadnessRandomization { get; set; }

		public static ConfigEntry<int> NumberOfSeeds { get; set; }

		public static ConfigEntry<string> LocationToSearchForItem1 { get; set; }

		public static ConfigEntry<string> LocationToSearchForItem2 { get; set; }

		public static ConfigEntry<string> LocationToSearchForItem3 { get; set; }

		public static ConfigEntry<string> LocationToSearchForItem4 { get; set; }

		public static ConfigEntry<string> ItemToSearchFor1 { get; set; }

		public static ConfigEntry<string> ItemToSearchFor2 { get; set; }

		public static ConfigEntry<string> ItemToSearchFor3 { get; set; }

		public static ConfigEntry<string> ItemToSearchFor4 { get; set; }

		public static ConfigEntry<bool> SearchForItemsOnChange { get; set; }

		public static ConfigEntry<bool> WriteItemsToTextFile { get; set; }

		public static ConfigEntry<string> WriteItemsToTextFilePath { get; set; }

		private void Awake()
		{
			//IL_002e: 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_0049: Expected O, but got Unknown
			//IL_0049: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			//IL_0076: Expected O, but got Unknown
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Expected O, but got Unknown
			//IL_00a3: Expected O, but got Unknown
			//IL_00b5: 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_00d0: Expected O, but got Unknown
			//IL_00d0: Expected O, but got Unknown
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Expected O, but got Unknown
			//IL_00fd: Expected O, but got Unknown
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Expected O, but got Unknown
			//IL_012a: Expected O, but got Unknown
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: Expected O, but got Unknown
			//IL_0157: Expected O, but got Unknown
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Expected O, but got Unknown
			//IL_0184: Expected O, but got Unknown
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Expected O, but got Unknown
			//IL_01b5: Expected O, but got Unknown
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Expected O, but got Unknown
			//IL_0206: Expected O, but got Unknown
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Expected O, but got Unknown
			//IL_0237: Expected O, but got Unknown
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Expected O, but got Unknown
			//IL_0268: Expected O, but got Unknown
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: Expected O, but got Unknown
			//IL_0299: Expected O, but got Unknown
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Expected O, but got Unknown
			//IL_02ca: Expected O, but got Unknown
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fb: Expected O, but got Unknown
			//IL_02fb: Expected O, but got Unknown
			//IL_030d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Expected O, but got Unknown
			//IL_032c: Expected O, but got Unknown
			//IL_033e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0353: Unknown result type (might be due to invalid IL or missing references)
			//IL_035d: Expected O, but got Unknown
			//IL_035d: Expected O, but got Unknown
			//IL_036f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0380: Unknown result type (might be due to invalid IL or missing references)
			//IL_038a: Expected O, but got Unknown
			//IL_038a: Expected O, but got Unknown
			//IL_039c: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b7: Expected O, but got Unknown
			//IL_03b7: Expected O, but got Unknown
			//IL_03c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03de: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e8: Expected O, but got Unknown
			//IL_03e8: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Log.LogInfo((object)"com.binbin.SeedSearcher 1.2.1 has loaded!");
			string text = "SeedSearcher";
			EnableMod = ((BaseUnityPlugin)this).Config.Bind<bool>(new ConfigDefinition(text, "EnableMod"), true, new ConfigDescription("If false, disables the mod. Restart the game upon changing this setting.", (AcceptableValueBase)null, Array.Empty<object>()));
			SearchForItemsOnStartup = ((BaseUnityPlugin)this).Config.Bind<bool>(new ConfigDefinition(text, "SearchForItemsOnStartup"), false, new ConfigDescription("Has the game search through seeds on startup for a predefined list of items. Items are stored in the LogOutput.log file. To execute, set this value to true and then restart your game. ", (AcceptableValueBase)null, Array.Empty<object>()));
			MadnessLevel = ((BaseUnityPlugin)this).Config.Bind<int>(new ConfigDefinition(text, "MadnessLevel"), 1, new ConfigDescription("Madness level to search through. 0 - 9. Purple items cannot spawn if Madness Level is 0.", (AcceptableValueBase)null, Array.Empty<object>()));
			CorruptorCount = ((BaseUnityPlugin)this).Config.Bind<int>(new ConfigDefinition(text, "CorruptorCount"), 0, new ConfigDescription("Corruptor count to search through. 0 - 9. Purple items are more common at higher corruptor counts.", (AcceptableValueBase)null, Array.Empty<object>()));
			PovertyEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>(new ConfigDefinition(text, "PovertyEnabled"), false, new ConfigDescription("If true, will search through seeds with poverty enabled.", (AcceptableValueBase)null, Array.Empty<object>()));
			StopSearchOnSeedFound = ((BaseUnityPlugin)this).Config.Bind<bool>(new ConfigDefinition(text, "StopSearchOnSeedFound"), false, new ConfigDescription("If true, will stop searching through seeds when a seed with the items set in the menu is found.", (AcceptableValueBase)null, Array.Empty<object>()));
			SaveSeedToGame = ((BaseUnityPlugin)this).Config.Bind<bool>(new ConfigDefinition(text, "SaveSeedToGame"), true, new ConfigDescription("If true, will save the seed to the game. Only works if StopSearchOnSeedFound is true.", (AcceptableValueBase)null, Array.Empty<object>()));
			BypassMadnessRandomization = ((BaseUnityPlugin)this).Config.Bind<bool>(new ConfigDefinition(text, "BypassMadnessRandomization"), true, new ConfigDescription("If true, will bypass the seed randomization on High Madness. Works for any seed, not just ones found by this mod.", (AcceptableValueBase)null, Array.Empty<object>()));
			NumberOfSeeds = ((BaseUnityPlugin)this).Config.Bind<int>(new ConfigDefinition(text, "Seeds to Search"), 200000, new ConfigDescription("Maximum number of seeds to search through (I believe it takes around 2 minutes to search through 1 million seeds)", (AcceptableValueBase)null, Array.Empty<object>()));
			AcceptableValueList<string> val = new AcceptableValueList<string>(GetItemList().ToArray());
			AcceptableValueList<string> val2 = new AcceptableValueList<string>(GetLocationList().ToArray());
			LocationToSearchForItem1 = ((BaseUnityPlugin)this).Config.Bind<string>(new ConfigDefinition(text, "LocationToSearchForItem1"), "caravanshop", new ConfigDescription("Location to search for the first item", (AcceptableValueBase)(object)val2, Array.Empty<object>()));
			ItemToSearchFor1 = ((BaseUnityPlugin)this).Config.Bind<string>(new ConfigDefinition(text, "ItemToSearchFor1"), "cheese", new ConfigDescription("First item to search for in the caravanshop", (AcceptableValueBase)(object)val, Array.Empty<object>()));
			LocationToSearchForItem2 = ((BaseUnityPlugin)this).Config.Bind<string>(new ConfigDefinition(text, "LocationToSearchForItem2"), "caravanshop", new ConfigDescription("Location to search for the second item", (AcceptableValueBase)(object)val2, Array.Empty<object>()));
			ItemToSearchFor2 = ((BaseUnityPlugin)this).Config.Bind<string>(new ConfigDefinition(text, "ItemToSearchFor2"), "cheese", new ConfigDescription("Second item to search for in the caravanshop", (AcceptableValueBase)(object)val, Array.Empty<object>()));
			LocationToSearchForItem3 = ((BaseUnityPlugin)this).Config.Bind<string>(new ConfigDefinition(text, "LocationToSearchForItem3"), "caravanshop", new ConfigDescription("Location to search for the third item", (AcceptableValueBase)(object)val2, Array.Empty<object>()));
			ItemToSearchFor3 = ((BaseUnityPlugin)this).Config.Bind<string>(new ConfigDefinition(text, "ItemToSearchFor3"), "cheese", new ConfigDescription("Third item to search for in the caravanshop", (AcceptableValueBase)(object)val, Array.Empty<object>()));
			LocationToSearchForItem4 = ((BaseUnityPlugin)this).Config.Bind<string>(new ConfigDefinition(text, "LocationToSearchForItem4"), "caravanshop", new ConfigDescription("Location to search for the fourth item", (AcceptableValueBase)(object)val2, Array.Empty<object>()));
			ItemToSearchFor4 = ((BaseUnityPlugin)this).Config.Bind<string>(new ConfigDefinition(text, "ItemToSearchFor4"), "cheese", new ConfigDescription("Fourth item to search for in the caravanshop", (AcceptableValueBase)(object)val, Array.Empty<object>()));
			SearchForItemsOnChange = ((BaseUnityPlugin)this).Config.Bind<bool>(new ConfigDefinition(text, "SearchForItemsOnChange"), false, new ConfigDescription("When clicked, will search through seeds for the items. May cause the game to temporarily freeze.", (AcceptableValueBase)null, Array.Empty<object>()));
			WriteItemsToTextFile = ((BaseUnityPlugin)this).Config.Bind<bool>(new ConfigDefinition(text, "WriteItemsToTextFile"), false, new ConfigDescription("If true, when this config is saved, write the items to a text file. File will be saved according to the file path set in the next setting.", (AcceptableValueBase)null, Array.Empty<object>()));
			WriteItemsToTextFilePath = ((BaseUnityPlugin)this).Config.Bind<string>(new ConfigDefinition(text, "WriteItemsToTextFilePath"), "AllItems.txt", new ConfigDescription("File path to the text file to write the items to. Default is in the BepInEx/logs folder. Use a relative path to the BepInEx/logs folder.", (AcceptableValueBase)null, Array.Empty<object>()));
			WriteItemsToTextFilePath.SettingChanged += delegate
			{
				if (WriteItemsToTextFile.Value)
				{
					LogInfo("Writing items to text file");
					SeedSearcherFunctions.WriteItemsToText();
					WriteItemsToTextFile.Value = false;
				}
			};
			SearchForItemsOnChange.SettingChanged += delegate
			{
				if (SearchForItemsOnChange.Value)
				{
					LogInfo("Searching for items on change");
					SeedSearcherFunctions.ExecuteSearch();
					SearchForItemsOnChange.Value = false;
				}
			};
			PluginName = "SeedSearcher";
			PluginVersion = "1.2.1";
			PluginGUID = "com.binbin.SeedSearcher";
			if (EnableMod.Value)
			{
				if (EssentialsCompatibility.Enabled)
				{
					EssentialsCompatibility.EssentialsRegister();
				}
				else
				{
					LogInfo(PluginGUID + " " + PluginVersion + " has loaded!");
				}
				harmony.PatchAll();
			}
		}

		internal static void LogDebug(string msg)
		{
			Log.LogDebug((object)(debugBase + msg));
		}

		internal static void LogInfo(string msg)
		{
			Log.LogInfo((object)(debugBase + msg));
		}

		internal static void LogError(string msg)
		{
			Log.LogError((object)(debugBase + msg));
		}

		public static List<string> GetItemList()
		{
			if ((Object)(object)Globals.Instance != (Object)null)
			{
				return Globals.Instance.CardListByClass[(CardClass)8];
			}
			return new List<string>
			{
				"acolytetunic", "acolytetunicrare", "advancedhandbook", "advancedhandbookrare", "aegis", "aegisrare", "agateamulet", "agateamuletrare", "alarmbell", "alarmbellrare",
				"albatrosspendant", "albatrosspendantrare", "alchemypot", "alchemypotrare", "allseeingamulet", "allseeingamuletrare", "amberamulet", "amberamuletrare", "amethystring", "amethystringrare",
				"amuletofprotection", "amuletofprotectionrare", "amuletofspeed", "amuletofspeedrare", "amuletofthorns", "amuletofthornsrare", "ankhoflife", "ankhofliferare", "antiquefigurine", "antiquefigurinerare",
				"aquamarinebracelet", "aquamarinebraceletrare", "architectsring", "architectsringrare", "archmagebook", "archmagebookrare", "asmody", "asmodyrare", "assassintools", "assassintoolsrare",
				"avoidancecollar", "avoidancecollarrare", "ballofwool", "ballofwoolrare", "bandages", "bandagesrare", "bastion", "bastionrare", "batsy", "batsyrare",
				"battleaxe", "battleaxerare", "beermug", "beermugrare", "bell", "bellrare", "belphyorpipe", "belphyorpiperare", "berserkerclaw", "berserkerclawrare",
				"berserkpotion", "berserkpotionrare", "betty", "bettyrare", "blackdeck", "blackdeckrare", "blackguard", "blackguardrare", "blackpyramid", "blackpyramidrare",
				"bloodamulet", "bloodamuleta", "bloodamuletb", "bloodamuletrare", "bloodblobpet", "bloodblobpetrare", "blooddguard", "blooddguardrare", "bloodgoblet", "bloodgobletrare",
				"bloodlettersfang", "bloodlettersfangrare", "bloodseeker", "bloodseekerrare", "bloodstone", "bloodstonerare", "blowgun", "blowgunrare", "bluefeather", "bluefeatherrare",
				"blueprints", "blueprintsrare", "blunderbluss", "blunderblussrare", "boneclaws", "boneclawsa", "boneclawsb", "boneclawsrare", "bonering", "boneringrare",
				"bonkhammer", "bonkhammerrare", "bootsofswiftness", "bootsofswiftnessrare", "brassamulet", "brassamuletrare", "brasslantern", "brasslanternrare", "breastplate", "breastplaterare",
				"brigandarmor", "brigandarmorrare", "brokenitem", "bronzegear", "bronzegearrare", "bucket", "bucketrare", "bunny", "bunnyrare", "burialmask",
				"burialmaskrare", "burneditem", "burningorb", "burningorbrare", "butcherblock", "butcherblockrare", "butchersknife", "butcherskniferare", "cauldron", "cauldronrare",
				"chaliceofkings", "chaliceofkingsrare", "chaliceofqueens", "chaliceofqueensrare", "champy", "champyrare", "chaosblobpet", "chaosblobpetrare", "chaoticspear", "chaoticspearrare",
				"chargedtrident", "chargedtridentrare", "cheese", "cheeserare", "chompy", "chompyrare", "chumpy", "chumpyrare", "clairvoyantscroll", "clairvoyantscrollrare",
				"clergyamulet", "clergyamuletrare", "cloackofevasion", "cloackofevasionrare", "cloackofspeed", "cloackofspeedrare", "cloudsong", "cloudsongrare", "club", "clubrare",
				"coldbonegoblet", "coldbonegobletrare", "coldbook", "coldbookrare", "coldrune", "coldrunerare", "combatbandages", "combatbandagesa", "combatbandagesb", "combatbandagesrare",
				"compass", "compassrare", "continuumblade", "continuumbladerare", "coolingservos", "coolingservosrare", "corruptedplate", "corruptedplatea", "corruptedplateb", "corruptedplaterare",
				"corsairhat", "corsairhatrare", "countsamulet", "countsamuletrare", "countscloak", "countscloakrare", "crankcrossbow", "crankcrossbowrare", "crescentmoon", "crescentmoonrare",
				"crimsonraiment", "crimsonraimentrare", "crossbow", "crossbowrare", "crusaderhelmet", "crusaderhelmetrare", "crystalball", "crystalballrare", "cuby", "cubyd",
				"cubydrare", "cubyrare", "cupcake", "cupcakerare", "cupofdeath", "cupofdeathrare", "curseddagger", "curseddaggerrare", "cursedjewelersring", "dagger",
				"daggerrare", "daley", "daleyrare", "darkblobpet", "darkblobpetrare", "darkflamering", "darkflameringrare", "darkhood", "darkhoodrare", "dartpouch",
				"dartpouchrare", "deformeditem", "desertjam", "desertjamrare", "dessert", "dessertrare", "destiny", "destinyrare", "destroyergauntlets", "destroyergauntletsrare",
				"detoxpotion", "detoxpotionrare", "diamondring", "diamondringrare", "dimensionalcrystal", "dimensionalcrystalrare", "dirtybandages", "dirtybandagesrare", "divinationorb", "divinationorbrare",
				"divinghelmet", "divinghelmetrare", "dracomancerstaff", "dracomancerstaffrare", "dreamcatcher", "dreamcatcherrare", "dreamsphere", "dreamsphererare", "druidicamulet", "druidicamuletrare",
				"dryadmask", "dryadmaskrare", "durandal", "durandalrare", "duskforgedarmor", "duskforgedarmora", "duskforgedarmorb", "duskforgedarmorrare", "dwarvenhelmet", "dwarvenhelmetrare",
				"dynamite", "dynamiterare", "edgeoffury", "edgeoffuryrare", "eeriering", "eerieringrare", "eldritchcloak", "eldritchcloakrare", "eldritchring", "eldritchringrare",
				"eldritchsword", "eldritchswordrare", "eldritchwand", "eldritchwandrare", "electricblobpet", "electricblobpetrare", "elvencuirass", "elvencuirassrare", "elvenquiver", "elvenquiverrare",
				"emeraldnecklace", "emeraldnecklacerare", "emeraldstaff", "emeraldstaffrare", "endlessbag", "endlessbagrare", "energyshield", "energyshieldrare", "eternalcandle", "eternalcandlerare",
				"exoticspices", "exoticspicesrare", "faeborgscale", "faeborgscalerare", "faithring", "faithringrare", "familyjewels", "familyjewelsa", "familyjewelsb", "familyjewelsrare",
				"featherearring", "featherearringrare", "fenny", "fennyrare", "ferventring", "ferventringrare", "fierywand", "fierywandrare", "firebook", "firebookrare",
				"firerune", "firerunerare", "fishbonesoup", "fishbonesouprare", "fishcage", "fishcagerare", "fishingrod", "fishingrodrare", "fistofthedamned", "fistofthedamnedrare",
				"flail", "flailrare", "flamingsword", "flamingswordrare", "flamy", "flamyrare", "floaty", "floatyrare", "flute", "fluterare",
				"forestbanner", "forestbannera", "forestbannerb", "forestbannerrare", "forestcrown", "forestcrownrare", "fork", "forkrare", "fountainpen", "fountainpenrare",
				"fourleafclover", "fourleafcloverrare", "freelover", "freeloverrare", "freezingink", "freezinginkrare", "frostaxe", "frostaxerare", "frostfirering", "frostfireringrare",
				"frostguard", "frostguardrare", "frozenarrows", "frozenarrowsrare", "frozenheirloom", "frozenheirloomrare", "frozenorb", "frozenorbrare", "frozentear", "frozentearrare",
				"garnetearrings", "garnetearringsrare", "gauntlets", "gauntletsrare", "gihlrunestone", "gihlrunestonerare", "gildedplate", "gildedplatea", "gildedplateb", "gildedplaterare",
				"glacialhammer", "glacialhammerrare", "gladiatorhelmet", "gladiatorhelmetrare", "gloves", "glovesofagility", "glovesofagilityrare", "glovesrare", "goblinamulet", "goblinamuletrare",
				"goggles", "gogglesrare", "goldchain", "goldchainrare", "goldenbell", "goldenbellrare", "goldenchalice", "goldenchalicerare", "goldencloak", "goldencloakrare",
				"goldencross", "goldencrossrare", "goldenharp", "goldenharprare", "goldenlaurel", "goldenlaurelrare", "goldring", "goldringrare", "greaterhealthpotion", "greaterhealthpotionrare",
				"greatermanapotion", "greatermanapotionrare", "handbook", "handbookrare", "harbingerofdeath", "harbingerofdeathrare", "healingbook", "healingbookrare", "healthpotion", "healthpotionrare",
				"heartamulet", "heartamuletrare", "heartofthorns", "heartofthornsrare", "heavybelt", "heavybeltrare", "heavypackage", "hellblade", "hellbladerare", "helmet",
				"helmetrare", "hightchancellorstaff", "hightchancellorstaffa", "hightchancellorstaffb", "hightchancellorstaffrare", "holyblobpet", "holyblobpetrare", "holybook", "holybookrare", "holygrail",
				"holygrailrare", "holyhammer", "holyhammerrare", "holyrune", "holyrunerare", "hornethelmet", "hornethelmetrare", "hourglassofdeath", "hourglassofdeathrare", "hunterscharm",
				"hunterscharmrare", "hunterswhip", "hunterswhiprare", "huntingring", "huntingringrare", "hydraegg", "hydraeggrare", "hypnoshell", "hypnoshellrare", "icebreaker",
				"icebreakerrare", "iceorb", "iceorbrare", "icyblobpet", "icyblobpetrare", "icywand", "icywandrare", "ignidohscore", "ignidohscorerare", "igniscloack",
				"igniscloackrare", "impstatuette", "impstatuetterare", "infusedgem", "infusedgemrare", "inky", "inkyrare", "ironfortress", "ironfortressrare", "ironkanabo",
				"ironkanaborare", "ironwand", "ironwandrare", "jadering", "jaderingrare", "jelly", "jellyrare", "jewelersring", "jewelersringrare", "jinglebell",
				"jinglebella", "jinglebellb", "jinglebellrare", "jollyroger", "jollyrogerrare", "justicarring", "justicarringrare", "kingmaker", "kingmakerrare", "kiteshield",
				"kiteshieldrare", "krakensushi", "krakensushirare", "lapisnecklace", "lapisnecklacerare", "largepouch", "largepouchrare", "largeshield", "largeshieldrare", "lavablobpet",
				"lavablobpetrare", "lavacrystal", "lavacrystalrare", "lavaorb", "lavaorbrare", "lavapotion", "lavapotionrare", "leatherarmor", "leatherarmorrare", "leatherboots",
				"leatherbootsrare", "leathergloves", "leatherglovesrare", "liante", "lianterare", "lifebindersashes", "lifebindersashesrare", "lifeessence", "lifeessencerare", "lightbringer",
				"lightbringerrare", "lightningbook", "lightningbookrare", "lightningrune", "lightningrunerare", "lightningspear", "lightningspearrare", "lockpicks", "lockpicksrare", "longbow",
				"longbowrare", "longevitypotion", "longevitypotiona", "longevitypotionb", "longevitypotionrare", "lostmail", "lostmailrare", "luckypaw", "luckypawrare", "lunaring",
				"lunaringrare", "lychee", "lycheerare", "machineoil", "machineoilrare", "madnessring", "madnessringrare", "magictome", "magictomerare", "magusstaff",
				"magusstaffrare", "manaloop", "manalooprare", "manapotion", "manapotionrare", "maskofanger", "maskofangerrare", "maskofjoy", "maskofjoyrare", "maskoftolerance",
				"maskoftolerancerare", "matey", "mateyrare", "matriarchsclaw", "matriarchsclawrare", "megaphone", "megaphonerare", "merchantbadge", "merchantbadgerare", "metalblobpet",
				"metalblobpetrare", "midnightgloves", "midnightglovesrare", "mildbroth", "mildbrothrare", "mimy", "mimyrare", "mindbook", "mindbookrare", "minotaurhorn",
				"minotaurhornrare", "mirrorofkalandra", "mirrorofkalandrarare", "mixedsalad", "mixedsaladrare", "mjolnir", "mjolnirrare", "mnemrunestone", "mnemrunestonerare", "morningstar",
				"morningstarrare", "mortarandpestle", "mortarandpestlerare", "mountainking", "mountainkingrare", "mozzy", "mozzyrare", "mysticstaff", "mysticstaffrare", "necromancerrobe",
				"necromancerroberare", "netherblade", "netherbladerare", "neverfrost", "neverfrostrare", "nightveil", "nightveilrare", "ninjascroll", "ninjascrollrare", "nobleshield",
				"nobleshieldrare", "nullifier", "nullifierrare", "obeliskscroll", "obeliskscrollrare", "obsidiandagger", "obsidiandaggerrare", "obsidianring", "obsidianringrare", "obsidianrod",
				"obsidianrodrare", "oculy", "oculyrare", "oldhorseshoe", "oldhorseshoerare", "onyxamulet", "onyxamuletrare", "opalring", "opalringrare", "orbofstorms",
				"orbofstormsrare", "orby", "orbyrare", "osmiumfeet", "osmiumfeetrare", "paladingauntlets", "paladingauntletsrare", "pancakes", "pancakesrare", "pandorasbox",
				"pandorasboxrare", "pearlbelt", "pearlbeltrare", "penitencering", "penitenceringrare", "piggybank", "piousring", "piousringrare", "pirategrog", "pirategrograre",
				"piratehat", "piratehatrare", "platemail", "platemailrare", "platinumring", "platinumringrare", "pointyhat", "pointyhatrare", "poisoneddagger", "poisoneddaggerrare",
				"powdercask", "powdercaskrare", "powercoil", "powercoilrare", "powerglove", "powerglovea", "powergloveb", "powergloverare", "primalnecklace", "primalnecklacerare",
				"prophetstaff", "prophetstaffa", "prophetstaffb", "prophetstaffrare", "purpletentacle", "purpletentaclerare", "pyromancerrobe", "pyromancerroberare", "quill", "quillrare",
				"raggeddoll", "raggeddolla", "raggeddollb", "raggeddollrare", "raiderslicer", "raiderslicerrare", "raincoat", "raincoatrare", "rangerarmor", "rangerarmora",
				"rangerarmorb", "rangerarmorrare", "ravenstaff", "ravenstaffrare", "razor", "razorrare", "redcape", "redcaperare", "redfeather", "redfeatherrare",
				"redsteelcloack", "redsteelcloackrare", "reforgedcore", "reforgedcorea", "reforgedcoreb", "reforgedcorerare", "reinforcedarmor", "reinforcedarmorrare", "rejuvenationpotion", "rejuvenationpotionrare",
				"retaliator", "retaliatorrare", "riftshard", "riftshardrare", "riftshield", "riftshieldrare", "rifty", "riftyrare", "ringoffire", "ringoffirerare",
				"ringofhope", "ringofhoperare", "ringofprotection", "ringofprotectionrare", "ritualdagger", "ritualdaggerrare", "rocketboots", "rocketbootsa", "rocketbootsb", "rocketbootsrare",
				"rocky", "rockyrare", "roundshield", "roundshieldrare", "royalcoin", "royalcoinrare", "rubyamulet", "rubyamuletrare", "rubycuirass", "rubycuirassrare",
				"rudder", "rudderrare", "runicdice", "runicdicerare", "runicring", "runicringrare", "rustyarmor", "rustyarmorrare", "rustyboots", "rustybootsrare",
				"rustyhook", "rustyhookrare", "rustyring", "rustyringrare", "sacredaxe", "sacredaxerare", "sacredtablet", "sacredtabletrare", "sahtipendant", "sahtipendantrare",
				"salt", "saltrare", "samuraiarmor", "samuraiarmorrare", "sapphireamulet", "sapphireamuletrare", "sapphirering", "sapphireringrare", "savantrobe", "savantroberare",
				"scarabshield", "scarabshieldrare", "scaraby", "scarabyrare", "scholarrobe", "scholarroberare", "screwdriver", "screwdriverrare", "scrollofresurrection", "scrollofresurrectionrare",
				"scryerstaff", "scryerstaffrare", "searingdagger", "searingdaggerrare", "seashell", "seashellamulet", "seashellamuletrare", "seashellrare", "seashellring", "seashellringrare",
				"serenityring", "serenityringrare", "sextant", "sextantrare", "shacklesofwar", "shacklesofwarrare", "shadowbook", "shadowbookrare", "shadowcloack", "shadowcloackrare",
				"shadoworb", "shadoworbrare", "shadowrune", "shadowrunerare", "sharpscimitar", "sharpscimitarrare", "sharpy", "sharpyrare", "shieldofthorns", "shieldofthornsrare",
				"shortsword", "shortswordrare", "shoulderplate", "shoulderplaterare", "sidearm", "sidearmrare", "silverchalice", "silverchalicerare", "silverring", "silverringrare",
				"simplehat", "simplehatrare", "singingsword", "singingswordrare", "slimy", "slimyrare", "slingshot", "slingshotrare", "slippers", "slippersrare",
				"smallchest", "smallchestrare", "smallpouch", "smallpouchrare", "soap", "soaprare", "solring", "solringrare", "soullantern", "soullanterna",
				"soullanternb", "soullanternrare", "soulreaver", "soulreaverrare", "spear", "spearrare", "spicydish", "spicydishrare", "spiderqueeneye", "spiderqueeneyerare",
				"spikedbracers", "spikedbracersrare", "spikedshoulderpads", "spikedshoulderpadsrare", "spikygauntlets", "spikygauntletsrare", "spooky", "spookyrare", "spyglass", "spyglassrare",
				"squidtoken", "stainlesscuirass", "stainlesscuirassrare", "steadfastboots", "steadfastbootsrare", "steadfastshield", "steadfastshieldrare", "steelrod", "steelrodrare", "stimulantpills",
				"stimulantpillsrare", "stoneamulet", "stoneamuletrare", "stonemaul", "stonemaulrare", "stormcallerfeather", "stormcallerfeatherrare", "storminabottle", "storminabottlerare", "stormtiara",
				"stormtiararare", "stormy", "stormyrare", "strawhat", "strawhatrare", "strongmojo", "strongmojorare", "suppressionhelmet", "suppressionhelmetrare", "surprisebox",
				"surpriseboxrare", "surprisegiftbox", "surprisegiftboxrare", "taintedrod", "taintedrodrare", "tempest", "tempestrare", "templeamulet", "templeamuletrare", "terrorring",
				"terrorringrare", "tesseract", "tesseractrare", "theanvil", "theanvilrare", "thedarkone", "thedarkonerare", "thedefiler", "thedefilerrare", "thejuggernaut",
				"thejuggernautrare", "theone", "theonerare", "thepolluter", "thepolluterrare", "theporcupine", "theporcupinerare", "theproficient", "theproficientrare", "thermalamulet",
				"thermalamuletrare", "thermalring", "thermalringrare", "thewall", "thewallrare", "thewolfslayer", "thewolfslayera", "thewolfslayerb", "thewolfslayerrare", "thorimsrod",
				"thornyring", "thornyringrare", "tikimask", "tikimaskrare", "timepiece", "timepiecea", "timepieceb", "timepiecerare", "tinycannon", "tinycannonrare",
				"titangauntlets", "titangauntletsrare", "topazring", "topazringrare", "torch", "torchrare", "touristmap", "touristmaprare", "toxicblobpet", "toxicblobpetrare",
				"turban", "turbanrare", "turboboots", "turbobootsrare", "twinblades", "twinbladesrare", "tyrantnecklace", "tyrantnecklacerare", "undeathichor", "undeathichorrare",
				"unholyhammer", "unholyhammerrare", "uselessitem", "veiledbonds", "veiledbondsrare", "venomamulet", "venomamuletrare", "venomfang", "venomfangrare", "venomflask",
				"venomflaska", "venomflaskb", "venomflaskrare", "veteranarmor", "veteranarmorrare", "vilering", "vileringrare", "viperring", "viperringrare", "virulentring",
				"virulentringrare", "visionring", "visionringrare", "volcanicaxe", "volcanicaxerare", "voodoodoll", "voodoodollrare", "warbanner", "warbannerrare", "wardrum",
				"wardrumrare", "warhammer", "warhammerrare", "warriorcode", "warriorcoderare", "waterblobpet", "waterblobpetrare", "waterskin", "waterskinrare", "watervase",
				"watervaserare", "weaponpouch", "weaponpouchrare", "winebottle", "winebottlerare", "wingblade", "wingbladerare", "wingedhelmet", "wingedhelmeta", "wingedhelmetb",
				"wingedhelmetrare", "wingedwand", "wingedwandrare", "wolfskincloack", "wolfskincloackrare", "wolfy", "wolfyrare", "woodencrosier", "woodencrosiera", "woodencrosierb",
				"woodencrosierrare", "woollyhat", "woollyhatrare", "xulrunestone", "xulrunestonerare", "yellowfeather", "yellowfeatherrare", "yggdrasilroot", "yggdrasilrootrare", "yinyangbadge",
				"yinyangbadgerare", "ylmerbranch", "ylmerbranchrare", "yoggercleaver", "yoggercleaverrare"
			};
		}

		public static List<string> GetLocationList()
		{
			return new List<string>
			{
				"apothecaryhigh", "apothecarylow", "apprentince", "aquarvendor", "bakerson_a", "bakerson_b", "balanceblack", "balanceboth", "balancewhite", "Basthet",
				"battlefield", "Behindwaterfall", "belphyor", "belphyorquest", "betty", "blobbleed", "blobcold", "blobdire", "blobholy", "bloblightning",
				"blobmetal", "blobmind", "blobpoison", "blobselem", "blobshadow", "blobsmyst", "blobsphys", "blobwater", "bridge", "burninghand",
				"burninghouse_a", "burninghouse_b", "caravanshop", "challenge_boss_fisher", "challenge_boss_high", "challenge_boss_hydra", "challenge_boss_low", "challenge_chest_final", "challenge_chest_high", "challenge_chest_low",
				"challenge_start", "chappel", "courtcraftobsidian", "crane", "crocoloot", "crocosmugglers", "crossroads_a", "crossroads_b", "crossroads_c", "cuby",
				"cubyd", "daley", "daleyrare", "desertreliquary", "dreadcosme", "dreadcuthbert", "dreadfrancis", "dreadhalfman", "dreadhoratio", "dreadjack",
				"dreadmimic", "dreadpurser", "dreadpurserstash", "dreadrhodogor", "dream_13_loot", "dream_6_loot", "dream_9_loot", "Dryad_a", "Dryad_b", "eeriechest_a",
				"eeriechest_b", "elvenarmory", "elvenarmoryplus", "elvenemporium", "exoticshop_tier0", "exoticshop_tier1", "exoticshop_tier2", "exoticshop_tier3", "Faeborg", "felineshop",
				"fenny", "fennyrare", "firebazaar", "fishermanchest", "fishlava", "fishlavarare", "franky", "FrozenSewersElves", "FrozenSewersMix", "FrozenSewersRatmen",
				"gobletsmerchant", "goblinchest", "goblintown", "Goblintown_a", "Goblintown_b", "Goblintown_c", "harpychest", "harpyfight", "heronshop", "Hydra",
				"Ignidoh", "inky", "Jelly", "Jeweler", "Jewelerrings", "khazakdhum", "kingrat", "laircocoon", "lavacascade", "lavacascadepet",
				"liante", "lootedarmory", "Mansionleft", "Mansionleftplus", "Mansionright", "matey", "mateyrare", "Merchantwares", "mimy", "minotaurcave",
				"Mortis", "mutatedcocoon", "nagashop", "nagavendor", "obechampy", "obechompy", "obechumpy", "obeliskash", "obeliskdelivery", "obeliskgirl",
				"obeliskshophigh", "obeliskshoplow", "obelisktreasure", "obsidianall", "obsidiananvil", "obsidiananvilrare", "obsidianboots", "obsidianbootsrare", "obsidianrings", "obsidianringsrare",
				"obsidianrods", "obsidianrodsrare", "oculy", "petshop", "rareshop_tier0", "rareshop_tier1", "rareshop_tier2", "rareshop_tier3", "reverie", "rift",
				"riftsen", "Rocky", "rubychest", "rubyrefuges", "ruinedplaza", "ruinedplaza_crit", "ruinedplaza_fail", "sahtibernardstash", "sahtibernardstashshop", "sahtidaleshop",
				"sahtidomedesert", "sahtidomeice", "sahtidomemain", "sahtidomemountain", "sahtidomeswamp", "sahtifishingshop", "sahtikraken", "sahtikrakenmjolmir", "sahtipiratearsenal", "sahtipiratewarehouse",
				"sahtiplaguecot", "sahtirustkingtreasure", "sahtisurgeonarsenal", "sahtisurgeonstash", "sahtitreasurechamber", "sahtivalkyriestash", "Sailor", "Shady", "sharpy", "slimy",
				"spiderqueen", "Stolenitems", "stormy", "Sunkenblooddelighted", "Sunkenblooddisrespected", "Sunkenbloodpleased", "sunkenholelab", "sunkenmineslave", "sunkenofferingroom", "Sunkensaflamedelighted",
				"Sunkensaflamedisrespected", "Sunkensaflamepleased", "sunkenspidershrine", "Sunkenthunderdelighted", "Sunkenthunderdisrespected", "Sunkenthunderpleased", "Sylviehome", "thorimsrod", "towntier0", "towntier0_a",
				"towntier0_b", "towntier1", "towntier1_a", "towntier1_b", "towntier2", "towntier2_a", "towntier2_b", "towntier3", "towntier3_a", "towntier3_b",
				"tradeship1", "tradeship10", "tradeship2", "tradeship3", "tradeship4", "tradeship5", "tradeship6", "tradeship7", "tradeship8", "tradeship9",
				"treasureaquarfall", "Tulah", "tyrant", "tyrantbeavers", "tyrantchampy", "tyrantchompy", "tyrantchumpy", "uprienergy", "uprimagma", "upripreboss",
				"upriprebossnenukill", "voidasmody", "voidcraftemerald", "voidcraftgolden", "voidcraftobsidian", "voidcraftpearl", "voidcraftring", "voidcraftruby", "voidcraftsapphire", "voidcrafttopaz",
				"voidshop", "voidtreasure", "voidtreasurejade", "voidtsnemo", "voidtwins", "voodooshop", "wareacc0", "wareacc1", "wareacc2", "warearm0",
				"warearm1", "warearm2", "warejew0", "warejew1", "warejew2", "warenavalea", "wareweap0", "wareweap1", "wareweap2", "watermill",
				"weekly1", "weekly10", "weekly11", "weekly12", "weekly13", "weekly2", "weekly3", "weekly4", "weekly5", "weekly6",
				"weekly7", "weekly8", "weekly9", "weeklychristmas", "weeklyhalloween", "weeklylunar", "werewolfstall_a", "werewolfstall_b", "wolfy", "woodsshop",
				"woodstreasurechest", "Ylmer", "yogger"
			};
		}

		public static string DictToString(Dictionary<string, List<string>> dict)
		{
			if (dict == null)
			{
				throw new ArgumentNullException("dict");
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append('{');
			List<string> list = dict.Keys.OrderBy((string k) => k).ToList();
			for (int i = 0; i < list.Count; i++)
			{
				string text = list[i];
				List<string> list2 = dict[text];
				stringBuilder.Append("\"" + text + "\":[");
				for (int j = 0; j < list2.Count; j++)
				{
					stringBuilder.Append("\"" + list2[j] + "\"");
					if (j < list2.Count - 1)
					{
						stringBuilder.Append(',');
					}
				}
				stringBuilder.Append(']');
				if (i < list.Count - 1)
				{
					stringBuilder.Append(',');
				}
			}
			stringBuilder.Append('}');
			return stringBuilder.ToString();
		}
	}
	[HarmonyPatch]
	public class SeedSearcherFunctions
	{
		public static Dictionary<string, string> allLootLocations = new Dictionary<string, string>
		{
			{ "FrozenSewersElves", "sewers_11" },
			{ "towntier0_b", "sen_41" },
			{ "chappel", "sen_21" },
			{ "voidtsnemo", "voidlow_24" },
			{ "voidshop", "voidlow_8" },
			{ "rubychest", "aqua_20" },
			{ "rubyrefuges", "aqua_20" },
			{ "caravanshop", "sen_44" },
			{ "Basthet", "pyr_7" },
			{ "Dryad_a", "sen_31" },
			{ "Dryad_b", "sen_32" },
			{ "Faeborg", "faen_38" },
			{ "Hydra", "aqua_35" },
			{ "Ignidoh", "velka_32" },
			{ "Mansionright", "faen_35" },
			{ "Mortis", "ulmin_56" },
			{ "Tulah", "spider_8" },
			{ "Ylmer", "sen_33" },
			{ "belphyor", "secta_5" },
			{ "belphyorquest", "velka_8" },
			{ "burninghand", "velka_25" },
			{ "dreadhalfman", "dread_11" },
			{ "elvenarmory", "faen_29" },
			{ "elvenarmoryplus", "faen_29" },
			{ "goblintown", "velka_6" },
			{ "harpychest", "velka_27" },
			{ "harpyfight", "velka_27" },
			{ "khazakdhum", "velka_29" },
			{ "kingrat", "sewers_8" },
			{ "minotaurcave", "velka_9" },
			{ "sahtikraken", "sahti_65" },
			{ "sahtikrakenmjolmir", "sahti_65" },
			{ "sahtirustkingtreasure", "sahti_62" },
			{ "spiderqueen", "sen_1" },
			{ "tyrant", "faen_25" },
			{ "tyrantbeavers", "faen_25" },
			{ "tyrantchampy", "faen_25" },
			{ "tyrantchompy", "faen_25" },
			{ "tyrantchumpy", "faen_25" },
			{ "upripreboss", "uprising_13" },
			{ "yogger", "sen_27" },
			{ "voidtwins", "voidlow_25" },
			{ "voidtreasurejade", "voidlow_16" }
		};

		public static Dictionary<string, string> guaranteedDropNodeMap = new Dictionary<string, string>
		{
			{ "rubychest", "aqua_20" },
			{ "rubyrefuges", "aqua_20" },
			{ "FrozenSewersElves", "sewers_11" },
			{ "FrozenSewersMix", "sewers_11" },
			{ "FrozenSewersRatmen", "sewers_11" },
			{ "Jewelerrings", "sen_35" },
			{ "Mansionleft", "faen_35" },
			{ "Mansionleftplus", "faen_35" },
			{ "Sailor", "faen_4" },
			{ "Stolenitems", "faen_10" },
			{ "apprentince", "sen_24" },
			{ "balanceblack", "ulmin_52" },
			{ "balanceboth", "ulmin_52" },
			{ "balancewhite", "ulmin_52" },
			{ "battlefield", "aqua_6" },
			{ "bridge", "sen_17" },
			{ "chappel", "sen_21" },
			{ "crane", "velka_21" },
			{ "crocoloot", "aqua_7" },
			{ "crocosmugglers", "aqua_48" },
			{ "desertreliquary", "ulmin_58" },
			{ "dreadcosme", "dread_2" },
			{ "dreadcuthbert", "dread_2" },
			{ "dreadfrancis", "dread_2" },
			{ "dreadhoratio", "dread_2" },
			{ "dreadjack", "dread_2" },
			{ "dreadmimic", "dread_10" },
			{ "dreadrhodogor", "dread_2" },
			{ "eeriechest_a", "sen_6" },
			{ "eeriechest_b", "sen_6" },
			{ "lavacascade", "velka_22" },
			{ "lootedarmory", "pyr_10" },
			{ "obsidianall", "forge_3" },
			{ "obsidiananvil", "forge_3" },
			{ "obsidianboots", "forge_3" },
			{ "obsidianrings", "forge_3" },
			{ "obsidianrods", "forge_3" },
			{ "rift", "velka_40" },
			{ "riftsen", "sen_48" },
			{ "sahtibernardstash", "sahti_52" },
			{ "sahtidomedesert", "sahti_49" },
			{ "sahtidomeice", "sahti_49" },
			{ "sahtidomemain", "sahti_49" },
			{ "sahtidomemountain", "sahti_49" },
			{ "sahtidomeswamp", "sahti_49" },
			{ "sahtipiratearsenal", "sahti_25" },
			{ "sahtipiratewarehouse", "sahti_25" },
			{ "sahtiplaguecot", "sahti_11" },
			{ "sahtisurgeonarsenal", "sahti_13" },
			{ "sahtisurgeonstash", "sahti_13" },
			{ "sahtitreasurechamber", "sahti_25" },
			{ "sahtivalkyriestash", "sahti_19" },
			{ "thorimsrod", "forge_8" },
			{ "treasureaquarfall", "aqua_28" },
			{ "uprienergy", "uprising_5" },
			{ "uprimagma", "uprising_4" },
			{ "voidcraftemerald", "voidlow_14" },
			{ "voidcraftgolden", "voidlow_14" },
			{ "voidcraftobsidian", "voidlow_14" },
			{ "voidcraftpearl", "voidlow_14" },
			{ "voidcraftring", "voidlow_14" },
			{ "voidcraftruby", "voidlow_14" },
			{ "voidcraftsapphire", "voidlow_14" },
			{ "voidcrafttopaz", "voidlow_14" },
			{ "voidtreasurejade", "voidlow_16" },
			{ "watermill", "sen_15" }
		};

		public static Dictionary<string, string> MythicLocations = new Dictionary<string, string>
		{
			{ "towntier3", "voidlow_1" },
			{ "towntier3_a", "voidlow_1" },
			{ "towntier3_b", "voidlow_1" },
			{ "ruinedplaza", "voidlow_5" },
			{ "ruinedplaza_crit", "voidlow_5" },
			{ "voidasmody", "voidhigh_6" },
			{ "voidshop", "voidlow_8" },
			{ "voidtreasure", "voidlow_16" },
			{ "voidtreasurejade", "voidlow_16" },
			{ "voidtsnemo", "voidlow_24" },
			{ "voidtwins", "voidlow_25" },
			{ "wareacc1", "voidlow_4" },
			{ "wareacc2", "voidlow_4" },
			{ "warearm1", "voidlow_4" },
			{ "warearm2", "voidlow_4" },
			{ "warejew1", "voidlow_4" },
			{ "warejew2", "voidlow_4" },
			{ "warenavalea", "voidlow_4" },
			{ "wareweap1", "voidlow_4" },
			{ "wareweap2", "voidlow_4" }
		};

		public static Dictionary<string, string> allItemDropLocations = new Dictionary<string, string>
		{
			{ "towntier0", "sen_41" },
			{ "towntier0_a", "sen_41" },
			{ "towntier0_b", "sen_41" },
			{ "towntier3", "voidlow_1" },
			{ "towntier3_a", "voidlow_1" },
			{ "towntier3_b", "voidlow_1" },
			{ "ruinedplaza", "voidlow_5" },
			{ "ruinedplaza_crit", "voidlow_5" },
			{ "voidasmody", "voidhigh_6" },
			{ "voidshop", "voidlow_8" },
			{ "voidtreasure", "voidlow_16" },
			{ "voidtreasurejade", "voidlow_16" },
			{ "voidtsnemo", "voidlow_24" },
			{ "voidtwins", "voidlow_25" },
			{ "wareacc1", "voidlow_4" },
			{ "wareacc2", "voidlow_4" },
			{ "warearm1", "voidlow_4" },
			{ "warearm2", "voidlow_4" },
			{ "warejew1", "voidlow_4" },
			{ "warejew2", "voidlow_4" },
			{ "warenavalea", "voidlow_4" },
			{ "wareweap1", "voidlow_4" },
			{ "wareweap2", "voidlow_4" },
			{ "aquarvendor", "aqua_26" },
			{ "elvenemporium", "faen_23" },
			{ "felineshop", "ulmin_29" },
			{ "firebazaar", "velka_20" },
			{ "heronshop", "ulmin_27" },
			{ "Merchantwares", "velka_7" },
			{ "voodooshop", "aqua_23" },
			{ "Jeweler", "sen_35" },
			{ "gobletsmerchant", "sewers_4" },
			{ "werewolfstall_a", "sen_30" },
			{ "werewolfstall_b", "sen_30" },
			{ "FrozenSewersElves", "sewers_11" },
			{ "FrozenSewersMix", "sewers_11" },
			{ "FrozenSewersRatmen", "sewers_11" },
			{ "Jewelerrings", "sen_35" },
			{ "Mansionleft", "faen_35" },
			{ "Mansionleftplus", "faen_35" },
			{ "Sailor", "faen_4" },
			{ "Stolenitems", "faen_10" },
			{ "apprentince", "sen_24" },
			{ "balanceblack", "ulmin_52" },
			{ "balanceboth", "ulmin_52" },
			{ "balancewhite", "ulmin_52" },
			{ "battlefield", "aqua_6" },
			{ "bridge", "sen_17" },
			{ "chappel", "sen_21" },
			{ "crane", "velka_21" },
			{ "crocoloot", "aqua_7" },
			{ "crocosmugglers", "aqua_48" },
			{ "desertreliquary", "ulmin_58" },
			{ "dreadcosme", "dread_2" },
			{ "dreadcuthbert", "dread_2" },
			{ "dreadfrancis", "dread_2" },
			{ "dreadhoratio", "dread_2" },
			{ "dreadjack", "dread_2" },
			{ "dreadmimic", "dread_10" },
			{ "dreadrhodogor", "dread_2" },
			{ "eeriechest_a", "sen_6" },
			{ "eeriechest_b", "sen_6" },
			{ "lavacascade", "velka_22" },
			{ "lootedarmory", "pyr_10" },
			{ "obsidianall", "forge_3" },
			{ "obsidiananvil", "forge_3" },
			{ "obsidianboots", "forge_3" },
			{ "obsidianrings", "forge_3" },
			{ "obsidianrods", "forge_3" },
			{ "rift", "velka_40" },
			{ "riftsen", "sen_48" },
			{ "sahtibernardstash", "sahti_52" },
			{ "sahtidomedesert", "sahti_49" },
			{ "sahtidomeice", "sahti_49" },
			{ "sahtidomemain", "sahti_49" },
			{ "sahtidomemountain", "sahti_49" },
			{ "sahtidomeswamp", "sahti_49" },
			{ "sahtipiratearsenal", "sahti_25" },
			{ "sahtipiratewarehouse", "sahti_25" },
			{ "sahtiplaguecot", "sahti_11" },
			{ "sahtisurgeonarsenal", "sahti_13" },
			{ "sahtisurgeonstash", "sahti_13" },
			{ "sahtitreasurechamber", "sahti_25" },
			{ "sahtivalkyriestash", "sahti_19" },
			{ "thorimsrod", "forge_8" },
			{ "treasureaquarfall", "aqua_28" },
			{ "uprienergy", "uprising_5" },
			{ "uprimagma", "uprising_4" },
			{ "voidcraftemerald", "voidlow_14" },
			{ "voidcraftgolden", "voidlow_14" },
			{ "voidcraftobsidian", "voidlow_14" },
			{ "voidcraftpearl", "voidlow_14" },
			{ "voidcraftring", "voidlow_14" },
			{ "voidcraftruby", "voidlow_14" },
			{ "voidcraftsapphire", "voidlow_14" },
			{ "voidcrafttopaz", "voidlow_14" },
			{ "watermill", "sen_15" },
			{ "Jelly", "aqua_41" },
			{ "betty", "sen_39" },
			{ "blobbleed", "sen_29" },
			{ "blobcold", "sewers_13" },
			{ "blobdire", "velka_37" },
			{ "blobholy", "pyr_12" },
			{ "bloblightning", "sahti_30" },
			{ "blobmetal", "velka_38" },
			{ "blobmind", "dread_7" },
			{ "blobpoison", "aqua_44" },
			{ "blobselem", "voidlow_28" },
			{ "blobshadow", "ulmin_59" },
			{ "blobsmyst", "voidlow_28" },
			{ "blobsphys", "voidlow_28" },
			{ "blobwater", "aqua_45" },
			{ "cuby", "pyr_9" },
			{ "cubyd", "pyr_9" },
			{ "daley", "faen_7" },
			{ "fenny", "ulmin_6" },
			{ "fishlava", "forge_8" },
			{ "inky", "aqua_41" },
			{ "liante", "spider_5" },
			{ "matey", "sahti_20" },
			{ "mimy", "dread_10" },
			{ "oculy", "aqua_41" },
			{ "sharpy", "aqua_18" },
			{ "slimy", "spider_7" },
			{ "stormy", "aqua_24" },
			{ "wolfy", "sen_46" },
			{ "Basthet", "pyr_7" },
			{ "Dryad_a", "sen_31" },
			{ "Dryad_b", "sen_32" },
			{ "Faeborg", "faen_38" },
			{ "Hydra", "aqua_35" },
			{ "Ignidoh", "velka_32" },
			{ "Mansionright", "faen_35" },
			{ "Mortis", "ulmin_56" },
			{ "Tulah", "spider_8" },
			{ "Ylmer", "sen_33" },
			{ "belphyor", "secta_5" },
			{ "belphyorquest", "velka_8" },
			{ "burninghand", "velka_25" },
			{ "dreadhalfman", "dread_11" },
			{ "elvenarmory", "faen_29" },
			{ "elvenarmoryplus", "faen_29" },
			{ "goblintown", "velka_6" },
			{ "harpychest", "velka_27" },
			{ "harpyfight", "velka_27" },
			{ "khazakdhum", "velka_29" },
			{ "kingrat", "sewers_8" },
			{ "minotaurcave", "velka_9" },
			{ "sahtikraken", "sahti_65" },
			{ "sahtikrakenmjolmir", "sahti_65" },
			{ "sahtirustkingtreasure", "sahti_62" },
			{ "spiderqueen", "sen_1" },
			{ "tyrant", "faen_25" },
			{ "tyrantbeavers", "faen_25" },
			{ "tyrantchampy", "faen_25" },
			{ "tyrantchompy", "faen_25" },
			{ "tyrantchumpy", "faen_25" },
			{ "upripreboss", "uprising_13" },
			{ "yogger", "sen_27" }
		};

		public static Dictionary<string, string> petDropNodeMap = new Dictionary<string, string>
		{
			{ "Jelly", "aqua_41" },
			{ "betty", "sen_39" },
			{ "blobbleed", "sen_29" },
			{ "blobcold", "sewers_13" },
			{ "blobdire", "velka_37" },
			{ "blobholy", "pyr_12" },
			{ "bloblightning", "sahti_30" },
			{ "blobmetal", "velka_38" },
			{ "blobmind", "dread_7" },
			{ "blobpoison", "aqua_44" },
			{ "blobselem", "voidlow_28" },
			{ "blobshadow", "ulmin_59" },
			{ "blobsmyst", "voidlow_28" },
			{ "blobsphys", "voidlow_28" },
			{ "blobwater", "aqua_45" },
			{ "cuby", "pyr_9" },
			{ "cubyd", "pyr_9" },
			{ "daley", "faen_7" },
			{ "fenny", "ulmin_6" },
			{ "fishlava", "forge_8" },
			{ "inky", "aqua_41" },
			{ "liante", "spider_5" },
			{ "matey", "sahti_20" },
			{ "mimy", "dread_10" },
			{ "oculy", "aqua_41" },
			{ "sharpy", "aqua_18" },
			{ "slimy", "spider_7" },
			{ "stormy", "aqua_24" },
			{ "wolfy", "sen_46" }
		};

		public static Dictionary<string, string> dropNodeMap = new Dictionary<string, string>
		{
			{ "Basthet", "pyr_7" },
			{ "Dryad_a", "sen_31" },
			{ "Dryad_b", "sen_32" },
			{ "Faeborg", "faen_38" },
			{ "Hydra", "aqua_35" },
			{ "Ignidoh", "velka_32" },
			{ "Mansionright", "faen_35" },
			{ "Mortis", "ulmin_56" },
			{ "Tulah", "spider_8" },
			{ "Ylmer", "sen_33" },
			{ "belphyor", "secta_5" },
			{ "belphyorquest", "velka_8" },
			{ "burninghand", "velka_25" },
			{ "dreadhalfman", "dread_11" },
			{ "elvenarmory", "faen_29" },
			{ "elvenarmoryplus", "faen_29" },
			{ "goblintown", "velka_6" },
			{ "harpychest", "velka_27" },
			{ "harpyfight", "velka_27" },
			{ "khazakdhum", "velka_29" },
			{ "kingrat", "sewers_8" },
			{ "minotaurcave", "velka_9" },
			{ "sahtikraken", "sahti_65" },
			{ "sahtikrakenmjolmir", "sahti_65" },
			{ "sahtirustkingtreasure", "sahti_62" },
			{ "spiderqueen", "sen_1" },
			{ "tyrant", "faen_25" },
			{ "tyrantbeavers", "faen_25" },
			{ "tyrantchampy", "faen_25" },
			{ "tyrantchompy", "faen_25" },
			{ "tyrantchumpy", "faen_25" },
			{ "upripreboss", "uprising_13" },
			{ "yogger", "sen_27" }
		};

		private static Random random = new Random();

		public static string SavedSeed = "";

		public static void ExecuteSearch()
		{
			List<(string, string)> itemsAndShops = new List<(string, string)>
			{
				(Plugin.ItemToSearchFor1.Value, Plugin.LocationToSearchForItem1.Value),
				(Plugin.ItemToSearchFor2.Value, Plugin.LocationToSearchForItem2.Value),
				(Plugin.ItemToSearchFor3.Value, Plugin.LocationToSearchForItem3.Value),
				(Plugin.ItemToSearchFor4.Value, Plugin.LocationToSearchForItem4.Value)
			};
			Plugin.LogDebug("dict init");
			int value = Plugin.NumberOfSeeds.Value;
			List<string> values = CheckSeeds(itemsAndShops, value, Plugin.MadnessLevel.Value, Plugin.CorruptorCount.Value);
			Plugin.LogInfo("List of Seeds with good things: \n " + string.Join(", ", values));
		}

		internal static void LogListInfoFromSeed(string seed, string shop, string node)
		{
			List<string> itemsFromSeed = GetItemsFromSeed(seed, shop, node, 0, _obeliskChallenge: false, 1);
			Plugin.LogDebug(seed);
			Plugin.LogDebug(string.Join(", ", itemsFromSeed));
		}

		public static string RandomString(int length)
		{
			return new string((from s in Enumerable.Repeat("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", length)
				select s[random.Next(s.Length)]).ToArray());
		}

		internal static string DoubleCaravanEpics(List<(string, string)> listOfPairs, int nSeeds)
		{
			StringBuilder stringBuilder = new StringBuilder();
			for (int i = 0; i < nSeeds; i++)
			{
				string text = RandomString(8).ToUpper();
				if (i % 100000 == 0)
				{
					Plugin.LogDebug($"On Seed {i}: {text}");
				}
				List<string> itemsFromSeed = GetItemsFromSeed(text, "caravanshop", "sen_44", 0, _obeliskChallenge: false, 1);
				if (ItemListContains(itemsFromSeed, "darkhood") && ItemListContains(itemsFromSeed, "assassintools") && (ItemListContains(itemsFromSeed, "longbow") || ItemListContains(itemsFromSeed, "twinblades")) && ItemListContains(itemsFromSeed, "brassamulet"))
				{
					Plugin.LogDebug("FOUND THE PERFECT DARKHOOD/ASSASSIN TOOL SEED + " + text);
				}
				foreach (var listOfPair in listOfPairs)
				{
					if ((itemsFromSeed.Contains(listOfPair.Item1) || itemsFromSeed.Contains(listOfPair.Item1 + "rare")) && (itemsFromSeed.Contains(listOfPair.Item2) || itemsFromSeed.Contains(listOfPair.Item2 + "rare")))
					{
						stringBuilder.Append(text + " - " + listOfPair.Item1 + " and " + listOfPair.Item2 + " \n");
						Plugin.LogDebug(text + " - " + listOfPair.Item1 + " and " + listOfPair.Item2);
					}
				}
			}
			return stringBuilder.ToString();
		}

		public static bool ItemListContains(List<string> itemList, string item)
		{
			return itemList.Contains(item) || itemList.Contains(item + "rare");
		}

		internal static bool SeedHasAllItemsInLocations(string seed, List<(string, string)> itemsAndShops, int madness = 1, int corruptorCount = 0)
		{
			foreach (var itemsAndShop in itemsAndShops)
			{
				string text;
				(text, _) = itemsAndShop;
				if (!(text == ""))
				{
					text = (char.IsDigit(text[text.Length - 1]) ? text.Remove(text.Length - 1) : text);
					string item = itemsAndShop.Item2;
					if (!CheckSingleShopHasItem(text, item, seed, madness, corruptorCount))
					{
						return false;
					}
				}
			}
			return true;
		}

		internal static bool CheckSingleShopHasItem(string item, string shop, string seed, int madness, int corruptorCount, string node = null)
		{
			string text = (allLootLocations.ContainsKey(shop) ? allLootLocations[shop] : node);
			if (text == null)
			{
				Plugin.LogDebug("improper LootLocation - " + shop);
				return false;
			}
			if (!NodeExists(text, seed))
			{
				Plugin.LogDebug("CheckSingleShop null node: " + text + " in seed " + seed);
				return false;
			}
			List<string> itemsFromSeed = GetItemsFromSeed(seed, shop, text, 0, _obeliskChallenge: false, madness, corruptorCount, Plugin.PovertyEnabled.Value);
			return itemsFromSeed.Contains(item);
		}

		internal static bool CheckSingleNodeAndShop(string item, string shop, string node, string seed, int madness = 1, int corruptorCount = 0, string eventId = null)
		{
			if (eventId == null)
			{
				if (!NodeExists(node, seed))
				{
					Plugin.LogDebug("CheckSingleNodeAndShop null node: " + node + " in seed " + seed);
					return false;
				}
			}
			else if (!EventExists(seed, node, eventId))
			{
				return false;
			}
			if (node == "")
			{
				Plugin.LogDebug("improper LootLocation - " + shop);
				return false;
			}
			List<string> itemsFromSeed = GetItemsFromSeed(seed, shop, node, 0, _obeliskChallenge: false, madness, corruptorCount);
			return itemsFromSeed.Contains(item);
		}

		internal static List<string> CheckSeeds(List<(string, string)> itemsAndShops, int nSeeds, int madness = 1, int corruptorCount = 0)
		{
			Plugin.LogDebug("CheckSeeds - Begin");
			List<string> list = new List<string>();
			int num = Mathf.Clamp(nSeeds / 100, 1000, 100000);
			for (int i = 0; i < nSeeds; i++)
			{
				string text = RandomString(8).ToUpper();
				if (i % num == 0)
				{
					Plugin.LogDebug($"On Seed {i}: {text}");
				}
				if (!SeedHasAllItemsInLocations(text, itemsAndShops, madness, corruptorCount))
				{
					continue;
				}
				list.Append(text);
				List<string> values = itemsAndShops.Select(((string, string) x) => x.Item1).ToList();
				string text2 = string.Join(", ", values);
				Plugin.LogInfo("Found Seed with " + text2 + ": " + text);
				if (Plugin.StopSearchOnSeedFound.Value)
				{
					Plugin.LogInfo("Stopping search on seed found: " + text);
					if (Plugin.SaveSeedToGame.Value)
					{
						SavedSeed = text;
					}
					AlertManager.Instance.AlertConfirm("Seed found " + (Plugin.SaveSeedToGame.Value ? "and saved to game" : "") + ":\n " + text + " \n Contains: " + text2, "");
					return list;
				}
			}
			return list;
		}

		internal static void LogSeedsNodeSpecified(List<(string, string, string)> thingsToSearch, int nSeeds = 20000, int madness = 1, int corruptorCount = 0)
		{
			List<string> list = new List<string>();
			for (int i = 0; i < nSeeds; i++)
			{
				if (i % 10000 == 0)
				{
					Plugin.LogDebug($"On Seed {i}");
				}
				string text = RandomString(8).ToUpper();
				bool flag = true;
				foreach (var item4 in thingsToSearch)
				{
					string item = item4.Item1;
					string item2 = item4.Item2;
					string item3 = item4.Item3;
					string eventId = ((item3 == "sen_29") ? "e_sen29_a" : null);
					if (!CheckSingleNodeAndShop(item, item2, item3, text, madness, corruptorCount, eventId))
					{
						flag = false;
						break;
					}
				}
				if (flag)
				{
					list.Add(text);
				}
				if (list.Count() >= 10)
				{
					break;
				}
			}
			List<string> values = thingsToSearch.Select(((string, string, string) thing) => thing.Item1).ToList();
			Plugin.LogDebug("Found Seeds with the following items: " + string.Join(", ", values) + " \n  " + string.Join(", ", list));
		}

		internal static void FindSeedWithItems()
		{
			List<string> list = new List<string>();
			int num = 5000;
			for (int i = 0; i < num; i++)
			{
				string seed = RandomString(8).ToUpper();
				List<string> list2 = new List<string>();
				foreach (string key in allItemDropLocations.Keys)
				{
					string node = allItemDropLocations[key];
					List<string> itemsFromSeed = GetItemsFromSeed(seed, key, node, 0, _obeliskChallenge: false, 1);
				}
			}
		}

		public static void LogAllItems()
		{
			Plugin.LogInfo("LogAllItems - Start");
			int nSeeds = 1000000;
			LogCaravanItems(nSeeds);
			nSeeds = 1000;
			LogGuaranteedDropItems(nSeeds);
			LogBossDropItems(nSeeds);
			LogPetItems(nSeeds);
			LogMythicItems();
		}

		internal static void LogMythicItems(int nSeeds = 2000)
		{
			HandleMythics(MythicLocations, nSeeds);
			Plugin.LogInfo("Completed Mythic Items");
		}

		internal static void HandleMythics(Dictionary<string, string> lootNodeMap, int nSeeds = 300, bool rareOnly = false)
		{
			Dictionary<string, List<string>> itemDict = new Dictionary<string, List<string>>();
			foreach (string key in lootNodeMap.Keys)
			{
				Plugin.LogDebug("Searching Location " + key);
				for (int i = 0; i < nSeeds; i++)
				{
					string seed = RandomString(7).ToUpper();
					string node = lootNodeMap[key];
					List<string> itemsFromSeed = GetItemsFromSeed(seed, key, node, 0, _obeliskChallenge: false, 1);
					UpdateItemDictForMythics(ref itemDict, itemsFromSeed, seed, key, 10);
				}
			}
			Plugin.LogDebug("Shop Items - " + Plugin.DictToString(itemDict));
		}

		internal static bool EventExists(string seed, string nodeId, string eventId, bool assumePlayerHasReqs = false)
		{
			//IL_0487: Unknown result type (might be due to invalid IL or missing references)
			//IL_048c: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ba: Unknown result type (might be due to invalid IL or missing references)
			Globals instance = Globals.Instance;
			NodeData val = ((instance != null) ? instance.GetNodeData(nodeId) : null);
			if ((Object)(object)val == (Object)null)
			{
				Plugin.LogDebug("Null nodedata/Globals");
				return false;
			}
			Random.InitState(Functions.GetDeterministicHashCode(val.NodeId + seed + "AssignSingleGameNode"));
			if (Random.Range(0, 100) >= val.ExistsPercent)
			{
				return false;
			}
			bool flag = true;
			bool flag2 = true;
			if (val.NodeEvent != null && val.NodeEvent.Length != 0 && val.NodeCombat != null && val.NodeCombat.Length != 0)
			{
				if (Random.Range(0, 100) < val.CombatPercent)
				{
					flag = false;
				}
				else
				{
					flag2 = false;
				}
			}
			if (flag && val.NodeEvent != null && val.NodeEvent.Length != 0)
			{
				string text = "";
				Dictionary<string, int> dictionary = new Dictionary<string, int>();
				for (int i = 0; i < val.NodeEvent.Length; i++)
				{
					if (!((Object)(object)val.NodeEvent[i] != (Object)null))
					{
						continue;
					}
					bool flag3 = true;
					if ((Object)(object)val.NodeEvent[i].Requirement != (Object)null && assumePlayerHasReqs)
					{
						flag3 = false;
					}
					if ((Object)(object)val.NodeEvent[i].RequiredClass != (Object)null && assumePlayerHasReqs)
					{
						flag3 = false;
					}
					if (flag3)
					{
						int value = 10000;
						if (i < val.NodeEventPriority.Length)
						{
							value = val.NodeEventPriority[i];
						}
						dictionary.Add(val.NodeEvent[i].EventId, value);
					}
				}
				if (dictionary.Count == 0)
				{
					return false;
				}
				Dictionary<string, int> dictionary2 = dictionary.OrderBy((KeyValuePair<string, int> x) => x.Value).ToDictionary((KeyValuePair<string, int> x) => x.Key, (KeyValuePair<string, int> x) => x.Value);
				int j = 1;
				for (int value2 = dictionary2.ElementAt(0).Value; j < dictionary2.Count && dictionary2.ElementAt(j).Value == value2; j++)
				{
				}
				if (j == 1)
				{
					text = dictionary2.ElementAt(0).Key;
				}
				else
				{
					if (val.NodeEventPercent != null && val.NodeEvent.Length == val.NodeEventPercent.Length)
					{
						Dictionary<string, int> dictionary3 = new Dictionary<string, int>();
						int num = 0;
						for (int k = 0; k < j; k++)
						{
							int num2 = 0;
							while (k < val.NodeEvent.Length)
							{
								if (val.NodeEvent[num2].EventId == dictionary2.ElementAt(num).Key)
								{
									dictionary3.Add(val.NodeEvent[num2].EventId, val.NodeEventPercent[num2]);
									num++;
									break;
								}
								num2++;
							}
						}
						int num3 = Random.Range(0, 100);
						int num4 = 0;
						foreach (KeyValuePair<string, int> item in dictionary3)
						{
							num4 += item.Value;
							if (num3 < num4)
							{
								text = item.Key;
								break;
							}
						}
					}
					if (text == "")
					{
						int index = Random.Range(0, j);
						text = dictionary2.ElementAt(index).Key;
					}
				}
				if (text == eventId)
				{
					return true;
				}
			}
			else if (flag2 && val.NodeCombat != null && val.NodeCombat.Length != 0)
			{
				string text2 = "";
				if (text2 == "")
				{
					int num5 = 0;
					if (val.NodeId == "of1_10" || val.NodeId == "of2_10")
					{
						State state = Random.state;
						Random.InitState(Functions.GetDeterministicHashCode(val.NodeId + seed + "finalBoss"));
						num5 = Random.Range(0, val.NodeCombat.Length);
						Random.state = state;
					}
					text2 = val.NodeCombat[num5].CombatId;
					if (text2 == eventId)
					{
						return true;
					}
				}
			}
			return false;
		}

		internal static bool EventExists(string seed, NodeData nodeData, string eventId)
		{
			string nodeId = nodeData.NodeId;
			return EventExists(seed, nodeId, eventId);
		}

		internal static void FindAndLogSeedsWithEvent(List<string> eventsToFind, int nSeeds = 20000)
		{
			List<string> list = new List<string>();
			for (int i = 0; i < nSeeds; i++)
			{
				if (i % 10000 == 0)
				{
					Plugin.LogDebug($"On Seed {i}");
				}
				string text = RandomString(8).ToUpper();
				bool flag = true;
				foreach (string item in eventsToFind)
				{
					string nodeId = ConvertEventToNode(item);
					if (!EventExists(text, nodeId, item))
					{
						flag = false;
						break;
					}
				}
				if (flag)
				{
					list.Add(text);
				}
				if (list.Count() >= 10)
				{
					break;
				}
			}
			Plugin.LogDebug("Found Seeds with events: " + string.Join(", ", list));
		}

		internal static bool NodeExists(string nodeId, string seed, string hasEvent = null)
		{
			if ((Object)(object)Globals.Instance == (Object)null)
			{
				return false;
			}
			if (nodeId == "caravanshop")
			{
				return true;
			}
			NodeData nodeData = Globals.Instance.GetNodeData(nodeId);
			if ((Object)(object)nodeData == (Object)null)
			{
				return false;
			}
			Random.InitState(Functions.GetDeterministicHashCode(nodeId + seed + "AssignSingleGameNode"));
			if (Random.Range(0, 100) >= nodeData.ExistsPercent)
			{
				return false;
			}
			if (hasEvent != null && (Object)(object)AtOManager.Instance != (Object)null)
			{
				Dictionary<string, string> value = Traverse.Create((object)AtOManager.Instance).Field("gameNodeAssigned").GetValue<Dictionary<string, string>>();
				if (value == null)
				{
					return false;
				}
				if (value.ContainsKey(nodeId))
				{
					string text = value[nodeId];
					Plugin.LogDebug(text);
					return text.Split(new char[1] { ':' })[1] == hasEvent;
				}
				return false;
			}
			return true;
		}

		internal static void LogPetItems(int nSeeds = 500)
		{
			HandleDropItems(petDropNodeMap, nSeeds, rareOnly: true);
			Plugin.LogInfo("Completed Pet Items");
		}

		internal static void LogBossDropItems(int nSeeds = 500)
		{
			HandleDropItems(dropNodeMap, nSeeds, rareOnly: true);
			Plugin.LogInfo("Completed Boss Items");
		}

		internal static void LogGuaranteedDropItems(int nSeeds = 500)
		{
			HandleDropItems(guaranteedDropNodeMap, nSeeds, rareOnly: true);
			Plugin.LogInfo("Completed Guaranteed Items");
		}

		internal static void LogSingleShop(string shop, string seed, string node = null, int madness = 1, int corruptorCount = 0, bool poverty = false)
		{
			if (node == null)
			{
				Plugin.LogError("Node is null");
				return;
			}
			List<string> itemsFromSeed = GetItemsFromSeed(seed, shop, node, 0, _obeliskChallenge: false, 1, 0, poverty);
			Plugin.LogDebug("Shop - " + shop + " itemList Items - " + string.Join(", ", itemsFromSeed));
		}

		internal static void LogShopItems()
		{
			Dictionary<string, string> lootNodeMap = new Dictionary<string, string>
			{
				{ "aquarvendor", "aqua_26" },
				{ "elvenemporium", "faen_23" },
				{ "felineshop", "ulmin_29" },
				{ "firebazaar", "velka_20" }
			};
			int nSeeds = 300;
			HandleDropItems(lootNodeMap, nSeeds);
		}

		internal static void HandleDropItems(Dictionary<string, string> lootNodeMap, int nSeeds = 300, bool rareOnly = false)
		{
			Dictionary<string, List<string>> itemDict = new Dictionary<string, List<string>>();
			foreach (string key in lootNodeMap.Keys)
			{
				LootData lootData = Globals.Instance.GetLootData(key);
				List<string> list = new List<string>();
				LootItem[] lootItemTable = lootData.LootItemTable;
				foreach (LootItem val in lootItemTable)
				{
					if (!((Object)(object)val.LootCard == (Object)null) && val.LootCard.CardName != "")
					{
						if (rareOnly)
						{
							list.Add(val.LootCard.Id + "rare");
						}
						else
						{
							list.Add(val.LootCard.Id);
						}
					}
				}
				Plugin.LogDebug("Shop - " + key + " Valid Items - " + string.Join(", ", list));
				for (int j = 0; j < nSeeds; j++)
				{
					string seed = RandomString(7).ToUpper();
					string node = lootNodeMap[key];
					List<string> itemsFromSeed = GetItemsFromSeed(seed, key, node, 0, _obeliskChallenge: false, 1);
					UpdateItemDictForShops(ref itemDict, itemsFromSeed, list, seed, key, 10);
				}
			}
			Plugin.LogDebug("Shop Items - " + Plugin.DictToString(itemDict));
		}

		internal static void UpdateItemDictForMythics(ref Dictionary<string, List<string>> itemDict, List<string> itemList, string seed, string shopName, int count = 5)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Invalid comparison between Unknown and I4
			foreach (string item in itemList)
			{
				CardData cardData = Globals.Instance.GetCardData(item, false);
				if (!((Object)(object)cardData == (Object)null) && (int)cardData.CardRarity == 4)
				{
					string key = shopName + " - " + cardData.CardName;
					if (!itemDict.ContainsKey(key))
					{
						itemDict.Add(key, new List<string>());
					}
					if (itemDict[key].Count() < count)
					{
						itemDict[key].Add(seed);
					}
				}
			}
		}

		internal static void LogCaravanItems(int nSeeds = 1000)
		{
			Dictionary<string, List<string>> itemDict = new Dictionary<string, List<string>>();
			for (int i = 0; i < nSeeds; i++)
			{
				if (i % 50000 == 0)
				{
					Plugin.LogDebug($"On seed {i}");
				}
				string seed = RandomString(7).ToUpper();
				string shop = "caravanshop";
				string node = "sen_44";
				List<string> itemsFromSeed = GetItemsFromSeed(seed, shop, node, 0, _obeliskChallenge: false, 1);
				UpdateItemDict(ref itemDict, itemsFromSeed, seed);
			}
			Plugin.LogDebug("Dictionary - " + Plugin.DictToString(itemDict));
		}

		internal static void UpdateItemDictForShops(ref Dictionary<string, List<string>> itemDict, List<string> itemList, List<string> validItems, string seed, string shopName, int count = 5)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Invalid comparison between Unknown and I4
			foreach (string item in itemList)
			{
				if (!validItems.Contains(item))
				{
					continue;
				}
				CardData cardData = Globals.Instance.GetCardData(item, false);
				if (!((Object)(object)cardData == (Object)null) && (int)cardData.CardUpgraded == 3)
				{
					string key = shopName + " - " + cardData.CardName;
					if (!itemDict.ContainsKey(key))
					{
						itemDict.Add(key, new List<string>());
					}
					if (itemDict[key].Count() < count)
					{
						itemDict[key].Add(seed);
					}
				}
			}
		}

		internal static void UpdateItemDict(ref Dictionary<string, List<string>> itemDict, List<string> itemList, string seed, int count = 5)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Invalid comparison between Unknown and I4
			foreach (string item in itemList)
			{
				CardData cardData = Globals.Instance.GetCardData(item, false);
				string key = (((int)cardData.CardUpgraded == 3) ? (cardData.CardName + " (Corrupted)") : cardData.CardName);
				if (!itemDict.ContainsKey(key))
				{
					itemDict.Add(key, new List<string>());
				}
				if (itemDict[key].Count() < count)
				{
					itemDict[key].Add(seed);
				}
			}
		}

		internal static List<string> GetItemsFromSeed(string _seed = "", string _shop = "caravanshop", string _node = "", int _townReroll = 0, bool _obeliskChallenge = false, int _madness = 0, int _corruptorCount = 0, bool _poverty = false)
		{
			//IL_03b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bb: Invalid comparison between Unknown and I4
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Invalid comparison between Unknown and I4
			//IL_0672: Unknown result type (might be due to invalid IL or missing references)
			//IL_0678: Invalid comparison between Unknown and I4
			//IL_067c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0682: Invalid comparison between Unknown and I4
			//IL_069c: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a2: Invalid comparison between Unknown and I4
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_0428: Unknown result type (might be due to invalid IL or missing references)
			//IL_042e: Invalid comparison between Unknown and I4
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_045c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0462: Invalid comparison between Unknown and I4
			//IL_06bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c2: Invalid comparison between Unknown and I4
			//IL_0498: Unknown result type (might be due to invalid IL or missing references)
			//IL_049e: Invalid comparison between Unknown and I4
			//IL_027c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0283: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f5: Invalid comparison between Unknown and I4
			//IL_04d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04df: Invalid comparison between Unknown and I4
			//IL_028c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_06dc: Unknown result type (might be due to invalid IL or missing references)
			string text = "";
			string text2 = _node;
			if (_shop == "caravanshop" && text2 == "")
			{
				text2 = "sen_44";
			}
			if (_townReroll > 0)
			{
			}
			LootData lootData = Globals.Instance.GetLootData(_shop);
			if ((Object)(object)lootData == (Object)null)
			{
				Plugin.LogError("Unable to get shop items for " + _shop + " (shop does not exist!)");
				return null;
			}
			List<string> list = new List<string>();
			List<string> list2 = new List<string>();
			for (int i = 0; i < Globals.Instance.CardListByClass[(CardClass)8].Count; i++)
			{
				list2.Add(Globals.Instance.CardListByClass[(CardClass)8][i]);
			}
			int deterministicHashCode = Functions.GetDeterministicHashCode(text2 + _seed + text);
			Random.InitState(deterministicHashCode);
			IListExtensions.Shuffle<string>((IList<string>)list2, deterministicHashCode);
			int num = 0;
			int num2 = ((!_obeliskChallenge) ? lootData.NumItems : lootData.LootItemTable.Length);
			for (int j = 0; j < num2; j++)
			{
				if (list.Count >= lootData.NumItems)
				{
					break;
				}
				if (j >= lootData.LootItemTable.Length)
				{
					continue;
				}
				LootItem val = lootData.LootItemTable[j];
				if (!((double)Random.Range(0, 100) < (double)val.LootPercent))
				{
					continue;
				}
				if ((Object)(object)val.LootCard != (Object)null)
				{
					list.Add(val.LootCard.Id);
					continue;
				}
				bool flag = false;
				int num3 = 0;
				CardData val2 = null;
				while (!flag && num3 < 10000)
				{
					if (num >= list2.Count)
					{
						num = 0;
					}
					string text3 = list2[num];
					if (!list.Contains(text3))
					{
						val2 = Globals.Instance.GetCardData(text3, false);
						if ((Object)(object)val2.Item != (Object)null && !val2.Item.DropOnly)
						{
							if ((int)val2.CardUpgraded == 3)
							{
								flag = false;
							}
							else if (val2.Item.PercentRetentionEndGame > 0 && (_madness > 2 || _obeliskChallenge))
							{
								flag = false;
							}
							else if (val2.Item.PercentDiscountShop > 0 && _poverty)
							{
								flag = false;
							}
							else if ((int)val.LootType == 0 && val2.CardRarity == val.LootRarity)
							{
								flag = true;
							}
							else if (val2.CardType == val.LootType && val2.CardRarity == val.LootRarity)
							{
								flag = true;
							}
						}
					}
					num++;
					num3++;
				}
				if (flag && (Object)(object)val2 != (Object)null)
				{
					list.Add(val2.Id);
				}
			}
			for (int k = list.Count; k < lootData.NumItems; k++)
			{
				bool flag2 = false;
				int num4 = 0;
				CardData val3 = null;
				int num5 = Random.Range(0, 100);
				while (!flag2 && num4 < 10000)
				{
					if (num >= list2.Count)
					{
						num = 0;
					}
					string text4 = list2[num];
					if (!list.Contains(text4))
					{
						val3 = Globals.Instance.GetCardData(text4, false);
						if ((Object)(object)val3.Item != (Object)null && !val3.Item.DropOnly)
						{
							if ((int)val3.CardUpgraded == 3)
							{
								flag2 = false;
							}
							else if (val3.Item.PercentRetentionEndGame > 0 && (_madness > 2 || _obeliskChallenge))
							{
								flag2 = false;
							}
							else if (val3.Item.PercentDiscountShop > 0 && _poverty)
							{
								flag2 = false;
							}
							else if ((double)num5 < (double)lootData.DefaultPercentMythic)
							{
								if ((int)val3.CardRarity == 4)
								{
									flag2 = true;
								}
							}
							else if ((double)num5 < (double)lootData.DefaultPercentEpic + (double)lootData.DefaultPercentMythic)
							{
								if ((int)val3.CardRarity == 3)
								{
									flag2 = true;
								}
							}
							else if ((double)num5 < (double)lootData.DefaultPercentRare + (double)lootData.DefaultPercentEpic + (double)lootData.DefaultPercentMythic)
							{
								if ((int)val3.CardRarity == 2)
								{
									flag2 = true;
								}
							}
							else if ((double)num5 < (double)lootData.DefaultPercentUncommon + (double)lootData.DefaultPercentRare + (double)lootData.DefaultPercentEpic + (double)lootData.DefaultPercentMythic)
							{
								if ((int)val3.CardRarity == 1)
								{
									flag2 = true;
								}
							}
							else if ((int)val3.CardRarity == 0)
							{
								flag2 = true;
							}
						}
					}
					num++;
					num4++;
					if (!flag2 && num4 % 100 == 0)
					{
						num5 += 10;
					}
				}
				if (flag2 && (Object)(object)val3 != (Object)null)
				{
					list.Add(val3.Id);
					continue;
				}
				break;
			}
			IListExtensions.Shuffle<string>((IList<string>)list, deterministicHashCode);
			if (!_shop.Contains("towntier") && ((!_obeliskChallenge && _madness > 0) || _obeliskChallenge))
			{
				int num6 = 0;
				if (_shop.Contains("exoticshop"))
				{
					num6 += 8;
				}
				else if (_shop.Contains("rareshop"))
				{
					num6 += 4;
				}
				if (_obeliskChallenge)
				{
					if (_madness > 8)
					{
						num6 += 4;
					}
					else if (_madness > 4)
					{
						num6 += 2;
					}
				}
				else
				{
					num6 += Functions.FuncRoundToInt(0.2f * (float)(_madness + _corruptorCount));
				}
				for (int l = 0; l < list.Count; l++)
				{
					int num7 = Random.Range(0, 100);
					CardData cardData = Globals.Instance.GetCardData(list[l], false);
					if (!((Object)(object)cardData == (Object)null))
					{
						bool flag3 = false;
						if (((int)cardData.CardRarity == 4 || (int)cardData.CardRarity == 3) && num7 < 3 + num6)
						{
							flag3 = true;
						}
						else if ((int)cardData.CardRarity == 2 && num7 < 5 + num6)
						{
							flag3 = true;
						}
						else if ((int)cardData.CardRarity == 1 && num7 < 7 + num6)
						{
							flag3 = true;
						}
						else if ((int)cardData.CardRarity == 0 && num7 < 9 + num6)
						{
							flag3 = true;
						}
						if (flag3 && (Object)(object)cardData.UpgradesToRare != (Object)null)
						{
							list[l] = cardData.UpgradesToRare.Id;
						}
					}
				}
			}
			return list;
		}

		public static string ConvertEventToNode(string eventId)
		{
			string pattern = "[^_]*_([^_\\d]*)(\\d+).*";
			Match match = Regex.Match(eventId, pattern);
			if (match.Success)
			{
				string value = match.Groups[1].Value;
				string value2 = match.Groups[2].Value;
				return value + "_" + value2;
			}
			return eventId;
		}

		public static void ListToJson(List<ItemObject> inputList, string filePath)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Expected O, but got Unknown
			try
			{
				DataContractJsonSerializer val = new DataContractJsonSerializer(inputList.GetType());
				using MemoryStream memoryStream = new MemoryStream();
				((XmlObjectSerializer)val).WriteObject((Stream)memoryStream, (object)inputList);
				memoryStream.Position = 0L;
				using StreamReader streamReader = new StreamReader(memoryStream);
				string contents = streamReader.ReadToEnd();
				File.WriteAllText(filePath, contents);
			}
			catch (Exception ex)
			{
				Plugin.LogDebug("ERROR: Could not create JSON file " + ex.Message);
			}
		}

		public static void ListToText(List<ItemObject> inputList, string filePath)
		{
			try
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.Append("{");
				foreach (ItemObject input in inputList)
				{
					string id = input.Id;
					string value = "\"" + id + "\": ";
					stringBuilder.Append(value);
					stringBuilder.Append("{");
					string value2 = "\"CardName\":\"" + input.Name + "\", ";
					string value3 = "\"CardClass\":\"" + input.CardType + "\", ";
					string value4 = "\"CardRarity\":\"" + input.CardRarity + "\", ";
					string value5 = "\"DropOnly\":" + input.Droponly.ToString().ToLower() + ", ";
					string value6 = "\"CardUpgraded\":\"" + input.CardUpgraded + "\", ";
					string value7 = "\"UpgradesToRareId\":\"" + input.UpgradesToRareId + "\", ";
					string value8 = $"\"PercentRetentionEndGame\":{input.PercentRetentionEndGame}, ";
					string value9 = $"\"PercentDiscountShop\":{input.PercentDiscountShop}";
					stringBuilder.Append(value2);
					stringBuilder.Append(value3);
					stringBuilder.Append(value4);
					stringBuilder.Append(value5);
					stringBuilder.Append(value6);
					stringBuilder.Append(value7);
					stringBuilder.Append(value8);
					stringBuilder.Append(value9);
					stringBuilder.Append("}, ");
				}
				stringBuilder.Remove(stringBuilder.Length - 2, 2);
				stringBuilder.Append("}");
				File.WriteAllText(filePath, stringBuilder.ToString());
				Plugin.LogDebug("Text file successfully created at: " + filePath);
			}
			catch (Exception ex)
			{
				Plugin.LogDebug("ERROR: Could not create text file " + ex.Message);
			}
		}

		public static void WriteItemsToText()
		{
			Plugin.LogDebug("Logging all Keys");
			List<ItemObject> list = new List<ItemObject>();
			List<string> list2 = Globals.Instance.CardListByClass[(CardClass)8];
			foreach (string item2 in list2)
			{
				CardData cardData = Globals.Instance.GetCardData(item2, true);
				if ((Object)(object)cardData == (Object)null || (Object)(object)cardData.Item == (Object)null)
				{
					Plugin.LogDebug("CardData is null for " + item2);
					continue;
				}
				ItemObject item = new ItemObject(item2, cardData);
				list.Add(item);
			}
			if (Plugin.WriteItemsToTextFile.Value)
			{
				string text = (Path.IsPathRooted(Plugin.WriteItemsToTextFilePath.Value) ? Plugin.WriteItemsToTextFilePath.Value : (Utility.IsNullOrWhiteSpace(Plugin.WriteItemsToTextFilePath.Value) ? (Paths.BepInExRootPath + "/Logs/AllItems.txt") : (Paths.BepInExRootPath + Plugin.WriteItemsToTextFilePath.Value)));
				ListToText(list, text);
				AlertManager.Instance.AlertConfirm("All Items written to text at " + text, "");
			}
		}

		public static string GetSavedSeed()
		{
			if (Utility.IsNullOrWhiteSpace(SavedSeed))
			{
				AtOManager instance = AtOManager.Instance;
				return ((instance != null) ? instance.GetGameId() : null) ?? RandomString(7);
			}
			return SavedSeed;
		}
	}
	[HarmonyPatch]
	public class SeedSearcherPatches
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(HeroSelectionManager), "Start")]
		public static void HeroSelectionManagerStartPrefix(ref HeroSelectionManager __instance, TMP_Text ___gameSeedTxt)
		{
			if (Plugin.SaveSeedToGame.Value)
			{
				AtOManager instance = AtOManager.Instance;
				if (instance != null)
				{
					instance.SetGameId(SeedSearcherFunctions.GetSavedSeed());
				}
				___gameSeedTxt.text = SeedSearcherFunctions.GetSavedSeed();
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(AtOManager), "BeginAdventure")]
		public static void BeginAdventurePrefix(ref AtOManager __instance)
		{
			if (Plugin.SaveSeedToGame.Value || Plugin.BypassMadnessRandomization.Value)
			{
				SeedSearcherFunctions.SavedSeed = __instance.GetGameId();
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(AtOManager), "BeginAdventure")]
		public static void BeginAdventurePostfix(ref AtOManager __instance)
		{
			if (Plugin.SaveSeedToGame.Value || Plugin.BypassMadnessRandomization.Value)
			{
				Plugin.LogDebug("BeginAdventurePostfix - Setting GameID to " + SeedSearcherFunctions.GetSavedSeed());
				__instance.SetGameId(SeedSearcherFunctions.GetSavedSeed());
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Globals), "CreateGameContent")]
		public static void CreateGameContentPostfix(ref Globals __instance)
		{
			Plugin.LogInfo("CreateGameContentPostfix - Start");
			if (Plugin.SearchForItemsOnStartup.Value)
			{
				SeedSearcherFunctions.ExecuteSearch();
			}
			if (false)
			{
				List<(string, string, string)> list = new List<(string, string, string)>(1) { ("heartofthornsrare", "caravanshop", "sen_44") };
				List<(string, string)> list2 = new List<(string, string)>(1) { ("sen_29", "e_sen29_a") };
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "com.binbin.SeedSearcher";

		public const string PLUGIN_NAME = "SeedSearcher";

		public const string PLUGIN_VERSION = "1.2.1";
	}
}