Decompiled source of TILER2nt v7.4.6

TILER2.dll

Decompiled 5 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Linq.Expressions;
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.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HG;
using HG.Reflection;
using IL.RoR2;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using MonoMod.RuntimeDetour.HookGen;
using On.RoR2;
using On.RoR2.Items;
using On.RoR2.Networking;
using On.RoR2.UI;
using On.RoR2.UI.LogBook;
using R2API;
using R2API.Networking;
using R2API.Networking.Interfaces;
using R2API.Utils;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RoR2;
using RoR2.Artifacts;
using RoR2.ConVar;
using RoR2.ExpansionManagement;
using RoR2.Items;
using RoR2.Navigation;
using RoR2.Networking;
using RoR2.Orbs;
using RoR2.Skills;
using RoR2.UI;
using RoR2.UI.LogBook;
using ShareSuite;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: OptIn]
[assembly: IgnoresAccessChecksTo("RoR2")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("TILER2")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+5ff65b1ae6f307a3e756167b80472d61388ff1a2")]
[assembly: AssemblyProduct("TILER2")]
[assembly: AssemblyTitle("TILER2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: UnverifiableCode]
namespace TILER2
{
	public static class Compat_RiskOfOptions
	{
		public struct OptionIdentityStrings
		{
			public string category;

			public string name;

			public string description;

			public string modName;

			public string modGuid;
		}

		private static bool? _enabled;

		public static bool enabled
		{
			get
			{
				if (!_enabled.HasValue)
				{
					_enabled = Chainloader.PluginInfos.ContainsKey("com.rune580.riskofoptions");
				}
				return _enabled.Value;
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void SetupMod(string modGuid, string modName, string description, Sprite icon = null)
		{
			ModSettingsManager.SetModDescription(description, modGuid, modName);
			if ((Object)(object)icon != (Object)null)
			{
				ModSettingsManager.SetModIcon(icon, modGuid, modName);
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void AddOption_CheckBox(ConfigEntry<bool> configEntry, OptionIdentityStrings ident, bool restartRequired, Func<bool> isDisabledDelegate)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_0056: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(configEntry, new CheckBoxConfig
			{
				category = ident.category,
				name = ident.name,
				restartRequired = restartRequired,
				description = ident.description,
				checkIfDisabled = (IsDisabledDelegate)(() => isDisabledDelegate())
			}), ident.modGuid, ident.modName);
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void AddOption_Slider(ConfigEntry<float> configEntry, OptionIdentityStrings ident, float min, float max, string formatString, bool restartRequired, Func<bool> isDisabledDelegate)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			//IL_006e: Expected O, but got Unknown
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			ModSettingsManager.AddOption((BaseOption)new SliderOption(configEntry, new SliderConfig
			{
				category = ident.category,
				name = ident.name,
				max = max,
				min = min,
				formatString = formatString,
				restartRequired = restartRequired,
				description = ident.description,
				checkIfDisabled = (IsDisabledDelegate)(() => isDisabledDelegate())
			}), ident.modGuid, ident.modName);
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void AddOption_IntSlider(ConfigEntry<int> configEntry, OptionIdentityStrings ident, int min, int max, string formatString, bool restartRequired, Func<bool> isDisabledDelegate)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			//IL_006e: Expected O, but got Unknown
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			ModSettingsManager.AddOption((BaseOption)new IntSliderOption(configEntry, new IntSliderConfig
			{
				category = ident.category,
				name = ident.name,
				max = max,
				min = min,
				formatString = formatString,
				restartRequired = restartRequired,
				description = ident.description,
				checkIfDisabled = (IsDisabledDelegate)(() => isDisabledDelegate())
			}), ident.modGuid, ident.modName);
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void AddOption_Choice(ConfigEntryBase configEntry, OptionIdentityStrings ident, bool restartRequired, Func<bool> isDisabledDelegate)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_0056: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			ModSettingsManager.AddOption((BaseOption)new ChoiceOption(configEntry, new ChoiceConfig
			{
				category = ident.category,
				name = ident.name,
				restartRequired = restartRequired,
				description = ident.description,
				checkIfDisabled = (IsDisabledDelegate)(() => isDisabledDelegate())
			}), ident.modGuid, ident.modName);
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void AddOption_Keybind(ConfigEntry<KeyboardShortcut> configEntry, OptionIdentityStrings ident, bool restartRequired, Func<bool> isDisabledDelegate)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_0056: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			ModSettingsManager.AddOption((BaseOption)new KeyBindOption(configEntry, new KeyBindConfig
			{
				category = ident.category,
				name = ident.name,
				restartRequired = restartRequired,
				description = ident.description,
				checkIfDisabled = (IsDisabledDelegate)(() => isDisabledDelegate())
			}), ident.modGuid, ident.modName);
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void AddOption_String(ConfigEntry<string> configEntry, OptionIdentityStrings ident, bool restartRequired, Func<bool> isDisabledDelegate)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Expected O, but got Unknown
			//IL_0056: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			ModSettingsManager.AddOption((BaseOption)new StringInputFieldOption(configEntry, new InputFieldConfig
			{
				category = ident.category,
				name = ident.name,
				restartRequired = restartRequired,
				description = ident.description,
				checkIfDisabled = (IsDisabledDelegate)(() => isDisabledDelegate())
			}), ident.modGuid, ident.modName);
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void AddOption_StepSlider(ConfigEntry<float> configEntry, OptionIdentityStrings ident, float min, float max, float step, string formatString, bool restartRequired, Func<bool> isDisabledDelegate)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_004b: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Expected O, but got Unknown
			//IL_0076: Expected O, but got Unknown
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			ModSettingsManager.AddOption((BaseOption)new StepSliderOption(configEntry, new StepSliderConfig
			{
				category = ident.category,
				name = ident.name,
				min = min,
				max = max,
				formatString = formatString,
				increment = step,
				restartRequired = restartRequired,
				description = ident.description,
				checkIfDisabled = (IsDisabledDelegate)(() => isDisabledDelegate())
			}), ident.modGuid, ident.modName);
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void AddOption_Button(OptionIdentityStrings ident, string text, UnityAction del)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			ModSettingsManager.AddOption((BaseOption)new GenericButtonOption(ident.name, ident.category, ident.description, text, del), ident.modGuid, ident.modName);
		}
	}
	public static class Compat_ShareSuite
	{
		private static bool? _enabled;

		public static bool enabled
		{
			get
			{
				if (!_enabled.HasValue)
				{
					_enabled = Chainloader.PluginInfos.ContainsKey("com.funkfrog_sipondo.sharesuite");
				}
				return _enabled.Value;
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static void GiveMoney(uint amount)
		{
			MoneySharingHooks.AddMoneyExternal((int)amount);
		}

		[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
		public static bool MoneySharing()
		{
			if (ShareSuite.MoneyIsShared.Value)
			{
				return true;
			}
			return false;
		}
	}
	[RequireComponent(typeof(Inventory))]
	public class FakeInventory : NetworkBehaviour
	{
		internal class FakeInventoryModule : T2Module<FakeInventoryModule>
		{
			public override void SetupConfig()
			{
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_001f: Expected O, but got Unknown
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_0031: Expected O, but got Unknown
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_0043: Expected O, but got Unknown
				//IL_004b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0055: Expected O, but got Unknown
				//IL_005d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0067: Expected O, but got Unknown
				//IL_006f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0079: Expected O, but got Unknown
				//IL_0081: Unknown result type (might be due to invalid IL or missing references)
				//IL_008b: Expected O, but got Unknown
				//IL_0093: Unknown result type (might be due to invalid IL or missing references)
				//IL_009d: Expected O, but got Unknown
				//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00af: Expected O, but got Unknown
				//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
				//IL_00c1: Expected O, but got Unknown
				//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d3: Expected O, but got Unknown
				//IL_00db: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e5: Expected O, but got Unknown
				//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f7: Expected O, but got Unknown
				//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
				//IL_0109: Expected O, but got Unknown
				//IL_0111: Unknown result type (might be due to invalid IL or missing references)
				//IL_011b: Expected O, but got Unknown
				//IL_0123: Unknown result type (might be due to invalid IL or missing references)
				//IL_012d: Expected O, but got Unknown
				//IL_0135: Unknown result type (might be due to invalid IL or missing references)
				//IL_013f: Expected O, but got Unknown
				//IL_0147: Unknown result type (might be due to invalid IL or missing references)
				//IL_0151: Expected O, but got Unknown
				//IL_0159: Unknown result type (might be due to invalid IL or missing references)
				//IL_0163: Expected O, but got Unknown
				//IL_016b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0175: Expected O, but got Unknown
				//IL_017d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0187: Expected O, but got Unknown
				//IL_018f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0199: Expected O, but got Unknown
				//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ab: Expected O, but got Unknown
				//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
				//IL_01bd: Expected O, but got Unknown
				base.SetupConfig();
				NetworkingAPI.RegisterMessageType<MsgSyncAll>();
				Inventory.GetItemCount_ItemIndex += new hook_GetItemCount_ItemIndex(On_InvGetItemCountByIndex);
				LunarItemOrEquipmentCostTypeHelper.IsAffordable += new hook_IsAffordable(LunarItemOrEquipmentCostTypeHelper_IsAffordable);
				Inventory.HasAtLeastXTotalItemsOfTier += new hook_HasAtLeastXTotalItemsOfTier(Inventory_HasAtLeastXTotalItemsOfTier);
				Inventory.GetTotalItemCountOfTier += new hook_GetTotalItemCountOfTier(Inventory_GetTotalItemCountOfTier);
				StolenInventoryInfo.StealItem += new hook_StealItem(StolenInventoryInfo_StealItem);
				RunReport.Generate += new hook_Generate(RunReport_Generate);
				ShrineCleanseBehavior.CleanseInventoryServer += new hook_CleanseInventoryServer(ShrineCleanseBehavior_CleanseInventoryServer);
				ShrineCleanseBehavior.InventoryIsCleansable += new hook_InventoryIsCleansable(ShrineCleanseBehavior_InventoryIsCleansable);
				Util.GetItemCountForTeam += new hook_GetItemCountForTeam(Util_GetItemCountForTeam);
				PickupPickerController.GetGeneratedOptionsFromInteractor += new Manipulator(PickupPickerController_GetGeneratedOptionsFromInteractor);
				ContagiousItemManager.StepInventoryInfection += new hook_StepInventoryInfection(ContagiousItemManager_StepInventoryInfection);
				ContagiousItemManager.OnInventoryChangedGlobal += new hook_OnInventoryChangedGlobal(ContagiousItemManager_OnInventoryChangedGlobal);
				SuppressedItemManager.OnInventoryChangedGlobal += new hook_OnInventoryChangedGlobal(SuppressedItemManager_OnInventoryChangedGlobal);
				SuppressedItemManager.SuppressItem += new hook_SuppressItem(SuppressedItemManager_SuppressItem);
				SuppressedItemManager.TransformItem += new hook_TransformItem(SuppressedItemManager_TransformItem);
				CharacterMaster.TryCloverVoidUpgrades += new hook_TryCloverVoidUpgrades(CharacterMaster_TryCloverVoidUpgrades);
				ArtifactTrialMissionController.RemoveAllMissionKeys += new hook_RemoveAllMissionKeys(ArtifactTrialMissionController_RemoveAllMissionKeys);
				StolenInventoryInfo.TakeItemFromLendee += new hook_TakeItemFromLendee(StolenInventoryInfo_TakeItemFromLendee);
				StolenInventoryInfo.TakeBackItemsFromLendee += new hook_TakeBackItemsFromLendee(StolenInventoryInfo_TakeBackItemsFromLendee);
				LunarSunBehavior.FixedUpdate += new hook_FixedUpdate(LunarSunBehavior_FixedUpdate);
				CostTypeDef.IsAffordable += new hook_IsAffordable(CostTypeDef_IsAffordable);
				Run.FixedUpdate += new hook_FixedUpdate(Run_FixedUpdate);
				ItemInventoryDisplay.UpdateDisplay += new hook_UpdateDisplay(On_IIDUpdateDisplay);
				ItemInventoryDisplay.OnInventoryChanged += new hook_OnInventoryChanged(On_IIDInventoryChanged);
			}
		}

		protected struct MsgSyncAll : INetMessage, ISerializableObject
		{
			private NetworkInstanceId _ownerNetId;

			private int[] _itemsToSync;

			public void Serialize(NetworkWriter writer)
			{
				//IL_0003: Unknown result type (might be due to invalid IL or missing references)
				writer.Write(_ownerNetId);
				NetworkExtensions.WriteItemStacks(writer, _itemsToSync);
			}

			public void Deserialize(NetworkReader reader)
			{
				//IL_0003: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				_ownerNetId = reader.ReadNetworkId();
				_itemsToSync = new int[ItemCatalog.itemCount];
				NetworkExtensions.ReadItemStacks(reader, _itemsToSync);
			}

			public void OnReceived()
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				GameObject val = Util.FindNetworkObject(_ownerNetId);
				if (!Object.op_Implicit((Object)(object)val))
				{
					TILER2Plugin._logger.LogWarning((object)$"FakeInventory.MsgSyncAll received for missing NetworkObject with ID {_ownerNetId}");
					return;
				}
				FakeInventory fakeInventory = val.GetComponent<FakeInventory>();
				if (!Object.op_Implicit((Object)(object)fakeInventory))
				{
					fakeInventory = val.AddComponent<FakeInventory>();
				}
				fakeInventory._itemStacks = _itemsToSync;
				if (NetworkServer.active)
				{
					((NetworkBehaviour)fakeInventory.inventory).SetDirtyBit(1u);
					((NetworkBehaviour)fakeInventory.inventory).SetDirtyBit(8u);
				}
				MulticastDelegate multicastDelegate = (MulticastDelegate)Reflection.GetFieldCached(typeof(Inventory), "onInventoryChanged").GetValue(fakeInventory.inventory);
				Delegate[] invocationList = multicastDelegate.GetInvocationList();
				foreach (Delegate obj in invocationList)
				{
					obj.Method.Invoke(obj.Target, null);
				}
			}

			public MsgSyncAll(NetworkInstanceId ownerNetId, int[] itemsToSync)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0003: Unknown result type (might be due to invalid IL or missing references)
				_ownerNetId = ownerNetId;
				_itemsToSync = itemsToSync;
			}
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static Func<Instruction, bool> <>9__31_1;

			public static Func<Instruction, bool> <>9__31_2;

			public static Func<bool, ItemDef, Inventory, bool> <>9__31_3;

			public static Manipulator <>9__31_0;

			internal void <PickupPickerController_GetGeneratedOptionsFromInteractor>b__31_0(ILContext il)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Expected O, but got Unknown
				//IL_005b: 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)
				ILCursor val = new ILCursor(il);
				val.GotoNext((MoveType)2, new Func<Instruction, bool>[2]
				{
					(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 2),
					(Instruction x) => ILPatternMatchingExt.MatchLdfld<ItemDef>(x, "canRemove")
				});
				val.Emit(OpCodes.Ldarg_2);
				val.Emit(OpCodes.Ldarg_3);
				val.EmitDelegate<Func<bool, ItemDef, Inventory, bool>>((Func<bool, ItemDef, Inventory, bool>)delegate(bool origDoContinue, ItemDef itemdef, Inventory inventoryofplayer)
				{
					//IL_0011: Unknown result type (might be due to invalid IL or missing references)
					bool result = origDoContinue;
					ignoreFakes++;
					if (inventoryofplayer.GetItemCountPermanent(itemdef.itemIndex) <= 0)
					{
						result = false;
					}
					ignoreFakes--;
					return result;
				});
			}

			internal bool <PickupPickerController_GetGeneratedOptionsFromInteractor>b__31_1(Instruction x)
			{
				return ILPatternMatchingExt.MatchLdarg(x, 2);
			}

			internal bool <PickupPickerController_GetGeneratedOptionsFromInteractor>b__31_2(Instruction x)
			{
				return ILPatternMatchingExt.MatchLdfld<ItemDef>(x, "canRemove");
			}

			internal bool <PickupPickerController_GetGeneratedOptionsFromInteractor>b__31_3(bool origDoContinue, ItemDef itemdef, Inventory inventoryofplayer)
			{
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				bool result = origDoContinue;
				ignoreFakes++;
				if (inventoryofplayer.GetItemCountPermanent(itemdef.itemIndex) <= 0)
				{
					result = false;
				}
				ignoreFakes--;
				return result;
			}
		}

		private int[] _itemStacks = ItemCatalog.RequestItemStackArray();

		public readonly ReadOnlyCollection<int> itemStacks;

		private static Dictionary<Inventory, FakeInventory> instancesByInventory = new Dictionary<Inventory, FakeInventory>();

		public static ReadOnlyDictionary<Inventory, FakeInventory> readOnlyInstancesByInventory = new ReadOnlyDictionary<Inventory, FakeInventory>(instancesByInventory);

		internal static ManualLogSource _logger;

		public static HashSet<ItemDef> blacklist = new HashSet<ItemDef>();

		private bool itemsDirty = false;

		public static int ignoreFakes = 0;

		public Inventory inventory { get; private set; }

		public Type itsprivate => typeof(ItemStealController).GetNestedType("StolenItemInfo", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		public FakeInventory()
		{
			itemStacks = new ReadOnlyCollection<int>(_itemStacks);
		}

		private void OnDestroy()
		{
			instancesByInventory.Remove(inventory);
			ItemCatalog.ReturnItemStackArray(_itemStacks);
		}

		private void DeltaItem(ItemIndex ind, int count)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (!blacklist.Contains(ItemCatalog.GetItemDef(ind)))
			{
				_itemStacks[ind] = Mathf.Max(_itemStacks[ind] + count, 0);
				itemsDirty = true;
			}
		}

		public void GiveItem(ItemIndex ind, int count = 1)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active)
			{
				return;
			}
			if (count <= 0)
			{
				if (count < 0)
				{
					RemoveItem(ind, -count);
				}
			}
			else
			{
				DeltaItem(ind, count);
			}
		}

		public void RemoveItem(ItemIndex ind, int count = 1)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active)
			{
				return;
			}
			if (count <= 0)
			{
				if (count < 0)
				{
					GiveItem(ind, -count);
				}
			}
			else
			{
				DeltaItem(ind, -count);
			}
		}

		public int GetItemCount(ItemIndex ind)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected I4, but got Unknown
			return ArrayUtils.GetSafe<int>(_itemStacks, (int)ind);
		}

		public int GetRealItemCount(ItemIndex ind)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Expected I4, but got Unknown
			return ArrayUtils.GetSafe<int>(_itemStacks, (int)ind);
		}

		public int GetAdjustedItemCount(ItemIndex ind)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Invalid comparison between Unknown and I4
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			ItemIndex transformedItemIndex = ContagiousItemManager.GetTransformedItemIndex(ind);
			IEnumerable<TransformationInfo> source = ((IEnumerable<TransformationInfo>)(object)ContagiousItemManager.transformationInfos).Where((TransformationInfo x) => x.transformedItem == ind);
			bool flag = (int)transformedItemIndex != -1;
			bool flag2 = source.Count() > 0;
			int realItemCount = GetRealItemCount(ind);
			if (flag && GetRealItemCount(transformedItemIndex) > 0)
			{
				return realItemCount;
			}
			if (flag2 && realItemCount > 0)
			{
				return realItemCount + source.Sum((TransformationInfo x) => GetItemCount(x.originalItem)) + GetItemCount(ind);
			}
			return realItemCount + GetItemCount(ind);
		}

		private void Awake()
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			inventory = ((Component)this).GetComponent<Inventory>();
			if (instancesByInventory.ContainsKey(inventory))
			{
				TILER2Plugin._logger.LogError((object)("Inventory on object " + ((Object)((Component)inventory).gameObject).name + " already has a FakeInventory assigned, can't add another!"));
				Object.Destroy((Object)(object)this);
				return;
			}
			instancesByInventory[inventory] = this;
			if (NetworkServer.active)
			{
				NetworkInstanceId netId = ((NetworkBehaviour)this).netId;
				if (((NetworkInstanceId)(ref netId)).Value != 0)
				{
					NetMessageExtensions.Send((INetMessage)(object)new MsgSyncAll(((NetworkBehaviour)this).netId, _itemStacks), (NetworkDestination)1);
				}
			}
		}

		private void Update()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if (itemsDirty && NetworkServer.active)
			{
				NetworkInstanceId netId = ((NetworkBehaviour)this).netId;
				if (((NetworkInstanceId)(ref netId)).Value != 0)
				{
					NetMessageExtensions.Send((INetMessage)(object)new MsgSyncAll(((NetworkBehaviour)this).netId, _itemStacks), (NetworkDestination)1);
					itemsDirty = false;
				}
			}
		}

		private static void Run_FixedUpdate(orig_FixedUpdate orig, Run self)
		{
			orig.Invoke(self);
			if (ignoreFakes != 0)
			{
				TILER2Plugin._logger.LogError((object)$"FakeInventory ignoreFakes count = {ignoreFakes} on new frame (!= 0, very bad!), clearing");
				ignoreFakes = 0;
			}
		}

		private static void StolenInventoryInfo_TakeBackItemsFromLendee(orig_TakeBackItemsFromLendee orig, StolenInventoryInfo self)
		{
			ignoreFakes++;
			orig.Invoke(self);
			ignoreFakes--;
		}

		private static void LunarSunBehavior_FixedUpdate(orig_FixedUpdate orig, LunarSunBehavior self)
		{
			ignoreFakes++;
			orig.Invoke(self);
			ignoreFakes--;
		}

		private static int StolenInventoryInfo_TakeItemFromLendee(orig_TakeItemFromLendee orig, StolenInventoryInfo self, ItemIndex itemIndex, int maxStackToTake)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			ignoreFakes++;
			int result = orig.Invoke(self, itemIndex, maxStackToTake);
			ignoreFakes--;
			return result;
		}

		private static void ArtifactTrialMissionController_RemoveAllMissionKeys(orig_RemoveAllMissionKeys orig)
		{
			ignoreFakes++;
			orig.Invoke();
			ignoreFakes--;
		}

		private static void PickupPickerController_GetGeneratedOptionsFromInteractor(ILContext il)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			MethodInfo method = typeof(PickupPickerController).GetMethod("<GetGeneratedOptionsFromInteractor>g__IsItemValidAsAnOption|84_0", BindingFlags.Instance | BindingFlags.NonPublic);
			object obj = <>c.<>9__31_0;
			if (obj == null)
			{
				Manipulator val = delegate(ILContext val4)
				{
					//IL_0002: Unknown result type (might be due to invalid IL or missing references)
					//IL_0008: Expected O, but got Unknown
					//IL_005b: 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)
					ILCursor val3 = new ILCursor(val4);
					val3.GotoNext((MoveType)2, new Func<Instruction, bool>[2]
					{
						(Instruction x) => ILPatternMatchingExt.MatchLdarg(x, 2),
						(Instruction x) => ILPatternMatchingExt.MatchLdfld<ItemDef>(x, "canRemove")
					});
					val3.Emit(OpCodes.Ldarg_2);
					val3.Emit(OpCodes.Ldarg_3);
					val3.EmitDelegate<Func<bool, ItemDef, Inventory, bool>>((Func<bool, ItemDef, Inventory, bool>)delegate(bool origDoContinue, ItemDef itemdef, Inventory inventoryofplayer)
					{
						//IL_0011: Unknown result type (might be due to invalid IL or missing references)
						bool result = origDoContinue;
						ignoreFakes++;
						if (inventoryofplayer.GetItemCountPermanent(itemdef.itemIndex) <= 0)
						{
							result = false;
						}
						ignoreFakes--;
						return result;
					});
				};
				<>c.<>9__31_0 = val;
				obj = (object)val;
			}
			Manipulator val2 = (Manipulator)obj;
			HookEndpointManager.Modify((MethodBase)method, (Delegate)(object)val2);
		}

		private static bool CostTypeDef_IsAffordable(orig_IsAffordable orig, CostTypeDef self, int cost, Interactor activator)
		{
			ignoreFakes++;
			bool result = orig.Invoke(self, cost, activator);
			ignoreFakes--;
			return result;
		}

		private static int Util_GetItemCountForTeam(orig_GetItemCountForTeam orig, TeamIndex teamIndex, ItemIndex itemIndex, bool requiresAlive, bool requiresConnected)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			ignoreFakes++;
			int result = orig.Invoke(teamIndex, itemIndex, requiresAlive, requiresConnected);
			ignoreFakes--;
			return result;
		}

		private static bool ShrineCleanseBehavior_InventoryIsCleansable(orig_InventoryIsCleansable orig, Inventory inventory)
		{
			ignoreFakes++;
			bool result = orig.Invoke(inventory);
			ignoreFakes--;
			return result;
		}

		private static int ShrineCleanseBehavior_CleanseInventoryServer(orig_CleanseInventoryServer orig, Inventory inventory)
		{
			ignoreFakes++;
			int result = orig.Invoke(inventory);
			ignoreFakes--;
			return result;
		}

		private static RunReport RunReport_Generate(orig_Generate orig, Run run, GameEndingDef gameEnding)
		{
			ignoreFakes++;
			RunReport result = orig.Invoke(run, gameEnding);
			ignoreFakes--;
			return result;
		}

		private static int StolenInventoryInfo_StealItem(orig_StealItem orig, StolenInventoryInfo self, ItemIndex itemIndex, int maxStackToSteal, bool? useOrbOverride)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			ignoreFakes++;
			int result = orig.Invoke(self, itemIndex, maxStackToSteal, useOrbOverride);
			ignoreFakes--;
			return result;
		}

		private static int Inventory_GetTotalItemCountOfTier(orig_GetTotalItemCountOfTier orig, Inventory self, ItemTier itemTier)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			ignoreFakes++;
			int result = orig.Invoke(self, itemTier);
			ignoreFakes--;
			return result;
		}

		private static bool Inventory_HasAtLeastXTotalItemsOfTier(orig_HasAtLeastXTotalItemsOfTier orig, Inventory self, ItemTier itemTier, int x)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			ignoreFakes++;
			bool result = orig.Invoke(self, itemTier, x);
			ignoreFakes--;
			return result;
		}

		private static bool LunarItemOrEquipmentCostTypeHelper_IsAffordable(orig_IsAffordable orig, CostTypeDef costTypeDef, IsAffordableContext context)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			ignoreFakes++;
			bool result = orig.Invoke(costTypeDef, context);
			ignoreFakes--;
			return result;
		}

		private static bool ContagiousItemManager_StepInventoryInfection(orig_StepInventoryInfection orig, Inventory inventory, ItemIndex originalItem, int limit, bool isForced)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			ignoreFakes++;
			bool result = orig.Invoke(inventory, originalItem, limit, isForced);
			ignoreFakes--;
			return result;
		}

		private static void ContagiousItemManager_OnInventoryChangedGlobal(orig_OnInventoryChangedGlobal orig, Inventory inventory)
		{
			ignoreFakes++;
			orig.Invoke(inventory);
			ignoreFakes--;
		}

		private static void SuppressedItemManager_OnInventoryChangedGlobal(orig_OnInventoryChangedGlobal orig, Inventory inventory)
		{
			ignoreFakes++;
			orig.Invoke(inventory);
			ignoreFakes--;
		}

		private static bool SuppressedItemManager_SuppressItem(orig_SuppressItem orig, ItemIndex suppressedIndex, ItemIndex transformedIndex)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			ignoreFakes++;
			bool result = orig.Invoke(suppressedIndex, transformedIndex);
			ignoreFakes--;
			return result;
		}

		private static void SuppressedItemManager_TransformItem(orig_TransformItem orig, Inventory inventory, ItemIndex suppressedIndex, ItemIndex transformedIndex)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			ignoreFakes++;
			orig.Invoke(inventory, suppressedIndex, transformedIndex);
			ignoreFakes--;
		}

		private static void CharacterMaster_TryCloverVoidUpgrades(orig_TryCloverVoidUpgrades orig, CharacterMaster self)
		{
			ignoreFakes++;
			orig.Invoke(self);
			ignoreFakes--;
		}

		private static int On_InvGetItemCountByIndex(orig_GetItemCount_ItemIndex orig, Inventory self, ItemIndex itemIndex)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			int result = orig.Invoke(self, itemIndex);
			if (ignoreFakes > 0 || !Object.op_Implicit((Object)(object)self))
			{
				return result;
			}
			if (readOnlyInstancesByInventory.TryGetValue(self, out var value))
			{
				return value.GetAdjustedItemCount(itemIndex);
			}
			return result;
		}

		private static void On_IIDInventoryChanged(orig_OnInventoryChanged orig, ItemInventoryDisplay self)
		{
			orig.Invoke(self);
			if (!Object.op_Implicit((Object)(object)self) || !((Behaviour)self).isActiveAndEnabled || !Object.op_Implicit((Object)(object)self.inventory) || !readOnlyInstancesByInventory.TryGetValue(self.inventory, out var value))
			{
				return;
			}
			List<ItemIndex> list = self.itemOrder.Take(self.itemOrderCount).ToList();
			for (int i = 0; i < self.itemStacks.Length; i++)
			{
				int adjustedItemCount = value.GetAdjustedItemCount((ItemIndex)i);
				if (self.itemStacks[i] == 0)
				{
					if (adjustedItemCount > 0)
					{
						list.Add((ItemIndex)i);
					}
					else
					{
						list.Remove((ItemIndex)i);
					}
				}
				self.itemStacks[i] = adjustedItemCount;
			}
			list = list.Distinct().ToList();
			list.CopyTo(0, self.itemOrder, 0, Mathf.Min(self.itemOrder.Length, list.Count));
			self.itemOrderCount = list.Count;
		}

		private static void On_IIDUpdateDisplay(orig_UpdateDisplay orig, ItemInventoryDisplay self)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			orig.Invoke(self);
			Inventory val = self.inventory;
			if (!Object.op_Implicit((Object)(object)val) || !readOnlyInstancesByInventory.TryGetValue(self.inventory, out var value))
			{
				return;
			}
			foreach (ItemIcon itemIcon in self.itemIcons)
			{
				int realItemCount = value.GetRealItemCount(itemIcon.itemIndex);
				int num = value.GetAdjustedItemCount(itemIcon.itemIndex) - realItemCount;
				SpriteAsNumberManager spriteAsNumberManager = itemIcon.spriteAsNumberManager;
				spriteAsNumberManager.SetSpriteColor(Color.white);
				if (num != 0)
				{
					spriteAsNumberManager.TrySetup();
					spriteAsNumberManager.isVisible = true;
					List<int> list = new List<int>();
					spriteAsNumberManager.LoadListWithDigitPositions(num, ref list, 0);
					list.Add(-6666);
					spriteAsNumberManager.LoadListWithDigitPositions(realItemCount, ref list, 0);
					list.Add(-6666);
					spriteAsNumberManager.UpdateSpriteObjectsWithListValues(list, 0);
					for (int i = 0; i <= spriteAsNumberManager.GetTotalDigitPositions(num); i++)
					{
						((Graphic)spriteAsNumberManager.imageList[i]).color = new Color(0.75686276f, 0.56078434f, 0.8784314f);
					}
				}
			}
		}
	}
	[RequireComponent(typeof(NetworkIdentity))]
	public class ItemWard : NetworkBehaviour
	{
		public enum DisplayPerformanceMode
		{
			None,
			OnePerItemIndex,
			All
		}

		internal class ItemWardModule : T2Module<ItemWardModule>
		{
			[AutoConfigRoOChoice(null, null)]
			[AutoConfig("Controls how many item displays are created on ItemWards.", AutoConfigFlags.DeferUntilEndGame, new object[] { })]
			public DisplayPerformanceMode displayPerformanceMode { get; private set; } = DisplayPerformanceMode.All;

			public override void SetupConfig()
			{
				//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
				//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
				//IL_0119: Unknown result type (might be due to invalid IL or missing references)
				base.SetupConfig();
				NetworkingAPI.RegisterMessageType<MsgDeltaDisplay>();
				NetworkingAPI.RegisterMessageType<MsgSyncRadius>();
				GameObject val = PrefabAPI.InstantiateClone(LegacyResourcesAPI.Load<GameObject>("prefabs/effects/orbeffects/ItemTransferOrbEffect"), "TILER2TempSetupPrefab", false);
				((Behaviour)val.GetComponent<EffectComponent>()).enabled = false;
				((Behaviour)val.GetComponent<OrbEffect>()).enabled = false;
				((Behaviour)val.GetComponent<ItemTakenOrbEffect>()).enabled = false;
				displayPrefab = PrefabAPI.InstantiateClone(val, "ItemWardDisplay", false);
				GameObject val2 = PrefabAPI.InstantiateClone(LegacyResourcesAPI.Load<GameObject>("Prefabs/NetworkedObjects/WarbannerWard"), "TILER2TempSetupPrefab", false);
				GameObject gameObject = ((Component)val2.transform.Find("Indicator")).gameObject;
				gameObject.transform.SetParent((Transform)null);
				MeshRenderer component = ((Component)gameObject.transform.Find("IndicatorSphere")).gameObject.GetComponent<MeshRenderer>();
				((Renderer)component).material.SetTexture("_RemapTex", (Texture)(object)Addressables.LoadAssetAsync<Texture2D>((object)"RoR2/Base/Common/ColorRamps/texRampDefault.png").WaitForCompletion());
				((Renderer)component).material.SetColor("_CutoffScroll", new Color(0.8f, 0.8f, 0.85f));
				((Renderer)component).material.SetColor("_RimColor", new Color(0.8f, 0.8f, 0.85f));
				stockIndicatorPrefab = PrefabAPI.InstantiateClone(gameObject, "ItemWardStockIndicator", false);
				Object.Destroy((Object)(object)val2);
				Object.Destroy((Object)(object)gameObject);
			}
		}

		protected struct MsgSyncRadius : INetMessage, ISerializableObject
		{
			private ItemWard _targetWard;

			private float _newRadius;

			public void Serialize(NetworkWriter writer)
			{
				writer.Write(((Component)_targetWard).gameObject);
				writer.Write(_newRadius);
			}

			public void Deserialize(NetworkReader reader)
			{
				_targetWard = reader.ReadGameObject().GetComponent<ItemWard>();
				_newRadius = reader.ReadSingle();
			}

			public void OnReceived()
			{
				_targetWard._radius = _newRadius;
				_targetWard.radSq = _newRadius * _newRadius;
			}

			public MsgSyncRadius(ItemWard targetWard, float newRadius)
			{
				_targetWard = targetWard;
				_newRadius = newRadius;
			}
		}

		protected struct MsgDeltaDisplay : INetMessage, ISerializableObject
		{
			private NetworkInstanceId _ownerNetId;

			private ItemIndex _itemIndex;

			private bool _isAdd;

			public void Serialize(NetworkWriter writer)
			{
				//IL_0003: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Expected I4, but got Unknown
				writer.Write(_ownerNetId);
				writer.Write((int)_itemIndex);
				writer.Write(_isAdd);
			}

			public void Deserialize(NetworkReader reader)
			{
				//IL_0003: Unknown result type (might be due to invalid IL or missing references)
				//IL_0008: Unknown result type (might be due to invalid IL or missing references)
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				_ownerNetId = reader.ReadNetworkId();
				_itemIndex = (ItemIndex)reader.ReadInt32();
				_isAdd = reader.ReadBoolean();
			}

			public void OnReceived()
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				ItemWard component = Util.FindNetworkObject(_ownerNetId).GetComponent<ItemWard>();
				if (_isAdd)
				{
					component.ClientAddItemDisplay(_itemIndex);
				}
				else
				{
					component.ClientRemoveItemDisplay(_itemIndex);
				}
			}

			public MsgDeltaDisplay(NetworkInstanceId ownerNetId, ItemIndex itemIndex, bool isAdd)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0003: Unknown result type (might be due to invalid IL or missing references)
				//IL_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				_ownerNetId = ownerNetId;
				_itemIndex = itemIndex;
				_isAdd = isAdd;
			}
		}

		public static GameObject stockIndicatorPrefab;

		public static GameObject displayPrefab;

		public float displayRadiusFracH = 0.5f;

		public float displayRadiusFracV = 0.3f;

		public Vector3 displayIndivScale = Vector3.one;

		public Vector3 displayRadiusOffset = new Vector3(0f, 0f, 0f);

		public Transform rangeIndicator;

		public Dictionary<ItemIndex, int> itemcounts = new Dictionary<ItemIndex, int>();

		private const float updateTickRate = 1f;

		private float stopwatch = 0f;

		private TeamFilter teamFilter;

		private TeamComponent teamComponent;

		private float rangeIndicatorScaleVelocity;

		private readonly List<GameObject> displays = new List<GameObject>();

		private readonly List<Vector3> displayVelocities = new List<Vector3>();

		private readonly List<ItemIndex> displayItems = new List<ItemIndex>();

		private readonly List<Inventory> trackedInventories = new List<Inventory>();

		private float _radius = 10f;

		public float radius
		{
			get
			{
				return _radius;
			}
			set
			{
				_radius = value;
				radSq = _radius * _radius;
				if (NetworkServer.active)
				{
					NetMessageExtensions.Send((INetMessage)(object)new MsgSyncRadius(this, value), (NetworkDestination)1);
				}
			}
		}

		public float radSq { get; private set; } = 100f;

		public TeamIndex currentTeam => (TeamIndex)((!Object.op_Implicit((Object)(object)teamFilter)) ? ((!Object.op_Implicit((Object)(object)teamComponent)) ? (-1) : ((int)teamComponent.teamIndex)) : ((int)teamFilter.teamIndex));

		private void Awake()
		{
			teamFilter = ((Component)this).GetComponent<TeamFilter>();
			teamComponent = ((Component)this).GetComponent<TeamComponent>();
		}

		private void OnDestroy()
		{
			if (!NetworkServer.active)
			{
				return;
			}
			foreach (GameObject display in displays)
			{
				Object.Destroy((Object)(object)display);
			}
		}

		private void OnEnable()
		{
			if (Object.op_Implicit((Object)(object)rangeIndicator))
			{
				((Component)rangeIndicator).gameObject.SetActive(true);
			}
			foreach (GameObject display in displays)
			{
				display.SetActive(true);
			}
		}

		private void OnDisable()
		{
			if (Object.op_Implicit((Object)(object)rangeIndicator))
			{
				((Component)rangeIndicator).gameObject.SetActive(false);
			}
			foreach (GameObject display in displays)
			{
				display.SetActive(false);
			}
			trackedInventories.RemoveAll((Inventory x) => !Object.op_Implicit((Object)(object)x) || !Object.op_Implicit((Object)(object)((Component)x).gameObject));
			for (int num = trackedInventories.Count - 1; num >= 0; num--)
			{
				DeregInv(trackedInventories[num]);
			}
		}

		private void Update()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: 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: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkClient.active)
			{
				if (Object.op_Implicit((Object)(object)rangeIndicator))
				{
					float num = Mathf.SmoothDamp(rangeIndicator.localScale.x, radius, ref rangeIndicatorScaleVelocity, 0.2f);
					rangeIndicator.localScale = new Vector3(num, num, num);
				}
				float num2 = -0.125f * (MathF.PI * 2f * Time.time);
				float num3 = MathF.PI * 2f / (float)displays.Count;
				float num4 = radius * displayRadiusFracH;
				float num5 = Mathf.Max(radius * displayRadiusFracV, 1f);
				for (int num6 = displays.Count - 1; num6 >= 0; num6--)
				{
					Vector3 val = new Vector3(Mathf.Cos(num3 * (float)num6 + num2) * num4, num5, Mathf.Sin(num3 * (float)num6 + num2) * num4) + displayRadiusOffset;
					Vector3 value = displayVelocities[num6];
					displays[num6].transform.localPosition = Vector3.SmoothDamp(displays[num6].transform.localPosition, val, ref value, 1f);
					displays[num6].transform.localScale = displayIndivScale;
					displayVelocities[num6] = value;
				}
			}
		}

		private void FixedUpdate()
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			stopwatch += Time.fixedDeltaTime;
			if (!(stopwatch > 1f))
			{
				return;
			}
			stopwatch = 0f;
			trackedInventories.RemoveAll((Inventory x) => !Object.op_Implicit((Object)(object)x) || !Object.op_Implicit((Object)(object)((Component)x).gameObject));
			IEnumerable<CharacterBody> enumerable = from tc in TeamComponent.GetTeamMembers(currentTeam)
				select tc.body;
			foreach (CharacterBody item in enumerable)
			{
				if (Object.op_Implicit((Object)(object)item))
				{
					Vector3 val = item.transform.position - ((Component)this).transform.position;
					if (((Vector3)(ref val)).sqrMagnitude <= radSq)
					{
						RegBody(item);
					}
					else
					{
						DeregBody(item);
					}
				}
			}
		}

		private void RegBody(CharacterBody cb)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			Inventory inventory = cb.inventory;
			if (!Object.op_Implicit((Object)(object)inventory) || trackedInventories.Contains(inventory))
			{
				return;
			}
			trackedInventories.Add(inventory);
			if (!FakeInventory.readOnlyInstancesByInventory.TryGetValue(inventory, out var value))
			{
				value = ((Component)inventory).gameObject.AddComponent<FakeInventory>();
			}
			foreach (KeyValuePair<ItemIndex, int> itemcount in itemcounts)
			{
				value.GiveItem(itemcount.Key, itemcount.Value);
			}
		}

		private void DeregBody(CharacterBody cb)
		{
			Inventory inventory = cb.inventory;
			if (Object.op_Implicit((Object)(object)inventory))
			{
				DeregInv(inventory);
			}
		}

		private void DeregInv(Inventory inv)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			if (!trackedInventories.Contains(inv))
			{
				return;
			}
			if (!FakeInventory.readOnlyInstancesByInventory.TryGetValue(inv, out var value))
			{
				TILER2Plugin._logger.LogError((object)("ItemWard.DeregInv: Inventory on object " + ((Object)((Component)inv).gameObject).name + " had its FakeInventory unexpectedly removed"));
				return;
			}
			foreach (KeyValuePair<ItemIndex, int> itemcount in itemcounts)
			{
				value.RemoveItem(itemcount.Key, itemcount.Value);
			}
			trackedInventories.Remove(inv);
		}

		public void ServerAddItem(ItemIndex ind)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: 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_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active)
			{
				return;
			}
			if (!itemcounts.ContainsKey(ind))
			{
				itemcounts[ind] = 1;
			}
			else
			{
				itemcounts[ind]++;
			}
			trackedInventories.RemoveAll((Inventory x) => !Object.op_Implicit((Object)(object)x));
			foreach (Inventory trackedInventory in trackedInventories)
			{
				if (!FakeInventory.readOnlyInstancesByInventory.TryGetValue(trackedInventory, out var value))
				{
					TILER2Plugin._logger.LogError((object)("ItemWard.ServerAddItem: Inventory on object " + ((Object)((Component)trackedInventory).gameObject).name + " had its FakeInventory unexpectedly removed"));
				}
				else
				{
					value.GiveItem(ind);
				}
			}
			NetMessageExtensions.Send((INetMessage)(object)new MsgDeltaDisplay(((NetworkBehaviour)this).netId, ind, isAdd: true), (NetworkDestination)1);
		}

		public void ServerRemoveItem(ItemIndex ind)
		{
			//IL_0018: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active || !itemcounts.ContainsKey(ind))
			{
				return;
			}
			itemcounts[ind]--;
			if (itemcounts[ind] == 0)
			{
				itemcounts.Remove(ind);
			}
			NetMessageExtensions.Send((INetMessage)(object)new MsgDeltaDisplay(((NetworkBehaviour)this).netId, ind, isAdd: false), (NetworkDestination)1);
			trackedInventories.RemoveAll((Inventory x) => !Object.op_Implicit((Object)(object)x) || !Object.op_Implicit((Object)(object)((Component)x).gameObject));
			foreach (Inventory trackedInventory in trackedInventories)
			{
				if (!FakeInventory.readOnlyInstancesByInventory.TryGetValue(trackedInventory, out var value))
				{
					TILER2Plugin._logger.LogError((object)("ItemWard.ServerRemoveItem: Inventory on object " + ((Object)((Component)trackedInventory).gameObject).name + " had its FakeInventory unexpectedly removed"));
				}
				else
				{
					value.RemoveItem(ind);
				}
			}
		}

		internal void ClientAddItemDisplay(ItemIndex ind)
		{
			//IL_0014: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active)
			{
				if (!itemcounts.ContainsKey(ind))
				{
					itemcounts[ind] = 1;
				}
				else
				{
					itemcounts[ind]++;
				}
			}
			if (T2Module<ItemWardModule>.instance.displayPerformanceMode != DisplayPerformanceMode.None && (T2Module<ItemWardModule>.instance.displayPerformanceMode != DisplayPerformanceMode.OnePerItemIndex || !displayItems.Contains(ind)))
			{
				GameObject val = Object.Instantiate<GameObject>(displayPrefab, ((Component)this).transform.position, ((Component)this).transform.rotation);
				((Component)val.transform.Find("BillboardBase").Find("PickupSprite")).GetComponent<SpriteRenderer>().sprite = ItemCatalog.GetItemDef(ind).pickupIconSprite;
				val.transform.parent = ((Component)this).transform;
				displays.Add(val);
				displayItems.Add(ind);
				displayVelocities.Add(new Vector3(0f, 0f, 0f));
			}
		}

		internal void ClientRemoveItemDisplay(ItemIndex ind)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0037: 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_008d: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active)
			{
				if (!itemcounts.ContainsKey(ind))
				{
					return;
				}
				itemcounts[ind]--;
				if (itemcounts[ind] == 0)
				{
					itemcounts.Remove(ind);
				}
			}
			if (T2Module<ItemWardModule>.instance.displayPerformanceMode != DisplayPerformanceMode.None && (T2Module<ItemWardModule>.instance.displayPerformanceMode != DisplayPerformanceMode.OnePerItemIndex || itemcounts[ind] == 0))
			{
				int index = displayItems.IndexOf(ind);
				Object.Destroy((Object)(object)displays[index]);
				displays.RemoveAt(index);
				displayItems.RemoveAt(index);
				displayVelocities.RemoveAt(index);
			}
		}
	}
	public class AutoConfigBinding
	{
		public enum DeferType
		{
			UpdateImmediately,
			WaitForNextStage,
			WaitForRunEnd,
			NeverAutoUpdate
		}

		internal static readonly List<AutoConfigBinding> instances = new List<AutoConfigBinding>();

		internal static readonly Dictionary<AutoConfigBinding, (object, bool)> stageDirtyInstances = new Dictionary<AutoConfigBinding, (object, bool)>();

		internal static readonly Dictionary<AutoConfigBinding, object> runDirtyInstances = new Dictionary<AutoConfigBinding, object>();

		internal bool isOverridden = false;

		public AutoConfigContainer owner { get; internal set; }

		public object target { get; internal set; }

		public ConfigEntryBase configEntry { get; internal set; }

		public PropertyInfo boundProperty { get; internal set; }

		public string modName { get; internal set; }

		public AutoConfigUpdateActionsAttribute updateEventAttribute { get; internal set; }

		public MethodInfo propGetter { get; internal set; }

		public MethodInfo propSetter { get; internal set; }

		public Type propType { get; internal set; }

		public object boundKey { get; internal set; }

		public bool onDict { get; internal set; }

		public bool allowConCmd { get; internal set; }

		public bool allowNetMismatch { get; internal set; }

		public bool netMismatchCritical { get; internal set; }

		public object cachedValue { get; internal set; }

		public DeferType deferType { get; internal set; }

		public string readablePath => modName + "/" + configEntry.Definition.Section + "/" + configEntry.Definition.Key;

		internal static void CleanupDirty(bool isRunEnd)
		{
			TILER2Plugin._logger.LogDebug((object)$"Stage ended; applying {stageDirtyInstances.Count} deferred config changes...");
			foreach (AutoConfigBinding key in stageDirtyInstances.Keys)
			{
				key.DeferredUpdateProperty(stageDirtyInstances[key].Item1, stageDirtyInstances[key].Item2);
			}
			stageDirtyInstances.Clear();
			if (!isRunEnd)
			{
				return;
			}
			TILER2Plugin._logger.LogDebug((object)$"Run ended; applying {runDirtyInstances.Count} deferred config changes...");
			foreach (AutoConfigBinding key2 in runDirtyInstances.Keys)
			{
				key2.DeferredUpdateProperty(runDirtyInstances[key2], silent: true);
			}
			runDirtyInstances.Clear();
		}

		internal AutoConfigBinding()
		{
			instances.Add(this);
		}

		~AutoConfigBinding()
		{
			if (instances.Contains(this))
			{
				instances.Remove(this);
			}
		}

		internal void OverrideProperty(object newValue, bool silent = false)
		{
			if (!isOverridden)
			{
				runDirtyInstances[this] = cachedValue;
			}
			isOverridden = true;
			UpdateProperty(newValue, silent);
		}

		private void DeferredUpdateProperty(object newValue, bool silent = false)
		{
			object oldValue = propGetter.Invoke(target, (!onDict) ? new object[0] : new object[1] { boundKey });
			propSetter.Invoke(target, (!onDict) ? new object[1] { newValue } : new object[2] { boundKey, newValue });
			AutoConfigUpdateActionTypes autoConfigUpdateActionTypes = updateEventAttribute?.flags ?? AutoConfigUpdateActionTypes.None;
			AutoConfigUpdateActionsAttribute autoConfigUpdateActionsAttribute = updateEventAttribute;
			if (autoConfigUpdateActionsAttribute != null && !autoConfigUpdateActionsAttribute.ignoreDefault)
			{
				autoConfigUpdateActionTypes |= owner.defaultEnabledUpdateFlags;
			}
			cachedValue = newValue;
			owner.OnConfigChanged(new AutoConfigUpdateActionEventArgs
			{
				flags = autoConfigUpdateActionTypes,
				oldValue = oldValue,
				newValue = newValue,
				target = this,
				silent = silent
			});
		}

		internal void UpdateProperty(object newValue, bool silent = false)
		{
			if (NetworkServer.active && !allowNetMismatch)
			{
				NetConfigModule.ServerSyncOneToAll(this, newValue);
			}
			if (deferType == DeferType.UpdateImmediately || (Object)(object)Run.instance == (Object)null || !((Behaviour)Run.instance).enabled)
			{
				DeferredUpdateProperty(newValue, silent);
			}
			else if (deferType == DeferType.WaitForNextStage)
			{
				stageDirtyInstances[this] = (newValue, silent);
			}
			else if (deferType == DeferType.WaitForRunEnd)
			{
				runDirtyInstances[this] = newValue;
			}
			else
			{
				TILER2Plugin._logger.LogWarning((object)("Something attempted to set the value of an AutoConfigBinding with the DeferForever flag: \"" + readablePath + "\""));
			}
		}

		public static (List<AutoConfigBinding> results, string errorMsg) FindFromPath(string path1, string path2, string path3)
		{
			string p1u = path1.ToUpper();
			string p2u = path2?.ToUpper();
			string p3u = path3?.ToUpper();
			List<AutoConfigBinding> matchesLevel1 = new List<AutoConfigBinding>();
			List<AutoConfigBinding> matchesLevel2 = new List<AutoConfigBinding>();
			List<AutoConfigBinding> matchesLevel3 = new List<AutoConfigBinding>();
			List<AutoConfigBinding> matchesLevel4 = new List<AutoConfigBinding>();
			instances.ForEach(delegate(AutoConfigBinding x)
			{
				if (x.allowConCmd)
				{
					string key = x.configEntry.Definition.Key;
					string text = key.ToUpper();
					string section = x.configEntry.Definition.Section;
					string text2 = section.ToUpper();
					string text3 = x.modName;
					string text4 = text3.ToUpper();
					if (path2 == null)
					{
						if (text.Contains(p1u) || text2.Contains(p1u) || text4.Contains(p1u))
						{
							matchesLevel1.Add(x);
							matchesLevel2.Add(x);
							if (text == p1u)
							{
								matchesLevel3.Add(x);
								if (key == path1)
								{
									matchesLevel4.Add(x);
								}
							}
						}
					}
					else if (path3 == null)
					{
						bool flag = text4.Contains(p1u);
						bool flag2 = text2.Contains(p1u);
						bool flag3 = text2.Contains(p2u);
						bool flag4 = text.Contains(p2u);
						if ((flag && flag3) || (flag2 && flag4) || (flag && flag4))
						{
							matchesLevel1.Add(x);
							if (!(flag && flag4))
							{
								matchesLevel2.Add(x);
								bool flag5 = text3.Contains(path1);
								bool flag6 = section.Contains(path1);
								bool flag7 = section.Contains(path2);
								bool flag8 = key.Contains(path2);
								if ((flag5 && flag7) || (flag6 && flag8))
								{
									matchesLevel3.Add(x);
									bool flag9 = text3 == path1;
									bool flag10 = section == path1;
									bool flag11 = section == path2;
									bool flag12 = key == path2;
									if ((flag9 && flag11) || (flag10 && flag12))
									{
										matchesLevel4.Add(x);
									}
								}
							}
						}
					}
					else if (text.Contains(p3u) && text2.Contains(p2u) && text4.Contains(p1u))
					{
						matchesLevel1.Add(x);
						matchesLevel2.Add(x);
						if (text4 == p3u && text2 == p2u && text == p1u)
						{
							matchesLevel3.Add(x);
							if (text3 == path3 && section == path2 && key == path1)
							{
								matchesLevel4.Add(x);
							}
						}
					}
				}
			});
			if (matchesLevel1.Count == 0)
			{
				return (results: null, errorMsg: "no level 1 matches");
			}
			if (matchesLevel1.Count == 1)
			{
				return (results: matchesLevel1, errorMsg: null);
			}
			if (matchesLevel2.Count == 0)
			{
				return (results: matchesLevel1, errorMsg: "multiple level 1 matches, no level 2 matches");
			}
			if (matchesLevel2.Count == 1)
			{
				return (results: matchesLevel2, errorMsg: null);
			}
			if (matchesLevel3.Count == 0)
			{
				return (results: matchesLevel2, errorMsg: "multiple level 2 matches, no level 3 matches");
			}
			if (matchesLevel3.Count == 1)
			{
				return (results: matchesLevel3, errorMsg: null);
			}
			if (matchesLevel4.Count == 0)
			{
				return (results: matchesLevel3, errorMsg: "multiple level 3 matches, no level 4 matches");
			}
			if (matchesLevel4.Count == 1)
			{
				return (results: matchesLevel4, errorMsg: null);
			}
			Debug.LogError((object)("TILER2 AutoConfig: There are multiple config entries with the path \"" + matchesLevel4[0].readablePath + "\"; this should never happen! Please report this as a bug."));
			return (results: matchesLevel4, errorMsg: "multiple level 4 matches");
		}
	}
	public class AutoConfigContainer
	{
		public struct BindSubDictInfo
		{
			public object key;

			public object val;

			public Type keyType;

			public int index;
		}

		protected internal readonly List<AutoConfigBinding> bindings = new List<AutoConfigBinding>();

		private static readonly Dictionary<ConfigFile, DateTime> observedFiles = new Dictionary<ConfigFile, DateTime>();

		private const float filePollingRate = 10f;

		private static float filePollingStopwatch = 0f;

		protected internal virtual AutoConfigUpdateActionTypes defaultEnabledUpdateFlags => AutoConfigUpdateActionTypes.None;

		public event EventHandler<AutoConfigUpdateActionEventArgs> ConfigEntryChanged;

		public AutoConfigBinding FindConfig(string propName)
		{
			return bindings.Find((AutoConfigBinding x) => x.boundProperty.Name == propName && !x.onDict);
		}

		public AutoConfigBinding FindConfig(string propName, object dictKey)
		{
			return bindings.Find((AutoConfigBinding x) => x.boundProperty.Name == propName && x.onDict && x.boundKey == dictKey);
		}

		internal void OnConfigChanged(AutoConfigUpdateActionEventArgs e)
		{
			this.ConfigEntryChanged?.Invoke(this, e);
			Debug.Log((object)$"{e.target.readablePath}: {e.oldValue} > {e.newValue}");
			if ((Object)(object)Run.instance != (Object)null && ((Behaviour)Run.instance).isActiveAndEnabled)
			{
				if ((e.flags & AutoConfigUpdateActionTypes.InvalidateStats) == AutoConfigUpdateActionTypes.InvalidateStats)
				{
					AutoConfigModule.globalStatsDirty = true;
				}
				if ((e.flags & AutoConfigUpdateActionTypes.InvalidateDropTable) == AutoConfigUpdateActionTypes.InvalidateDropTable)
				{
					AutoConfigModule.globalDropsDirty = true;
				}
				if (!e.silent && (e.flags & AutoConfigUpdateActionTypes.AnnounceToRun) == AutoConfigUpdateActionTypes.AnnounceToRun && NetworkServer.active)
				{
					NetUtil.ServerSendGlobalChatMsg(Language.GetStringFormatted("TILER2_AUTOCONFIG_ANNOUNCE_CHANGE", new object[3]
					{
						e.target.readablePath,
						e.oldValue,
						e.newValue
					}));
				}
			}
		}

		internal static void FilePollUpdateHook(orig_Update orig, RoR2Application self)
		{
			orig.Invoke(self);
			filePollingStopwatch += Time.unscaledDeltaTime;
			if (!(filePollingStopwatch >= 10f))
			{
				return;
			}
			filePollingStopwatch = 0f;
			foreach (ConfigFile item in observedFiles.Keys.ToList())
			{
				DateTime lastWriteTime = File.GetLastWriteTime(item.ConfigFilePath);
				if (observedFiles[item] < lastWriteTime)
				{
					observedFiles[item] = lastWriteTime;
					TILER2Plugin._logger.LogDebug((object)("A config file tracked by AutoItemConfig has been changed: " + item.ConfigFilePath));
					item.Reload();
				}
			}
		}

		private string ReplaceTags(string orig, PropertyInfo prop, string categoryName, BindSubDictInfo? subDict = null)
		{
			return Regex.Replace(orig, "<AIC.([a-zA-Z\\.]+)>", delegate(Match m)
			{
				string value = m.Groups[0].Value;
				string[] array = Regex.Split(value.Substring(1, value.Length - 1 - 1), "(?<!\\\\)\\.");
				if (array.Length >= 2)
				{
					string text = "AutoConfigContainer.Bind on property " + prop.Name + " in category " + categoryName + ": malformed string param \"" + m.Value + "\" ";
					switch (array[1])
					{
					case "Prop":
					{
						if (array.Length < 3)
						{
							TILER2Plugin._logger.LogWarning((object)(text + "(not enough params for Prop tag)."));
							return m.Value;
						}
						PropertyInfo property2 = prop.DeclaringType.GetProperty(array[2], BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						if (property2 == null)
						{
							TILER2Plugin._logger.LogWarning((object)(text + "(could not find Prop \"" + array[2] + "\")."));
							return m.Value;
						}
						return property2.GetValue(this).ToString();
					}
					case "Field":
					{
						if (array.Length < 3)
						{
							TILER2Plugin._logger.LogWarning((object)(text + "(not enough params for Field tag)."));
							return m.Value;
						}
						FieldInfo field2 = prop.DeclaringType.GetField(array[2], BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						if (field2 == null)
						{
							TILER2Plugin._logger.LogWarning((object)(text + "(could not find Field \"" + array[2] + "\")."));
							return m.Value;
						}
						return field2.GetValue(this).ToString();
					}
					case "DictKey":
						if (!subDict.HasValue)
						{
							TILER2Plugin._logger.LogWarning((object)(text + "(DictKey tag used on non-BindDict)."));
							return m.Value;
						}
						return subDict.Value.key.ToString();
					case "DictInd":
						if (!subDict.HasValue)
						{
							TILER2Plugin._logger.LogWarning((object)(text + "(DictInd tag used on non-BindDict)."));
							return m.Value;
						}
						return subDict.Value.index.ToString();
					case "DictKeyProp":
					{
						if (!subDict.HasValue)
						{
							TILER2Plugin._logger.LogWarning((object)(text + "(DictKeyProp tag used on non-BindDict)."));
							return m.Value;
						}
						if (array.Length < 3)
						{
							TILER2Plugin._logger.LogWarning((object)(text + "(not enough params for DictKeyProp tag)."));
							return m.Value;
						}
						PropertyInfo property = subDict.Value.key.GetType().GetProperty(array[2], BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						if (property == null)
						{
							TILER2Plugin._logger.LogWarning((object)(text + "(could not find DictKeyProp \"" + array[2] + "\")."));
							return m.Value;
						}
						return property.GetValue(subDict.Value.key).ToString();
					}
					case "DictKeyField":
					{
						if (!subDict.HasValue)
						{
							TILER2Plugin._logger.LogWarning((object)(text + "(DictKeyField tag used on non-BindDict)."));
							return m.Value;
						}
						if (array.Length < 3)
						{
							TILER2Plugin._logger.LogWarning((object)(text + "(not enough params for DictKeyField tag)."));
							return m.Value;
						}
						FieldInfo field = subDict.Value.key.GetType().GetField(array[2], BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						if (field == null)
						{
							TILER2Plugin._logger.LogWarning((object)(text + "(could not find DictKeyField \"" + array[2] + "\")."));
							return m.Value;
						}
						return field.GetValue(subDict.Value.key).ToString();
					}
					default:
						TILER2Plugin._logger.LogWarning((object)(text + "(unknown tag \"" + array[1] + "\")."));
						return m.Value;
					}
				}
				return m.Value;
			});
		}

		public void Bind(PropertyInfo prop, ConfigFile cfl, string modName, string categoryName, AutoConfigAttribute attrib, AutoConfigUpdateActionsAttribute eiattr = null, BindSubDictInfo? subDict = null)
		{
			//IL_06c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_06cb: Expected O, but got Unknown
			//IL_06e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_06e6: Expected O, but got Unknown
			//IL_06eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_06f5: Expected O, but got Unknown
			string text = "AutoConfigContainer.Bind on property " + prop.Name + " in category " + categoryName + " failed: ";
			if (!subDict.HasValue)
			{
				if (bindings.Exists((AutoConfigBinding x) => x.boundProperty == prop))
				{
					TILER2Plugin._logger.LogError((object)(text + "this property has already been bound."));
					return;
				}
				if ((attrib.flags & AutoConfigFlags.BindDict) == AutoConfigFlags.BindDict)
				{
					if (!prop.PropertyType.GetInterfaces().Any((Type i) => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IDictionary<, >)))
					{
						TILER2Plugin._logger.LogError((object)(text + "BindDict flag cannot be used on property types which don't implement IDictionary."));
						return;
					}
					Type type = prop.PropertyType.GetGenericArguments()[1];
					if (attrib.avb != null && attrib.avbType != type)
					{
						TILER2Plugin._logger.LogError((object)(text + "dict value and AcceptableValue types must match (received " + type.Name + " and " + attrib.avbType.Name + ")."));
						return;
					}
					if (!TomlTypeConverter.CanConvert(type))
					{
						TILER2Plugin._logger.LogError((object)(text + "dict value type cannot be converted by BepInEx.Configuration.TomlTypeConverter (received " + type.Name + ")."));
						return;
					}
					IDictionary dictionary = (IDictionary)prop.GetValue(this, null);
					int num = 0;
					List<object> list = (from object k in dictionary.Keys
						select (k)).ToList();
					if (list.Count == 0)
					{
						TILER2Plugin._logger.LogError((object)(text + "BindDict was used on an empty dictionary. All intended keys must be present at time of binding and cannot be added afterwards."));
					}
					{
						foreach (object item in list)
						{
							Bind(prop, cfl, modName, categoryName, attrib, eiattr, new BindSubDictInfo
							{
								key = item,
								val = dictionary[item],
								keyType = type,
								index = num
							});
							num++;
						}
						return;
					}
				}
			}
			if (!subDict.HasValue)
			{
				if (attrib.avb != null && attrib.avbType != prop.PropertyType)
				{
					TILER2Plugin._logger.LogError((object)(text + "property and AcceptableValue types must match (received " + prop.PropertyType.Name + " and " + attrib.avbType.Name + ")."));
					return;
				}
				if (!TomlTypeConverter.CanConvert(prop.PropertyType))
				{
					TILER2Plugin._logger.LogError((object)(text + "property type cannot be converted by BepInEx.Configuration.TomlTypeConverter (received " + prop.PropertyType.Name + ")."));
					return;
				}
			}
			object obj = (subDict.HasValue ? prop.GetValue(this) : this);
			IDictionary dictionary2 = (subDict.HasValue ? ((IDictionary)obj) : null);
			MethodInfo methodInfo = (subDict.HasValue ? dictionary2.GetType().GetProperty("Item").GetGetMethod(nonPublic: true) : (prop.GetGetMethod(nonPublic: true) ?? prop.DeclaringType.GetProperty(prop.Name)?.GetGetMethod(nonPublic: true)));
			MethodInfo methodInfo2 = (subDict.HasValue ? dictionary2.GetType().GetProperty("Item").GetSetMethod(nonPublic: true) : (prop.GetSetMethod(nonPublic: true) ?? prop.DeclaringType.GetProperty(prop.Name)?.GetSetMethod(nonPublic: true)));
			Type type2 = (subDict.HasValue ? subDict.Value.keyType : prop.PropertyType);
			if (methodInfo == null || methodInfo2 == null)
			{
				TILER2Plugin._logger.LogError((object)(text + "property (or IDictionary Item property, if using BindDict flag) must have both a getter and a setter."));
				return;
			}
			string name = attrib.name;
			if (name != null)
			{
				name = ReplaceTags(name, prop, categoryName, subDict);
			}
			else
			{
				object arg = char.ToUpperInvariant(prop.Name[0]);
				string name2 = prop.Name;
				name = string.Format("{0}{1}{2}", arg, name2.Substring(1, name2.Length - 1), subDict.HasValue ? (":" + subDict.Value.index) : "");
			}
			string desc = attrib.desc;
			desc = ((desc == null) ? ("Automatically generated from a C# " + (subDict.HasValue ? "dictionary " : "") + "property.") : ReplaceTags(desc, prop, categoryName, subDict));
			MethodInfo methodInfo3 = typeof(ConfigFile).GetMethods().First((MethodInfo x) => x.Name == "Bind" && x.GetParameters().Length == 3 && x.GetParameters()[0].ParameterType == typeof(ConfigDefinition) && x.GetParameters()[2].ParameterType == typeof(ConfigDescription)).MakeGenericMethod(type2);
			object obj2 = (subDict.HasValue ? subDict.Value.val : prop.GetValue(this));
			bool flag = (attrib.flags & AutoConfigFlags.PreventNetMismatch) != AutoConfigFlags.PreventNetMismatch;
			bool flag2 = (attrib.flags & AutoConfigFlags.DeferForever) == AutoConfigFlags.DeferForever;
			bool flag3 = (attrib.flags & AutoConfigFlags.DeferUntilEndGame) == AutoConfigFlags.DeferUntilEndGame;
			bool flag4 = (attrib.flags & AutoConfigFlags.DeferUntilNextStage) == AutoConfigFlags.DeferUntilNextStage;
			bool flag5 = (attrib.flags & AutoConfigFlags.PreventConCmd) != AutoConfigFlags.PreventConCmd;
			if (flag2 && !flag)
			{
				desc += "\nWARNING: THIS SETTING CANNOT BE CHANGED WHILE THE GAME IS RUNNING, AND MUST BE SYNCED MANUALLY FOR MULTIPLAYER!";
			}
			ConfigEntryBase cfe = (ConfigEntryBase)methodInfo3.Invoke(cfl, new object[3]
			{
				(object)new ConfigDefinition(categoryName, name),
				obj2,
				(object)new ConfigDescription(desc, attrib.avb, Array.Empty<object>())
			});
			observedFiles[cfl] = File.GetLastWriteTime(cfl.ConfigFilePath);
			AutoConfigBinding newBinding = new AutoConfigBinding
			{
				boundProperty = prop,
				allowConCmd = (flag5 && !flag2 && !flag3),
				allowNetMismatch = flag,
				netMismatchCritical = (!flag && flag2),
				deferType = (flag2 ? AutoConfigBinding.DeferType.NeverAutoUpdate : (flag3 ? AutoConfigBinding.DeferType.WaitForRunEnd : (flag4 ? AutoConfigBinding.DeferType.WaitForNextStage : AutoConfigBinding.DeferType.UpdateImmediately))),
				configEntry = cfe,
				modName = modName,
				owner = this,
				propGetter = methodInfo,
				propSetter = methodInfo2,
				propType = type2,
				onDict = subDict.HasValue,
				boundKey = (subDict.HasValue ? subDict.Value.key : null),
				updateEventAttribute = eiattr,
				cachedValue = obj2,
				target = obj
			};
			bindings.Add(newBinding);
			if (!flag2)
			{
				Type type3 = typeof(ConfigEntry<>).MakeGenericType(type2);
				EventInfo evt = type3.GetEvent("SettingChanged");
				evt.ReflAddEventHandler(cfe, delegate
				{
					newBinding.UpdateProperty(cfe.BoxedValue);
				});
			}
			if ((attrib.flags & AutoConfigFlags.NoInitialRead) != AutoConfigFlags.NoInitialRead)
			{
				methodInfo2.Invoke(obj, (!subDict.HasValue) ? new object[1] { cfe.BoxedValue } : new object[2]
				{
					subDict.Value.key,
					cfe.BoxedValue
				});
				newBinding.cachedValue = cfe.BoxedValue;
			}
			BindRoO(cfe, prop, type2, categoryName, name, desc, flag2, flag3 || flag2);
		}

		public void BindRoO(AutoConfigBinding bind, params Attribute[] entryRoOAttributes)
		{
			BindRoO(bind.configEntry, bind.boundProperty, bind.propType, bind.configEntry.Definition.Section, bind.configEntry.Definition.Key, bind.configEntry.Description.Description, bind.deferType >= AutoConfigBinding.DeferType.NeverAutoUpdate, bind.deferType >= AutoConfigBinding.DeferType.WaitForRunEnd, entryRoOAttributes);
		}

		public void BindRoO(ConfigEntryBase cfe, PropertyInfo prop, Type propType, string categoryName, string cfgName, string cfgDesc, bool deferForever, bool deferRun, params Attribute[] entryRoOAttributes)
		{
			if (!Compat_RiskOfOptions.enabled)
			{
				return;
			}
			string text = "AutoConfigContainer.Bind on property " + prop.Name + " in category " + categoryName + " could not apply Risk of Options compat: ";
			AutoConfigRoOInfoOverridesAttribute customAttribute = GetType().GetCustomAttribute<AutoConfigRoOInfoOverridesAttribute>();
			AutoConfigRoOInfoOverridesAttribute customAttribute2 = prop.GetCustomAttribute<AutoConfigRoOInfoOverridesAttribute>();
			if (entryRoOAttributes.Length == 0)
			{
				return;
			}
			if ((from x in entryRoOAttributes
				group x by x.GetType()).Any((IGrouping<Type, Attribute> x) => x.Count() > 1))
			{
				TILER2Plugin._logger.LogWarning((object)("AutoConfigContainer.BindRoO on property " + prop.Name + " in category " + categoryName + " has multiple RoO options of the same type"));
			}
			string text2 = null;
			string text3 = null;
			bool flag = false;
			if (customAttribute != null)
			{
				text2 = customAttribute.modGuid;
				text3 = customAttribute.modName;
				flag = true;
			}
			else
			{
				Assembly assembly = Assembly.GetAssembly(GetType());
				Type[] types;
				try
				{
					types = assembly.GetTypes();
				}
				catch (ReflectionTypeLoadException ex)
				{
					types = ex.Types;
				}
				Type[] array = types;
				foreach (Type element in array)
				{
					BepInPlugin customAttribute3 = ((MemberInfo)element).GetCustomAttribute<BepInPlugin>();
					if (customAttribute3 != null)
					{
						text2 = customAttribute3.GUID;
						text3 = customAttribute3.Name;
						flag = true;
						break;
					}
				}
			}
			if (!flag)
			{
				TILER2Plugin._logger.LogError((object)(text + "could not find mod info. Declaring type must be in an assembly with a BepInPlugin, or have an AutoConfigContainerRoOInfoAttribute on it."));
				return;
			}
			Compat_RiskOfOptions.OptionIdentityStrings identStrings = new Compat_RiskOfOptions.OptionIdentityStrings
			{
				category = (customAttribute2?.categoryName ?? customAttribute?.categoryName ?? categoryName),
				name = (customAttribute2?.entryName ?? customAttribute?.entryName ?? cfgName),
				description = cfgDesc,
				modGuid = (customAttribute2?.modGuid ?? text2),
				modName = (customAttribute2?.modName ?? text3)
			};
			for (int num2 = 0; num2 < entryRoOAttributes.Length; num2++)
			{
				BaseAutoConfigRoOAttribute baseAutoConfigRoOAttribute = (BaseAutoConfigRoOAttribute)entryRoOAttributes[num2];
				if ((baseAutoConfigRoOAttribute.requiredType == typeof(Enum)) ? (!propType.IsEnum) : (propType != baseAutoConfigRoOAttribute.requiredType))
				{
					TILER2Plugin._logger.LogError((object)(text + baseAutoConfigRoOAttribute.GetType().Name + " may only be applied to " + baseAutoConfigRoOAttribute.requiredType.Name + " properties (got " + propType.Name + ")."));
				}
				else
				{
					baseAutoConfigRoOAttribute.Apply(cfe, identStrings, deferForever, () => (deferRun && Object.op_Implicit((Object)(object)Run.instance)) ? true : false);
				}
			}
		}

		internal void BindRoO(ConfigEntryBase cfe, PropertyInfo prop, Type propType, string categoryName, string cfgName, string cfgDesc, bool deferForever, bool deferRun)
		{
			if (Compat_RiskOfOptions.enabled)
			{
				Attribute[] entryRoOAttributes = prop.GetCustomAttributes<BaseAutoConfigRoOAttribute>().ToArray();
				BindRoO(cfe, prop, propType, categoryName, cfgName, cfgDesc, deferForever, deferRun, entryRoOAttributes);
			}
		}

		public void BindAll(ConfigFile cfl, string modName, string categoryName)
		{
			PropertyInfo[] properties = GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (PropertyInfo propertyInfo in properties)
			{
				AutoConfigAttribute customAttribute = propertyInfo.GetCustomAttribute<AutoConfigAttribute>(inherit: true);
				if (customAttribute != null)
				{
					Bind(propertyInfo, cfl, modName, categoryName, customAttribute, propertyInfo.GetCustomAttribute<AutoConfigUpdateActionsAttribute>(inherit: true));
				}
			}
		}
	}
	internal class AutoConfigModule : T2Module<AutoConfigModule>
	{
		internal static bool globalStatsDirty;

		internal static bool globalDropsDirty;

		internal static bool globalLanguageDirty;

		public override bool managedEnable => false;

		public override void SetupConfig()
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			base.SetupConfig();
			RoR2Application.Update += new hook_Update(AutoConfigContainer.FilePollUpdateHook);
			NetworkManagerSystem.Disconnect += new hook_Disconnect(On_GNMDisconnect);
			SceneManager.sceneLoaded += Evt_USMSceneLoaded;
		}

		internal static void Update()
		{
			if (!((Object)(object)Run.instance != (Object)null) || !((Behaviour)Run.instance).isActiveAndEnabled)
			{
				globalStatsDirty = false;
				globalDropsDirty = false;
			}
			else
			{
				if (globalStatsDirty)
				{
					globalStatsDirty = false;
					MiscUtil.AliveList().ForEach(delegate(CharacterMaster cm)
					{
						if (cm.hasBody)
						{
							cm.GetBody().RecalculateStats();
						}
					});
				}
				if (globalDropsDirty)
				{
					globalDropsDirty = false;
					Run.instance.OnRuleBookUpdated(Run.instance.networkRuleBookComponent);
					Run.instance.BuildDropTable();
				}
			}
			if (globalLanguageDirty)
			{
				globalLanguageDirty = false;
				Language.SetCurrentLanguage(Language.currentLanguageName, false);
			}
		}

		internal static void On_GNMDisconnect(orig_Disconnect orig, NetworkManagerSystem self)
		{
			orig.Invoke(self);
			AutoConfigBinding.CleanupDirty(isRunEnd: true);
		}

		internal static void Evt_USMSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			AutoConfigBinding.CleanupDirty(isRunEnd: false);
		}
	}
	[Flags]
	public enum AutoConfigFlags
	{
		None = 0,
		AVIsList = 1,
		DeferUntilNextStage = 2,
		DeferUntilEndGame = 4,
		DeferForever = 8,
		PreventConCmd = 0x10,
		NoInitialRead = 0x20,
		PreventNetMismatch = 0x40,
		BindDict = 0x80
	}
	[Flags]
	public enum AutoConfigUpdateActionTypes
	{
		None = 0,
		InvalidateLanguage = 1,
		InvalidateModel = 2,
		InvalidateStats = 4,
		InvalidateDropTable = 8,
		AnnounceToRun = 0x10
	}
	public class AutoConfigUpdateActionEventArgs : EventArgs
	{
		public AutoConfigUpdateActionTypes flags;

		public object oldValue;

		public object newValue;

		public AutoConfigBinding target;

		public bool silent;
	}
	[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
	public class AutoConfigUpdateActionsAttribute : Attribute
	{
		public readonly AutoConfigUpdateActionTypes flags;

		public readonly bool ignoreDefault;

		public AutoConfigUpdateActionsAttribute(AutoConfigUpdateActionTypes flags, bool ignoreDefault = false)
		{
			this.flags = flags;
			this.ignoreDefault = ignoreDefault;
		}
	}
	[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
	public class AutoConfigAttribute : Attribute
	{
		public readonly string name = null;

		public readonly string desc = null;

		public readonly AcceptableValueBase avb = null;

		public readonly Type avbType = null;

		public readonly AutoConfigFlags flags;

		public AutoConfigAttribute(string name, string desc, AutoConfigFlags flags = AutoConfigFlags.None, params object[] acceptableValues)
			: this(desc, flags, acceptableValues)
		{
			this.name = name;
		}

		public AutoConfigAttribute(string desc, AutoConfigFlags flags = AutoConfigFlags.None, params object[] acceptableValues)
			: this(flags, acceptableValues)
		{
			this.desc = desc;
		}

		public AutoConfigAttribute(AutoConfigFlags flags = AutoConfigFlags.None, params object[] acceptableValues)
		{
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Expected O, but got Unknown
			if (acceptableValues.Length != 0)
			{
				bool flag = (flags & AutoConfigFlags.AVIsList) == AutoConfigFlags.AVIsList;
				if (!flag && acceptableValues.Length != 2)
				{
					throw new ArgumentException("Range mode for acceptableValues (flag AVIsList not set) requires either 0 or 2 params; received " + acceptableValues.Length + ".\nThe description provided was: \"" + desc + "\".");
				}
				Type type = acceptableValues[0].GetType();
				for (int i = 1; i < acceptableValues.Length; i++)
				{
					if (type != acceptableValues[i].GetType())
					{
						throw new ArgumentException("Types of all acceptableValues must match");
					}
				}
				avb = (AcceptableValueBase)Activator.CreateInstance(flag ? typeof(AcceptableValueList<>).MakeGenericType(type) : typeof(AcceptableValueRange<>).MakeGenericType(type), acceptableValues);
				avbType = type;
			}
			this.flags = flags;
		}
	}
	public abstract class BaseAutoConfigRoOAttribute : Attribute
	{
		public string nameOverride;

		public string catOverride;

		public abstract Type requiredType { get; }

		public BaseAutoConfigRoOAttribute(string nameOverride = null, string catOverride = null)
		{
			this.nameOverride = nameOverride;
			this.catOverride = catOverride;
		}

		public abstract void Apply(ConfigEntryBase cfe, Compat_RiskOfOptions.OptionIdentityStrings identStrings, bool deferForever, Func<bool> isDisabledDelegate);
	}
	[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
	public class AutoConfigRoOSliderAttribute : BaseAutoConfigRoOAttribute
	{
		public string format;

		public float min;

		public float max;

		public override Type requiredType => typeof(float);

		public AutoConfigRoOSliderAttribute(string format, float min, float max, string nameOverride = null, string catOverride = null)
			: base(nameOverride, catOverride)
		{
			this.format = format;
			this.min = min;
			this.max = max;
		}

		public override void Apply(ConfigEntryBase cfe, Compat_RiskOfOptions.OptionIdentityStrings identStrings, bool deferForever, Func<bool> isDisabledDelegate)
		{
			Compat_RiskOfOptions.AddOption_Slider((ConfigEntry<float>)(object)cfe, identStrings, min, max, format, deferForever, isDisabledDelegate);
		}
	}
	[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
	public class AutoConfigRoOStepSliderAttribute : BaseAutoConfigRoOAttribute
	{
		public string format;

		public float min;

		public float max;

		public float step;

		public override Type requiredType => typeof(float);

		public AutoConfigRoOStepSliderAttribute(string format, float min, float max, float step, string nameOverride = null, string catOverride = null)
			: base(nameOverride, catOverride)
		{
			this.format = format;
			this.min = min;
			this.max = max;
			this.step = step;
		}

		public override void Apply(ConfigEntryBase cfe, Compat_RiskOfOptions.OptionIdentityStrings identStrings, bool deferForever, Func<bool> isDisabledDelegate)
		{
			Compat_RiskOfOptions.AddOption_StepSlider((ConfigEntry<float>)(object)cfe, identStrings, min, max, step, format, deferForever, isDisabledDelegate);
		}
	}
	[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
	public class AutoConfigRoOIntSliderAttribute : BaseAutoConfigRoOAttribute
	{
		public string format;

		public int min;

		public int max;

		public override Type requiredType => typeof(int);

		public AutoConfigRoOIntSliderAttribute(string format, int min, int max, string nameOverride = null, string catOverride = null)
			: base(nameOverride, catOverride)
		{
			this.format = format;
			this.min = min;
			this.max = max;
		}

		public override void Apply(ConfigEntryBase cfe, Compat_RiskOfOptions.OptionIdentityStrings identStrings, bool deferForever, Func<bool> isDisabledDelegate)
		{
			Compat_RiskOfOptions.AddOption_IntSlider((ConfigEntry<int>)(object)cfe, identStrings, min, max, format, deferForever, isDisabledDelegate);
		}
	}
	[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
	public class AutoConfigRoOChoiceAttribute : BaseAutoConfigRoOAttribute
	{
		public override Type requiredType => typeof(Enum);

		public AutoConfigRoOChoiceAttribute(string nameOverride = null, string catOverride = null)
			: base(nameOverride, catOverride)
		{
		}

		public override void Apply(ConfigEntryBase cfe, Compat_RiskOfOptions.OptionIdentityStrings identStrings, bool deferForever, Func<bool> isDisabledDelegate)
		{
			Compat_RiskOfOptions.AddOption_Choice(cfe, identStrings, deferForever, isDisabledDelegate);
		}
	}
	[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
	public class AutoConfigRoOKeybindAttribute : BaseAutoConfigRoOAttribute
	{
		public override Type requiredType => typeof(KeyboardShortcut);

		public AutoConfigRoOKeybindAttribute(string nameOverride = null, string catOverride = null)
			: base(nameOverride, catOverride)
		{
		}

		public override void Apply(ConfigEntryBase cfe, Compat_RiskOfOptions.OptionIdentityStrings identStrings, bool deferForever, Func<bool> isDisabledDelegate)
		{
			Compat_RiskOfOptions.AddOption_Keybind((ConfigEntry<KeyboardShortcut>)(object)cfe, identStrings, deferForever, isDisabledDelegate);
		}
	}
	[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
	public class AutoConfigRoOCheckboxAttribute : BaseAutoConfigRoOAttribute
	{
		public override Type requiredType => typeof(bool);

		public AutoConfigRoOCheckboxAttribute(string nameOverride = null, string catOverride = null)
			: base(nameOverride, catOverride)
		{
		}

		public override void Apply(ConfigEntryBase cfe, Compat_RiskOfOptions.OptionIdentityStrings identStrings, bool deferForever, Func<bool> isDisabledDelegate)
		{
			Compat_RiskOfOptions.AddOption_CheckBox((ConfigEntry<bool>)(object)cfe, identStrings, deferForever, isDisabledDelegate);
		}
	}
	[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
	public class AutoConfigRoOStringAttribute : BaseAutoConfigRoOAttribute
	{
		public override Type requiredType => typeof(string);

		public AutoConfigRoOStringAttribute(string nameOverride = null, string catOverride = null)
			: base(nameOverride, catOverride)
		{
		}

		public override void Apply(ConfigEntryBase cfe, Compat_RiskOfOptions.OptionIdentityStrings identStrings, bool deferForever, Func<bool> isDisabledDelegate)
		{
			Compat_RiskOfOptions.AddOption_String((ConfigEntry<string>)(object)cfe, identStrings, deferForever, isDisabledDelegate);
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
	public class AutoConfigRoOInfoOverridesAttribute : Attribute
	{
		public string modGuid;

		public string modName;

		public string categoryName;

		public string entryName;

		public AutoConfigRoOInfoOverridesAttribute(string guid, string name, string cat = null, string ent = null)
		{
			modGuid = guid;
			modName = name;
			categoryName = cat;
			entryName = ent;
		}

		public AutoConfigRoOInfoOverridesAttribute(Type ownerPluginType, string cat = null, string ent = null)
		{
			BepInPlugin customAttribute = ((MemberInfo)ownerPluginType).GetCustomAttribute<BepInPlugin>();
			if (customAttribute == null)
			{
				TILER2Plugin._logger.LogError((object)("AutoConfigContainerRoOInfoAttribute received an invalid type " + ownerPluginType.Name + " with no BepInPluginAttribute"));
				return;
			}
			modGuid = customAttribute.GUID;
			modName = customAttribute.Name;
			categoryName = cat;
			entryName = ent;
		}
	}
	public static class AutoConfigPresetExtensions
	{
		public static void ApplyPreset(this AutoConfigContainer container, string name)
		{
			HashSet<ConfigFile> hashSet = new HashSet<ConfigFile>();
			foreach (AutoConfigBinding binding in container.bindings)
			{
				IEnumerable<AutoConfigPresetAttribute> source = binding.boundProperty.GetCustomAttributes(typeof(AutoConfigPresetAttribute), inherit: true).Cast<AutoConfigPresetAttribute>();
				AutoConfigPresetAttribute autoConfigPresetAttribute = source.FirstOrDefault((AutoConfigPresetAttribute p) => p.presetName == name);
				if (autoConfigPresetAttribute != null)
				{
					binding.configEntry.BoxedValue = autoConfigPresetAttribute.boxedValue;
					if (!binding.configEntry.ConfigFile.SaveOnConfigSet)
					{
						hashSet.Add(binding.configEntry.ConfigFile);
					}
				}
			}
			foreach (ConfigFile item in hashSet)
			{
				item.Save();
			}
		}
	}
	[AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = true)]
	public class AutoConfigPresetAttribute : Attribute
	{
		public readonly string presetName;

		public readonly object boxedValue;

		public AutoConfigPresetAttribute(string name, object value)
		{
			presetName = name;
			boxedValue = value;
		}
	}
	public abstract class CatalogBoilerplate : T2Module
	{
		public struct ConsoleStrings
		{
			public string className;

			public string objectName;

			public string formattedIndex;
		}

		public string nameToken { get; private protected set; }

		public string pickupToken { get; private protected set; }

		public string descToken { get; private protected set; }

		public string loreToken { get; private protected set; }

		public PickupDef pickupDef { get; internal set; }

		public PickupIndex