Decompiled source of ItemStringParser v2.1.0

ItemStringParser.dll

Decompiled 2 weeks 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.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Logging;
using HG.Reflection;
using Microsoft.CodeAnalysis;
using R2API.Utils;
using RoR2;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.AddressableAssets.ResourceLocators;
using UnityEngine.Networking;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.ResourceLocations;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ItemStringParser
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("Def.ItemStringParser", "ItemStringParser", "2.1.0")]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class ItemStringParser : BaseUnityPlugin
	{
		private class ItemStringEntry
		{
			public string itemKey;

			public int repeat = 1;

			public int multiplier = 1;

			public float weight = 1f;
		}

		public enum ItemStringFormat
		{
			DEFAULT,
			WEIGHTED_OR_ONLY
		}

		public const string PluginGUID = "Def.ItemStringParser";

		public const string PluginAuthor = "Def";

		public const string PluginName = "ItemStringParser";

		public const string PluginVersion = "2.1.0";

		private static readonly Regex tokenPattern = new Regex("^(?:(\\d+)\\s*x\\s*)?(\\w+(?:\\s*!\\s*\\w+)*)$", RegexOptions.IgnoreCase);

		private static ManualLogSource Log;

		private static readonly Dictionary<string, AsyncOperationHandle<PickupDropTable>> loadedDropTables = new Dictionary<string, AsyncOperationHandle<PickupDropTable>>();

		private static Dictionary<string, string> dropTables;

		private static readonly Xoroshiro128Plus dropTableRng = new Xoroshiro128Plus((ulong)DateTime.UtcNow.Ticks);

		private static readonly EquipmentLocationQueryArgs emptyEquipmentLocation = new EquipmentLocationQueryArgs
		{
			searchAllSlots = true,
			allowEmpty = true,
			searchPriority = (SearchPriority)1
		};

		public static PluginInfo PInfo { get; private set; }

		private static Dictionary<string, string> DropTables
		{
			get
			{
				if (dropTables == null)
				{
					dropTables = FindDropTables();
				}
				return dropTables;
			}
		}

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
		}

		private static Dictionary<string, string> FindDropTables()
		{
			Dictionary<string, string> dictionary = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
			IList<IResourceLocation> list = default(IList<IResourceLocation>);
			foreach (IResourceLocator resourceLocator in Addressables.ResourceLocators)
			{
				foreach (object key in resourceLocator.Keys)
				{
					if (!(key is string text) || !text.EndsWith(".asset", StringComparison.OrdinalIgnoreCase) || !resourceLocator.Locate((object)text, typeof(PickupDropTable), ref list) || list.Count == 0)
					{
						continue;
					}
					string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(text);
					if (dictionary.TryGetValue(fileNameWithoutExtension, out var value))
					{
						if (value != text)
						{
							ManualLogSource log = Log;
							if (log != null)
							{
								log.LogDebug((object)("Drop table name " + fileNameWithoutExtension + " is used twice; " + text + " is ignored in favor of " + value + "."));
							}
						}
					}
					else
					{
						dictionary.Add(fileNameWithoutExtension, text);
					}
				}
			}
			return dictionary;
		}

		private static PickupDropTable GetDroptable(string droptable)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			string text = DropTables[droptable];
			if (!loadedDropTables.TryGetValue(text, out var value))
			{
				value = Addressables.LoadAssetAsync<PickupDropTable>((object)text);
				loadedDropTables[text] = value;
			}
			return value.WaitForCompletion();
		}

		public static T GetRandom<T>(List<T> list, T defaultValue)
		{
			if (list == null || list.Count == 0)
			{
				return defaultValue;
			}
			return list[Random.RandomRangeInt(0, list.Count)];
		}

		private static string GenerateRandomString(int length = 12)
		{
			Random random = new Random();
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append("Set_");
			for (int i = 0; i < length; i++)
			{
				stringBuilder.Append("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"[random.Next("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".Length)]);
			}
			return stringBuilder.ToString();
		}

		private static (string replacedString, Dictionary<string, string> replacements) ReplaceOuterBraces(string input)
		{
			StringBuilder stringBuilder = new StringBuilder();
			int num = 0;
			List<(int, int)> list = new List<(int, int)>();
			for (int i = 0; i < input.Length; i++)
			{
				if (input[i] == '{')
				{
					if (num == 0)
					{
						list.Add((i, -1));
					}
					num++;
				}
				else if (input[i] == '}')
				{
					num--;
					if (num == 0)
					{
						(int, int) tuple = list[list.Count - 1];
						list[list.Count - 1] = (tuple.Item1, i);
					}
				}
			}
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			int num2 = 0;
			foreach (var item in list)
			{
				stringBuilder.Append(input.Substring(num2, item.Item1 - num2));
				string text = input.Substring(item.Item1, item.Item2 - item.Item1 + 1);
				string value = text.Substring(1, text.Length - 2);
				string text2;
				do
				{
					text2 = GenerateRandomString();
				}
				while (dictionary.ContainsKey(text2));
				dictionary[text2] = value;
				stringBuilder.Append(text2);
				num2 = item.Item2 + 1;
			}
			stringBuilder.Append(input.Substring(num2));
			return (replacedString: stringBuilder.ToString(), replacements: dictionary);
		}

		public static PickupIndex ResolveItemKey(string itemkey, bool availableOnly = true)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<PickupIndex, int> dictionary = new Dictionary<PickupIndex, int>();
			ResolveItemKey(itemkey, 1, dictionary, null, availableOnly);
			foreach (var (val2, num2) in dictionary)
			{
				if (num2 > 0 && val2 != PickupIndex.none)
				{
					return val2;
				}
			}
			return PickupIndex.none;
		}

		private static List<PickupIndex> GetTierDropList(string tier)
		{
			Run instance = Run.instance;
			return tier.ToLowerInvariant() switch
			{
				"tier1" => instance.availableTier1DropList, 
				"tier2" => instance.availableTier2DropList, 
				"tier3" => instance.availableTier3DropList, 
				"boss" => instance.availableBossDropList, 
				"lunar" => instance.availableLunarCombinedDropList, 
				"lunaritem" => instance.availableLunarItemDropList, 
				"lunarequipment" => instance.availableLunarEquipmentDropList, 
				"equipment" => instance.availableEquipmentDropList, 
				"voidtier1" => instance.availableVoidTier1DropList, 
				"voidtier2" => instance.availableVoidTier2DropList, 
				"voidtier3" => instance.availableVoidTier3DropList, 
				"voidboss" => instance.availableVoidBossDropList, 
				"foodtier" => instance.availableFoodTierDropList, 
				"cursed" => instance.availableCursedTierDropList, 
				"hex" => instance.availableHexTierDropList, 
				"page" => instance.availablePageTierDropList, 
				"powershape" => instance.availablePowerShapeItemsDropList, 
				"keyitem" => instance.availableKeyItemsDropList, 
				_ => null, 
			};
		}

		private static bool ResolveItemKey(string itemkey, int repeat, Dictionary<PickupIndex, int> resolvedItems, ManualLogSource log, bool availableOnly)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_027e: 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_0285: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0261: Unknown result type (might be due to invalid IL or missing references)
			List<PickupIndex> list = new List<PickupIndex>();
			string[] array = itemkey.Split("!");
			itemkey = array[0].Trim();
			for (int i = 1; i < array.Length; i++)
			{
				string text = array[i].Trim();
				PickupIndex val = FindPickupByName(text);
				if (val != PickupIndex.none)
				{
					list.Add(val);
				}
				else
				{
					HandleWarning(log, "ResolveItemKey: Could not get pickup from blacklisted item: " + text);
				}
			}
			List<PickupIndex> list2 = GetTierDropList(itemkey)?.Except(list).ToList();
			if (list2 != null)
			{
				while (repeat > 0)
				{
					PickupIndex random = GetRandom(list2, PickupIndex.none);
					if (random == PickupIndex.none)
					{
						HandleWarning(log, "ResolveItemKey: Could not get pickup from item tier: " + itemkey + ", as all candidates are either disabled or locked behind expansion");
						return false;
					}
					resolvedItems[random] = resolvedItems.GetValueOrDefault(random) + 1;
					repeat--;
				}
				return true;
			}
			if (DropTables.ContainsKey(itemkey))
			{
				PickupDropTable droptable = GetDroptable(itemkey);
				droptable.EnsureInitialization();
				BasicPickupDropTable val2 = (BasicPickupDropTable)(object)((droptable is BasicPickupDropTable) ? droptable : null);
				WeightedSelection<UniquePickup> val3 = ((val2 != null) ? val2.selector : ((ExplicitPickupDropTable)(((droptable is ExplicitPickupDropTable) ? droptable : null)?)).weightedSelection);
				WeightedSelection<UniquePickup> val4 = val3;
				if (val4 == null)
				{
					if (list.Count > 0)
					{
						HandleWarning(log, "ResolveItemKey: Droptable " + itemkey + " does not support blacklisting items.");
					}
					while (repeat > 0)
					{
						UniquePickup val5 = droptable.GeneratePickup(dropTableRng);
						if (!((UniquePickup)(ref val5)).isValid)
						{
							HandleWarning(log, "ResolveItemKey: Could not get pickup from droptable: " + itemkey);
							return false;
						}
						resolvedItems[val5.pickupIndex] = resolvedItems.GetValueOrDefault(val5.pickupIndex) + 1;
						repeat--;
					}
					return true;
				}
				WeightedSelection<UniquePickup> val6 = new WeightedSelection<UniquePickup>(8);
				for (int j = 0; j < val4.Count; j++)
				{
					ChoiceInfo<UniquePickup> choice = val4.GetChoice(j);
					PickupIndex pickupIndex = choice.value.pickupIndex;
					if (!list.Contains(pickupIndex) && Run.instance.IsPickupAvailable(pickupIndex))
					{
						val6.AddChoice(choice);
					}
				}
				if (val6.Count == 0)
				{
					HandleWarning(log, "ResolveItemKey: Could not get pickup from droptable: " + itemkey + ", as all candidates are either disabled or locked behind expansion");
					return false;
				}
				while (repeat > 0)
				{
					UniquePickup val7 = val6.Evaluate(Random.Range(0f, 1f));
					if (((UniquePickup)(ref val7)).Equals(UniquePickup.none))
					{
						HandleWarning(log, "ResolveItemKey: Could not get pickup from droptable: " + itemkey);
						return false;
					}
					resolvedItems[val7.pickupIndex] = resolvedItems.GetValueOrDefault(val7.pickupIndex) + 1;
					repeat--;
				}
				return true;
			}
			PickupIndex val8 = FindPickupByName(itemkey);
			if (val8 == PickupIndex.none)
			{
				HandleWarning(log, "ResolveItemKey: Could not find item key: " + itemkey);
				return false;
			}
			if (IsExpansionLocked(val8))
			{
				HandleWarning(log, "ResolveItemKey: " + itemkey + " cannot be resolved as its DLC is not enabled in this run.");
				return false;
			}
			if (availableOnly && !Run.instance.IsPickupAvailable(val8))
			{
				HandleWarning(log, "ResolveItemKey: " + itemkey + " cannot be resolved as it is disabled in this run.");
				return false;
			}
			resolvedItems[val8] = resolvedItems.GetValueOrDefault(val8) + repeat;
			return true;
		}

		private static bool IsExpansionLocked(PickupIndex pickupIndex)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Invalid comparison between Unknown and I4
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Invalid comparison between Unknown and I4
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Invalid comparison between Unknown and I4
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Invalid comparison between Unknown and I4
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			Run instance = Run.instance;
			PickupDef pickupDef = PickupCatalog.GetPickupDef(pickupIndex);
			if (!Object.op_Implicit((Object)(object)instance) || pickupDef == null)
			{
				return false;
			}
			if ((int)pickupDef.itemIndex != -1)
			{
				return instance.IsItemExpansionLocked(pickupDef.itemIndex);
			}
			if ((int)pickupDef.equipmentIndex != -1)
			{
				return instance.IsEquipmentExpansionLocked(pickupDef.equipmentIndex);
			}
			if ((int)pickupDef.droneIndex != -1)
			{
				return instance.IsDroneExpansionLocked(pickupDef.droneIndex);
			}
			if ((int)pickupDef.keyItemIndex != -1)
			{
				return instance.IsKeyItemExpansionLocked(pickupDef.keyItemIndex);
			}
			return false;
		}

		private static PickupIndex FindPickupByName(string name)
		{
			//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_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Invalid comparison between Unknown and I4
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Invalid comparison between Unknown and I4
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Invalid comparison between Unknown and I4
			//IL_001d: 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)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Invalid comparison between Unknown and I4
			//IL_002f: 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)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			EquipmentIndex val = EquipmentCatalog.FindEquipmentIndex(name);
			if ((int)val != -1)
			{
				return PickupCatalog.FindPickupIndex(val);
			}
			ItemIndex val2 = ItemCatalog.FindItemIndex(name);
			if ((int)val2 != -1)
			{
				return PickupCatalog.FindPickupIndex(val2);
			}
			DroneIndex val3 = DroneCatalog.FindDroneIndex(name);
			if ((int)val3 != -1)
			{
				return PickupCatalog.FindPickupIndex(val3);
			}
			KeyItemIndex val4 = KeyItemCatalog.FindKeyItemIndex(name);
			if ((int)val4 != -1)
			{
				return PickupCatalog.FindPickupIndex(val4);
			}
			return PickupIndex.none;
		}

		private static void HandleWarning(ManualLogSource log, string message)
		{
			if (log == null)
			{
				throw new ArgumentException(message);
			}
			log.LogWarning((object)message);
		}

		private static bool ParseItemString(string itemString, Dictionary<PickupIndex, int> resolvedItems, ManualLogSource log, bool availableOnly, int index, int repeat)
		{
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
			if (string.IsNullOrEmpty(itemString))
			{
				return true;
			}
			ItemStringFormat itemStringFormat = ItemStringFormat.DEFAULT;
			itemString = itemString.Trim();
			Dictionary<string, string> dictionary;
			(itemString, dictionary) = ReplaceOuterBraces(itemString);
			string[] array;
			bool flag;
			if (itemStringFormat == ItemStringFormat.WEIGHTED_OR_ONLY)
			{
				array = itemString.Split('|');
				flag = false;
			}
			else
			{
				if (itemString.Contains("&") && itemString.Contains("|"))
				{
					HandleWarning(log, "ParseItemStringReward: Cannot have & and | in the same group: '" + itemString + "'");
					return false;
				}
				if (itemString.Contains("|"))
				{
					array = itemString.Split('|');
					flag = false;
				}
				else
				{
					array = itemString.Split('&');
					flag = true;
				}
			}
			WeightedSelection<ItemStringEntry> val = new WeightedSelection<ItemStringEntry>(8);
			List<ItemStringEntry> list = new List<ItemStringEntry>();
			for (int i = 0; i < array.Length; i++)
			{
				ItemStringEntry itemStringEntry = new ItemStringEntry();
				string text = array[i];
				string text2 = text.Trim();
				string[] array2 = text2.Split(":", 2);
				text2 = array2[0].Trim();
				if (array2.Length > 1)
				{
					itemStringEntry.weight = float.Parse(array2[1].Trim());
				}
				if (itemStringFormat == ItemStringFormat.WEIGHTED_OR_ONLY)
				{
					itemStringEntry.itemKey = text2;
				}
				else
				{
					array2 = text2.Split("*", 2);
					text2 = array2[0].Trim();
					if (array2.Length > 1)
					{
						itemStringEntry.multiplier = int.Parse(array2[1].Trim());
					}
					Match match = tokenPattern.Match(text2);
					if (!match.Success)
					{
						HandleWarning(log, "Cannot parse segment '" + text.Trim() + "'");
						return false;
					}
					if (match.Groups[1].Success)
					{
						itemStringEntry.repeat = int.Parse(match.Groups[1].Value);
					}
					if (!match.Groups[2].Success)
					{
						HandleWarning(log, "Cannot parse segment '" + text.Trim() + "'");
						return false;
					}
					itemStringEntry.itemKey = match.Groups[2].Value;
				}
				val.AddChoice(itemStringEntry, itemStringEntry.weight);
				list.Add(itemStringEntry);
			}
			while (repeat > 0)
			{
				PickupIndex key;
				int value;
				if (flag)
				{
					foreach (ItemStringEntry item in list)
					{
						Dictionary<PickupIndex, int> dictionary2 = new Dictionary<PickupIndex, int>();
						if (!((!dictionary.ContainsKey(item.itemKey)) ? ResolveItemKey(item.itemKey, item.repeat, dictionary2, log, availableOnly) : ParseItemString(dictionary[item.itemKey], dictionary2, log, availableOnly, -1, item.repeat)))
						{
							continue;
						}
						foreach (KeyValuePair<PickupIndex, int> item2 in dictionary2)
						{
							item2.Deconstruct(out key, out value);
							PickupIndex key2 = key;
							int num = value;
							resolvedItems[key2] = resolvedItems.GetValueOrDefault(key2) + num * item.multiplier;
						}
					}
				}
				else
				{
					bool flag2 = false;
					int num2 = 10;
					int num3 = 0;
					while (!flag2)
					{
						num2--;
						if (num2 == 0)
						{
							HandleWarning(log, "Could not resolve to item rewards: " + itemString);
							return false;
						}
						ItemStringEntry itemStringEntry2 = ((index < 0) ? val.Evaluate(Random.Range(0f, 1f)) : list[(index + num3) % list.Count]);
						Dictionary<PickupIndex, int> dictionary3 = new Dictionary<PickupIndex, int>();
						flag2 = ((!dictionary.ContainsKey(itemStringEntry2.itemKey)) ? ResolveItemKey(itemStringEntry2.itemKey, itemStringEntry2.repeat, dictionary3, log, availableOnly) : ParseItemString(dictionary[itemStringEntry2.itemKey], dictionary3, log, availableOnly, -1, itemStringEntry2.repeat));
						if (flag2)
						{
							foreach (KeyValuePair<PickupIndex, int> item3 in dictionary3)
							{
								item3.Deconstruct(out key, out value);
								PickupIndex key3 = key;
								int num4 = value;
								resolvedItems[key3] = resolvedItems.GetValueOrDefault(key3) + num4 * itemStringEntry2.multiplier;
							}
						}
						else
						{
							num3++;
						}
					}
				}
				repeat--;
			}
			return true;
		}

		public static void ParseItemStringStrict(string itemString, Dictionary<PickupIndex, int> resolvedItems, bool availableOnly = true, int index = -1)
		{
			ParseItemString(itemString, resolvedItems, null, availableOnly, index, 1);
		}

		public static bool ParseItemString(string itemString, Dictionary<PickupIndex, int> resolvedItems, ManualLogSource log, bool availableOnly = true, int index = -1)
		{
			return ParseItemString(itemString, resolvedItems, log, availableOnly, index, 1);
		}

		public static List<UniquePickup> GivePickups(CharacterBody body, Dictionary<PickupIndex, int> pickups)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Invalid comparison between Unknown and I4
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: 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_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Invalid comparison between Unknown and I4
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Invalid comparison between Unknown and I4
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Invalid comparison between Unknown and I4
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: 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_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Invalid comparison between Unknown and I4
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			List<UniquePickup> list = new List<UniquePickup>();
			Inventory val = (Object.op_Implicit((Object)(object)body) ? body.inventory : null);
			if (!NetworkServer.active || !Object.op_Implicit((Object)(object)val) || pickups == null)
			{
				return list;
			}
			bool flag = false;
			PickupIndex key;
			int value;
			foreach (KeyValuePair<PickupIndex, int> pickup in pickups)
			{
				pickup.Deconstruct(out key, out value);
				PickupIndex val2 = key;
				int num = value;
				PickupDef pickupDef = PickupCatalog.GetPickupDef(val2);
				if (num > 0 && pickupDef != null && (int)pickupDef.itemIndex != -1)
				{
					val.GiveItemPermanent(pickupDef.itemIndex, num);
					flag = true;
				}
			}
			if (flag)
			{
				val.RefreshInventoryStateServer();
			}
			bool gaveEquipment = false;
			foreach (KeyValuePair<PickupIndex, int> pickup2 in pickups)
			{
				pickup2.Deconstruct(out key, out value);
				PickupIndex val3 = key;
				int num2 = value;
				PickupDef pickupDef2 = PickupCatalog.GetPickupDef(val3);
				if (num2 <= 0 || pickupDef2 == null || (int)pickupDef2.itemIndex != -1)
				{
					continue;
				}
				for (int i = 0; i < num2; i++)
				{
					if ((int)pickupDef2.equipmentIndex != -1)
					{
						GiveEquipment(val, pickupDef2.equipmentIndex, ref gaveEquipment, list);
						continue;
					}
					if ((int)pickupDef2.keyItemIndex != -1)
					{
						KeyItemIndex keyItemIndex = val.GetKeyItemIndex();
						val.SetKeyItem(pickupDef2.keyItemIndex);
						if ((int)keyItemIndex != -1 && keyItemIndex != pickupDef2.keyItemIndex)
						{
							list.Add(new UniquePickup(PickupCatalog.FindPickupIndex(keyItemIndex)));
						}
						continue;
					}
					GrantContext val4 = new GrantContext
					{
						body = body,
						uniquePickup = new UniquePickup(val3),
						position = body.corePosition,
						rotation = body.transform.rotation
					};
					AttemptGrantDelegate attemptGrant = pickupDef2.attemptGrant;
					if (attemptGrant != null)
					{
						attemptGrant.Invoke(ref val4);
					}
				}
			}
			return list;
		}

		private static void GiveEquipment(Inventory inventory, EquipmentIndex equipmentIndex, ref bool gaveEquipment, List<UniquePickup> leftOver)
		{
			//IL_0010: 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_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Invalid comparison between Unknown and I4
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			EquipmentLocation val = default(EquipmentLocation);
			if (inventory.TryFindBestEquipmentLocation(ref emptyEquipmentLocation, ref val))
			{
				inventory.SetEquipmentIndex(equipmentIndex, ref val);
				gaveEquipment = true;
				return;
			}
			if (gaveEquipment)
			{
				leftOver.Add(new UniquePickup(PickupCatalog.FindPickupIndex(equipmentIndex)));
				return;
			}
			val = inventory.FindBestEquipmentLocationOrCurrent(ref EquipmentLocationQueryArgs.defaultPickup);
			EquipmentIndex equipmentIndex2 = inventory.GetEquipmentIndex(ref val);
			inventory.SetEquipmentIndex(equipmentIndex, ref val);
			gaveEquipment = true;
			if ((int)equipmentIndex2 != -1)
			{
				leftOver.Add(new UniquePickup(PickupCatalog.FindPickupIndex(equipmentIndex2)));
			}
		}

		public unsafe static void WriteDropTablesMarkdownFile(string filePath)
		{
			//IL_03d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_044b: Unknown result type (might be due to invalid IL or missing references)
			//IL_044d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0452: Unknown result type (might be due to invalid IL or missing references)
			//IL_0459: Unknown result type (might be due to invalid IL or missing references)
			//IL_0445: Unknown result type (might be due to invalid IL or missing references)
			//IL_0448: Unknown result type (might be due to invalid IL or missing references)
			//IL_0449: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_045d: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_04af: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b0: Unknown result type (might be due to invalid IL or missing references)
			using StreamWriter streamWriter = new StreamWriter(filePath);
			streamWriter.WriteLine("# Survivors");
			string[] array = SurvivorCatalog.allSurvivorDefs.Select((SurvivorDef survivor) => survivor.cachedName).ToArray();
			foreach (string text in array)
			{
				streamWriter.WriteLine(text ?? "");
			}
			streamWriter.WriteLine("# Bodies");
			array = BodyCatalog.allBodyPrefabs.Select((GameObject prefab) => ((Object)prefab).name).ToArray();
			foreach (string text2 in array)
			{
				streamWriter.WriteLine(text2 ?? "");
			}
			streamWriter.WriteLine("# DropTables");
			streamWriter.WriteLine("| Drop Table Name                  | tier1 | tier2 | tier3 | boss | lunarEquipment | lunarItem | lunarCombined | equipment | voidTier1 | voidTier2 | voidTier3 | voidBoss | foodTier | powerShapes | cursed | hex | page | canDropBeReplaced | requiredItemTags | bannedItemTags |");
			streamWriter.WriteLine("|----------------------------------|-------|-------|-------|------|----------------|-----------|---------------|-----------|-----------|-----------|-----------|----------|----------|-------------|--------|-----|------|-------------------|------------------|----------------|");
			List<string> list = new List<string>();
			List<string> list2 = DropTables.Keys.OrderBy<string, string>((string name) => name, StringComparer.OrdinalIgnoreCase).ToList();
			foreach (string item in list2)
			{
				PickupDropTable droptable = GetDroptable(item);
				BasicPickupDropTable val = (BasicPickupDropTable)(object)((droptable is BasicPickupDropTable) ? droptable : null);
				if (val == null)
				{
					list.Add($"| {item,-32} | {((object)droptable).GetType().Name} |");
					continue;
				}
				string text3 = string.Join(", ", val.requiredItemTags.Select((ItemTag e) => ((object)(*(ItemTag*)(&e))/*cast due to .constrained prefix*/).ToString()));
				string text4 = string.Join(", ", val.bannedItemTags.Select((ItemTag e) => ((object)(*(ItemTag*)(&e))/*cast due to .constrained prefix*/).ToString()));
				streamWriter.WriteLine($"| {item,-32} | {val.tier1Weight} | {val.tier2Weight} | {val.tier3Weight} | {val.bossWeight} | {val.lunarEquipmentWeight} | {val.lunarItemWeight} | {val.lunarCombinedWeight} | {val.equipmentWeight} | {val.voidTier1Weight} | {val.voidTier2Weight} | {val.voidTier3Weight} | {val.voidBossWeight} | {val.foodTierWeight} | {val.powerShapesWeight} | {val.cursedWeight} | {val.hexWeight} | {val.pageWeight} | {((PickupDropTable)val).canDropBeReplaced} | {text3} | {text4} |");
			}
			streamWriter.WriteLine("# Other DropTables");
			streamWriter.WriteLine("| Drop Table Name                  | Type |");
			streamWriter.WriteLine("|----------------------------------|------|");
			foreach (string item2 in list)
			{
				streamWriter.WriteLine(item2);
			}
			string text5 = string.Join(" | ", list2.Select((string name) => "\"" + name + "\""));
			string text6 = "";
			ItemIndex val2 = (ItemIndex)0;
			for (ItemIndex val3 = (ItemIndex)ItemCatalog.itemCount; val2 < val3; val2 = (ItemIndex)(val2 + 1))
			{
				ItemDef itemDef = ItemCatalog.GetItemDef(val2);
				if (!itemDef.tags.Contains((ItemTag)25) && itemDef.DoesNotContainTag((ItemTag)9))
				{
					text6 = ((!string.IsNullOrWhiteSpace(text6)) ? (text6 + " | \"" + ((Object)itemDef).name + "\"") : ("\"" + ((Object)itemDef).name + "\""));
				}
			}
			EquipmentIndex val4 = (EquipmentIndex)0;
			for (EquipmentIndex val5 = (EquipmentIndex)EquipmentCatalog.equipmentCount; val4 < val5; val4 = (EquipmentIndex)(val4 + 1))
			{
				EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef(val4);
				if (equipmentDef.canDrop)
				{
					text6 = ((!string.IsNullOrWhiteSpace(text6)) ? (text6 + " | \"" + ((Object)equipmentDef).name + "\"") : ("\"" + ((Object)equipmentDef).name + "\""));
				}
			}
			foreach (DroneDef allDroneDef in DroneCatalog.allDroneDefs)
			{
				text6 += (string.IsNullOrWhiteSpace(text6) ? ("\"" + ((Object)allDroneDef).name + "\"") : (" | \"" + ((Object)allDroneDef).name + "\""));
			}
			foreach (KeyItemDef allKeyItemDef in KeyItemCatalog.allKeyItemDefs)
			{
				text6 += (string.IsNullOrWhiteSpace(text6) ? ("\"" + ((Object)allKeyItemDef).name + "\"") : (" | \"" + ((Object)allKeyItemDef).name + "\""));
			}
			streamWriter.WriteLine("# EBNF");
			streamWriter.WriteLine("```");
			streamWriter.WriteLine("<itemname>  ::= " + text6);
			streamWriter.WriteLine("<droptable> ::= " + text5);
			streamWriter.WriteLine("```");
		}
	}
}