Decompiled source of AutoItemPickup v2.2.0

AutoItemPickup/AutoItemPickup.dll

Decompiled 3 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using AutoItemPickup.Configuration;
using AutoItemPickup.Enums;
using AutoItemPickup.Hooks;
using AutoItemPickup.ItemDistributors;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using EntityStates.Scrapper;
using IL.EntityStates.Scrapper;
using IL.RoR2;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using MonoMod.RuntimeDetour.HookGen;
using On.RoR2;
using RoR2;
using UnityEngine;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("KubeRoot")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("3.0.0.0")]
[assembly: AssemblyInformationalVersion("3.0.0")]
[assembly: AssemblyProduct("AutoItemPickup")]
[assembly: AssemblyTitle("AutoItemPickup")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("3.0.0.0")]
namespace AutoItemPickup
{
	[BepInPlugin("com.kuberoot.autoitempickup", "AutoItemPickup", "2.2.0")]
	public class AutoItemPickup : BaseUnityPlugin
	{
		private static readonly MethodInfo GenericPickupController_AttemptGrant = typeof(GenericPickupController).GetMethod("AttemptGrant", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly FieldInfo GenericPickupController_consumed = typeof(GenericPickupController).GetField("consumed", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private bool distributorNeedsUpdate;

		private HookManager hookManager;

		public ItemDistributor Distributor { get; private set; }

		public Config ModConfig { get; private set; }

		public void OnEnable()
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			ModConfig = new Config(this, ((BaseUnityPlugin)this).Logger);
			hookManager = new HookManager(this);
			hookManager.RegisterHooks();
			PlayerCharacterMasterController.OnBodyDeath += (hook_OnBodyDeath)delegate(orig_OnBodyDeath orig, PlayerCharacterMasterController self)
			{
				orig.Invoke(self);
				UpdateTargets();
			};
			PlayerCharacterMasterController.OnBodyStart += (hook_OnBodyStart)delegate(orig_OnBodyStart orig, PlayerCharacterMasterController self)
			{
				orig.Invoke(self);
				UpdateTargets();
			};
			PickupDropletController.CreatePickup += new Manipulator(ModifyCreatePickup);
			PlayerCharacterMasterController.Awake += new hook_Awake(OnPlayerAwake);
			PlayerCharacterMasterController.onPlayerAdded += UpdateTargetsWrapper;
			PlayerCharacterMasterController.onPlayerRemoved += UpdateTargetsWrapper;
			ModConfig.distributeToDeadPlayers.SettingChanged += delegate
			{
				UpdateTargets();
			};
			ModConfig.distributionMode.SettingChanged += delegate
			{
				Distributor = ItemDistributor.GetItemDistributor(ModConfig.distributionMode.Value, this);
			};
		}

		public void OnDisable()
		{
			hookManager.UnregisterHooks();
			HookEndpointManager.RemoveAllOwnedBy(HookEndpointManager.GetOwner((Delegate)new Action(OnDisable)));
			PlayerCharacterMasterController.onPlayerAdded -= UpdateTargetsWrapper;
			PlayerCharacterMasterController.onPlayerRemoved -= UpdateTargetsWrapper;
		}

		private void UpdateTargetsWrapper(PlayerCharacterMasterController player)
		{
			UpdateTargets();
		}

		private void OnPlayerAwake(orig_Awake orig, PlayerCharacterMasterController self)
		{
			orig.Invoke(self);
			if (!NetworkServer.active)
			{
				return;
			}
			CharacterMaster master = self.master;
			if (Object.op_Implicit((Object)(object)master))
			{
				master.onBodyStart += delegate
				{
					UpdateTargets();
				};
			}
		}

		private void ModifyCreatePickup(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: 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>[1]
			{
				(Instruction i) => ILPatternMatchingExt.MatchCall<GenericPickupController>(i, "CreatePickup")
			});
			val.Emit(OpCodes.Dup);
			val.Emit(OpCodes.Ldarg_0);
			val.EmitDelegate<Action<GenericPickupController, PickupDropletController>>((Action<GenericPickupController, PickupDropletController>)delegate(GenericPickupController pickupController, PickupDropletController self)
			{
				OverrideDistributorBehaviour component = ((Component)self).GetComponent<OverrideDistributorBehaviour>();
				if (Object.op_Implicit((Object)(object)component))
				{
					((Component)pickupController).gameObject.AddComponent<OverrideDistributorBehaviour>().Distributor = component.Distributor;
				}
			});
		}

		[Server]
		public static void GrantItem(GenericPickupController item, CharacterMaster master)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_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: Invalid comparison between Unknown and I4
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			if (master.hasBody)
			{
				GenericPickupController_AttemptGrant.Invoke(item, new object[1] { master.GetBody() });
				return;
			}
			PickupDef pickupDef = PickupCatalog.GetPickupDef(item.pickupIndex);
			ItemIndex val = (ItemIndex)((pickupDef == null) ? (-1) : ((int)pickupDef.itemIndex));
			if ((int)val != -1)
			{
				master.inventory.GiveItem(val, 1);
				PlayerCharacterMasterController playerCharacterMasterController = master.playerCharacterMasterController;
				NetworkUser subjectAsNetworkUser = (((Object)(object)playerCharacterMasterController != (Object)null) ? playerCharacterMasterController.networkUser : null);
				PickupDef pickupDef2 = PickupCatalog.GetPickupDef(item.pickupIndex);
				Chat.AddMessage(((ChatMessageBase)new PlayerPickupChatMessage
				{
					subjectAsNetworkUser = subjectAsNetworkUser,
					baseToken = "PLAYER_PICKUP",
					pickupToken = (pickupDef2?.nameToken ?? PickupCatalog.invalidPickupToken),
					pickupColor = Color32.op_Implicit(pickupDef2?.baseColor ?? Color.black),
					pickupQuantity = (uint)master.inventory.GetItemCount(val)
				}).ConstructChatString());
				GenericPickupController_consumed.SetValue(item, true);
				Object.Destroy((Object)(object)((Component)item).gameObject);
			}
		}

		private void UpdateTargets()
		{
			distributorNeedsUpdate = true;
		}

		public void PreDistributeItemInternal(Cause cause)
		{
			if (Distributor == null)
			{
				Distributor = ItemDistributor.GetItemDistributor(ModConfig.distributionMode.Value, this);
			}
			if (distributorNeedsUpdate)
			{
				distributorNeedsUpdate = false;
				Distributor?.UpdateTargets();
			}
		}

		public void DistributeItemInternal(GenericPickupController item, Cause cause)
		{
			ItemDistributor distributorInternal = GetDistributorInternal(((Component)item).gameObject, cause);
			try
			{
				distributorInternal.DistributeItem(item);
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)$"Caught AutoItemPickup distributor exception:\n{ex}\n{ex.StackTrace}");
			}
		}

		public void DistributeItem(GenericPickupController item, Cause cause)
		{
			PreDistributeItemInternal(cause);
			DistributeItemInternal(item, cause);
		}

		public void DistributeItems(IEnumerable<GenericPickupController> items, Cause cause)
		{
			PreDistributeItemInternal(cause);
			foreach (GenericPickupController item in items)
			{
				DistributeItemInternal(item, cause);
			}
		}

		public ItemDistributor GetDistributorInternal(GameObject item, Cause cause)
		{
			if ((Object)(object)item != (Object)null)
			{
				OverrideDistributorBehaviour component = item.GetComponent<OverrideDistributorBehaviour>();
				if ((Object)(object)component != (Object)null)
				{
					return component.Distributor;
				}
			}
			return Distributor;
		}

		public ItemDistributor GetDistributor(GameObject item, Cause cause)
		{
			PreDistributeItemInternal(cause);
			return GetDistributorInternal(item, cause);
		}
	}
	public abstract class ItemDistributor
	{
		public delegate bool TargetFilter(CharacterMaster target);

		private readonly AutoItemPickup plugin;

		protected ItemDistributor(AutoItemPickup plugin)
		{
			this.plugin = plugin;
			UpdateTargets();
		}

		public abstract CharacterMaster GetTarget(Vector3 position, PickupIndex pickupIndex, TargetFilter extraFilter = null);

		public virtual void DistributeItem(ref CreatePickupInfo pickupInfo, TargetFilter extraFilter = null)
		{
			//IL_0002: 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_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: 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)
			CharacterMaster target = GetTarget(pickupInfo.position, ((CreatePickupInfo)(ref pickupInfo)).pickupIndex, extraFilter);
			if (!((Object)(object)target == (Object)null))
			{
				Vector3 position = target.GetBody().transform.position + Vector3.up * 2f;
				pickupInfo.position = position;
			}
		}

		public virtual void DistributeItem(GenericPickupController item, TargetFilter extraFilter = null)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			CharacterMaster target = GetTarget(((Component)item).transform.position, item.pickupIndex, extraFilter);
			if (!((Object)(object)target == (Object)null))
			{
				AutoItemPickup.GrantItem(item, target);
			}
		}

		public abstract void UpdateTargets();

		public virtual bool IsValid()
		{
			return true;
		}

		protected bool IsValidTarget(CharacterMaster master)
		{
			return plugin.ModConfig.CheckTarget(master);
		}

		protected bool IsValidTarget(PlayerCharacterMasterController player)
		{
			if ((Object)(object)player != (Object)null)
			{
				return IsValidTarget(player.master);
			}
			return false;
		}

		protected List<PlayerCharacterMasterController> GetValidTargets()
		{
			return PlayerCharacterMasterController.instances.Where(IsValidTarget).ToList();
		}

		public static ItemDistributor GetItemDistributor(Mode mode, AutoItemPickup plugin)
		{
			return mode switch
			{
				Mode.Closest => new ClosestDistributor(plugin), 
				Mode.LeastItems => new LeastItemsDistributor(plugin), 
				Mode.Random => new RandomDistributor(plugin), 
				_ => new SequentialDistributor(plugin), 
			};
		}
	}
	public class OverrideDistributorBehaviour : MonoBehaviour
	{
		public ItemDistributor Distributor;
	}
}
namespace AutoItemPickup.ItemDistributors
{
	internal class ClosestDistributor : ItemDistributor
	{
		private CharacterMaster[] targets;

		public ClosestDistributor(AutoItemPickup plugin)
			: base(plugin)
		{
		}

		public override void UpdateTargets()
		{
			targets = (from player in GetValidTargets()
				select player.master).ToArray();
		}

		public override CharacterMaster GetTarget(Vector3 position, PickupIndex pickupIndex, TargetFilter extraFilter = null)
		{
			//IL_0008: 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_0047: 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_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			CharacterMaster result = null;
			float num = float.MaxValue;
			CharacterMaster[] array = targets;
			foreach (CharacterMaster val in array)
			{
				if (extraFilter == null || extraFilter(val))
				{
					Vector3 val2 = (val.hasBody ? val.GetBodyObject().transform.position : val.deathFootPosition);
					Vector3 val3 = position - val2;
					float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude;
					if (sqrMagnitude < num)
					{
						result = val;
						num = sqrMagnitude;
					}
				}
			}
			return result;
		}
	}
	internal class FixedTargetDistributor : ItemDistributor
	{
		private readonly CharacterMaster target;

		public FixedTargetDistributor(AutoItemPickup plugin, PlayerCharacterMasterController target)
			: this(plugin, target.master)
		{
		}

		public FixedTargetDistributor(AutoItemPickup plugin, CharacterMaster target)
			: base(plugin)
		{
			this.target = target;
		}

		public override bool IsValid()
		{
			return IsValidTarget(target);
		}

		public override void UpdateTargets()
		{
		}

		public override CharacterMaster GetTarget(Vector3 position, PickupIndex pickupIndex, TargetFilter extraFilter = null)
		{
			if (extraFilter != null && !extraFilter(target))
			{
				return null;
			}
			return target;
		}
	}
	internal class LeastItemsDistributor : ItemDistributor
	{
		private CharacterMaster[] targets;

		public LeastItemsDistributor(AutoItemPickup plugin)
			: base(plugin)
		{
		}

		public override void UpdateTargets()
		{
			List<PlayerCharacterMasterController> validTargets = GetValidTargets();
			targets = (CharacterMaster[])(object)new CharacterMaster[validTargets.Count];
			for (int i = 0; i < validTargets.Count; i++)
			{
				PlayerCharacterMasterController val = validTargets[i];
				targets[i] = val.master;
			}
		}

		public override CharacterMaster GetTarget(Vector3 position, PickupIndex pickupIndex, TargetFilter extraFilter = null)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			CharacterMaster result = null;
			int num = int.MaxValue;
			PickupDef pickupDef = PickupCatalog.GetPickupDef(pickupIndex);
			if (pickupDef == null)
			{
				return targets.First();
			}
			ItemTier tier = ItemCatalog.GetItemDef(pickupDef.itemIndex).tier;
			CharacterMaster[] array = targets;
			foreach (CharacterMaster val in array)
			{
				if (extraFilter == null || extraFilter(val))
				{
					int totalItemCountOfTier = val.inventory.GetTotalItemCountOfTier(tier);
					if (totalItemCountOfTier < num)
					{
						result = val;
						num = totalItemCountOfTier;
					}
				}
			}
			return result;
		}
	}
	internal class RandomDistributor : ItemDistributor
	{
		private CharacterMaster[] targets;

		public RandomDistributor(AutoItemPickup plugin)
			: base(plugin)
		{
		}

		public override void UpdateTargets()
		{
			targets = (from pcmc in GetValidTargets()
				select pcmc.master).ToArray();
		}

		public override CharacterMaster GetTarget(Vector3 position, PickupIndex pickupIndex, TargetFilter extraFilter = null)
		{
			IEnumerable<CharacterMaster> source = targets.AsEnumerable();
			if (extraFilter != null)
			{
				source = source.Where((CharacterMaster target) => extraFilter(target));
			}
			CharacterMaster[] array = source.ToArray();
			return array.ElementAtOrDefault(Random.Range(0, array.Length));
		}
	}
	internal class SequentialDistributor : ItemDistributor
	{
		private int index;

		private CharacterMaster[] playerDistribution;

		public SequentialDistributor(AutoItemPickup plugin)
			: base(plugin)
		{
		}

		public override void UpdateTargets()
		{
			CharacterMaster[] array = playerDistribution;
			CharacterMaster val = ((array != null) ? array[index] : null);
			List<PlayerCharacterMasterController> validTargets = GetValidTargets();
			playerDistribution = (CharacterMaster[])(object)new CharacterMaster[validTargets.Count];
			index = -1;
			for (int i = 0; i < validTargets.Count; i++)
			{
				PlayerCharacterMasterController val2 = validTargets[i];
				playerDistribution[i] = val2.master;
				if ((Object)(object)val2.master == (Object)(object)val)
				{
					index = i;
				}
			}
			if (index == -1)
			{
				index = Random.Range(0, playerDistribution.Length);
			}
		}

		public override CharacterMaster GetTarget(Vector3 position, PickupIndex pickupIndex, TargetFilter extraFilter = null)
		{
			if (playerDistribution.Length == 0)
			{
				return null;
			}
			CharacterMaster result = null;
			if (extraFilter != null)
			{
				for (int i = 0; i < playerDistribution.Length; i++)
				{
					CharacterMaster val = playerDistribution[(index + i) % playerDistribution.Length];
					if (extraFilter(val))
					{
						result = val;
						index = (index + i + 1) % playerDistribution.Length;
						break;
					}
				}
			}
			else
			{
				result = playerDistribution[index];
				index = ++index % playerDistribution.Length;
			}
			return result;
		}
	}
}
namespace AutoItemPickup.Enums
{
	public enum Cause
	{
		Teleport,
		Drop
	}
	public enum Mode
	{
		Sequential,
		Random,
		Closest,
		LeastItems
	}
}
namespace AutoItemPickup.Configuration
{
	public class Config
	{
		public readonly AutoItemPickup Plugin;

		private readonly ManualLogSource logger;

		public ConfigEntry<Mode> distributionMode;

		public ConfigEntry<bool> printerOverrideTarget;

		public ConfigEntry<bool> scrapperOverrideTarget;

		public ConfigEntry<bool> teleportCommandObeyTier;

		public ConfigEntry<bool> distributeToDeadPlayers;

		public ConfigEntry<bool> distributeOnDrop;

		public ConfigEntry<bool> distributeOnTeleport;

		public ItemFilter OnDrop;

		public ItemFilter OnTeleport;

		public ConfigEntry<bool> teleportCommandOnDrop;

		public ConfigEntry<bool> teleportCommandOnTeleport;

		public ConfigMigrator migrator;

		private bool OnDropReady => OnDrop?.Ready ?? false;

		private bool OnTeleportReady => OnTeleport?.Ready ?? false;

		public bool Ready
		{
			get
			{
				if (OnDropReady)
				{
					return OnTeleportReady;
				}
				return false;
			}
		}

		private ConfigFile config => ((BaseUnityPlugin)Plugin).Config;

		public event Action OnConfigReady;

		public Config(AutoItemPickup plugin, ManualLogSource _logger)
		{
			Plugin = plugin;
			logger = _logger;
			migrator = new ConfigMigrator(config, this);
			OnTeleport = new ItemFilter("OnTeleportFilter", config);
			OnDrop = new ItemFilter("OnDropFilter", config);
			distributeToDeadPlayers = config.Bind<bool>("General", "DistributeToDeadPlayers", true, "Should items be distributed to dead players?");
			printerOverrideTarget = config.Bind<bool>("General", "OverridePrinterTarget", true, "Should items from printers and cauldrons be distributed only to activator as long as they're a valid target?");
			scrapperOverrideTarget = config.Bind<bool>("General", "OverrideScrapperTarget", true, "Should scrap from scrappers be distributed only to activator as long as they're a valid target?");
			distributionMode = config.Bind<Mode>("General", "DistributionMode", Mode.Sequential, "Decide how to distribute items among the players\nSequential - Goes over all players, giving each of them one item\nRandom - Chooses which player receives the item randomly\nClosest - Gives the item to the nearest player\nLeastItems - Gives the item to the player with least total items of the item's tier");
			distributeOnDrop = config.Bind<bool>("Items", "DistributeOnDrop", false, "Should items be distributed when they drop?");
			distributeOnTeleport = config.Bind<bool>("Items", "DistributeOnTeleport", true, "Should items be distributed when the teleporter is activated?");
			teleportCommandOnDrop = config.Bind<bool>("Command", "DistributeOnDrop", true, "Should Command essences be teleported to players?\nIf enabled, when an essence is spawned, it will teleport to a player using distribution mode rules. It will not be opened automatically.\nNote: Doesn't work well with LeastItems, due to LeastItems only accounting for the current number of items and not including any unopened command essences.");
			teleportCommandOnTeleport = config.Bind<bool>("Command", "DistributeOnTeleport", true, "Should Command essences be teleported to the teleporter when charged?\nIf enabled, when the teleporter is charged, all essences are teleported nearby the teleporter.\nAfterwards, any new essences that do not fit the requirements for OnDrop distribution will also be teleported nearby the teleporter.");
			teleportCommandObeyTier = config.Bind<bool>("Command", "UseTierWhitelist", true, "Should Command essence teleportation be restricted by item tiers?\nIf enabled, when deciding if a command essence should be teleported, its tier will be compared against the OnDrop/OnTeleport tier whitelist.");
			config.SettingChanged += ConfigOnSettingChanged;
			OnTeleport.OnReady += CheckReadyStatus;
			OnDrop.OnReady += CheckReadyStatus;
			OnConfigReady += DoMigrationIfReady;
			DoMigrationIfReady();
		}

		private void CheckReadyStatus()
		{
			if (Ready)
			{
				this.OnConfigReady?.Invoke();
			}
		}

		private void DoMigrationIfReady()
		{
			if (Ready && migrator.NeedsMigration)
			{
				migrator.DoMigration();
			}
		}

		public bool CheckTarget(CharacterMaster master)
		{
			if ((Object)(object)master != (Object)null)
			{
				if (!master.hasBody)
				{
					return distributeToDeadPlayers.Value;
				}
				return true;
			}
			return false;
		}

		public bool ShouldDistribute(PickupIndex index, Cause cause)
		{
			//IL_001b: 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)
			//IL_002c: Invalid comparison between Unknown and I4
			//IL_0031: 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)
			if (!((cause == Cause.Drop) ? distributeOnDrop : distributeOnTeleport).Value)
			{
				return false;
			}
			PickupDef pickupDef = PickupCatalog.GetPickupDef(index);
			if (pickupDef == null || (int)pickupDef.itemIndex == -1)
			{
				return false;
			}
			ItemDef itemDef = ItemCatalog.GetItemDef(pickupDef.itemIndex);
			if ((Object)(object)itemDef == (Object)null)
			{
				return false;
			}
			return ((cause == Cause.Drop) ? OnDrop : OnTeleport).CheckFilter(itemDef.itemIndex);
		}

		public bool ShouldDistributeCommand(ItemTier tier, Cause cause)
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			if (!((cause == Cause.Drop) ? teleportCommandOnDrop : teleportCommandOnTeleport).Value)
			{
				return false;
			}
			if (!teleportCommandObeyTier.Value)
			{
				return true;
			}
			return ((cause == Cause.Drop) ? OnDrop : OnTeleport).CheckFilterTier(tier);
		}

		public bool ShouldDistributeCommand(PickupIndex index, Cause cause)
		{
			//IL_001b: 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)
			//IL_002c: Invalid comparison between Unknown and I4
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			if (!((cause == Cause.Drop) ? teleportCommandOnDrop : teleportCommandOnTeleport).Value)
			{
				return false;
			}
			PickupDef pickupDef = PickupCatalog.GetPickupDef(index);
			if (pickupDef == null || (int)pickupDef.itemIndex == -1)
			{
				return false;
			}
			if (!teleportCommandObeyTier.Value)
			{
				return true;
			}
			ItemDef itemDef = ItemCatalog.GetItemDef(pickupDef.itemIndex);
			if ((Object)(object)itemDef == (Object)null)
			{
				return false;
			}
			return ((cause == Cause.Drop) ? OnDrop : OnTeleport).CheckFilterTier(itemDef.tier);
		}

		private void ConfigOnSettingChanged(object sender, SettingChangedEventArgs e)
		{
			if (e.ChangedSetting.SettingType == typeof(ItemSet))
			{
				ConfigEntry<ItemSet> val = (ConfigEntry<ItemSet>)(object)e.ChangedSetting;
				ItemSet value = val.Value;
				IList<string> parseErrors = value.ParseErrors;
				if (parseErrors != null && parseErrors.Count > 0)
				{
					string text = "Errors found when parsing " + ((ConfigEntryBase)val).Definition.Key + " for " + ((ConfigEntryBase)val).Definition.Section + ":\n\t" + string.Join("\n\t", value.ParseErrors);
					logger.LogWarning((object)text);
				}
			}
		}
	}
	public class ConfigMigrator
	{
		private static PropertyInfo Property_ConfigFiles_OrphanedEntries = typeof(ConfigFile).GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private ConfigFile config;

		private Dictionary<ConfigDefinition, string> OrphanedEntries;

		private Config ModConfig;

		private static Dictionary<ConfigDefinition, Action<Config, string>> migrations = new Dictionary<ConfigDefinition, Action<Config, string>>
		{
			{
				new ConfigDefinition("General", "TeleportCommandCubes"),
				delegate(Config config, string value)
				{
					ConfigEntry<bool> teleportCommandOnDrop = config.teleportCommandOnDrop;
					bool value2 = (config.teleportCommandOnTeleport.Value = value == "true");
					teleportCommandOnDrop.Value = value2;
				}
			},
			{
				new ConfigDefinition("General", "DebugItemDefinitions"),
				delegate
				{
				}
			},
			{
				new ConfigDefinition("General", "DistributeOnDrop"),
				delegate(Config config, string value)
				{
					config.distributeOnDrop.Value = value == "true";
				}
			},
			{
				new ConfigDefinition("General", "DistributeOnTeleport"),
				delegate(Config config, string value)
				{
					config.distributeOnTeleport.Value = value == "true";
				}
			},
			{
				new ConfigDefinition("OnDrop", "ItemDistributionMode"),
				delegate(Config config, string value)
				{
					config.distributionMode.Value = (Mode)Enum.Parse(typeof(Mode), value);
				}
			},
			{
				new ConfigDefinition("OnDrop", "DistributeWhiteItems"),
				delegate(Config config, string value)
				{
					MigrateItemTier(config.OnDrop.TierWhitelist, (ItemTier)0, value);
				}
			},
			{
				new ConfigDefinition("OnDrop", "DistributeGreenItems"),
				delegate(Config config, string value)
				{
					MigrateItemTier(config.OnDrop.TierWhitelist, (ItemTier)1, value);
				}
			},
			{
				new ConfigDefinition("OnDrop", "DistributeRedItems"),
				delegate(Config config, string value)
				{
					MigrateItemTier(config.OnDrop.TierWhitelist, (ItemTier)2, value);
				}
			},
			{
				new ConfigDefinition("OnDrop", "DistributeLunarItems"),
				delegate(Config config, string value)
				{
					MigrateItemTier(config.OnDrop.TierWhitelist, (ItemTier)3, value);
				}
			},
			{
				new ConfigDefinition("OnDrop", "DistributeBossItems"),
				delegate(Config config, string value)
				{
					MigrateItemTier(config.OnDrop.TierWhitelist, (ItemTier)4, value);
				}
			},
			{
				new ConfigDefinition("OnDrop", "ItemBlacklist"),
				delegate(Config config, string value)
				{
					config.OnDrop.ItemBlacklistEntry.Value = ItemSet.Deserialize(value);
				}
			},
			{
				new ConfigDefinition("OnTeleport", "ItemDistributionMode"),
				delegate
				{
				}
			},
			{
				new ConfigDefinition("OnTeleport", "DistributeWhiteItems"),
				delegate(Config config, string value)
				{
					MigrateItemTier(config.OnTeleport.TierWhitelist, (ItemTier)0, value);
				}
			},
			{
				new ConfigDefinition("OnTeleport", "DistributeGreenItems"),
				delegate(Config config, string value)
				{
					MigrateItemTier(config.OnTeleport.TierWhitelist, (ItemTier)1, value);
				}
			},
			{
				new ConfigDefinition("OnTeleport", "DistributeRedItems"),
				delegate(Config config, string value)
				{
					MigrateItemTier(config.OnTeleport.TierWhitelist, (ItemTier)2, value);
				}
			},
			{
				new ConfigDefinition("OnTeleport", "DistributeLunarItems"),
				delegate(Config config, string value)
				{
					MigrateItemTier(config.OnTeleport.TierWhitelist, (ItemTier)3, value);
				}
			},
			{
				new ConfigDefinition("OnTeleport", "DistributeBossItems"),
				delegate(Config config, string value)
				{
					MigrateItemTier(config.OnTeleport.TierWhitelist, (ItemTier)4, value);
				}
			},
			{
				new ConfigDefinition("OnTeleport", "ItemBlacklist"),
				delegate(Config config, string value)
				{
					config.OnTeleport.ItemBlacklistEntry.Value = ItemSet.Deserialize(value);
				}
			}
		};

		public bool NeedsMigration => migrations.Keys.Any((ConfigDefinition def) => OrphanedEntries.ContainsKey(def));

		public ConfigMigrator(ConfigFile config, Config modConfig)
		{
			this.config = config;
			ModConfig = modConfig;
			OrphanedEntries = (Dictionary<ConfigDefinition, string>)Property_ConfigFiles_OrphanedEntries.GetValue(config);
		}

		private static void MigrateItemTier(ItemTierSet set, ItemTier tier, string value)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (value == "true")
			{
				set.Add(tier);
			}
			else
			{
				set.Remove(tier);
			}
		}

		public void DoMigration()
		{
			List<ConfigDefinition> list = new List<ConfigDefinition>();
			foreach (KeyValuePair<ConfigDefinition, Action<Config, string>> migration in migrations)
			{
				ConfigDefinition key = migration.Key;
				Action<Config, string> value = migration.Value;
				if (OrphanedEntries.TryGetValue(key, out var value2))
				{
					value(ModConfig, value2);
					list.Add(key);
				}
			}
			foreach (ConfigDefinition item in list)
			{
				OrphanedEntries.Remove(item);
			}
			config.Save();
		}
	}
	public class ItemFilter
	{
		private readonly ConfigFile config;

		public ConfigEntry<ItemSet> ItemBlacklistEntry;

		public ConfigEntry<ItemSet> ItemWhitelistEntry;

		public ConfigEntry<ItemTierSet> TierWhitelistEntry;

		public string Type;

		public bool Ready;

		public ItemTierSet TierWhitelist => TierWhitelistEntry.Value;

		public ItemSet ItemWhitelist => ItemWhitelistEntry.Value;

		public ItemSet ItemBlacklist => ItemBlacklistEntry.Value;

		public event Action OnReady;

		static ItemFilter()
		{
			//IL_000a: 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)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Expected O, but got Unknown
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Expected O, but got Unknown
			TomlTypeConverter.AddConverter(typeof(ItemTierSet), new TypeConverter
			{
				ConvertToObject = (string str, Type type) => ItemTierSet.Deserialize(str),
				ConvertToString = (object obj, Type type) => obj.ToString()
			});
			TomlTypeConverter.AddConverter(typeof(ItemSet), new TypeConverter
			{
				ConvertToObject = (string str, Type type) => ItemSet.Deserialize(str),
				ConvertToString = (object obj, Type type) => obj.ToString()
			});
		}

		public ItemFilter(string type, ConfigFile config)
		{
			Type = type;
			this.config = config;
			if (ItemSet.Initialized)
			{
				CreateSets();
			}
			else
			{
				ItemSet.OnInitialized += CreateSets;
			}
		}

		public bool CheckFilter(ItemIndex index)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: 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_002e: Unknown result type (might be due to invalid IL or missing references)
			ItemTier tier = ItemCatalog.GetItemDef(index).tier;
			if (!ItemBlacklist.HasItem(index))
			{
				if (!TierWhitelist.Contains(tier))
				{
					return ItemWhitelist.HasItem(index);
				}
				return true;
			}
			return false;
		}

		public bool CheckFilterTier(ItemTier tier)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return TierWhitelist.Contains(tier);
		}

		private void CreateSets()
		{
			//IL_0012: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			//IL_0086: Expected O, but got Unknown
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Expected O, but got Unknown
			//IL_00bc: Expected O, but got Unknown
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Expected O, but got Unknown
			//IL_00f2: Expected O, but got Unknown
			TierWhitelistEntry = config.Bind<ItemTierSet>(new ConfigDefinition(Type, "TierWhitelist"), new ItemTierSet
			{
				(ItemTier)0,
				(ItemTier)1,
				(ItemTier)2
			}, new ConfigDescription("Which item tiers should be distributed?\nValid values: " + string.Join(", ", ((IEnumerable<ItemTierDef>)(object)ItemTierCatalog.allItemTierDefs).Select((ItemTierDef def) => ((Object)def).name)), (AcceptableValueBase)null, Array.Empty<object>()));
			ItemWhitelistEntry = config.Bind<ItemSet>(new ConfigDefinition(Type, "ItemWhitelist"), new ItemSet(), new ConfigDescription("Which items should be distributed, regardless of tier?\nAccepts localized english item names and internal names, use backslash for escapes", (AcceptableValueBase)null, Array.Empty<object>()));
			ItemBlacklistEntry = config.Bind<ItemSet>(new ConfigDefinition(Type, "ItemBlacklist"), new ItemSet(), new ConfigDescription("Which items should NOT be distributed, regardless of tier?\nAccepts localized english item names and internal names, use backslash for escapes", (AcceptableValueBase)null, Array.Empty<object>()));
			Ready = true;
			this.OnReady?.Invoke();
		}
	}
	public class ItemSet
	{
		public enum ItemNameSource
		{
			EN_Name,
			Def_Name
		}

		public struct ItemWrapper
		{
			public ItemIndex itemIndex;

			public string EN_Name;

			public string Def_Name;

			public ItemNameSource itemNameSource;

			public string GetName()
			{
				return itemNameSource switch
				{
					ItemNameSource.EN_Name => EN_Name, 
					ItemNameSource.Def_Name => Def_Name, 
					_ => EN_Name ?? Def_Name ?? ((object)(ItemIndex)(ref itemIndex)).ToString(), 
				};
			}

			public override bool Equals(object obj)
			{
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_001a: Unknown result type (might be due to invalid IL or missing references)
				if (!(obj is ItemWrapper itemWrapper))
				{
					return false;
				}
				if (itemIndex == itemWrapper.itemIndex)
				{
					return EN_Name == itemWrapper.EN_Name;
				}
				return false;
			}

			public override int GetHashCode()
			{
				return ((17 * 31 + ((object)(ItemIndex)(ref itemIndex)).GetHashCode()) * 31 + EqualityComparer<string>.Default.GetHashCode(EN_Name)) * 31 + EqualityComparer<string>.Default.GetHashCode(Def_Name);
			}
		}

		public static readonly Dictionary<string, ItemWrapper> ItemsByEnglishName;

		public static readonly Dictionary<string, ItemWrapper> ItemsByDefName;

		public static readonly Dictionary<ItemIndex, ItemWrapper> ItemsByIndex;

		private static readonly Regex regexEscapes;

		private static readonly Regex regexEntries;

		private readonly HashSet<ItemWrapper> items = new HashSet<ItemWrapper>();

		public IList<string> ParseErrors;

		public static bool Initialized { get; private set; }

		internal static event Action OnInitialized;

		static ItemSet()
		{
			ItemsByEnglishName = new Dictionary<string, ItemWrapper>();
			ItemsByDefName = new Dictionary<string, ItemWrapper>();
			ItemsByIndex = new Dictionary<ItemIndex, ItemWrapper>();
			regexEscapes = new Regex("(?:([^\\\\]+)|(?:\\\\(.)))", RegexOptions.IgnoreCase | RegexOptions.Compiled);
			regexEntries = new Regex("([^,]*)(,|$)", RegexOptions.IgnoreCase | RegexOptions.Compiled);
			TryInitialize();
			((ResourceAvailability)(ref ItemCatalog.availability)).CallWhenAvailable((Action)delegate
			{
				TryInitialize();
			});
			RoR2Application.onLoad = (Action)Delegate.Combine(RoR2Application.onLoad, (Action)delegate
			{
				TryInitialize();
			});
		}

		public ItemSet()
		{
			if (!Initialized)
			{
				TryInitialize();
			}
		}

		public static string Escape(string s)
		{
			return s.Replace(",", "\\,");
		}

		public void AddParseError(string error)
		{
			if (ParseErrors == null)
			{
				ParseErrors = new List<string>();
			}
			ParseErrors.Add(error);
		}

		public static IEnumerable<string> Parse(string s)
		{
			MatchCollection matchCollection = regexEscapes.Matches(s);
			List<string> list = new List<string>();
			StringBuilder stringBuilder = new StringBuilder();
			foreach (Match item in matchCollection)
			{
				if (item.Groups[2].Length > 0)
				{
					stringBuilder.Append(item.Groups[2].Value);
					continue;
				}
				foreach (Match item2 in regexEntries.Matches(item.Groups[1].Value))
				{
					stringBuilder.Append(item2.Groups[1].Value);
					if (item2.Groups[2].Length > 0)
					{
						list.Add(stringBuilder.ToString());
						stringBuilder.Clear();
					}
				}
			}
			if (stringBuilder.Length > 0)
			{
				list.Add(stringBuilder.ToString());
			}
			return list.Select((string entry) => entry.Trim());
		}

		public static string Serialize(ItemSet self)
		{
			if (!TryInitialize())
			{
				throw new InvalidOperationException("ItemSet cannot be initialized at this point");
			}
			StringBuilder stringBuilder = new StringBuilder();
			using (IEnumerator<string> enumerator = self.items.Select((ItemWrapper item) => Escape(item.GetName())).GetEnumerator())
			{
				if (enumerator.MoveNext())
				{
					stringBuilder.Append(enumerator.Current);
					while (enumerator.MoveNext())
					{
						stringBuilder.Append(", ");
						stringBuilder.Append(enumerator.Current);
					}
				}
			}
			return stringBuilder.ToString();
		}

		public static ItemSet Deserialize(string src)
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			if (!TryInitialize())
			{
				throw new InvalidOperationException("ItemSet cannot be initialized at this point");
			}
			ItemSet itemSet = new ItemSet();
			foreach (string item in Parse(src))
			{
				if (!ItemsByEnglishName.TryGetValue(item, out var value) && !ItemsByDefName.TryGetValue(item, out value))
				{
					itemSet.AddParseError("Invalid item in blacklist: " + item + "; ignoring");
					ItemWrapper itemWrapper = default(ItemWrapper);
					itemWrapper.itemIndex = (ItemIndex)(-1);
					itemWrapper.EN_Name = item;
					itemWrapper.itemNameSource = ItemNameSource.EN_Name;
					value = itemWrapper;
				}
				itemSet.items.Add(value);
			}
			return itemSet;
		}

		public override string ToString()
		{
			return Serialize(this);
		}

		public static bool TryInitialize()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			if (Initialized)
			{
				return true;
			}
			if (!((ResourceAvailability)(ref ItemCatalog.availability)).available || Language.english == null)
			{
				return false;
			}
			Language english = Language.english;
			foreach (ItemDef item in ((IEnumerable<ItemIndex>)(object)ItemCatalog.allItems).Select((Func<ItemIndex, ItemDef>)ItemCatalog.GetItemDef))
			{
				ItemIndex itemIndex = item.itemIndex;
				string text = null;
				if (item.nameToken != null)
				{
					text = english.GetLocalizedStringByToken(item.nameToken);
				}
				ItemWrapper itemWrapper = default(ItemWrapper);
				itemWrapper.itemIndex = itemIndex;
				itemWrapper.EN_Name = text;
				itemWrapper.Def_Name = ((Object)item).name;
				itemWrapper.itemNameSource = ItemNameSource.EN_Name;
				ItemWrapper value = itemWrapper;
				ItemsByIndex[itemIndex] = value;
				if (text != null)
				{
					ItemsByEnglishName[text] = value;
				}
				value.itemNameSource = ItemNameSource.Def_Name;
				ItemsByDefName[((Object)item).name] = value;
			}
			foreach (ItemWrapper item2 in ItemsByIndex.Values.Where((ItemWrapper wrapper) => wrapper.EN_Name != null))
			{
				string key = item2.EN_Name.Trim();
				if (!ItemsByEnglishName.ContainsKey(key))
				{
					ItemsByEnglishName[key] = item2;
				}
			}
			Initialized = true;
			ItemSet.OnInitialized?.Invoke();
			return true;
		}

		public void AddItem(ItemWrapper item)
		{
			items.Add(item);
		}

		public void RemoveItem(ItemWrapper item)
		{
			items.Remove(item);
		}

		public bool HasItem(ItemWrapper item)
		{
			return items.Contains(item);
		}

		public void AddItem(ItemWrapper? item)
		{
			AddItem(item.Value);
		}

		public void RemoveItem(ItemWrapper? item)
		{
			RemoveItem(item.Value);
		}

		public bool HasItem(ItemWrapper? item)
		{
			return HasItem(item.Value);
		}

		public void AddItem(string name)
		{
			AddItem(GetItemByName(name));
		}

		public void RemoveItem(string name)
		{
			RemoveItem(GetItemByName(name));
		}

		public bool HasItem(string name)
		{
			return HasItem(GetItemByName(name));
		}

		public void AddItem(ItemIndex name)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			AddItem(GetItemByIndex(name));
		}

		public void RemoveItem(ItemIndex name)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			RemoveItem(GetItemByIndex(name));
		}

		public bool HasItem(ItemIndex name)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			return HasItem(GetItemByIndex(name));
		}

		public static ItemWrapper? GetItemByName(string name)
		{
			if (!ItemsByDefName.TryGetValue(name, out var value) && !ItemsByEnglishName.TryGetValue(name, out value) && !ItemsByEnglishName.TryGetValue(name.Trim(), out value))
			{
				return null;
			}
			return value;
		}

		public static ItemWrapper? GetItemByIndex(ItemIndex index)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			if (!ItemsByIndex.TryGetValue(index, out var value))
			{
				return null;
			}
			return value;
		}
	}
	public class ItemTierSet : SortedSet<ItemTier>
	{
		public static string Serialize(ItemTierSet self)
		{
			return string.Join(", ", self.Select((ItemTier x) => ((Object)ItemTierCatalog.GetItemTierDef(x)).name));
		}

		public static ItemTierSet Deserialize(string src)
		{
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			ItemTierSet itemTierSet = new ItemTierSet();
			foreach (string item in from s in src.Split(',')
				select s.Trim())
			{
				if (Enum.TryParse<ItemTier>(item, out ItemTier result))
				{
					itemTierSet.Add(result);
					continue;
				}
				ItemTierDef val = ItemTierCatalog.FindTierDef(item);
				int result2;
				if ((Object)(object)val != (Object)null)
				{
					itemTierSet.Add(val.tier);
				}
				else if (int.TryParse(item, out result2))
				{
					itemTierSet.Add((ItemTier)result2);
				}
			}
			return itemTierSet;
		}

		public override string ToString()
		{
			return Serialize(this);
		}
	}
}
namespace AutoItemPickup.Hooks
{
	public abstract class AbstractHookHandler
	{
		internal HookManager hookManager;

		protected AutoItemPickup Plugin => hookManager.Plugin;

		protected Config ModConfig => Plugin.ModConfig;

		public void Init(HookManager _hookManager)
		{
			hookManager = _hookManager;
		}

		public abstract void RegisterHooks();

		public abstract void UnregisterHooks();
	}
	public class HookManager
	{
		public readonly Dictionary<Type, AbstractHookHandler> HookHandlers = new Dictionary<Type, AbstractHookHandler>();

		public readonly AutoItemPickup Plugin;

		public HookManager(AutoItemPickup pluginInstance)
		{
			Plugin = pluginInstance;
			RegisterHandler<CreatePickupDropletHandler>();
			RegisterHandler<PrinterTargetHandler>();
			RegisterHandler<ScrapperTargetHandler>();
			RegisterHandler<CommandTargetHandler>();
			RegisterHandler<CommandHandler>();
			RegisterHandler<ItemHandler>();
			RegisterHandler<PickupDropletOnCollisionOverrideHandler>();
		}

		public void RegisterHandler<T>() where T : AbstractHookHandler, new()
		{
			T val = new T();
			val.Init(this);
			HookHandlers[typeof(T)] = val;
		}

		public T GetHandler<T>() where T : AbstractHookHandler
		{
			return (T)HookHandlers[typeof(T)];
		}

		public void RegisterHooks()
		{
			foreach (AbstractHookHandler value in HookHandlers.Values)
			{
				value.RegisterHooks();
			}
		}

		public void UnregisterHooks()
		{
			foreach (AbstractHookHandler value in HookHandlers.Values)
			{
				value.UnregisterHooks();
			}
		}
	}
	public class CommandHandler : AbstractHookHandler
	{
		public override void RegisterHooks()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			PickupDropletController.CreateCommandCube += new hook_CreateCommandCube(On_PickupDropletController_CreateCommandCube);
			TeleporterInteraction.onTeleporterChargedGlobal += OnTeleporterCharged;
		}

		public override void UnregisterHooks()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			PickupDropletController.CreateCommandCube -= new hook_CreateCommandCube(On_PickupDropletController_CreateCommandCube);
			TeleporterInteraction.onTeleporterChargedGlobal -= OnTeleporterCharged;
		}

		private void On_PickupDropletController_CreateCommandCube(orig_CreateCommandCube orig, PickupDropletController self)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			if (base.ModConfig.ShouldDistributeCommand(((CreatePickupInfo)(ref self.createPickupInfo)).pickupIndex, Cause.Drop))
			{
				base.Plugin.GetDistributor(((Component)hookManager.GetHandler<PickupDropletOnCollisionOverrideHandler>().CurrentDroplet).gameObject, Cause.Drop)?.DistributeItem(ref self.createPickupInfo, (CharacterMaster target) => target.hasBody);
			}
			else if (Object.op_Implicit((Object)(object)TeleporterInteraction.instance) && TeleporterInteraction.instance.isCharged && base.ModConfig.ShouldDistributeCommand(((CreatePickupInfo)(ref self.createPickupInfo)).pickupIndex, Cause.Teleport))
			{
				self.createPickupInfo.position = GetTeleporterCommandTargetPosition();
			}
			orig.Invoke(self);
		}

		private Vector3 GetTeleporterCommandTargetPosition()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = ((Component)TeleporterInteraction.instance).transform.position;
			float num = Random.Range(0f, MathF.PI * 2f);
			float num2 = Random.Range(4, 15);
			return position + Mathf.Sin(num) * num2 * Vector3.forward + Mathf.Cos(num) * num2 * Vector3.right + Vector3.up * 10f;
		}

		private void TeleportToTeleporter(NetworkBehaviour obj)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			TeleportHelper.TeleportGameObject(((Component)obj).gameObject, GetTeleporterCommandTargetPosition());
		}

		private void OnTeleporterCharged(TeleporterInteraction obj)
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active || !base.ModConfig.teleportCommandOnTeleport.Value)
			{
				return;
			}
			List<PickupPickerController> instancesList = InstanceTracker.GetInstancesList<PickupPickerController>();
			PickupPickerController[] array = (PickupPickerController[])(object)new PickupPickerController[instancesList.Count];
			instancesList.CopyTo(array);
			Vector3 position = ((Component)TeleporterInteraction.instance).transform.position;
			PickupPickerController[] array2 = array;
			foreach (PickupPickerController val in array2)
			{
				PickupIndexNetworker component = ((Component)val).GetComponent<PickupIndexNetworker>();
				if (Object.op_Implicit((Object)(object)component))
				{
					Vector3 val2 = ((Component)val).transform.position - position;
					if (((Vector3)(ref val2)).sqrMagnitude > 100f && base.ModConfig.ShouldDistributeCommand(component.pickupIndex, Cause.Teleport))
					{
						TeleportToTeleporter((NetworkBehaviour)(object)val);
					}
				}
			}
		}
	}
	public class CommandTargetHandler : AbstractHookHandler
	{
		private static readonly FieldInfo Field_PickupPickerController_networkUIPromptController = typeof(PickupPickerController).GetField("networkUIPromptController", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		public override void RegisterHooks()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			PickupPickerController.CreatePickup_PickupIndex += new Manipulator(IL_PickupPickerController_CreatePickup);
		}

		public override void UnregisterHooks()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			PickupPickerController.CreatePickup_PickupIndex -= new Manipulator(IL_PickupPickerController_CreatePickup);
		}

		private void IL_PickupPickerController_CreatePickup(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: 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>[1]
			{
				(Instruction i) => ILPatternMatchingExt.MatchCallOrCallvirt<GenericPickupController>(i, "CreatePickup")
			});
			val.Emit(OpCodes.Dup);
			val.Emit(OpCodes.Ldarg_0);
			val.EmitDelegate<Action<GenericPickupController, PickupPickerController>>((Action<GenericPickupController, PickupPickerController>)delegate(GenericPickupController pickup, PickupPickerController self)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				PickupDef pickupDef = PickupCatalog.GetPickupDef(pickup.pickupIndex);
				if (pickupDef != null && !((Object)(object)ItemCatalog.GetItemDef(pickupDef.itemIndex) == (Object)null))
				{
					CharacterMaster currentParticipantMaster = ((NetworkUIPromptController)Field_PickupPickerController_networkUIPromptController.GetValue(self)).currentParticipantMaster;
					ItemDistributor distributor = new FixedTargetDistributor(base.Plugin, currentParticipantMaster);
					((Component)pickup).gameObject.AddComponent<OverrideDistributorBehaviour>().Distributor = distributor;
				}
			});
		}
	}
	public class CreatePickupDropletHandler : AbstractHookHandler
	{
		public ItemDistributor DistributorOverride;

		public override void RegisterHooks()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			PickupDropletController.CreatePickupDroplet_CreatePickupInfo_Vector3_Vector3 += new Manipulator(IL_PickupDropletController_CreatePickupDroplet);
		}

		public override void UnregisterHooks()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			PickupDropletController.CreatePickupDroplet_CreatePickupInfo_Vector3_Vector3 -= new Manipulator(IL_PickupDropletController_CreatePickupDroplet);
		}

		private void IL_PickupDropletController_CreatePickupDroplet(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0038: 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>[1]
			{
				(Instruction i) => ILPatternMatchingExt.MatchCall<Object>(i, "Instantiate")
			});
			val.Emit(OpCodes.Dup);
			val.EmitDelegate<Action<GameObject>>((Action<GameObject>)delegate(GameObject obj)
			{
				if (DistributorOverride != null)
				{
					obj.AddComponent<OverrideDistributorBehaviour>().Distributor = DistributorOverride;
				}
			});
		}
	}
	public class ItemHandler : AbstractHookHandler
	{
		public override void RegisterHooks()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			SceneExitController.Begin += new hook_Begin(On_SceneExitController_Begin);
			GenericPickupController.Start += new hook_Start(On_GenericPickupController_Start);
		}

		public override void UnregisterHooks()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			SceneExitController.Begin -= new hook_Begin(On_SceneExitController_Begin);
			GenericPickupController.Start -= new hook_Start(On_GenericPickupController_Start);
		}

		private void On_GenericPickupController_Start(orig_Start orig, GenericPickupController self)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			if (NetworkServer.active && base.ModConfig.distributeOnDrop.Value && base.ModConfig.ShouldDistribute(self.pickupIndex, Cause.Drop))
			{
				base.Plugin.DistributeItem(self, Cause.Drop);
			}
			orig.Invoke(self);
		}

		private void On_SceneExitController_Begin(orig_Begin orig, SceneExitController self)
		{
			if (NetworkServer.active && base.ModConfig.distributeOnTeleport.Value)
			{
				List<GenericPickupController> instancesList = InstanceTracker.GetInstancesList<GenericPickupController>();
				GenericPickupController[] array = (GenericPickupController[])(object)new GenericPickupController[instancesList.Count];
				instancesList.CopyTo(array);
				base.Plugin.DistributeItems(array.Where((GenericPickupController pickup) => base.ModConfig.ShouldDistribute(pickup.pickupIndex, Cause.Teleport)), Cause.Teleport);
			}
			orig.Invoke(self);
		}
	}
	public class PickupDropletOnCollisionOverrideHandler : AbstractHookHandler
	{
		public PickupDropletController CurrentDroplet;

		public override void RegisterHooks()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			PickupDropletController.OnCollisionEnter += new hook_OnCollisionEnter(On_PickupDropletController_OnCollisionEnter);
		}

		public override void UnregisterHooks()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			PickupDropletController.OnCollisionEnter -= new hook_OnCollisionEnter(On_PickupDropletController_OnCollisionEnter);
		}

		private void On_PickupDropletController_OnCollisionEnter(orig_OnCollisionEnter orig, PickupDropletController self, Collision collision)
		{
			CurrentDroplet = self;
			orig.Invoke(self, collision);
			CurrentDroplet = null;
		}
	}
	public class PrinterTargetHandler : AbstractHookHandler
	{
		public override void RegisterHooks()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			ShopTerminalBehavior.DropPickup += new hook_DropPickup(On_ShopTerminalBehavior_DropPickup);
		}

		public override void UnregisterHooks()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			ShopTerminalBehavior.DropPickup -= new hook_DropPickup(On_ShopTerminalBehavior_DropPickup);
		}

		private void On_ShopTerminalBehavior_DropPickup(orig_DropPickup orig, ShopTerminalBehavior self)
		{
			//IL_0022: 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_0039: Invalid comparison between Unknown and I4
			if (base.ModConfig.printerOverrideTarget.Value)
			{
				PurchaseInteraction component = ((Component)self).GetComponent<PurchaseInteraction>();
				if (Object.op_Implicit((Object)(object)component))
				{
					CostTypeDef costTypeDef = CostTypeCatalog.GetCostTypeDef(component.costType);
					if (costTypeDef == null || (int)costTypeDef.itemTier != 5)
					{
						Interactor lastActivator = component.lastActivator;
						CharacterBody val = (((Object)(object)lastActivator != (Object)null) ? ((Component)lastActivator).GetComponent<CharacterBody>() : null);
						CharacterMaster val2 = (((Object)(object)val != (Object)null) ? val.master : null);
						if (Object.op_Implicit((Object)(object)val2))
						{
							hookManager.GetHandler<CreatePickupDropletHandler>().DistributorOverride = new FixedTargetDistributor(base.Plugin, val2);
						}
					}
				}
			}
			orig.Invoke(self);
			hookManager.GetHandler<CreatePickupDropletHandler>().DistributorOverride = null;
		}
	}
	public class ScrapperTargetHandler : AbstractHookHandler
	{
		internal static FieldInfo Field_ScrapperBaseState_scrapperController = typeof(ScrapperBaseState).GetField("scrapperController", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		internal static FieldInfo Field_ScrapperController_interactor = typeof(ScrapperController).GetField("interactor", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		public override void RegisterHooks()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			ScrappingToIdle.OnEnter += new Manipulator(IL_ScrappingToIdle_OnEnter);
		}

		public override void UnregisterHooks()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			ScrappingToIdle.OnEnter -= new Manipulator(IL_ScrappingToIdle_OnEnter);
		}

		private void IL_ScrappingToIdle_OnEnter(ILContext il)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			val.GotoNext((MoveType)0, new Func<Instruction, bool>[1]
			{
				(Instruction i) => ILPatternMatchingExt.MatchCall<PickupDropletController>(i, "CreatePickupDroplet")
			});
			val.Emit(OpCodes.Ldarg_0);
			val.Emit(OpCodes.Ldfld, Field_ScrapperBaseState_scrapperController);
			val.Emit(OpCodes.Ldfld, Field_ScrapperController_interactor);
			val.EmitDelegate<Action<Interactor>>((Action<Interactor>)delegate(Interactor interactor)
			{
				if (base.ModConfig.scrapperOverrideTarget.Value)
				{
					CharacterMaster master = ((Component)interactor).GetComponent<CharacterBody>().master;
					if (Object.op_Implicit((Object)(object)master))
					{
						hookManager.GetHandler<CreatePickupDropletHandler>().DistributorOverride = new FixedTargetDistributor(base.Plugin, master);
					}
				}
			});
			int index = val.Index;
			val.Index = index + 1;
			val.EmitDelegate<Action>((Action)delegate
			{
				hookManager.GetHandler<CreatePickupDropletHandler>().DistributorOverride = null;
			});
		}
	}
}