Decompiled source of InventoryReforged v0.1.1

InventoryReforged.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("InventoryReforged")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+c22b6113e73f7d18e66f88d4ffc9bfcb6a2808b2")]
[assembly: AssemblyProduct("InventoryReforged")]
[assembly: AssemblyTitle("InventoryReforged")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace InventoryReforged
{
	public static class ArmourSlots
	{
		[HarmonyPatch(typeof(Player), "SetInventorySize")]
		private static class OneRowTaller
		{
			private static bool Prefix(Player __instance, int rows)
			{
				if (!On)
				{
					return true;
				}
				rows = Mathf.Clamp(rows, 0, 9);
				((Humanoid)__instance).GetInventory().SetHeight(rows + 1);
				__instance.AddUniqueKeyValue("invrows", rows.ToString());
				InventoryGui.instance.SetInventorySize(rows + 1);
				if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer)
				{
					s_sized = true;
				}
				((Humanoid)__instance).DropInvalidItems();
				return false;
			}
		}

		[HarmonyPatch(typeof(Player), "Awake")]
		private static class ResetOnNewPlayer
		{
			private static void Postfix()
			{
				s_sized = false;
			}
		}

		[HarmonyPatch(typeof(Player), "Update")]
		private static class ReconcileEachFrame
		{
			private static void Postfix(Player __instance)
			{
				if (On && (Object)(object)__instance == (Object)(object)Player.m_localPlayer)
				{
					Reconcile(__instance);
				}
			}
		}

		[HarmonyPatch(typeof(Inventory), "FindEmptySlot")]
		private static class SlotSearchMainGridOnly
		{
			private static void Prefix(Inventory __instance, ref int __state)
			{
				__state = -1;
				if (IsLocal(__instance))
				{
					__state = Height.Invoke(__instance);
					Height.Invoke(__instance) = __state - 1;
				}
			}

			private static void Postfix(Inventory __instance, int __state)
			{
				if (__state >= 0)
				{
					Height.Invoke(__instance) = __state;
				}
			}
		}

		[HarmonyPatch(typeof(Inventory), "GetEmptySlots")]
		private static class CountMainGrid
		{
			private static bool Prefix(Inventory __instance, ref int __result)
			{
				if (!IsLocal(__instance))
				{
					return true;
				}
				__result = MainFreeSlots(__instance);
				return false;
			}
		}

		[HarmonyPatch(typeof(Inventory), "HaveEmptySlot")]
		private static class HaveMainGridSlot
		{
			private static bool Prefix(Inventory __instance, ref bool __result)
			{
				if (!IsLocal(__instance))
				{
					return true;
				}
				__result = MainFreeSlots(__instance) > 0;
				return false;
			}
		}

		[HarmonyPatch(typeof(Inventory), "CanAddItem", new Type[]
		{
			typeof(ItemData),
			typeof(int)
		})]
		private static class CanAddToMainGrid
		{
			private static bool Prefix(Inventory __instance, ItemData item, int stack, ref bool __result)
			{
				if (!IsLocal(__instance))
				{
					return true;
				}
				if (stack <= 0)
				{
					stack = item.m_stack;
				}
				__result = __instance.FindFreeStackSpace(item.m_shared.m_name, (float)item.m_worldLevel) + MainFreeSlots(__instance) * item.m_shared.m_maxStackSize >= stack;
				return false;
			}
		}

		[HarmonyPatch(typeof(InventoryGrid), "DropItem")]
		private static class DropRules
		{
			private static bool Prefix(InventoryGrid __instance, ItemData item, Vector2i pos, ref bool __result)
			{
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				if (!IsLocal(__instance.GetInventory()) || pos.y != RowOf(__instance.GetInventory()))
				{
					return true;
				}
				if (pos.x >= Slots.Length || SlotFor(item) != pos.x)
				{
					__result = false;
					return false;
				}
				return true;
			}

			private static void Postfix(InventoryGrid __instance, Vector2i pos, bool __result)
			{
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0030: Unknown result type (might be due to invalid IL or missing references)
				if (__result && IsLocal(__instance.GetInventory()) && pos.y == RowOf(__instance.GetInventory()))
				{
					ItemData itemAt = __instance.GetInventory().GetItemAt(pos.x, pos.y);
					if (itemAt != null && !itemAt.m_equipped)
					{
						((Humanoid)Player.m_localPlayer).EquipItem(itemAt, true);
					}
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGrid), "UpdateGui")]
		private static class DressRow
		{
			private static void Postfix(InventoryGrid __instance)
			{
				//IL_0042: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
				//IL_011e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0133: Unknown result type (might be due to invalid IL or missing references)
				//IL_0148: Unknown result type (might be due to invalid IL or missing references)
				//IL_015c: Unknown result type (might be due to invalid IL or missing references)
				Inventory inventory = __instance.GetInventory();
				if (!IsLocal(inventory))
				{
					return;
				}
				int num = RowOf(inventory);
				foreach (InventoryElement item in Elements.Invoke(__instance))
				{
					if (!Object.op_Implicit((Object)(object)item) || item.Position.y != num)
					{
						continue;
					}
					if (item.Position.x >= Slots.Length)
					{
						if (((Component)item).gameObject.activeSelf)
						{
							((Component)item).gameObject.SetActive(false);
						}
						continue;
					}
					Transform obj = ((Component)item).transform.Find("binding");
					TMP_Text val = ((obj != null) ? ((Component)obj).GetComponent<TMP_Text>() : null);
					if (Object.op_Implicit((Object)(object)val) && !((Behaviour)val).enabled)
					{
						((Behaviour)val).enabled = true;
						val.text = Labels[item.Position.x];
						val.fontSize *= 0.8f;
						val.enableWordWrapping = false;
						val.overflowMode = (TextOverflowModes)0;
						val.alignment = (TextAlignmentOptions)257;
						RectTransform rectTransform = val.rectTransform;
						rectTransform.anchorMin = new Vector2(0f, 0f);
						rectTransform.anchorMax = new Vector2(1f, 1f);
						rectTransform.offsetMin = new Vector2(4f, 0f);
						rectTransform.offsetMax = new Vector2(0f, -2f);
						Tint(item);
					}
				}
			}
		}

		private static bool s_sized;

		private static readonly ItemType[] Slots;

		private static readonly string[] Labels;

		private static readonly Color SlotTint;

		private static readonly FieldRef<Inventory, int> Height;

		private static readonly FieldRef<InventoryGrid, List<InventoryElement>> Elements;

		private static readonly FieldRef<Inventory, List<ItemData>> Items;

		private static bool On => Plugin.ArmourSlots.Value;

		private static int RowOf(Inventory inv)
		{
			return inv.GetHeight() - 1;
		}

		private static bool IsLocal(Inventory inv)
		{
			if (On && s_sized && Object.op_Implicit((Object)(object)Player.m_localPlayer))
			{
				return ((Humanoid)Player.m_localPlayer).GetInventory() == inv;
			}
			return false;
		}

		public static int SlotFor(ItemData item)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Invalid comparison between I4 and Unknown
			for (int i = 0; i < Slots.Length; i++)
			{
				if ((int)Slots[i] == (int)item.m_shared.m_itemType)
				{
					return i;
				}
			}
			return -1;
		}

		private static bool InSlot(Inventory inv, ItemData item)
		{
			return item.m_gridPos.y == RowOf(inv);
		}

		private static void Relocate(Inventory inv, ItemData item, Vector2i pos)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			inv.RemoveItem(item);
			if (!inv.AddItem(item, pos))
			{
				inv.AddItem(item);
			}
		}

		private static void Reconcile(Player player)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: 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_005e: 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_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			Inventory inventory = ((Humanoid)player).GetInventory();
			int num = RowOf(inventory);
			Vector2i val = default(Vector2i);
			foreach (ItemData item in new List<ItemData>(inventory.GetAllItems()))
			{
				int num2 = SlotFor(item);
				if (item.m_equipped && num2 >= 0)
				{
					((Vector2i)(ref val))..ctor(num2, num);
					if (item.m_gridPos == val)
					{
						continue;
					}
					ItemData itemAt = inventory.GetItemAt(val.x, val.y);
					if (itemAt != null)
					{
						Vector2i gridPos = itemAt.m_gridPos;
						inventory.RemoveItem(itemAt);
						if (!inventory.AddItem(itemAt))
						{
							inventory.AddItem(itemAt, gridPos);
							continue;
						}
					}
					Relocate(inventory, item, val);
				}
				else if (InSlot(inventory, item) && !item.m_equipped)
				{
					Vector2i gridPos2 = item.m_gridPos;
					inventory.RemoveItem(item);
					if (!inventory.AddItem(item))
					{
						inventory.AddItem(item, gridPos2);
					}
				}
			}
		}

		private static int MainFreeSlots(Inventory inv)
		{
			int num = RowOf(inv);
			int num2 = 0;
			foreach (ItemData item in Items.Invoke(inv))
			{
				if (item.m_gridPos.y < num)
				{
					num2++;
				}
			}
			return inv.GetWidth() * num - num2;
		}

		private static void Tint(InventoryElement el)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			Image component = ((Component)el).GetComponent<Image>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				Transform val = ((Component)el).transform.Find("bkg") ?? ((Component)el).transform.Find("background");
				if (Object.op_Implicit((Object)(object)val))
				{
					component = ((Component)val).GetComponent<Image>();
				}
			}
			if (Object.op_Implicit((Object)(object)component))
			{
				((Graphic)component).color = SlotTint;
			}
		}

		static ArmourSlots()
		{
			//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)
			ItemType[] array = new ItemType[6];
			RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
			Slots = (ItemType[])(object)array;
			Labels = new string[6] { "Head", "Chest", "Legs", "Cape", "Util", "Trinket" };
			SlotTint = new Color(0.85f, 0.7f, 0.45f, 1f);
			Height = AccessTools.FieldRefAccess<Inventory, int>("m_height");
			Elements = AccessTools.FieldRefAccess<InventoryGrid, List<InventoryElement>>("m_elements");
			Items = AccessTools.FieldRefAccess<Inventory, List<ItemData>>("m_inventory");
		}
	}
	public static class CraftFromChests
	{
		[HarmonyPatch(typeof(Inventory), "CountItems")]
		private static class PoolCount
		{
			private static void Postfix(Inventory __instance, string name, int quality, bool matchWorldLevel, ref int __result)
			{
				if (Active && IsLocal(__instance))
				{
					__result += ChestCount(name, quality, matchWorldLevel);
				}
			}
		}

		[HarmonyPatch(typeof(Inventory), "CountItemsByName")]
		private static class PoolCountByName
		{
			private static void Postfix(Inventory __instance, string[] names, int quality, bool matchWorldLevel, ref int __result)
			{
				if (Active && IsLocal(__instance))
				{
					foreach (string name in names)
					{
						__result += ChestCount(name, quality, matchWorldLevel);
					}
				}
			}
		}

		[HarmonyPatch(typeof(Inventory), "HaveItem", new Type[]
		{
			typeof(string),
			typeof(bool)
		})]
		private static class PoolHave
		{
			private static void Postfix(Inventory __instance, string name, bool matchWorldLevel, ref bool __result)
			{
				if (!__result && Active && IsLocal(__instance))
				{
					__result = ChestCount(name, -1, matchWorldLevel) > 0;
				}
			}
		}

		[HarmonyPatch(typeof(Inventory), "RemoveItem", new Type[]
		{
			typeof(string),
			typeof(int),
			typeof(int),
			typeof(bool)
		})]
		private static class PoolRemove
		{
			private static bool Prefix(Inventory __instance, string name, int amount, int itemQuality, bool worldLevelBased)
			{
				if (!Active || !IsLocal(__instance))
				{
					return true;
				}
				s_bypass = true;
				try
				{
					int num = Mathf.Min(__instance.CountItems(name, itemQuality, worldLevelBased), amount);
					if (num > 0)
					{
						__instance.RemoveItem(name, num, itemQuality, worldLevelBased);
					}
					if (amount - num > 0)
					{
						ChestRemove(name, amount - num, itemQuality, worldLevelBased);
					}
				}
				finally
				{
					s_bypass = false;
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(Player), "HaveRequirements", new Type[]
		{
			typeof(Recipe),
			typeof(bool),
			typeof(int),
			typeof(int)
		})]
		private static class Scope1
		{
			private static void Prefix()
			{
				Enter();
			}

			private static void Postfix()
			{
				Exit();
			}
		}

		[HarmonyPatch(typeof(Player), "HaveRequirements", new Type[]
		{
			typeof(Piece),
			typeof(RequirementMode)
		})]
		private static class Scope2
		{
			private static void Prefix()
			{
				Enter();
			}

			private static void Postfix()
			{
				Exit();
			}
		}

		[HarmonyPatch(typeof(Player), "GetFirstRequiredItem")]
		private static class Scope3
		{
			private static void Prefix()
			{
				Enter();
			}

			private static void Postfix()
			{
				Exit();
			}
		}

		[HarmonyPatch(typeof(Player), "ConsumeResources")]
		private static class Scope4
		{
			private static void Prefix()
			{
				Enter();
			}

			private static void Postfix()
			{
				Exit();
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "SetupRequirement")]
		private static class Scope5
		{
			private static void Prefix()
			{
				Enter();
			}

			private static void Postfix()
			{
				Exit();
			}
		}

		[HarmonyPatch(typeof(Smelter), "OnAddFuel")]
		private static class Scope6
		{
			private static void Prefix()
			{
				Enter();
			}

			private static void Postfix()
			{
				Exit();
			}
		}

		[HarmonyPatch(typeof(Smelter), "CanUseItems")]
		private static class Scope7
		{
			private static void Prefix()
			{
				Enter();
			}

			private static void Postfix()
			{
				Exit();
			}
		}

		[HarmonyPatch(typeof(CookingStation), "OnAddFuelSwitch")]
		private static class Scope8
		{
			private static void Prefix()
			{
				Enter();
			}

			private static void Postfix()
			{
				Exit();
			}
		}

		[HarmonyPatch(typeof(CookingStation), "CanUseItems")]
		private static class Scope9
		{
			private static void Prefix()
			{
				Enter();
			}

			private static void Postfix()
			{
				Exit();
			}
		}

		[HarmonyPatch(typeof(Fireplace), "Interact")]
		private static class Scope10
		{
			private static void Prefix()
			{
				Enter();
			}

			private static void Postfix()
			{
				Exit();
			}
		}

		[HarmonyPatch(typeof(Fireplace), "UseItem")]
		private static class Scope11
		{
			private static void Prefix()
			{
				Enter();
			}

			private static void Postfix()
			{
				Exit();
			}
		}

		[HarmonyPatch(typeof(Fireplace), "CanUseItems")]
		private static class Scope12
		{
			private static void Prefix()
			{
				Enter();
			}

			private static void Postfix()
			{
				Exit();
			}
		}

		[HarmonyPatch(typeof(Smelter), "OnAddOre")]
		private static class PullOre
		{
			private static void Prefix(Smelter __instance, Humanoid user, ItemData item)
			{
				if (item == null)
				{
					PullCookable(user, Froms(__instance.m_conversion));
				}
			}
		}

		[HarmonyPatch(typeof(CookingStation), "Interact")]
		private static class PullFood
		{
			private static void Prefix(CookingStation __instance, Humanoid user, bool hold)
			{
				if (!hold)
				{
					PullCookable(user, Froms(__instance.m_conversion));
				}
			}
		}

		[HarmonyPatch(typeof(Fermenter), "Interact")]
		private static class PullBrew
		{
			private static void Prefix(Fermenter __instance, Humanoid user, bool hold)
			{
				if (!hold)
				{
					PullCookable(user, Froms(__instance.m_conversion));
				}
			}
		}

		private static int s_depth;

		private static bool s_bypass;

		private static float s_cacheTime = -1f;

		private static List<Container> s_cache = new List<Container>();

		private static bool Active
		{
			get
			{
				if (Plugin.CraftFromChests.Value && s_depth > 0)
				{
					return !s_bypass;
				}
				return false;
			}
		}

		private static bool IsLocal(Inventory inv)
		{
			if (Object.op_Implicit((Object)(object)Player.m_localPlayer))
			{
				return ((Humanoid)Player.m_localPlayer).GetInventory() == inv;
			}
			return false;
		}

		public static List<Container> Nearby()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if (!Object.op_Implicit((Object)(object)localPlayer))
			{
				return new List<Container>();
			}
			if (Time.time - s_cacheTime > 0.5f)
			{
				s_cacheTime = Time.time;
				s_cache = Stash.FindNearby(((Component)localPlayer).transform.position, Plugin.CraftRange.Value);
				s_cache.RemoveAll(delegate(Container c)
				{
					ZNetView component = ((Component)c).GetComponent<ZNetView>();
					return !component.IsOwner() && component.GetZDO().GetInt(ZDOVars.s_inUse, 0) == 1;
				});
			}
			return s_cache;
		}

		private static int ChestCount(string name, int quality, bool wl)
		{
			int num = 0;
			foreach (Container item in Nearby())
			{
				num += item.GetInventory().CountItems(name, quality, wl);
			}
			return num;
		}

		private static void ChestRemove(string name, int amount, int quality, bool wl)
		{
			foreach (Container item in Nearby())
			{
				if (amount <= 0)
				{
					break;
				}
				Inventory inventory = item.GetInventory();
				int num = inventory.CountItems(name, quality, wl);
				if (num > 0)
				{
					int num2 = Mathf.Min(num, amount);
					((Component)item).GetComponent<ZNetView>().ClaimOwnership();
					inventory.RemoveItem(name, num2, quality, wl);
					amount -= num2;
				}
			}
		}

		public static ItemData PullOne(Humanoid user, string name)
		{
			Inventory inventory = user.GetInventory();
			foreach (Container item2 in Nearby())
			{
				Inventory inventory2 = item2.GetInventory();
				ItemData item = inventory2.GetItem(name, -1, false);
				if (item != null)
				{
					if (!inventory.CanAddItem(item, 1))
					{
						((Character)user).Message((MessageType)2, "$msg_noroom", 0, (Sprite)null, false);
						return null;
					}
					((Component)item2).GetComponent<ZNetView>().ClaimOwnership();
					ItemData val = item.Clone();
					val.m_stack = 1;
					inventory2.RemoveItem(item, 1);
					if (inventory.AddItem(val))
					{
						return inventory.GetItem(name, -1, false);
					}
					inventory2.AddItem(val);
					return null;
				}
			}
			return null;
		}

		private static ItemData FirstOwned(Humanoid user, IEnumerable<ItemDrop> froms)
		{
			foreach (ItemDrop from in froms)
			{
				if (Object.op_Implicit((Object)(object)from))
				{
					ItemData item = user.GetInventory().GetItem(from.m_itemData.m_shared.m_name, -1, false);
					if (item != null)
					{
						return item;
					}
				}
			}
			return null;
		}

		private static void PullCookable(Humanoid user, IEnumerable<ItemDrop> froms)
		{
			if (!Plugin.CraftFromChests.Value || !Object.op_Implicit((Object)(object)user) || (Object)(object)user != (Object)(object)Player.m_localPlayer || FirstOwned(user, froms) != null)
			{
				return;
			}
			foreach (ItemDrop from in froms)
			{
				if (Object.op_Implicit((Object)(object)from) && PullOne(user, from.m_itemData.m_shared.m_name) != null)
				{
					break;
				}
			}
		}

		private static void Enter()
		{
			s_depth++;
		}

		private static void Exit()
		{
			s_depth--;
		}

		private static IEnumerable<ItemDrop> Froms(List<ItemConversion> l)
		{
			foreach (ItemConversion item in l)
			{
				yield return item.m_from;
			}
		}

		private static IEnumerable<ItemDrop> Froms(List<ItemConversion> l)
		{
			foreach (ItemConversion item in l)
			{
				yield return item.m_from;
			}
		}

		private static IEnumerable<ItemDrop> Froms(List<ItemConversion> l)
		{
			foreach (ItemConversion item in l)
			{
				yield return item.m_from;
			}
		}
	}
	public static class Favourites
	{
		[HarmonyPatch(typeof(InventoryGui), "OnSelectedItem")]
		private static class ToggleOnAltClick
		{
			private static readonly FieldRef<InventoryGui, GameObject> DragGo = AccessTools.FieldRefAccess<InventoryGui, GameObject>("m_dragGo");

			private static bool Prefix(InventoryGui __instance, InventoryGrid grid, ItemData item, Modifier mod)
			{
				//IL_0003: Unknown result type (might be due to invalid IL or missing references)
				if (item == null || (int)mod != 0 || !AltHeld() || Object.op_Implicit((Object)(object)DragGo.Invoke(__instance)))
				{
					return true;
				}
				if (!Object.op_Implicit((Object)(object)Player.m_localPlayer) || grid.GetInventory() != ((Humanoid)Player.m_localPlayer).GetInventory())
				{
					return true;
				}
				Toggle(item);
				return false;
			}
		}

		[HarmonyPatch(typeof(InventoryGrid), "UpdateGui")]
		private static class ToggleOnKey
		{
			private static void Postfix(InventoryGrid __instance, Player player)
			{
				//IL_000d: 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_0057: 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)
				if (!Object.op_Implicit((Object)(object)player))
				{
					return;
				}
				KeyboardShortcut value = Plugin.FavouriteKey.Value;
				if (!((KeyboardShortcut)(ref value)).IsDown() || __instance.GetInventory() != ((Humanoid)player).GetInventory())
				{
					return;
				}
				InventoryElement value2 = Traverse.Create((object)__instance).Method("GetHoveredElement", Array.Empty<object>()).GetValue<InventoryElement>();
				if (Object.op_Implicit((Object)(object)value2))
				{
					ItemData itemAt = __instance.GetInventory().GetItemAt(value2.Position.x, value2.Position.y);
					if (itemAt != null)
					{
						Toggle(itemAt);
					}
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGrid), "UpdateGui")]
		private static class DrawStar
		{
			private static readonly FieldRef<InventoryGrid, List<InventoryElement>> Elements = AccessTools.FieldRefAccess<InventoryGrid, List<InventoryElement>>("m_elements");

			private static readonly Dictionary<InventoryElement, TMP_Text> s_stars = new Dictionary<InventoryElement, TMP_Text>();

			private static void Postfix(InventoryGrid __instance)
			{
				//IL_0031: 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)
				Inventory inventory = __instance.GetInventory();
				if (inventory == null)
				{
					return;
				}
				foreach (InventoryElement item in Elements.Invoke(__instance))
				{
					if (!Object.op_Implicit((Object)(object)item))
					{
						continue;
					}
					ItemData itemAt = inventory.GetItemAt(item.Position.x, item.Position.y);
					bool flag = itemAt != null && Is(itemAt);
					if (!s_stars.TryGetValue(item, out var value) || !Object.op_Implicit((Object)(object)value))
					{
						if (!flag)
						{
							continue;
						}
						value = MakeStar(item);
						if (!Object.op_Implicit((Object)(object)value))
						{
							continue;
						}
						s_stars[item] = value;
					}
					((Behaviour)value).enabled = flag;
				}
			}

			private static TMP_Text MakeStar(InventoryElement el)
			{
				//IL_0081: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
				Transform val = ((Component)el).transform.Find("binding");
				if (!Object.op_Implicit((Object)(object)val))
				{
					return null;
				}
				GameObject obj = Object.Instantiate<GameObject>(((Component)val).gameObject, ((Component)el).transform);
				((Object)obj).name = "IR_star";
				TMP_Text component = obj.GetComponent<TMP_Text>();
				component.text = ((Object.op_Implicit((Object)(object)component.font) && component.font.HasCharacter('★', false, false)) ? "★" : "*");
				((Graphic)component).color = new Color(1f, 0.85f, 0.2f);
				component.alignment = (TextAlignmentOptions)260;
				RectTransform component2 = obj.GetComponent<RectTransform>();
				component2.anchorMin = new Vector2(0f, 0f);
				component2.anchorMax = new Vector2(1f, 1f);
				component2.offsetMin = new Vector2(2f, 2f);
				component2.offsetMax = new Vector2(-4f, -2f);
				return component;
			}
		}

		private const string Key = "IR_fav";

		public static bool Is(ItemData item)
		{
			if (item?.m_customData != null)
			{
				return item.m_customData.ContainsKey("IR_fav");
			}
			return false;
		}

		public static void Toggle(ItemData item)
		{
			if (Is(item))
			{
				item.m_customData.Remove("IR_fav");
			}
			else
			{
				item.m_customData["IR_fav"] = "1";
			}
		}

		private static bool AltHeld()
		{
			if (!ZInput.GetKey((KeyCode)308, true))
			{
				return ZInput.GetKey((KeyCode)307, true);
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "Show", new Type[]
	{
		typeof(Container),
		typeof(int)
	})]
	internal static class LayoutDump
	{
		private static bool s_done;

		private static void Postfix(InventoryGui __instance)
		{
			if (!s_done && Plugin.DebugLayout.Value)
			{
				s_done = true;
				StringBuilder stringBuilder = new StringBuilder("[IR layout]\n");
				Dump((Transform)(object)__instance.m_player, 0, stringBuilder);
				Dump((Transform)(object)__instance.m_container, 0, stringBuilder);
				Debug.Log((object)stringBuilder.ToString());
			}
		}

		private static void Dump(Transform t, int depth, StringBuilder sb)
		{
			//IL_003d: 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_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			if (depth > 3)
			{
				return;
			}
			RectTransform val = (RectTransform)(object)((t is RectTransform) ? t : null);
			sb.Append(' ', depth * 2).Append(((Object)t).name);
			if (Object.op_Implicit((Object)(object)val))
			{
				object[] obj = new object[7] { val.anchoredPosition, val.sizeDelta, null, null, null, null, null };
				Rect rect = val.rect;
				obj[2] = ((Rect)(ref rect)).size;
				obj[3] = val.anchorMin;
				obj[4] = val.anchorMax;
				obj[5] = val.pivot;
				obj[6] = ((Component)t).gameObject.activeSelf;
				sb.Append(string.Format("  pos={0} size={1} rect={2} aMin={3} aMax={4} pivot={5} active={6}", obj));
			}
			Component[] components = ((Component)t).GetComponents<Component>();
			foreach (Component val2 in components)
			{
				if (Object.op_Implicit((Object)(object)val2) && !(val2 is Transform))
				{
					sb.Append(" [").Append(((object)val2).GetType().Name).Append(']');
				}
			}
			sb.Append('\n');
			for (int j = 0; j < t.childCount; j++)
			{
				Dump(t.GetChild(j), depth + 1, sb);
			}
		}
	}
	[BepInPlugin("games.loxley.inventoryreforged", "InventoryReforged", "0.1.1")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGUID = "games.loxley.inventoryreforged";

		public const string PluginName = "InventoryReforged";

		public const string PluginVersion = "0.1.1";

		public static ConfigEntry<KeyboardShortcut> StashKey;

		public static ConfigEntry<float> StashRange;

		public static ConfigEntry<bool> StashKeepHotbar;

		public static ConfigEntry<bool> StashPlayerBuiltOnly;

		public static ConfigEntry<KeyboardShortcut> FavouriteKey;

		public static ConfigEntry<bool> StashButton;

		public static ConfigEntry<float> StashButtonX;

		public static ConfigEntry<float> StashButtonY;

		public static ConfigEntry<float> StashButtonSize;

		public static ConfigEntry<bool> SharedChests;

		public static ConfigEntry<bool> ArmourSlots;

		public static ConfigEntry<bool> CraftFromChests;

		public static ConfigEntry<float> CraftRange;

		public static ConfigEntry<bool> DebugLayout;

		private void Awake()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			StashKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Stash", "Key", new KeyboardShortcut((KeyCode)112, Array.Empty<KeyCode>()), "Stash everything into nearby chests.");
			StashRange = ((BaseUnityPlugin)this).Config.Bind<float>("Stash", "Range", 10f, "How far (m) to look for chests.");
			StashKeepHotbar = ((BaseUnityPlugin)this).Config.Bind<bool>("Stash", "KeepHotbar", true, "Leave items on the hotbar alone.");
			StashPlayerBuiltOnly = ((BaseUnityPlugin)this).Config.Bind<bool>("Stash", "PlayerBuiltOnly", true, "Ignore chests you didn't build (dungeon chests, etc).");
			FavouriteKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Stash", "FavouriteKey", new KeyboardShortcut((KeyCode)102, Array.Empty<KeyCode>()), "Press while hovering an item to favourite it (Alt+click also works where the desktop lets it through).");
			StashButton = ((BaseUnityPlugin)this).Config.Bind<bool>("Stash", "ShowButton", true, "Add a Stash button to the inventory screen.");
			StashButtonX = ((BaseUnityPlugin)this).Config.Bind<float>("Stash", "ButtonX", 33f, "Button centre, relative to the bottom-right corner of the inventory panel.");
			StashButtonY = ((BaseUnityPlugin)this).Config.Bind<float>("Stash", "ButtonY", 8f, "Button centre, relative to the bottom-right corner of the inventory panel.");
			StashButtonSize = ((BaseUnityPlugin)this).Config.Bind<float>("Stash", "ButtonSize", 38f, "Button width and height (px).");
			SharedChests = ((BaseUnityPlugin)this).Config.Bind<bool>("SharedChests", "Enabled", true, "Let more than one player use a chest at the same time. Everyone needs the mod.");
			ArmourSlots = ((BaseUnityPlugin)this).Config.Bind<bool>("ArmourSlots", "Enabled", true, "Extra row with head / chest / legs / cape / utility / trinket slots.");
			CraftFromChests = ((BaseUnityPlugin)this).Config.Bind<bool>("CraftFromChests", "Enabled", true, "Crafting, building and stations (smelter, kiln, fire, cooking, fermenter) use items from nearby chests.");
			CraftRange = ((BaseUnityPlugin)this).Config.Bind<float>("CraftFromChests", "Range", 15f, "How far (m) to look for chests when crafting.");
			DebugLayout = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "DumpLayout", false, "Log the inventory panel hierarchy once when the inventory opens.");
			new Harmony("games.loxley.inventoryreforged").PatchAll();
		}

		private void Update()
		{
			//IL_0011: 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)
			if (!Object.op_Implicit((Object)(object)Player.m_localPlayer))
			{
				return;
			}
			KeyboardShortcut value = StashKey.Value;
			if (((KeyboardShortcut)(ref value)).IsDown() && !Console.IsVisible())
			{
				Chat instance = Chat.instance;
				if ((instance == null || !instance.HasFocus()) && !TextInput.IsVisible() && !Menu.IsVisible())
				{
					Stash.Run(Player.m_localPlayer);
				}
			}
		}
	}
	public static class SharedChest
	{
		private class PendingPut
		{
			public ItemData Item;

			public Inventory From;

			public int Amount;

			public Vector2i Origin;

			public float Sent;
		}

		private class PendingTake
		{
			public Container Chest;

			public Vector2i Slot;

			public Inventory To;

			public int X;

			public int Y;

			public bool Drop;

			public float Sent;
		}

		[HarmonyPatch(typeof(Container), "Awake")]
		private static class RegisterRpcs
		{
			private static void Postfix(Container __instance)
			{
				ZNetView val = View(__instance);
				if (Object.op_Implicit((Object)(object)val) && val.GetZDO() != null)
				{
					Container c = __instance;
					val.Register<ZPackage>("IR_Put", (Action<long, ZPackage>)delegate(long s, ZPackage p)
					{
						OnPut(c, s, p);
					});
					val.Register<ZPackage>("IR_PutResp", (Action<long, ZPackage>)delegate(long s, ZPackage p)
					{
						OnPutResp(c, s, p);
					});
					val.Register<ZPackage>("IR_Take", (Action<long, ZPackage>)delegate(long s, ZPackage p)
					{
						OnTake(c, s, p);
					});
					val.Register<ZPackage>("IR_TakeResp", (Action<long, ZPackage>)delegate(long s, ZPackage p)
					{
						OnTakeResp(c, s, p);
					});
					val.Register<ZPackage>("IR_Move", (Action<long, ZPackage>)delegate(long s, ZPackage p)
					{
						OnMove(c, s, p);
					});
					val.Register<ZPackage>("IR_Eat", (Action<long, ZPackage>)delegate(long s, ZPackage p)
					{
						OnEat(c, s, p);
					});
					val.Register<ZPackage>("IR_EatResp", (Action<long, ZPackage>)delegate(long s, ZPackage p)
					{
						OnEatResp(c, s, p);
					});
				}
			}
		}

		[HarmonyPatch(typeof(Container), "RPC_RequestOpen")]
		private static class GrantGuestOpen
		{
			private static bool Prefix(Container __instance, long uid, long playerID)
			{
				return GrantWithoutOwnership(__instance, uid, playerID, "RPC_OpenResponse");
			}
		}

		[HarmonyPatch(typeof(Container), "RPC_RequestStack")]
		private static class GrantGuestStack
		{
			private static bool Prefix(Container __instance, long uid, long playerID)
			{
				return GrantWithoutOwnership(__instance, uid, playerID, "RPC_StackResponse");
			}
		}

		[HarmonyPatch(typeof(Container), "RPC_StackResponse")]
		private static class RouteStackGrant
		{
			[HarmonyPriority(200)]
			private static bool Prefix(Container __instance, bool granted)
			{
				ZNetView val = View(__instance);
				if (!granted || !Object.op_Implicit((Object)(object)val) || !val.IsValid() || val.IsOwner() || !Object.op_Implicit((Object)(object)Player.m_localPlayer))
				{
					return true;
				}
				PutMatching(__instance, ((Humanoid)Player.m_localPlayer).GetInventory());
				return false;
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "UpdateContainer")]
		private static class KeepGuestPanelOpen
		{
			private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> il)
			{
				MethodInfo target = AccessTools.Method(typeof(Container), "IsOwner", (Type[])null, (Type[])null);
				MethodInfo repl = AccessTools.Method(typeof(SharedChest), "OwnerOrGuest", (Type[])null, (Type[])null);
				foreach (CodeInstruction item in il)
				{
					yield return CodeInstructionExtensions.Calls(item, target) ? CodeInstructionExtensions.WithBlocks(CodeInstructionExtensions.WithLabels(new CodeInstruction(OpCodes.Call, (object)repl), (IEnumerable<Label>)item.labels), (IEnumerable<ExceptionBlock>)item.blocks) : item;
				}
			}

			private static void Prefix()
			{
				ExpireLocks();
				Container current = Current;
				if (Object.op_Implicit((Object)(object)current) && IsGuestOf(current))
				{
					Traverse.Create((object)current).Method("Load", Array.Empty<object>()).GetValue<bool>();
				}
			}
		}

		[HarmonyPatch(typeof(Inventory), "Load", new Type[] { typeof(ZPackage) })]
		private static class KeepDragAcrossReload
		{
			private static void Postfix(Inventory __instance)
			{
				InventoryGui instance = InventoryGui.instance;
				if (!Object.op_Implicit((Object)(object)instance) || DragItem.Invoke(instance) == null || DragInventory.Invoke(instance) != __instance)
				{
					return;
				}
				Container current = Current;
				if (Object.op_Implicit((Object)(object)current) && current.GetInventory() == __instance)
				{
					ItemData val = DragItem.Invoke(instance);
					ItemData itemAt = __instance.GetItemAt(val.m_gridPos.x, val.m_gridPos.y);
					if (itemAt == null || NameOf(itemAt) != NameOf(val))
					{
						SetupDrag(null, null, 1);
					}
					else
					{
						SetupDrag(itemAt, __instance, Mathf.Min(itemAt.m_stack, DragAmount.Invoke(instance)));
					}
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGrid), "DropItem")]
		private static class RouteDrops
		{
			private static bool Prefix(InventoryGrid __instance, Inventory fromInventory, ItemData item, int amount, Vector2i pos, ref bool __result)
			{
				//IL_0046: 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_006d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0074: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
				//IL_008c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0093: Unknown result type (might be due to invalid IL or missing references)
				//IL_010a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0111: Unknown result type (might be due to invalid IL or missing references)
				Inventory inventory = __instance.GetInventory();
				Container container;
				bool flag = IsGuest(inventory, out container);
				Container container2;
				bool flag2 = IsGuest(fromInventory, out container2);
				if (!flag && !flag2)
				{
					if (!IsLocked(item))
					{
						return true;
					}
					return Refuse(ref __result);
				}
				__result = true;
				if (IsLocked(item) || (flag2 && s_lockedChestSlots.Contains(item.m_gridPos)) || (flag && s_lockedChestSlots.Contains(pos)))
				{
					return false;
				}
				if (flag && flag2)
				{
					Move(container, item, amount, pos.x, pos.y);
				}
				else if (flag)
				{
					Put(container, fromInventory, item, amount, pos.x, pos.y);
				}
				else
				{
					ItemData itemAt = inventory.GetItemAt(pos.x, pos.y);
					if (itemAt != null && !CanStack(itemAt, item) && !IsLocked(itemAt) && !((Humanoid)Player.m_localPlayer).IsItemEquiped(itemAt))
					{
						Put(container2, inventory, itemAt, itemAt.m_stack, item.m_gridPos.x, item.m_gridPos.y);
					}
					else
					{
						Take(container2, item, amount, inventory, pos.x, pos.y);
					}
				}
				return false;
			}

			private static bool Refuse(ref bool result)
			{
				result = false;
				return false;
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "OnSelectedItem")]
		private static class IgnoreLockedClicks
		{
			[HarmonyPriority(600)]
			private static bool Prefix(InventoryGrid grid, ItemData item, Vector2i pos)
			{
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				if (IsLocked(item))
				{
					return false;
				}
				if (IsLockedChestSlot(grid.GetInventory(), pos))
				{
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "OnRightClickItem")]
		private static class RouteEat
		{
			private static bool Prefix(InventoryGrid grid, ItemData item)
			{
				if (item == null || !IsGuest(grid.GetInventory(), out var container))
				{
					return true;
				}
				if (Object.op_Implicit((Object)(object)Player.m_localPlayer) && ((Humanoid)Player.m_localPlayer).CanConsumeItem(item, false))
				{
					Eat(container, item);
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(Inventory), "MoveItemToThis", new Type[]
		{
			typeof(Inventory),
			typeof(ItemData)
		})]
		private static class RouteQuickMove
		{
			private static bool Prefix(Inventory __instance, Inventory fromInventory, ItemData item)
			{
				if (IsGuest(__instance, out var container))
				{
					Put(container, fromInventory, item, item.m_stack, -1, -1);
					return false;
				}
				if (IsGuest(fromInventory, out var container2))
				{
					if (__instance.CanAddItem(item, -1))
					{
						Take(container2, item, item.m_stack, __instance, -1, -1);
					}
					return false;
				}
				return !IsLocked(item);
			}
		}

		[HarmonyPatch(typeof(Inventory), "MoveAll")]
		private static class RouteTakeAll
		{
			private static bool Prefix(Inventory __instance, Inventory fromInventory)
			{
				if (!IsGuest(fromInventory, out var container))
				{
					return true;
				}
				foreach (ItemData item in new List<ItemData>(fromInventory.GetAllItems()))
				{
					if (__instance.CanAddItem(item, -1))
					{
						Take(container, item, item.m_stack, __instance, -1, -1);
					}
				}
				return false;
			}
		}

		[HarmonyPatch(typeof(Inventory), "StackAll")]
		private static class RoutePlaceStacks
		{
			[HarmonyPriority(600)]
			private static bool Prefix(Inventory __instance, Inventory fromInventory, ref int __result)
			{
				if (!IsGuest(__instance, out var container))
				{
					return true;
				}
				PutMatching(container, fromInventory);
				__result = 0;
				return false;
			}
		}

		[HarmonyPatch(typeof(Container), "StackAll")]
		private static class RouteHoldToStack
		{
			private static bool Prefix(Container __instance)
			{
				if (!IsGuestOf(__instance) || !Object.op_Implicit((Object)(object)Player.m_localPlayer))
				{
					return true;
				}
				PutMatching(__instance, ((Humanoid)Player.m_localPlayer).GetInventory());
				return false;
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "OnDropOutside")]
		private static class RouteDropOutside
		{
			private static bool Prefix(InventoryGui __instance)
			{
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				if (!Object.op_Implicit((Object)(object)DragGo.Invoke(__instance)) || !IsGuest(DragInventory.Invoke(__instance), out var container))
				{
					return true;
				}
				ItemData val = DragItem.Invoke(__instance);
				if (val != null && !s_lockedChestSlots.Contains(val.m_gridPos))
				{
					Take(container, val, DragAmount.Invoke(__instance), null, -1, -1, drop: true);
				}
				SetupDrag(null, null, 1);
				return false;
			}
		}

		[HarmonyPatch(typeof(Humanoid), "DropItem")]
		private static class NoDropWhileLocked
		{
			private static bool Prefix(Inventory inventory, ItemData item, ref bool __result)
			{
				if (IsGuest(inventory, out var _) || IsLocked(item))
				{
					__result = false;
					return false;
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(Humanoid), "UseItem")]
		private static class NoUseWhileLocked
		{
			private static bool Prefix(ItemData item)
			{
				return !IsLocked(item);
			}
		}

		private const string RpcPut = "IR_Put";

		private const string RpcPutResp = "IR_PutResp";

		private const string RpcTake = "IR_Take";

		private const string RpcTakeResp = "IR_TakeResp";

		private const string RpcMove = "IR_Move";

		private const string RpcEat = "IR_Eat";

		private const string RpcEatResp = "IR_EatResp";

		private const float Timeout = 5f;

		private static readonly FieldRef<InventoryGui, Container> CurrentContainer = AccessTools.FieldRefAccess<InventoryGui, Container>("m_currentContainer");

		private static readonly FieldRef<InventoryGui, ItemData> DragItem = AccessTools.FieldRefAccess<InventoryGui, ItemData>("m_dragItem");

		private static readonly FieldRef<InventoryGui, Inventory> DragInventory = AccessTools.FieldRefAccess<InventoryGui, Inventory>("m_dragInventory");

		private static readonly FieldRef<InventoryGui, int> DragAmount = AccessTools.FieldRefAccess<InventoryGui, int>("m_dragAmount");

		private static readonly FieldRef<InventoryGui, GameObject> DragGo = AccessTools.FieldRefAccess<InventoryGui, GameObject>("m_dragGo");

		private static readonly FieldRef<Container, ZNetView> ContainerView = AccessTools.FieldRefAccess<Container, ZNetView>("m_nview");

		private static readonly Dictionary<int, PendingPut> s_puts = new Dictionary<int, PendingPut>();

		private static readonly Dictionary<int, PendingTake> s_takes = new Dictionary<int, PendingTake>();

		private static readonly HashSet<ItemData> s_lockedItems = new HashSet<ItemData>();

		private static readonly HashSet<Vector2i> s_lockedChestSlots = new HashSet<Vector2i>();

		private static bool s_eating;

		private static float s_eatSent;

		private static int s_req;

		public static Container Current
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)InventoryGui.instance))
				{
					return null;
				}
				return CurrentContainer.Invoke(InventoryGui.instance);
			}
		}

		private static ZNetView View(Container c)
		{
			if (!Object.op_Implicit((Object)(object)c))
			{
				return null;
			}
			return ContainerView.Invoke(c);
		}

		private static void SetupDrag(ItemData item, Inventory inv, int amount)
		{
			Traverse.Create((object)InventoryGui.instance).Method("SetupDragItem", new object[3] { item, inv, amount }).GetValue();
		}

		public static bool IsGuest(Inventory inv, out Container container)
		{
			container = null;
			if (!Plugin.SharedChests.Value)
			{
				return false;
			}
			Container current = Current;
			if (!Object.op_Implicit((Object)(object)current) || current.GetInventory() != inv)
			{
				return false;
			}
			ZNetView val = View(current);
			if (!Object.op_Implicit((Object)(object)val) || !val.IsValid())
			{
				return false;
			}
			if (!val.HasOwner())
			{
				Traverse.Create((object)current).Method("Load", Array.Empty<object>()).GetValue<bool>();
				val.ClaimOwnership();
				return false;
			}
			if (val.IsOwner())
			{
				return false;
			}
			container = current;
			return true;
		}

		public static bool IsGuestOf(Container c)
		{
			Container container;
			if (Object.op_Implicit((Object)(object)c) && (Object)(object)Current == (Object)(object)c)
			{
				return IsGuest(c.GetInventory(), out container);
			}
			return false;
		}

		private static ZPackage PackItem(ItemData item, int amount)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			ItemData obj = item.Clone();
			obj.m_stack = amount;
			ZPackage val = new ZPackage();
			val.Write(109);
			val.Write((ushort)1);
			obj.Save(val);
			return val;
		}

		private static ZPackage PackInventory(Inventory inv)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			ZPackage val = new ZPackage();
			inv.Save(val);
			return val;
		}

		private static Inventory Unpack(ZPackage pkg)
		{
			//IL_0008: 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)
			//IL_0015: Expected O, but got Unknown
			Inventory val = new Inventory("IR_tmp", (Sprite)null, 8, 8);
			val.Load(pkg);
			return val;
		}

		private static string NameOf(ItemData item)
		{
			return item.m_shared.m_name;
		}

		private static void DropInto(Inventory to, Inventory from, ItemData item, int amount, int x, int y)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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)
			ItemData itemAt = to.GetItemAt(x, y);
			if (itemAt != item)
			{
				if (itemAt != null && !CanStack(itemAt, item) && item.m_stack == amount)
				{
					Vector2i gridPos = item.m_gridPos;
					from.RemoveItem(item);
					from.MoveItemToThis(to, itemAt, itemAt.m_stack, gridPos.x, gridPos.y);
					to.MoveItemToThis(from, item, amount, x, y);
				}
				else
				{
					to.MoveItemToThis(from, item, amount, x, y);
				}
			}
		}

		private static bool CanStack(ItemData a, ItemData b)
		{
			if (a.m_shared.m_name == b.m_shared.m_name && (b.m_shared.m_maxQuality <= 1 || a.m_quality == b.m_quality))
			{
				return a.m_shared.m_maxStackSize > 1;
			}
			return false;
		}

		public static bool IsLocked(ItemData item)
		{
			if (item != null)
			{
				return s_lockedItems.Contains(item);
			}
			return false;
		}

		private static bool IsLockedChestSlot(Inventory inv, Vector2i pos)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (IsGuest(inv, out var _))
			{
				return s_lockedChestSlots.Contains(pos);
			}
			return false;
		}

		private static void ExpireLocks()
		{
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			float time = Time.time;
			List<int> list = new List<int>();
			foreach (KeyValuePair<int, PendingPut> s_put in s_puts)
			{
				if (time - s_put.Value.Sent > 5f)
				{
					list.Add(s_put.Key);
				}
			}
			foreach (int item in list)
			{
				s_lockedItems.Remove(s_puts[item].Item);
				s_puts.Remove(item);
			}
			list.Clear();
			foreach (KeyValuePair<int, PendingTake> s_take in s_takes)
			{
				if (time - s_take.Value.Sent > 5f)
				{
					list.Add(s_take.Key);
				}
			}
			foreach (int item2 in list)
			{
				s_lockedChestSlots.Remove(s_takes[item2].Slot);
				s_takes.Remove(item2);
			}
			if (s_eating && time - s_eatSent > 5f)
			{
				s_eating = false;
			}
		}

		public static void Put(Container c, Inventory from, ItemData item, int amount, int x, int y)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected O, but got Unknown
			if (!IsLocked(item))
			{
				int num = ++s_req;
				s_puts[num] = new PendingPut
				{
					Item = item,
					From = from,
					Amount = amount,
					Origin = item.m_gridPos,
					Sent = Time.time
				};
				s_lockedItems.Add(item);
				ZPackage val = new ZPackage();
				val.Write(num);
				val.Write(x);
				val.Write(y);
				val.Write(PackItem(item, amount));
				View(c).InvokeRPC("IR_Put", new object[1] { val });
			}
		}

		public static void Take(Container c, ItemData chestItem, int amount, Inventory to, int toX, int toY, bool drop = false)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Expected O, but got Unknown
			if (!s_lockedChestSlots.Contains(chestItem.m_gridPos))
			{
				int num = ++s_req;
				s_takes[num] = new PendingTake
				{
					Chest = c,
					Slot = chestItem.m_gridPos,
					To = to,
					X = toX,
					Y = toY,
					Drop = drop,
					Sent = Time.time
				};
				s_lockedChestSlots.Add(chestItem.m_gridPos);
				ZPackage val = new ZPackage();
				val.Write(num);
				val.Write(chestItem.m_gridPos.x);
				val.Write(chestItem.m_gridPos.y);
				val.Write(amount);
				val.Write(NameOf(chestItem));
				View(c).InvokeRPC("IR_Take", new object[1] { val });
			}
		}

		public static void Move(Container c, ItemData chestItem, int amount, int toX, int toY)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			if (!s_lockedChestSlots.Contains(chestItem.m_gridPos))
			{
				ZPackage val = new ZPackage();
				val.Write(chestItem.m_gridPos.x);
				val.Write(chestItem.m_gridPos.y);
				val.Write(toX);
				val.Write(toY);
				val.Write(amount);
				val.Write(NameOf(chestItem));
				View(c).InvokeRPC("IR_Move", new object[1] { val });
			}
		}

		public static void Eat(Container c, ItemData chestItem)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			if (!s_eating && !s_lockedChestSlots.Contains(chestItem.m_gridPos))
			{
				s_eating = true;
				s_eatSent = Time.time;
				ZPackage val = new ZPackage();
				val.Write(chestItem.m_gridPos.x);
				val.Write(chestItem.m_gridPos.y);
				val.Write(NameOf(chestItem));
				View(c).InvokeRPC("IR_Eat", new object[1] { val });
			}
		}

		public static void PutMatching(Container c, Inventory from)
		{
			Inventory inventory = c.GetInventory();
			foreach (ItemData item in new List<ItemData>(from.GetAllItems()))
			{
				if (Stash.CanLeave(item, respectHotbar: false) && inventory.ContainsItemByName(NameOf(item)))
				{
					Put(c, from, item, item.m_stack, -1, -1);
				}
			}
		}

		private static void OnPutResp(Container c, long sender, ZPackage pkg)
		{
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			int key = pkg.ReadInt();
			int num = pkg.ReadInt();
			Inventory val = Unpack(pkg.ReadPackage());
			if (!s_puts.TryGetValue(key, out var value))
			{
				return;
			}
			s_puts.Remove(key);
			s_lockedItems.Remove(value.Item);
			if (num > 0 && value.From.ContainsItem(value.Item))
			{
				value.From.RemoveItem(value.Item, Mathf.Min(num, value.Item.m_stack));
			}
			foreach (ItemData item in new List<ItemData>(val.GetAllItems()))
			{
				val.RemoveItem(item);
				if (!value.From.AddItem(item, value.Origin) && !value.From.AddItem(item))
				{
					DropAtFeet(item);
				}
			}
		}

		private static void OnTakeResp(Container c, long sender, ZPackage pkg)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			int key = pkg.ReadInt();
			Inventory val = Unpack(pkg.ReadPackage());
			if (!s_takes.TryGetValue(key, out var value))
			{
				return;
			}
			s_takes.Remove(key);
			s_lockedChestSlots.Remove(value.Slot);
			foreach (ItemData item in new List<ItemData>(val.GetAllItems()))
			{
				if (value.Drop)
				{
					val.RemoveItem(item);
					DropAtFeet(item);
					continue;
				}
				if (value.X >= 0)
				{
					ItemData itemAt = value.To.GetItemAt(value.X, value.Y);
					if (itemAt == null || CanStack(itemAt, item))
					{
						value.To.MoveItemToThis(val, item, item.m_stack, value.X, value.Y);
					}
				}
				if (val.ContainsItem(item) && item.m_stack > 0 && value.To.AddItem(item))
				{
					val.RemoveItem(item);
				}
			}
			foreach (ItemData item2 in new List<ItemData>(val.GetAllItems()))
			{
				val.RemoveItem(item2);
				if (IsGuestOf(c))
				{
					PutLoose(c, item2);
				}
				else
				{
					DropAtFeet(item2);
				}
			}
		}

		private static void PutLoose(Container c, ItemData item)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			ZPackage val = new ZPackage();
			val.Write(0);
			val.Write(-1);
			val.Write(-1);
			val.Write(PackItem(item, item.m_stack));
			View(c).InvokeRPC("IR_Put", new object[1] { val });
		}

		private static void OnEatResp(Container c, long sender, ZPackage pkg)
		{
			s_eating = false;
			Inventory val = Unpack(pkg.ReadPackage());
			Player localPlayer = Player.m_localPlayer;
			foreach (ItemData item in new List<ItemData>(val.GetAllItems()))
			{
				if (!Object.op_Implicit((Object)(object)localPlayer) || !((Humanoid)localPlayer).CanConsumeItem(item, false) || !((Humanoid)localPlayer).ConsumeItem(val, item, false))
				{
					val.RemoveItem(item);
					if (!Object.op_Implicit((Object)(object)localPlayer) || !((Humanoid)localPlayer).GetInventory().AddItem(item))
					{
						DropAtFeet(item);
					}
				}
			}
		}

		private static void DropAtFeet(ItemData item)
		{
			//IL_0025: 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_0035: 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_003f: 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)
			Player localPlayer = Player.m_localPlayer;
			if (Object.op_Implicit((Object)(object)localPlayer) && item.m_stack > 0)
			{
				ItemDrop val = ItemDrop.DropItem(item, item.m_stack, ((Component)localPlayer).transform.position + ((Component)localPlayer).transform.forward + Vector3.up, ((Component)localPlayer).transform.rotation);
				if (Object.op_Implicit((Object)(object)val))
				{
					val.OnPlayerDrop();
				}
			}
		}

		private static void OnPut(Container c, long sender, ZPackage pkg)
		{
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Expected O, but got Unknown
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: 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)
			if (!View(c).IsOwner())
			{
				return;
			}
			int num = pkg.ReadInt();
			int num2 = pkg.ReadInt();
			int y = pkg.ReadInt();
			Inventory val = Unpack(pkg.ReadPackage());
			int num3 = 0;
			List<ItemData> allItems = val.GetAllItems();
			if (allItems.Count > 0)
			{
				ItemData val2 = allItems[0];
				int stack = val2.m_stack;
				if (num2 < 0)
				{
					num3 = (c.GetInventory().AddItem(val2) ? stack : (stack - val2.m_stack));
				}
				else
				{
					DropInto(c.GetInventory(), val, val2, stack, num2, y);
					num3 = (val.ContainsItem(val2) ? (stack - val2.m_stack) : stack);
				}
				if (val.ContainsItem(val2))
				{
					val.RemoveItem(val2);
				}
			}
			if (num == 0)
			{
				foreach (ItemData item in new List<ItemData>(val.GetAllItems()))
				{
					ItemDrop.DropItem(item, item.m_stack, ((Component)c).transform.position + Vector3.up, Quaternion.identity);
				}
				return;
			}
			ZPackage val3 = new ZPackage();
			val3.Write(num);
			val3.Write(num3);
			val3.Write(PackInventory(val));
			View(c).InvokeRPC(sender, "IR_PutResp", new object[1] { val3 });
		}

		private static void OnTake(Container c, long sender, ZPackage pkg)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Expected O, but got Unknown
			if (View(c).IsOwner())
			{
				int num = pkg.ReadInt();
				int num2 = pkg.ReadInt();
				int num3 = pkg.ReadInt();
				int num4 = pkg.ReadInt();
				string text = pkg.ReadString();
				Inventory val = new Inventory("IR_tmp", (Sprite)null, 8, 8);
				ItemData itemAt = c.GetInventory().GetItemAt(num2, num3);
				if (itemAt != null && NameOf(itemAt) == text)
				{
					val.MoveItemToThis(c.GetInventory(), itemAt, Mathf.Min(num4, itemAt.m_stack), 0, 0);
				}
				ZPackage val2 = new ZPackage();
				val2.Write(num);
				val2.Write(PackInventory(val));
				View(c).InvokeRPC(sender, "IR_TakeResp", new object[1] { val2 });
			}
		}

		private static void OnMove(Container c, long sender, ZPackage pkg)
		{
			if (View(c).IsOwner())
			{
				int num = pkg.ReadInt();
				int num2 = pkg.ReadInt();
				int x = pkg.ReadInt();
				int y = pkg.ReadInt();
				int num3 = pkg.ReadInt();
				string text = pkg.ReadString();
				Inventory inventory = c.GetInventory();
				ItemData itemAt = inventory.GetItemAt(num, num2);
				if (itemAt != null && NameOf(itemAt) == text)
				{
					DropInto(inventory, inventory, itemAt, Mathf.Min(num3, itemAt.m_stack), x, y);
				}
			}
		}

		private static void OnEat(Container c, long sender, ZPackage pkg)
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Expected O, but got Unknown
			if (View(c).IsOwner())
			{
				int num = pkg.ReadInt();
				int num2 = pkg.ReadInt();
				string text = pkg.ReadString();
				Inventory val = new Inventory("IR_tmp", (Sprite)null, 8, 8);
				ItemData itemAt = c.GetInventory().GetItemAt(num, num2);
				if (itemAt != null && NameOf(itemAt) == text)
				{
					val.MoveItemToThis(c.GetInventory(), itemAt, 1, 0, 0);
				}
				ZPackage val2 = new ZPackage();
				val2.Write(PackInventory(val));
				View(c).InvokeRPC(sender, "IR_EatResp", new object[1] { val2 });
			}
		}

		private static bool GrantWithoutOwnership(Container c, long uid, long playerID, string response)
		{
			if (!Plugin.SharedChests.Value)
			{
				return true;
			}
			ZNetView val = View(c);
			if (!Object.op_Implicit((Object)(object)val) || !val.IsOwner())
			{
				return true;
			}
			if ((!c.IsInUse() && (!Object.op_Implicit((Object)(object)c.m_wagon) || !c.m_wagon.InUse())) || uid == ZNet.GetUID())
			{
				return true;
			}
			if (!Traverse.Create((object)c).Method("CheckAccess", new object[1] { playerID }).GetValue<bool>())
			{
				return true;
			}
			val.InvokeRPC(uid, response, new object[1] { true });
			return false;
		}

		public static bool OwnerOrGuest(Container c)
		{
			if (!c.IsOwner())
			{
				if (Plugin.SharedChests.Value)
				{
					return (Object)(object)Current == (Object)(object)c;
				}
				return false;
			}
			return true;
		}
	}
	public static class Stash
	{
		public static readonly HashSet<Container> Pending = new HashSet<Container>();

		public static int Moved;

		private static float s_lastRun;

		public static void Run(Player player)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if (Time.time - s_lastRun < 0.5f)
			{
				return;
			}
			s_lastRun = Time.time;
			List<Container> list = FindNearby(((Component)player).transform.position, Plugin.StashRange.Value);
			if (list.Count == 0)
			{
				((Character)player).Message((MessageType)2, "No chests nearby", 0, (Sprite)null, false);
				return;
			}
			Moved = 0;
			Pending.Clear();
			foreach (Container item in list)
			{
				Pending.Add(item);
				item.StackAll();
			}
			((MonoBehaviour)player).StartCoroutine(Report(player));
		}

		private static IEnumerator Report(Player player)
		{
			yield return (object)new WaitForSeconds(1.5f);
			Pending.Clear();
			((Character)player).Message((MessageType)2, (Moved > 0) ? $"Stashed {Moved} items" : "Nothing to stash", 0, (Sprite)null, false);
		}

		public static List<Container> FindNearby(Vector3 pos, float range)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			List<Container> list = new List<Container>();
			HashSet<Container> hashSet = new HashSet<Container>();
			Collider[] array = Physics.OverlapSphere(pos, range, LayerMask.GetMask(new string[2] { "piece", "item" }));
			for (int i = 0; i < array.Length; i++)
			{
				Container componentInParent = ((Component)array[i]).GetComponentInParent<Container>();
				if (!Object.op_Implicit((Object)(object)componentInParent) || !hashSet.Add(componentInParent))
				{
					continue;
				}
				ZNetView component = ((Component)componentInParent).GetComponent<ZNetView>();
				if (component == null || !component.IsValid() || Object.op_Implicit((Object)(object)componentInParent.m_wagon) || Object.op_Implicit((Object)(object)((Component)componentInParent).GetComponentInParent<Ship>()))
				{
					continue;
				}
				if (Plugin.StashPlayerBuiltOnly.Value)
				{
					Piece component2 = ((Component)componentInParent).GetComponent<Piece>();
					if (!Object.op_Implicit((Object)(object)component2) || !component2.IsPlacedByPlayer())
					{
						continue;
					}
				}
				if (!componentInParent.m_checkGuardStone || PrivateArea.CheckAccess(((Component)componentInParent).transform.position, 0f, false, false))
				{
					list.Add(componentInParent);
				}
			}
			return list;
		}

		public static bool CanLeave(ItemData item, bool respectHotbar)
		{
			if (item.m_equipped || Favourites.Is(item) || SharedChest.IsLocked(item))
			{
				return false;
			}
			if (respectHotbar && Plugin.StashKeepHotbar.Value && item.m_gridPos.y == 0)
			{
				return false;
			}
			return true;
		}

		public static int StackInto(Inventory chest, Inventory from)
		{
			int num = 0;
			foreach (ItemData item in new List<ItemData>(from.GetAllItems()))
			{
				if (CanLeave(item, respectHotbar: true) && chest.ContainsItemByName(item.m_shared.m_name))
				{
					int stack = item.m_stack;
					if (chest.AddItem(item))
					{
						from.RemoveItem(item);
						num += stack;
					}
				}
			}
			return num;
		}
	}
	[HarmonyPatch(typeof(Container), "RPC_StackResponse")]
	internal static class Container_RPC_StackResponse_Patch
	{
		private static bool Prefix(Container __instance, bool granted)
		{
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			if (!Stash.Pending.Remove(__instance))
			{
				return true;
			}
			if (!granted || !Object.op_Implicit((Object)(object)Player.m_localPlayer))
			{
				return false;
			}
			ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
			if (Object.op_Implicit((Object)(object)component) && component.IsValid() && !component.IsOwner())
			{
				SharedChest.PutMatching(__instance, ((Humanoid)Player.m_localPlayer).GetInventory());
				return false;
			}
			int num = Stash.StackInto(__instance.GetInventory(), ((Humanoid)Player.m_localPlayer).GetInventory());
			if (num > 0)
			{
				Stash.Moved += num;
				InventoryGui.instance.m_moveItemEffects.Create(((Component)__instance).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(Inventory), "StackAll")]
	internal static class Inventory_StackAll_Favourites
	{
		private static bool Prefix(Inventory __instance, Inventory fromInventory, bool message, ref int __result)
		{
			if (!Object.op_Implicit((Object)(object)Player.m_localPlayer) || fromInventory != ((Humanoid)Player.m_localPlayer).GetInventory())
			{
				return true;
			}
			if (SharedChest.IsGuest(__instance, out var _))
			{
				return true;
			}
			int num = 0;
			foreach (ItemData item in new List<ItemData>(fromInventory.GetAllItems()))
			{
				if (Stash.CanLeave(item, respectHotbar: false) && __instance.ContainsItemByName(item.m_shared.m_name))
				{
					int stack = item.m_stack;
					if (__instance.AddItem(item))
					{
						fromInventory.RemoveItem(item);
						num += stack;
					}
				}
			}
			if (message)
			{
				((Character)Player.m_localPlayer).Message((MessageType)2, (num > 0) ? ("$msg_stackall " + num) : "$msg_stackall_none", 0, (Sprite)null, false);
			}
			Game.instance.IncrementPlayerStat((PlayerStatType)82, 1f, false);
			__result = num;
			return false;
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "Awake")]
	internal static class StashButton
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static UnityAction <>9__0_0;

			internal void <Postfix>b__0_0()
			{
				if (Object.op_Implicit((Object)(object)Player.m_localPlayer))
				{
					Stash.Run(Player.m_localPlayer);
				}
			}
		}

		private static void Postfix(InventoryGui __instance)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			if (!Plugin.StashButton.Value || !Object.op_Implicit((Object)(object)__instance.m_takeAllButton))
			{
				return;
			}
			Button obj = Object.Instantiate<Button>(__instance.m_takeAllButton, (Transform)(object)__instance.m_player);
			((Object)obj).name = "IR_StashButton";
			obj.onClick = new ButtonClickedEvent();
			ButtonClickedEvent onClick = obj.onClick;
			object obj2 = <>c.<>9__0_0;
			if (obj2 == null)
			{
				UnityAction val = delegate
				{
					if (Object.op_Implicit((Object)(object)Player.m_localPlayer))
					{
						Stash.Run(Player.m_localPlayer);
					}
				};
				<>c.<>9__0_0 = val;
				obj2 = (object)val;
			}
			((UnityEvent)onClick).AddListener((UnityAction)obj2);
			TMP_Text componentInChildren = ((Component)obj).GetComponentInChildren<TMP_Text>();
			if (Object.op_Implicit((Object)(object)componentInChildren))
			{
				componentInChildren.text = "»";
				componentInChildren.alignment = (TextAlignmentOptions)514;
				componentInChildren.enableAutoSizing = false;
				componentInChildren.fontSize = 22f;
			}
			Text componentInChildren2 = ((Component)obj).GetComponentInChildren<Text>();
			if (Object.op_Implicit((Object)(object)componentInChildren2))
			{
				componentInChildren2.text = "»";
			}
			RectTransform component = ((Component)obj).GetComponent<RectTransform>();
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(1f, 0f);
			component.anchorMax = val2;
			component.anchorMin = val2;
			component.pivot = new Vector2(0.5f, 0.5f);
			component.sizeDelta = new Vector2(Plugin.StashButtonSize.Value, Plugin.StashButtonSize.Value);
			component.anchoredPosition = new Vector2(Plugin.StashButtonX.Value, Plugin.StashButtonY.Value);
			UITooltip component2 = ((Component)obj).GetComponent<UITooltip>();
			if (Object.op_Implicit((Object)(object)component2))
			{
				component2.m_text = "Stash to nearby chests";
				component2.m_topic = "";
			}
		}
	}
}