Decompiled source of MultiUserChest v0.5.10

MultiUserChest.dll

Decompiled 2 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Managers;
using Jotunn.Utils;
using MultiUserChest.Patches;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("MultiUserChest")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("MultiUserChest")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: InternalsVisibleTo("UnitTests")]
[assembly: InternalsVisibleTo("Tests")]
[assembly: ComVisible(false)]
[assembly: Guid("FE8B42E3-7082-4DFF-A5CC-6B62B0315ACA")]
[assembly: AssemblyFileVersion("0.5.10")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.5.10.0")]
[module: UnverifiableCode]
namespace MultiUserChest
{
	public static class CodeMatcherExtensions
	{
		public static CodeMatcher GetPosition(this CodeMatcher codeMatcher, out int position)
		{
			position = codeMatcher.Pos;
			return codeMatcher;
		}

		public static CodeMatcher AddLabel(this CodeMatcher codeMatcher, out Label label)
		{
			label = default(Label);
			codeMatcher.AddLabels((IEnumerable<Label>)new Label[1] { label });
			return codeMatcher;
		}

		public static CodeMatcher GetOperand(this CodeMatcher codeMatcher, out object operand)
		{
			operand = codeMatcher.Operand;
			return codeMatcher;
		}

		internal static CodeMatcher Print(this CodeMatcher codeMatcher, int before, int after)
		{
			for (int i = -before; i <= after; i++)
			{
				int num = i;
				int num2 = codeMatcher.Pos + num;
				if (num2 > 0)
				{
					if (num2 >= codeMatcher.Length)
					{
						break;
					}
					try
					{
						CodeInstruction val = codeMatcher.InstructionAt(num);
						Log.LogCodeInstruction($"[{num}] " + ((object)val).ToString());
					}
					catch (Exception ex)
					{
						Log.LogCodeInstruction(ex.Message);
					}
				}
			}
			return codeMatcher;
		}

		public static bool IsVirtCall(this CodeInstruction i, string declaringType, string name)
		{
			if (i.opcode == OpCodes.Callvirt && i.operand is MethodInfo methodInfo && methodInfo.DeclaringType?.Name == declaringType)
			{
				return methodInfo.Name == name;
			}
			return false;
		}
	}
	public static class Compatibility
	{
		private static bool IsExtendedInventory(this Inventory inventory, out List<Inventory> inventories)
		{
			if (inventory.IsType("ExtendedInventory") && inventory.HasField("_inventories"))
			{
				inventories = inventory.GetField<List<Inventory>>("_inventories");
				return true;
			}
			inventories = null;
			return false;
		}

		public static List<Inventory> GetInventories(this Inventory inventory)
		{
			if (inventory.IsExtendedInventory(out var inventories))
			{
				return inventories;
			}
			return new List<Inventory> { inventory };
		}
	}
	public class ContainerExtend : MonoBehaviour
	{
		private static readonly ConditionalWeakTable<Inventory, ContainerInventoryOwner> Containers = new ConditionalWeakTable<Inventory, ContainerInventoryOwner>();

		private Inventory inventory;

		private void Awake()
		{
			Container container = default(Container);
			if (!((Component)this).TryGetComponent<Container>(ref container))
			{
				return;
			}
			inventory = container.GetInventory();
			if (inventory != null)
			{
				Containers.TryAdd(inventory, (Inventory i) => new ContainerInventoryOwner(container));
			}
		}

		private void OnDestroy()
		{
			if (inventory != null)
			{
				Containers.Remove(inventory);
			}
		}

		public static bool GetContainer(Inventory inventory, out ContainerInventoryOwner container)
		{
			return Containers.TryGetValue(inventory, out container);
		}
	}
	public static class ContainerHandler
	{
		public static RequestChestAdd AddItemToChest(this Container container, ItemData item, Inventory sourceInventory, Vector2i to, ZDOID sender, int dragAmount = -1)
		{
			//IL_0022: 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_0048: 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_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)container) || !Object.op_Implicit((Object)(object)container.m_nview) || !container.m_nview.HasOwner())
			{
				return new RequestChestAdd(Vector2i.zero, 0, null, null, null);
			}
			dragAmount = PossibleDragAmount(container.GetInventory(), item, to, dragAmount);
			ItemData itemAt = container.GetInventory().GetItemAt(to.x, to.y);
			bool flag = itemAt != null && dragAmount != item.m_stack && !InventoryHelper.CanStack(itemAt, item);
			if (dragAmount <= 0 || flag || !sourceInventory.ContainsItem(item))
			{
				return new RequestChestAdd(Vector2i.zero, 0, null, null, null);
			}
			RequestChestAdd requestChestAdd = new RequestChestAdd(to, dragAmount, item, sourceInventory, container.GetInventory());
			InventoryBlock.Get(sourceInventory).BlockSlot(item.m_gridPos);
			InventoryPreview.AddPackage(requestChestAdd);
			sourceInventory.RemoveItem(item, dragAmount);
			if (container.m_nview.IsOwner())
			{
				RequestChestAddResponse response = container.GetInventory().RequestItemAdd(requestChestAdd);
				InventoryHandler.RPC_RequestItemAddResponse(sourceInventory, response);
				return null;
			}
			GamePatches.InvokeRPC(container.m_nview, "MUC_RequestItemAdd", requestChestAdd);
			return requestChestAdd;
		}

		internal static int PossibleDragAmount(Inventory inventoryTo, ItemData dragItem, Vector2i to, int dragAmount)
		{
			//IL_001c: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			dragAmount = ((dragAmount >= 0) ? Mathf.Min(dragAmount, dragItem.m_stack) : dragItem.m_stack);
			if (to.x >= 0 && to.y >= 0)
			{
				ItemData itemAt = inventoryTo.GetItemAt(to.x, to.y);
				if (itemAt != null && dragAmount < dragItem.m_stack)
				{
					if (InventoryHelper.CanStack(itemAt, dragItem))
					{
						return Mathf.Min(dragAmount, itemAt.m_shared.m_maxStackSize - itemAt.m_stack);
					}
					return 0;
				}
			}
			else if (!inventoryTo.HaveEmptySlot())
			{
				int num = inventoryTo.FindFreeStackSpace(dragItem.m_shared.m_name, (float)dragItem.m_worldLevel);
				return Mathf.Min(dragAmount, num);
			}
			return dragAmount;
		}

		public static RequestChestRemove RemoveItemFromChest(this Container container, ItemData item, Inventory destinationInventory, Vector2i to, ZDOID sender, int dragAmount = -1, ItemData switchItem = null)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: 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_005f: 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_0074: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)container) || !Object.op_Implicit((Object)(object)container.m_nview) || !container.m_nview.HasOwner())
			{
				return new RequestChestRemove(Vector2i.zero, Vector2i.zero, 0, null, container.GetInventory(), destinationInventory);
			}
			dragAmount = PossibleDragAmount(destinationInventory, item, to, dragAmount);
			if (dragAmount <= 0 || InventoryBlock.Get(destinationInventory).IsSlotBlocked(to))
			{
				return new RequestChestRemove(Vector2i.zero, Vector2i.zero, 0, null, container.GetInventory(), destinationInventory);
			}
			RequestChestRemove requestChestRemove = new RequestChestRemove(item.m_gridPos, to, dragAmount, switchItem, container.GetInventory(), destinationInventory);
			if (switchItem != null && !InventoryHelper.CanStack(item, switchItem))
			{
				if (dragAmount != item.m_stack)
				{
					return new RequestChestRemove(Vector2i.zero, Vector2i.zero, 0, null, container.GetInventory(), destinationInventory);
				}
				destinationInventory.RemoveItem(switchItem);
			}
			InventoryBlock.Get(destinationInventory).BlockSlot(requestChestRemove.toPos);
			InventoryPreview.AddPackage(requestChestRemove);
			if (container.m_nview.IsOwner())
			{
				RequestChestRemoveResponse response = container.GetInventory().RequestItemRemove(requestChestRemove);
				InventoryHandler.RPC_RequestItemRemoveResponse(destinationInventory, response);
				return null;
			}
			GamePatches.InvokeRPC(container.m_nview, "MUC_RequestItemRemove", requestChestRemove);
			return requestChestRemove;
		}

		public static void MoveItemInChest(this Container container, ItemData item, Vector2i toPos, int dragAmount)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			RequestMove package = new RequestMove(item, toPos, dragAmount, container.GetInventory());
			InventoryPreview.AddPackage(package);
			GamePatches.InvokeRPC(container.m_nview, "MUC_RequestItemMove", package);
		}
	}
	public static class ContainerRPCHandler
	{
		public static void RPC_RequestItemAdd(long sender, ZDOID containerId, ZPackage package)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			HandleRPC(containerId, sender, "MUC_RequestItemAddResponse", RequestItemAdd, new RequestChestAdd(package));
		}

		public static void RPC_RequestItemRemove(long sender, ZDOID containerId, ZPackage package)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			HandleRPC(containerId, sender, "MUC_RequestItemRemoveResponse", RequestItemRemove, new RequestChestRemove(package));
		}

		public static void RPC_RequestItemConsume(long sender, ZDOID containerId, ZPackage package)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			HandleRPC(containerId, sender, "MUC_RequestItemConsumeResponse", RequestItemConsume, new RequestConsume(package));
		}

		public static void RPC_RequestItemMove(long sender, ZDOID containerId, ZPackage package)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			HandleRPC(containerId, sender, "MUC_RequestItemMoveResponse", RequestItemMove, new RequestMove(package));
		}

		public static void RPC_RequestDrop(long sender, ZDOID containerId, ZPackage package)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			HandleRPC(containerId, sender, "MUC_RequestItemDropResponse", RequestDrop, new RequestDrop(package));
		}

		private static void HandleRPC<TResponse, TInput>(ZDOID containerId, long target, string rpcInvoke, Func<Inventory, TInput, TResponse> message, TInput input) where TResponse : IResponse, new() where TInput : IPackage
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			ZDO zDO = ZDOMan.instance.GetZDO(containerId);
			ZNetView val = ((zDO != null) ? ZNetScene.instance.FindInstance(zDO) : null);
			TResponse val2;
			if (!Object.op_Implicit((Object)(object)val) || !val.IsOwner())
			{
				val2 = FallbackResponse<TResponse>(input as IRequest);
			}
			else
			{
				Container componentInChildren = ((Component)val).GetComponentInChildren<Container>();
				if (Object.op_Implicit((Object)(object)componentInChildren))
				{
					val2 = message(componentInChildren.GetInventory(), input);
				}
				else
				{
					Log.LogWarning(input.GetType().Name + ": not handling RPC, Container component not found on " + ((Object)val).name);
					val2 = FallbackResponse<TResponse>(input as IRequest);
				}
			}
			ZRoutedRpc.instance.InvokeRoutedRPC(target, rpcInvoke, new object[2]
			{
				containerId,
				val2.WriteToPackage()
			});
		}

		private static TResponse FallbackResponse<TResponse>(IRequest request) where TResponse : IResponse, new()
		{
			//IL_0058: 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_005d: Unknown result type (might be due to invalid IL or missing references)
			TResponse val = new TResponse
			{
				SourceID = (request?.RequestID ?? 0)
			};
			if (request is RequestChestAdd requestChestAdd && (object)val is RequestChestAddResponse requestChestAddResponse)
			{
				requestChestAddResponse.switchItem = requestChestAdd.dragItem;
				requestChestAddResponse.inventoryPos = requestChestAdd.dragItem?.m_gridPos ?? Vector2i.zero;
			}
			else if (request is RequestChestRemove requestChestRemove && (object)val is RequestChestRemoveResponse requestChestRemoveResponse)
			{
				requestChestRemoveResponse.responseItem = requestChestRemove.switchItem;
			}
			return val;
		}

		public static RequestChestAddResponse RequestItemAdd(this Inventory inventory, RequestChestAdd request)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (request.dragItem == null)
			{
				return new RequestChestAddResponse(request.RequestID, success: false, Vector2i.zero, 0, request.dragItem);
			}
			if (request.toPos.x < 0 || request.toPos.y < 0)
			{
				return AddToAnySlot(inventory, request);
			}
			return AddToSlot(inventory, request);
		}

		private static RequestChestAddResponse AddToSlot(Inventory inventory, RequestChestAdd request)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: 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_0081: Unknown result type (might be due to invalid IL or missing references)
			if (!CanStack(inventory, request, out var stackSpace, out var removedItem))
			{
				return new RequestChestAddResponse(request.RequestID, success: false, request.dragItem.m_gridPos, 0, request.dragItem);
			}
			bool flag = inventory.AddItemToInventory(request.dragItem, stackSpace, request.toPos);
			if (!flag)
			{
				stackSpace = 0;
			}
			if (!flag || stackSpace != request.dragItem.m_stack)
			{
				removedItem = request.dragItem;
				removedItem.m_stack = request.dragItem.m_stack - stackSpace;
			}
			if (removedItem != null)
			{
				removedItem.m_gridPos = request.dragItem.m_gridPos;
			}
			return new RequestChestAddResponse(request.RequestID, flag, request.dragItem.m_gridPos, stackSpace, removedItem);
		}

		private static bool CanStack(Inventory inventory, RequestChestAdd request, out int stackSpace, out ItemData removedItem)
		{
			ItemData itemAt = inventory.GetItemAt(request.toPos.x, request.toPos.y);
			removedItem = null;
			if (itemAt == null)
			{
				stackSpace = request.dragItem.m_stack;
				return true;
			}
			if (InventoryHelper.CanStack(itemAt, request.dragItem))
			{
				stackSpace = Mathf.Min(itemAt.m_shared.m_maxStackSize - itemAt.m_stack, request.dragItem.m_stack);
				return true;
			}
			if (request.allowSwitch)
			{
				inventory.RemoveItem(itemAt, itemAt.m_stack);
				removedItem = itemAt;
				stackSpace = request.dragItem.m_stack;
				return true;
			}
			stackSpace = 0;
			return false;
		}

		private static RequestChestAddResponse AddToAnySlot(Inventory inventory, RequestChestAdd request)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Expected O, but got Unknown
			//IL_00bf: 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)
			Inventory val = new Inventory("tmp", (Sprite)null, 1, 1);
			val.AddItem(request.dragItem.Clone(), request.dragItem.m_stack, 0, 0);
			inventory.MoveItemToThis(val, val.GetItemAt(0, 0));
			ItemData itemAt = val.GetItemAt(0, 0);
			if (itemAt == null)
			{
				return new RequestChestAddResponse(request.RequestID, success: true, request.dragItem.m_gridPos, request.dragItem.m_stack, null);
			}
			ItemData val2 = request.dragItem.Clone();
			int num = request.dragItem.m_stack - itemAt.m_stack;
			val2.m_stack -= num;
			bool success = itemAt.m_stack != request.dragItem.m_stack;
			return new RequestChestAddResponse(request.RequestID, success, request.dragItem.m_gridPos, num, val2);
		}

		public static RequestChestRemoveResponse RequestItemRemove(this Inventory inventory, RequestChestRemove request)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			Vector2i fromPos = request.fromPos;
			int dragAmount = request.dragAmount;
			ItemData switchItem = request.switchItem;
			ItemData itemAt = inventory.GetItemAt(request.fromPos.x, request.fromPos.y);
			if (itemAt == null)
			{
				Log.LogDebug("from is null");
				return new RequestChestRemoveResponse(request.RequestID, success: false, 0, hasSwitched: false, null);
			}
			int num = 0;
			bool flag = false;
			bool flag2 = false;
			if (switchItem == null)
			{
				num = Mathf.Min(itemAt.m_stack, dragAmount);
				flag = inventory.RemoveItem(itemAt, num);
			}
			else if (InventoryHelper.CanStack(itemAt, switchItem))
			{
				num = Mathf.Min(switchItem.m_shared.m_maxStackSize - switchItem.m_stack, dragAmount);
				flag = inventory.RemoveItem(itemAt, num);
			}
			else
			{
				if (dragAmount < itemAt.m_stack)
				{
					return new RequestChestRemoveResponse(request.RequestID, success: false, 0, hasSwitched: false, request.switchItem);
				}
				flag = inventory.RemoveItem(itemAt, dragAmount);
				num = Mathf.Min(itemAt.m_stack, dragAmount);
				flag2 = inventory.AddItemToInventory(switchItem, switchItem.m_stack, fromPos);
				if (!flag2)
				{
					Log.LogWarning("Could not switch item in Remove Request");
					InventoryHandler.DropItem(switchItem, switchItem.m_stack);
				}
			}
			ItemData val = itemAt.Clone();
			val.m_stack = num;
			return new RequestChestRemoveResponse(request.RequestID, flag, num, flag2, val);
		}

		public static RequestConsumeResponse RequestItemConsume(this Inventory inventory, RequestConsume request)
		{
			ItemData itemAt = inventory.GetItemAt(request.itemPosX, request.itemPosY);
			if (itemAt == null || itemAt.m_stack <= 0)
			{
				return new RequestConsumeResponse(null, success: false, 0);
			}
			inventory.RemoveOneItem(itemAt);
			ItemData val = itemAt.Clone();
			val.m_stack = 1;
			return new RequestConsumeResponse(val, success: true, 1);
		}

		public static RequestMoveResponse RequestItemMove(this Inventory inventory, RequestMove request)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			Vector2i fromPos = request.fromPos;
			Vector2i toPos = request.toPos;
			int dragAmount = request.dragAmount;
			ItemData itemAt = inventory.GetItemAt(fromPos.x, fromPos.y);
			if (itemAt == null)
			{
				return new RequestMoveResponse(request.RequestID, success: false, 0);
			}
			if (StringExtensionMethods.GetStableHashCode(itemAt.PrefabName()) != request.itemHash)
			{
				return new RequestMoveResponse(request.RequestID, success: false, 0);
			}
			int movedAmount;
			bool success = InventoryHelper.MoveItem(inventory, itemAt, dragAmount, toPos, out movedAmount);
			return new RequestMoveResponse(request.RequestID, success, movedAmount);
		}

		public static RequestDropResponse RequestDrop(this Inventory inventory, RequestDrop request)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			ItemData itemAt = inventory.GetItemAt(request.targetContainerSlot.x, request.targetContainerSlot.y);
			if (itemAt == null)
			{
				return new RequestDropResponse(null, request.sender, success: false, 0);
			}
			int num = Mathf.Min(itemAt.m_stack, request.amount);
			inventory.RemoveItem(itemAt, num);
			if (num == 0)
			{
				return new RequestDropResponse(null, request.sender, success: false, 0);
			}
			ItemData val = itemAt.Clone();
			val.m_stack = num;
			return new RequestDropResponse(val, request.sender, success: true, num);
		}
	}
	public interface IPackage
	{
		ZPackage WriteToPackage();
	}
	public interface IRequest : IPackage
	{
		int RequestID { get; set; }

		Inventory SourceInventory { get; }

		Inventory TargetInventory { get; }
	}
	public interface IResponse : IPackage
	{
		int SourceID { get; set; }

		bool Success { get; set; }

		int Amount { get; set; }
	}
	public class RequestChestAdd : IRequest, IPackage
	{
		public readonly Vector2i toPos;

		public readonly ItemData dragItem;

		public readonly bool allowSwitch;

		public int RequestID { get; set; }

		public Inventory SourceInventory { get; }

		public Inventory TargetInventory { get; }

		public RequestChestAdd(Vector2i toPos, int dragAmount, ItemData dragItem, Inventory sourceInventory, Inventory targetInventory)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			this.toPos = toPos;
			if (dragItem != null)
			{
				this.dragItem = dragItem.Clone();
				this.dragItem.m_stack = Mathf.Min(dragAmount, this.dragItem.m_stack);
				allowSwitch = dragAmount == dragItem.m_stack;
			}
			SourceInventory = sourceInventory;
			TargetInventory = targetInventory;
		}

		public RequestChestAdd(ZPackage package)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			RequestID = package.ReadInt();
			toPos = package.ReadVector2i();
			dragItem = InventoryHelper.LoadItemFromPackage(package);
			allowSwitch = package.ReadBool();
		}

		public ZPackage WriteToPackage()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			ZPackage val = new ZPackage();
			val.Write(RequestID);
			val.Write(toPos);
			InventoryHelper.WriteItemToPackage(dragItem, val);
			val.Write(allowSwitch);
			return val;
		}
	}
	public class RequestChestAddResponse : IPackage, IResponse
	{
		public Vector2i inventoryPos;

		public ItemData switchItem;

		public int SourceID { get; set; }

		public bool Success { get; set; }

		public int Amount { get; set; }

		public RequestChestAddResponse(int sourceID, bool success, Vector2i inventoryPos, int amount, ItemData switchItem)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			SourceID = sourceID;
			Success = success;
			Amount = amount;
			this.inventoryPos = inventoryPos;
			this.switchItem = switchItem.ClampStackSize();
		}

		public RequestChestAddResponse(ZPackage package)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			SourceID = package.ReadInt();
			inventoryPos = package.ReadVector2i();
			Success = package.ReadBool();
			Amount = package.ReadInt();
			switchItem = InventoryHelper.LoadItemFromPackage(package);
		}

		public RequestChestAddResponse()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			SourceID = 0;
			Success = false;
			inventoryPos = new Vector2i(-1, -1);
			Amount = 0;
			switchItem = null;
		}

		public ZPackage WriteToPackage()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			ZPackage val = new ZPackage();
			val.Write(SourceID);
			val.Write(inventoryPos);
			val.Write(Success);
			val.Write(Amount);
			InventoryHelper.WriteItemToPackage(switchItem, val);
			return val;
		}
	}
	public class RequestConsume : IPackage
	{
		public readonly int itemPosX;

		public readonly int itemPosY;

		public RequestConsume(ItemData item)
		{
			itemPosX = item.m_gridPos.x;
			itemPosY = item.m_gridPos.y;
		}

		public RequestConsume(ZPackage package)
		{
			itemPosX = package.ReadInt();
			itemPosY = package.ReadInt();
		}

		public ZPackage WriteToPackage()
		{
			//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(itemPosX);
			val.Write(itemPosY);
			return val;
		}
	}
	public class RequestConsumeResponse : IPackage, IResponse
	{
		public readonly ItemData item;

		public int SourceID { get; set; }

		public bool Success { get; set; }

		public int Amount { get; set; }

		public RequestConsumeResponse(ZPackage package)
		{
			item = InventoryHelper.LoadItemFromPackage(package);
			Success = package.ReadBool();
			Amount = package.ReadInt();
		}

		public RequestConsumeResponse(ItemData item, bool success, int amount)
		{
			this.item = item.ClampStackSize();
			Success = success;
			Amount = amount;
		}

		public RequestConsumeResponse()
		{
			item = null;
		}

		public ZPackage WriteToPackage()
		{
			//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();
			InventoryHelper.WriteItemToPackage(item, val);
			val.Write(Success);
			val.Write(Amount);
			return val;
		}
	}
	public class RequestDrop : IPackage
	{
		public readonly Vector2i targetContainerSlot;

		public readonly int amount;

		public readonly ZDOID sender;

		public RequestDrop(Vector2i targetContainerSlot, int amount, ZDOID sender)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: 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)
			this.targetContainerSlot = targetContainerSlot;
			this.amount = amount;
			this.sender = sender;
		}

		public RequestDrop(ZPackage package)
		{
			//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_0020: 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)
			targetContainerSlot = package.ReadVector2i();
			amount = package.ReadInt();
			sender = package.ReadZDOID();
		}

		public ZPackage WriteToPackage()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0008: 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)
			ZPackage val = new ZPackage();
			val.Write(targetContainerSlot);
			val.Write(amount);
			val.Write(sender);
			return val;
		}
	}
	public class RequestDropResponse : IPackage, IResponse
	{
		public readonly ItemData responseItem;

		public readonly ZDOID sender;

		public int SourceID { get; set; }

		public bool Success { get; set; }

		public int Amount { get; set; }

		public RequestDropResponse(ItemData responseItem, ZDOID sender, bool success, int amount)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			this.responseItem = responseItem.ClampStackSize();
			this.sender = sender;
			Success = success;
			Amount = amount;
		}

		public RequestDropResponse(ZPackage package)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			responseItem = InventoryHelper.LoadItemFromPackage(package);
			sender = package.ReadZDOID();
			Success = package.ReadBool();
			Amount = package.ReadInt();
		}

		public RequestDropResponse()
		{
			responseItem = null;
		}

		public ZPackage WriteToPackage()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			ZPackage val = new ZPackage();
			InventoryHelper.WriteItemToPackage(responseItem, val);
			val.Write(sender);
			val.Write(Success);
			val.Write(Amount);
			return val;
		}
	}
	public class RequestMove : IRequest, IPackage
	{
		public readonly Vector2i fromPos;

		public readonly Vector2i toPos;

		public readonly int itemHash;

		public readonly int dragAmount;

		public readonly ItemData item;

		public int RequestID { get; set; }

		public Inventory SourceInventory { get; }

		public Inventory TargetInventory { get; }

		public RequestMove(ItemData itemToMove, Vector2i toPos, int dragAmount, Inventory inventory)
		{
			//IL_004e: 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_0059: 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_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (itemToMove == null)
			{
				Log.LogWarning("Item is null");
				fromPos = new Vector2i(-1, -1);
				this.toPos = new Vector2i(-1, -1);
				itemHash = 0;
				this.dragAmount = 0;
			}
			else
			{
				SourceInventory = inventory;
				TargetInventory = inventory;
				fromPos = itemToMove.m_gridPos;
				this.toPos = toPos;
				itemHash = StringExtensionMethods.GetStableHashCode(itemToMove.PrefabName());
				item = itemToMove.Clone();
				this.dragAmount = dragAmount;
			}
		}

		public RequestMove(ZPackage package)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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)
			RequestID = package.ReadInt();
			fromPos = package.ReadVector2i();
			toPos = package.ReadVector2i();
			itemHash = package.ReadInt();
			dragAmount = package.ReadInt();
		}

		public ZPackage WriteToPackage()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			ZPackage val = new ZPackage();
			val.Write(RequestID);
			val.Write(fromPos);
			val.Write(toPos);
			val.Write(itemHash);
			val.Write(dragAmount);
			return val;
		}
	}
	public class RequestChestRemove : IRequest, IPackage
	{
		public readonly Vector2i fromPos;

		public readonly Vector2i toPos;

		public readonly int dragAmount;

		public readonly ItemData switchItem;

		public readonly ItemData item;

		public int RequestID { get; set; }

		public Inventory SourceInventory { get; }

		public Inventory TargetInventory { get; }

		public RequestChestRemove(Vector2i fromPos, Vector2i toPos, int dragAmount, ItemData switchItem, Inventory sourceInventory, Inventory targetInventory)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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)
			this.fromPos = fromPos;
			this.toPos = toPos;
			this.dragAmount = dragAmount;
			this.switchItem = ((switchItem != null) ? switchItem.Clone() : null);
			SourceInventory = sourceInventory;
			TargetInventory = targetInventory;
			object obj;
			if (sourceInventory == null)
			{
				obj = null;
			}
			else
			{
				ItemData itemAt = sourceInventory.GetItemAt(fromPos.x, fromPos.y);
				obj = ((itemAt != null) ? itemAt.Clone() : null);
			}
			item = (ItemData)obj;
		}

		public RequestChestRemove(ZPackage package)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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)
			RequestID = package.ReadInt();
			fromPos = package.ReadVector2i();
			toPos = package.ReadVector2i();
			dragAmount = package.ReadInt();
			switchItem = InventoryHelper.LoadItemFromPackage(package);
		}

		public ZPackage WriteToPackage()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Expected O, but got Unknown
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			ZPackage val = new ZPackage();
			val.Write(RequestID);
			val.Write(fromPos);
			val.Write(toPos);
			val.Write(dragAmount);
			InventoryHelper.WriteItemToPackage(switchItem, val);
			return val;
		}
	}
	public class RequestChestRemoveResponse : IPackage, IResponse
	{
		public ItemData responseItem;

		public bool hasSwitched;

		public int SourceID { get; set; }

		public bool Success { get; set; }

		public int Amount { get; set; }

		public RequestChestRemoveResponse(int sourceID, bool success, int amount, bool hasSwitched, ItemData responseItem)
		{
			SourceID = sourceID;
			Success = success;
			Amount = amount;
			this.hasSwitched = hasSwitched;
			this.responseItem = responseItem.ClampStackSize();
		}

		public RequestChestRemoveResponse(ZPackage package)
		{
			SourceID = package.ReadInt();
			Success = package.ReadBool();
			Amount = package.ReadInt();
			hasSwitched = package.ReadBool();
			responseItem = InventoryHelper.LoadItemFromPackage(package);
		}

		public RequestChestRemoveResponse()
		{
			Success = false;
			Amount = 0;
			hasSwitched = false;
			responseItem = null;
		}

		public ZPackage WriteToPackage()
		{
			//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(SourceID);
			val.Write(Success);
			val.Write(Amount);
			val.Write(hasSwitched);
			InventoryHelper.WriteItemToPackage(responseItem, val);
			return val;
		}
	}
	public class RequestMoveResponse : IPackage, IResponse
	{
		public int SourceID { get; set; }

		public bool Success { get; set; }

		public int Amount { get; set; }

		public RequestMoveResponse(int sourceID, bool success, int amount)
		{
			SourceID = sourceID;
			Success = success;
			Amount = amount;
		}

		public RequestMoveResponse()
		{
			SourceID = 0;
			Success = false;
			Amount = 0;
		}

		public RequestMoveResponse(ZPackage package)
		{
			SourceID = package.ReadInt();
			Success = package.ReadBool();
			Amount = package.ReadInt();
		}

		public ZPackage WriteToPackage()
		{
			//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(SourceID);
			val.Write(Success);
			val.Write(Amount);
			return val;
		}
	}
	public class SlotPreview
	{
		private Inventory originalInventory;

		private Inventory inventory;

		private bool hasChanges;

		public SlotPreview(Inventory inventory)
		{
			originalInventory = inventory;
			this.inventory = InventoryHelper.CopyInventory(inventory);
		}

		public void Add(Vector2i pos, ItemData item, int amount)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			if (item != null && amount != 0)
			{
				ItemData val = item.Clone();
				val.m_stack = amount;
				if (pos.x >= 0 && pos.y >= 0)
				{
					inventory.AddItem(val, amount, pos.x, pos.y);
				}
				else
				{
					inventory.AddItem(val);
				}
				hasChanges = true;
			}
		}

		public void Add(Vector2i pos, ItemData item)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			Add(pos, item, item?.m_stack ?? 0);
		}

		public void Remove(Vector2i pos, ItemData item)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			Remove(pos, item, item?.m_stack ?? 0);
		}

		public void Remove(Vector2i pos, ItemData item, int amount)
		{
			//IL_000d: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			if (item != null && amount != 0)
			{
				ItemData itemAt = inventory.GetItemAt(pos.x, pos.y);
				if (itemAt != null)
				{
					inventory.RemoveItem(inventory.GetItemAt(pos.x, pos.y), amount);
					hasChanges = true;
				}
			}
		}

		public bool GetSlot(Vector2i pos, out ItemData item)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: 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)
			ItemData itemAt = originalInventory.GetItemAt(pos.x, pos.y);
			item = inventory.GetItemAt(pos.x, pos.y);
			if (itemAt == null && item == null)
			{
				return false;
			}
			if (itemAt == null || item == null)
			{
				return true;
			}
			if (!(itemAt.m_shared.m_name != item.m_shared.m_name))
			{
				return itemAt.m_stack != item.m_stack;
			}
			return true;
		}

		public bool HasChanges()
		{
			return hasChanges;
		}
	}
	public static class ConditionalWeakTableExtension
	{
		public static void TryAdd<TKey, TValue>(this ConditionalWeakTable<TKey, TValue> table, TKey key, ConditionalWeakTable<TKey, TValue>.CreateValueCallback createCallback) where TKey : class where TValue : class
		{
			table.GetValue(key, createCallback);
		}
	}
	public static class InventoryHelper
	{
		public delegate void MoveAction(Inventory from, Inventory to);

		private static MethodBase memberwiseCloneMethod = AccessTools.Method(typeof(object), "MemberwiseClone", (Type[])null, (Type[])null);

		public static ItemData LoadItemFromPackage(ZPackage pkg)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Expected O, but got Unknown
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			if (!pkg.ReadBool())
			{
				return null;
			}
			string text = pkg.ReadString();
			int num = pkg.ReadInt();
			float num2 = pkg.ReadSingle();
			Vector2i val = pkg.ReadVector2i();
			int num3 = pkg.ReadInt();
			int num4 = pkg.ReadInt();
			long num5 = pkg.ReadLong();
			string text2 = pkg.ReadString();
			int num6 = pkg.ReadInt();
			bool flag = pkg.ReadBool();
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			int num7 = pkg.ReadInt();
			for (int i = 0; i < num7; i++)
			{
				string key = pkg.ReadString();
				string value = pkg.ReadString();
				dictionary[key] = value;
			}
			Inventory val2 = new Inventory("tmp", (Sprite)null, val.x + 1, val.y + 1);
			val2.AddItem(text, num, num2, val, false, num3, num4, num5, text2, dictionary, num6, flag);
			ItemData itemAt = val2.GetItemAt(val.x, val.y);
			val2.RemoveItem(itemAt);
			return itemAt;
		}

		public static void WriteItemToPackage(ItemData itemData, ZPackage pkg)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			pkg.Write(itemData != null);
			if (itemData == null)
			{
				return;
			}
			pkg.Write(itemData.PrefabName());
			pkg.Write(itemData.m_stack);
			pkg.Write(itemData.m_durability);
			pkg.Write(itemData.m_gridPos);
			pkg.Write(itemData.m_quality);
			pkg.Write(itemData.m_variant);
			pkg.Write(itemData.m_crafterID);
			pkg.Write(itemData.m_crafterName);
			pkg.Write(itemData.m_worldLevel);
			pkg.Write(itemData.m_pickedUp);
			pkg.Write(itemData.m_customData.Count);
			foreach (KeyValuePair<string, string> customDatum in itemData.m_customData)
			{
				pkg.Write(customDatum.Key);
				pkg.Write(customDatum.Value);
			}
		}

		public static ItemData ClampStackSize(this ItemData item)
		{
			if (item == null)
			{
				return null;
			}
			ItemDrop prefab = Cache.GetPrefab<ItemDrop>(item.PrefabName());
			item.m_shared.m_maxStackSize = prefab.m_itemData.m_shared.m_maxStackSize;
			return item;
		}

		public static string PrefabName(this ItemData item)
		{
			if ((Object)(object)item.m_dropPrefab != (Object)null)
			{
				return ((Object)item.m_dropPrefab).name;
			}
			Log.LogWarning("Item missing prefab " + item.m_shared.m_name);
			return item.m_shared.m_name;
		}

		public static bool MoveItem(Inventory inventory, ItemData item, int amount, Vector2i toPos, out int movedAmount)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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_0069: 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_00b7: 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)
			movedAmount = 0;
			if (item == null)
			{
				return false;
			}
			ItemData itemAt = inventory.GetItemAt(toPos.x, toPos.y);
			if (itemAt == item)
			{
				return true;
			}
			if (itemAt == null)
			{
				movedAmount = amount;
				return inventory.MoveItemToThis(inventory, item, amount, toPos.x, toPos.y);
			}
			if (CanStack(itemAt, item))
			{
				movedAmount = Mathf.Min(amount, itemAt.m_shared.m_maxStackSize - itemAt.m_stack);
				return inventory.MoveItemToThis(inventory, item, movedAmount, toPos.x, toPos.y);
			}
			if (item.m_stack != amount)
			{
				return false;
			}
			inventory.RemoveItem(item);
			inventory.MoveItemToThis(inventory, itemAt, itemAt.m_stack, item.m_gridPos.x, item.m_gridPos.y);
			inventory.MoveItemToThis(inventory, item, amount, toPos.x, toPos.y);
			movedAmount = amount;
			return true;
		}

		public static bool CanStack(ItemData itemA, ItemData itemB)
		{
			if (itemA.m_shared.m_name == itemB.m_shared.m_name && (itemA.m_shared.m_maxQuality <= 1 || itemB.m_quality == itemA.m_quality))
			{
				return itemA.m_shared.m_maxStackSize != 1;
			}
			return false;
		}

		public static Vector2i FindEmptySlot(Inventory inventory, List<Vector2i> blockedSlots)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < inventory.m_height; i++)
			{
				for (int j = 0; j < inventory.m_width; j++)
				{
					if (inventory.GetItemAt(j, i) == null && !blockedSlots.Contains(new Vector2i(j, i)))
					{
						return new Vector2i(j, i);
					}
				}
			}
			return new Vector2i(-1, -1);
		}

		public static List<ItemData> GetAllMoveableItems(Inventory from, Inventory to, MoveAction moveAction)
		{
			Inventory val = CopyInventory(from);
			Inventory to2 = CopyInventory(to);
			moveAction(val, to2);
			return CountMoved(from, val);
		}

		public static List<ItemData> GetAllMoveableItems(Inventory from, Inventory to)
		{
			return GetAllMoveableItems(from, to, MoveAll);
		}

		public static void MoveAll(Inventory from, Inventory to)
		{
			to.MoveAll(from);
		}

		private static List<ItemData> CountMoved(Inventory from, Inventory fromCopy)
		{
			List<ItemData> list = new List<ItemData>();
			foreach (ItemData item in from.m_inventory)
			{
				ItemData itemAt = fromCopy.GetItemAt(item.m_gridPos.x, item.m_gridPos.y);
				if (itemAt == null)
				{
					list.Add(item);
				}
				else if (item.m_stack > itemAt.m_stack)
				{
					ItemData val = item.Clone();
					val.m_stack = item.m_stack - itemAt.m_stack;
					list.Add(val);
				}
			}
			return list;
		}

		public static Inventory CopyInventory(Inventory target)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			return new Inventory(target.m_name, target.m_bkg, target.m_width, target.m_height)
			{
				m_inventory = new List<ItemData>(from x in target.GetAllItems()
					select x.Clone())
			};
		}

		public static bool AddItemToInventory(this Inventory target, ItemData item, int amount, Vector2i pos)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			if (amount == 0)
			{
				return false;
			}
			ItemData itemAt = target.GetItemAt(pos.x, pos.y);
			if (itemAt != null)
			{
				if (!CanStack(itemAt, item))
				{
					return false;
				}
				if (itemAt.m_stack + amount > itemAt.m_shared.m_maxStackSize)
				{
					return false;
				}
			}
			ItemData val = item.CloneDeeper();
			val.m_stack = amount;
			return target.AddItem(val, amount, pos.x, pos.y);
		}

		public static ItemData CloneDeeper(this ItemData itemDrop)
		{
			ItemData val = itemDrop.Clone();
			ref SharedData shared = ref val.m_shared;
			object? obj = memberwiseCloneMethod.Invoke(itemDrop.m_shared, null);
			shared = (SharedData)((obj is SharedData) ? obj : null);
			return val;
		}

		public static void PrintItem(string title, ItemData itemData)
		{
		}
	}
	public static class Log
	{
		private static ManualLogSource logSource;

		internal static void Init(ManualLogSource manualLogSource)
		{
			logSource = manualLogSource;
		}

		public static void LogCodeInstruction(object data)
		{
		}

		public static void LogDebug(string data)
		{
		}

		public static void LogError(string data)
		{
			if (logSource != null)
			{
				logSource.LogError((object)data);
			}
			else
			{
				Debug.LogError((object)data);
			}
		}

		public static void LogFatal(string data)
		{
			if (logSource != null)
			{
				logSource.LogFatal((object)data);
			}
			else
			{
				Debug.LogError((object)data);
			}
		}

		public static void LogInfo(string data)
		{
			if (logSource != null)
			{
				logSource.LogInfo((object)data);
			}
			else
			{
				Debug.Log((object)data);
			}
		}

		public static void LogWarning(string data)
		{
			if (logSource != null)
			{
				logSource.LogWarning((object)data);
			}
			else
			{
				Debug.LogWarning((object)data);
			}
		}
	}
	public static class ReflectionHelper
	{
		private const BindingFlags allFlags = (BindingFlags)(-1);

		public static bool IsType(this object target, string name)
		{
			return target.GetType().Name == name;
		}

		public static bool HasField(this object target, string name)
		{
			return target.GetType().GetField(name, (BindingFlags)(-1)) != null;
		}

		public static T GetField<T>(this object target, string name)
		{
			return (T)(target.GetType().GetField(name, (BindingFlags)(-1))?.GetValue(target));
		}

		public static T InvokeMethod<T>(this object target, string name, params object[] parameter)
		{
			parameter = ((parameter.Length == 0) ? null : parameter);
			return (T)(target.GetType().GetMethod(name, (BindingFlags)(-1))?.Invoke(target, parameter));
		}

		public static T InvokeStaticMethod<T>(string type, string name, params object[] parameter)
		{
			parameter = ((parameter.Length == 0) ? null : parameter);
			return (T)(Type.GetType(type)?.GetMethod(name, (BindingFlags)(-1))?.Invoke(null, parameter));
		}
	}
	public class HumanoidExtend : MonoBehaviour
	{
		private static readonly ConditionalWeakTable<Inventory, HumanoidInventoryOwner> Humanoids = new ConditionalWeakTable<Inventory, HumanoidInventoryOwner>();

		private Inventory inventory;

		private void Awake()
		{
			UpdateInventory();
		}

		private void Start()
		{
			UpdateInventory();
		}

		private void UpdateInventory()
		{
			Humanoid humanoid = default(Humanoid);
			if (!((Component)this).TryGetComponent<Humanoid>(ref humanoid))
			{
				return;
			}
			inventory = humanoid.GetInventory();
			if (inventory == null)
			{
				return;
			}
			foreach (Inventory inventory in inventory.GetInventories())
			{
				Humanoids.TryAdd(inventory, (Inventory i) => new HumanoidInventoryOwner(humanoid, i));
			}
		}

		private void OnDestroy()
		{
			if (inventory == null)
			{
				return;
			}
			foreach (Inventory inventory in inventory.GetInventories())
			{
				Humanoids.Remove(inventory);
			}
		}

		public static bool GetHumanoid(Inventory inventory, out HumanoidInventoryOwner humanoid)
		{
			return Humanoids.TryGetValue(inventory, out humanoid);
		}
	}
	public class InventoryBlock
	{
		private static readonly Dictionary<Inventory, InventoryBlock> Inventories = new Dictionary<Inventory, InventoryBlock>();

		public bool BlockAllSlots { get; set; }

		public bool BlockConsume { get; set; }

		public Dictionary<Vector2i, int> BlockedSlots { get; } = new Dictionary<Vector2i, int>();


		public static InventoryBlock Get(Inventory inventory)
		{
			if (Inventories.TryGetValue(inventory, out var value))
			{
				return value;
			}
			InventoryBlock inventoryBlock = new InventoryBlock();
			Inventories.Add(inventory, inventoryBlock);
			return inventoryBlock;
		}

		public void BlockSlot(Vector2i slot)
		{
			//IL_0000: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: 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_0027: Unknown result type (might be due to invalid IL or missing references)
			if (CanBlockSlot(slot))
			{
				if (BlockedSlots.ContainsKey(slot))
				{
					BlockedSlots[slot]++;
				}
				else
				{
					BlockedSlots[slot] = 1;
				}
			}
		}

		public void ReleaseSlot(Vector2i slot)
		{
			//IL_0000: 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_001e: 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_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			if (CanBlockSlot(slot) && BlockedSlots.ContainsKey(slot))
			{
				BlockedSlots[slot]--;
				if (BlockedSlots[slot] <= 0)
				{
					BlockedSlots.Remove(slot);
				}
			}
		}

		public void ReleaseBlockedSlots()
		{
			BlockedSlots.Clear();
			BlockAllSlots = false;
			BlockConsume = false;
		}

		public bool IsSlotBlocked(Vector2i slot)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			if (!BlockConsume && !BlockAllSlots)
			{
				return BlockedSlots.ContainsKey(slot);
			}
			return true;
		}

		public bool IsAnySlotBlocked()
		{
			if (!BlockConsume && !BlockAllSlots)
			{
				return BlockedSlots.Count > 0;
			}
			return true;
		}

		private static bool CanBlockSlot(Vector2i slot)
		{
			//IL_0000: 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)
			if (slot.x >= 0)
			{
				return slot.y >= 0;
			}
			return false;
		}
	}
	public static class InventoryHandler
	{
		public static void RPC_RequestItemAddResponse(long sender, ZDOID containerId, ZPackage package)
		{
			HandleRPC(new RequestChestAddResponse(package), (RequestChestAddResponse p) => GetSourceInventory(p.SourceID), RPC_RequestItemAddResponse);
		}

		public static void RPC_RequestItemRemoveResponse(long sender, ZDOID containerId, ZPackage package)
		{
			HandleRPC(new RequestChestRemoveResponse(package), (RequestChestRemoveResponse p) => GetTargetInventory(p.SourceID), RPC_RequestItemRemoveResponse);
		}

		public static void RPC_RequestDropResponse(long sender, ZDOID containerId, ZPackage package)
		{
			HandleRPC(new RequestDropResponse(package), RPC_RequestDropResponse);
		}

		public static void RPC_RequestItemConsumeResponse(long sender, ZDOID containerId, ZPackage package)
		{
			HandleRPC(new RequestConsumeResponse(package), RPC_RequestItemConsumeResponse);
		}

		public static void RPC_RequestItemMoveResponse(long sender, ZDOID containerId, ZPackage package)
		{
			HandleRPC(new RequestMoveResponse(package), RPC_RequestItemMoveResponse);
		}

		private static void HandleRPC<T>(T package, Func<T, Inventory> inventory, Container container, Action<Inventory, Container, T> handle) where T : IPackage
		{
			CallRPC(handle.Method.Name, package, delegate
			{
				handle(inventory(package), container, package);
			});
		}

		private static void HandleRPC<T>(T package, Func<T, Inventory> inventory, Action<Inventory, T> handle) where T : IPackage
		{
			CallRPC(handle.Method.Name, package, delegate
			{
				handle(inventory(package), package);
			});
		}

		private static void HandleRPC<T>(T package, Action<T> handle) where T : IPackage
		{
			CallRPC(handle.Method.Name, package, delegate
			{
				handle(package);
			});
		}

		private static void CallRPC(string timerName, IPackage package, Action action)
		{
			action?.Invoke();
		}

		public static void RPC_RequestItemRemoveResponse(Inventory inventory, RequestChestRemoveResponse response)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Expected O, but got Unknown
			//IL_003a: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			Vector2i toPos = PackageHandler.GetPackage<RequestChestRemove>(response.SourceID).toPos;
			InventoryBlock.Get(inventory).ReleaseSlot(toPos);
			InventoryPreview.RemovePackage(response);
			if (response.Success && toPos.x >= 0 && toPos.y >= 0)
			{
				if (!inventory.AddItemToInventory(response.responseItem, response.Amount, toPos))
				{
					int num = response.Amount;
					ItemData itemAt = inventory.GetItemAt(toPos.x, toPos.y);
					if (itemAt != null && InventoryHelper.CanStack(response.responseItem, itemAt))
					{
						int maxStackSize = itemAt.m_shared.m_maxStackSize;
						int stack = itemAt.m_stack;
						int num2 = maxStackSize - stack;
						itemAt.m_stack += num2;
						num -= num2;
					}
					DropItem(response.responseItem, num);
				}
			}
			else if (response.responseItem != null)
			{
				Inventory val = new Inventory("tmp", (Sprite)null, 1, 1);
				val.AddItem(response.responseItem);
				inventory.MoveItemToThis(val, response.responseItem);
				ItemData itemAt2 = val.GetItemAt(0, 0);
				if (itemAt2 != null)
				{
					DropItem(itemAt2, itemAt2.m_stack);
				}
			}
			UpdateGUIAfterPlayerMove(GetTargetInventory(response.SourceID));
		}

		private static void RPC_RequestDropResponse(RequestDropResponse response)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			DropItem(response.responseItem, response.responseItem?.m_stack ?? 0);
			UpdateGUIAfterPlayerMove(response.sender);
		}

		private static void UpdateGUIAfterPlayerMove(ZDOID sender)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)InventoryGui.instance) && Object.op_Implicit((Object)(object)Player.m_localPlayer) && sender == ((Character)Player.m_localPlayer).GetZDOID())
			{
				InventoryGui.instance.UpdateCraftingPanel(false);
			}
		}

		private static void UpdateGUIAfterPlayerMove(Inventory inventory)
		{
			if (Object.op_Implicit((Object)(object)InventoryGui.instance) && Object.op_Implicit((Object)(object)Player.m_localPlayer) && ((Humanoid)Player.m_localPlayer).GetInventory().GetInventories().Contains(inventory))
			{
				InventoryGui.instance.UpdateCraftingPanel(false);
			}
		}

		public static void DropItem(ItemData item, int amount)
		{
			if (amount > 0 && item != null)
			{
				DropItem(Player.m_localPlayer, item, amount);
			}
		}

		private static void DropItem(Player player, ItemData item, int amount)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: 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_0043: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((Component)player).transform;
			ItemDrop val = ItemDrop.DropItem(item, amount, transform.position + transform.forward + transform.up, transform.rotation);
			val.OnPlayerDrop();
			((Component)val).GetComponent<Rigidbody>().velocity = (transform.forward + Vector3.up) * 5f;
			((Character)player).m_zanim.SetTrigger("interact");
			((Humanoid)player).m_dropEffects.Create(transform.position, Quaternion.identity, (Transform)null, 1f, -1);
			ItemData itemData = val.m_itemData;
			((Character)player).Message((MessageType)1, "$msg_dropped " + itemData.m_shared.m_name, itemData.m_stack, itemData.GetIcon());
		}

		public static void RPC_RequestItemAddResponse(Inventory inventory, RequestChestAddResponse response)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: 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)
			Vector2i inventoryPos = response.inventoryPos;
			ItemData switchItem = response.switchItem;
			InventoryBlock.Get(inventory).ReleaseSlot(inventoryPos);
			InventoryPreview.RemovePackage(response);
			if (switchItem != null && !inventory.AddItemToInventory(switchItem, switchItem.m_stack, inventoryPos))
			{
				DropItem(switchItem, switchItem.m_stack);
			}
			UpdateGUIAfterPlayerMove(GetSourceInventory(response.SourceID));
		}

		public static void RPC_RequestItemConsumeResponse(RequestConsumeResponse response)
		{
			Player localPlayer = Player.m_localPlayer;
			InventoryBlock.Get(((Humanoid)localPlayer).GetInventory()).BlockConsume = false;
			if (response.item != null && ((Humanoid)localPlayer).CanConsumeItem(response.item, false))
			{
				if (Object.op_Implicit((Object)(object)response.item.m_shared.m_consumeStatusEffect))
				{
					((Character)localPlayer).m_seman.AddStatusEffect(response.item.m_shared.m_consumeStatusEffect, true, 0, 0f);
				}
				if ((double)response.item.m_shared.m_food > 0.0)
				{
					localPlayer.EatFood(response.item);
				}
			}
		}

		public static void RPC_RequestItemMoveResponse(RequestMoveResponse response)
		{
			InventoryPreview.RemovePackage(response);
		}

		internal static Inventory GetSourceInventory(int id)
		{
			return PackageHandler.GetPackage<IRequest>(id)?.SourceInventory;
		}

		internal static Inventory GetTargetInventory(int id)
		{
			return PackageHandler.GetPackage<IRequest>(id)?.TargetInventory;
		}
	}
	public abstract class InventoryOwner
	{
		public abstract ZNetView ZNetView { get; }

		public abstract Inventory Inventory { get; }

		public virtual bool IsValid()
		{
			if (Object.op_Implicit((Object)(object)ZNetView) && ZNetView.HasOwner())
			{
				return Inventory != null;
			}
			return false;
		}

		public static InventoryOwner GetOwner(Inventory inventory)
		{
			if (HumanoidExtend.GetHumanoid(inventory, out var humanoid))
			{
				return humanoid;
			}
			if (ContainerExtend.GetContainer(inventory, out var container))
			{
				return container;
			}
			return null;
		}

		public static InventoryOwner GetOwner(ItemData item)
		{
			if (InventoryPatch.InventoryOfItem.TryGetValue(item, out var value))
			{
				return GetOwner(value);
			}
			return null;
		}

		public string GetDescription()
		{
			if (!IsValid())
			{
				return "-";
			}
			return $"{Inventory.GetName()} ({GetType().Name}), is owner: {ZNetView.IsOwner()}";
		}
	}
	public class ContainerInventoryOwner : InventoryOwner
	{
		public Container Container { get; }

		public bool IsItemDrawer { get; }

		public override ZNetView ZNetView => Container.m_nview;

		public override Inventory Inventory => Container.GetInventory();

		public ContainerInventoryOwner(Container container)
		{
			Container = container;
			IsItemDrawer = ItemDrawerCompat.IsItemDrawer(Container);
		}
	}
	public class HumanoidInventoryOwner : InventoryOwner
	{
		private readonly Inventory inventory;

		public Humanoid Humanoid { get; }

		public override ZNetView ZNetView => ((Character)Humanoid).m_nview;

		public override Inventory Inventory => inventory;

		public HumanoidInventoryOwner(Humanoid humanoid, Inventory inventory)
		{
			Humanoid = humanoid;
			this.inventory = inventory;
		}
	}
	public static class InventoryPreview
	{
		public static readonly ConditionalWeakTable<Inventory, List<IRequest>> PackageChanges = new ConditionalWeakTable<Inventory, List<IRequest>>();

		public static readonly ConditionalWeakTable<Inventory, List<IRequest>> ToRemovePackages = new ConditionalWeakTable<Inventory, List<IRequest>>();

		private static WaitForSeconds removeQueuedPackagesDelay = new WaitForSeconds(0.2f);

		public static void AddPackage(IRequest package)
		{
			package.RequestID = PackageHandler.AddPackage(package);
			AppendPackage(package.SourceInventory, package);
			AppendPackage(package.TargetInventory, package);
		}

		private static void AppendPackage(Inventory inventory, IRequest package)
		{
			if (PackageChanges.TryGetValue(inventory, out var value))
			{
				if (!value.Contains(package))
				{
					value.Add(package);
				}
				Log.LogDebug($"InventoryPreview: Appended package {package.RequestID} to inventory {inventory.m_name}, total packages: {value.Count}");
				return;
			}
			PackageChanges.Add(inventory, new List<IRequest> { package });
			Inventory obj = inventory;
			obj.m_onChanged = (Action)Delegate.Combine(obj.m_onChanged, (Action)delegate
			{
				RemoveQueuedPackages(inventory);
			});
			Log.LogDebug($"InventoryPreview: Added package {package.RequestID} to inventory {inventory.m_name}, total packages: 1 (new)");
		}

		public static void RemovePackage(IResponse package)
		{
			RemovePackage(InventoryHandler.GetSourceInventory(package.SourceID), package);
			RemovePackage(InventoryHandler.GetTargetInventory(package.SourceID), package);
			PackageHandler.RemovePackage(package.SourceID);
		}

		private static void RemovePackage(Inventory inventory, IResponse package)
		{
			if (inventory == null)
			{
				return;
			}
			InventoryOwner owner = InventoryOwner.GetOwner(inventory);
			IRequest request = null;
			if (PackageChanges.TryGetValue(inventory, out var value))
			{
				request = value.Find((IRequest p) => p.RequestID == package.SourceID);
			}
			if (request != null)
			{
				if (ToRemovePackages.TryGetValue(inventory, out var value2))
				{
					value2.Add(request);
				}
				else
				{
					ToRemovePackages.Add(inventory, new List<IRequest> { request });
				}
				if (owner != null && owner.IsValid() && owner.ZNetView.IsOwner())
				{
					RemoveQueuedPackages(inventory);
				}
				else if (!package.Success)
				{
					((MonoBehaviour)ThreadingHelper.Instance).StartCoroutine(RemoveQueuedPackagesDelayed(inventory));
				}
			}
		}

		private static void RemoveQueuedPackages(Inventory inventory)
		{
			if (!ToRemovePackages.TryGetValue(inventory, out var value) || value.Count <= 0)
			{
				return;
			}
			foreach (IRequest item in new List<IRequest>(value))
			{
				if (PackageChanges.TryGetValue(inventory, out var value2))
				{
					value2.Remove(item);
				}
				value.Remove(item);
				Log.LogDebug($"InventoryPreview: Removed package {item.RequestID} from inventory {inventory.m_name}, total packages: {value.Count}");
			}
		}

		private static IEnumerator RemoveQueuedPackagesDelayed(Inventory inventory)
		{
			yield return removeQueuedPackagesDelay;
			RemoveQueuedPackages(inventory);
		}

		public static bool GetChanges(Inventory inventory, out SlotPreview preview)
		{
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			if (inventory == null)
			{
				preview = null;
				return false;
			}
			if (PackageChanges.TryGetValue(inventory, out var value))
			{
				preview = new SlotPreview(inventory);
				foreach (IRequest item3 in value)
				{
					if (item3 is RequestChestAdd requestChestAdd)
					{
						if (requestChestAdd.dragItem != null)
						{
							ItemData item = null;
							if (requestChestAdd.allowSwitch)
							{
								item = item3.TargetInventory.GetItemAt(requestChestAdd.toPos.x, requestChestAdd.toPos.y);
							}
							if (inventory == item3.SourceInventory)
							{
								preview.Add(requestChestAdd.dragItem.m_gridPos, item);
							}
							if (inventory == item3.TargetInventory)
							{
								preview.Remove(requestChestAdd.toPos, item);
								preview.Add(requestChestAdd.toPos, requestChestAdd.dragItem);
							}
						}
					}
					else if (item3 is RequestChestRemove requestChestRemove)
					{
						Vector2i fromPos = requestChestRemove.fromPos;
						Vector2i toPos = requestChestRemove.toPos;
						if (inventory == item3.SourceInventory)
						{
							preview.Remove(fromPos, requestChestRemove.item, requestChestRemove.dragAmount);
							preview.Add(fromPos, requestChestRemove.switchItem);
						}
						if (inventory == item3.TargetInventory)
						{
							preview.Add(toPos, requestChestRemove.item, requestChestRemove.dragAmount);
						}
					}
					else
					{
						if (!(item3 is RequestMove requestMove) || (preview.GetSlot(requestMove.fromPos, out var item2) && requestMove.itemHash != ((item2 != null) ? new int?(StringExtensionMethods.GetStableHashCode(item2.PrefabName())) : null)))
						{
							continue;
						}
						ItemData itemAt = requestMove.TargetInventory.GetItemAt(requestMove.toPos.x, requestMove.toPos.y);
						if (itemAt != null && !InventoryHelper.CanStack(requestMove.item, itemAt))
						{
							if (requestMove.dragAmount == requestMove.item.m_stack)
							{
								preview.Remove(requestMove.fromPos, requestMove.item, requestMove.dragAmount);
								preview.Remove(requestMove.toPos, itemAt, itemAt.m_stack);
								preview.Add(requestMove.fromPos, itemAt, itemAt.m_stack);
								preview.Add(requestMove.toPos, requestMove.item, requestMove.dragAmount);
							}
						}
						else
						{
							int amount = Mathf.Max(0, requestMove.dragAmount);
							if (itemAt != null)
							{
								amount = Mathf.Min(itemAt.m_shared.m_maxStackSize - itemAt.m_stack, requestMove.dragAmount);
							}
							preview.Remove(requestMove.fromPos, requestMove.item, amount);
							preview.Add(requestMove.toPos, requestMove.item, amount);
						}
					}
				}
				return preview.HasChanges();
			}
			preview = null;
			return false;
		}
	}
	public static class ItemDrawerCompat
	{
		private static Type drawerContainerType;

		private static FieldRef<object, ItemData> drawerField_item;

		static ItemDrawerCompat()
		{
			if (Chainloader.PluginInfos.ContainsKey("mkz.itemdrawers"))
			{
				drawerContainerType = AccessTools.TypeByName("DrawerContainer, itemdrawers");
				drawerField_item = AccessTools.FieldRefAccess<ItemData>(drawerContainerType, "_item");
			}
		}

		public static bool IsItemDrawer(Container container)
		{
			if (drawerContainerType != null)
			{
				return Object.op_Implicit((Object)(object)((Component)container).GetComponent(drawerContainerType));
			}
			return false;
		}

		[HarmonyPatch("DrawerContainer, itemdrawers", "OnInventoryChanged")]
		[HarmonyPrefix]
		public static void UpdateItemOfDrawer(Container __instance)
		{
			if (__instance.m_inventory.m_inventory.Count != 0 && __instance.m_inventory.m_inventory[0] != null)
			{
				drawerField_item.Invoke((object)__instance) = __instance.m_inventory.m_inventory[0].Clone();
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Inventory), "AddItem", new Type[] { typeof(ItemData) })]
		[HarmonyPatch(typeof(Inventory), "AddItem", new Type[]
		{
			typeof(ItemData),
			typeof(int),
			typeof(int),
			typeof(int)
		})]
		[HarmonyPriority(700)]
		public static bool PreventItemAdd(Inventory __instance, ItemData item)
		{
			if (InventoryOwner.GetOwner(__instance) is ContainerInventoryOwner containerInventoryOwner && containerInventoryOwner.IsItemDrawer)
			{
				ItemData val = drawerField_item.Invoke((object)containerInventoryOwner.Container);
				if (val != null && val.PrefabName() != item?.PrefabName())
				{
					Log.LogInfo("PreventItemAdd: " + val.PrefabName() + " != " + item?.PrefabName());
					return false;
				}
			}
			return true;
		}

		[HarmonyPatch(typeof(Inventory), "CanAddItem", new Type[]
		{
			typeof(ItemData),
			typeof(int)
		})]
		[HarmonyPostfix]
		public static void CanAddItem(Inventory __instance, ref bool __result, ItemData item)
		{
			if (__result && InventoryOwner.GetOwner(__instance) is ContainerInventoryOwner containerInventoryOwner && containerInventoryOwner.IsItemDrawer)
			{
				ItemData val = drawerField_item.Invoke((object)containerInventoryOwner.Container);
				__result = val == null || val.PrefabName() == item?.PrefabName();
			}
		}

		[HarmonyPatch("DrawerContainer, itemdrawers", "AddItem")]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> CloneItemBeforeAssignmentTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Expected O, but got Unknown
			return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[2]
			{
				new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(ItemDrop), "m_itemData"), (string)null),
				new CodeMatch((OpCode?)OpCodes.Stfld, (object)AccessTools.Field(drawerContainerType, "_item"), (string)null)
			}).Advance(1).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(InventoryHelper), "CloneDeeper", (Type[])null, (Type[])null))
			})
				.InstructionEnumeration();
		}
	}
	public static class OdinShip
	{
		public static bool IsOdinShipInstalled()
		{
			if (!Chainloader.PluginInfos.ContainsKey("marlthon.OdinShipPlus"))
			{
				return Chainloader.PluginInfos.ContainsKey("marlthon.OdinShip");
			}
			return true;
		}

		public static bool IsOdinShipContainer(this Container container)
		{
			return ((object)container).GetType().FullName == "OdinShip.ShipContainer";
		}
	}
	public static class QuickStackPatch
	{
		[HarmonyPatch("QuickStack.QuickStackPlugin, QuickStack", "StackToMany")]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> QuickStackPatchTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[2]
			{
				new CodeMatch((OpCode?)OpCodes.Ldloc_S, (object)null, (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.IsVirtCall("ZNetView", "ClaimOwnership")), (string)null)
			}).RemoveInstructions(9).InstructionEnumeration();
		}
	}
	[BepInPlugin("com.maxsch.valheim.MultiUserChest", "MultiUserChest", "0.5.10")]
	[BepInIncompatibility("aedenthorn.QuickStore")]
	[BepInIncompatibility("aedenthorn.SimpleSort")]
	[BepInIncompatibility("org.bepinex.plugins.valheim.quick_stack")]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string ModName = "MultiUserChest";

		public const string ModGuid = "com.maxsch.valheim.MultiUserChest";

		public const string ModVersion = "0.5.10";

		private static Harmony harmony = new Harmony("com.maxsch.valheim.MultiUserChest");

		public static Plugin Instance { get; private set; }

		private void Awake()
		{
			Instance = this;
			Log.Init(((BaseUnityPlugin)this).Logger);
			harmony.PatchAll();
			((MonoBehaviour)this).InvokeRepeating("UpdateAccessedContainer", 0f, 0.1f);
		}

		private void Start()
		{
			ApplyModPatches();
		}

		internal static void ApplyModPatches()
		{
			if (Chainloader.PluginInfos.ContainsKey("mkz.itemdrawers"))
			{
				harmony.PatchAll(typeof(ItemDrawerCompat));
			}
		}

		private void UpdateAccessedContainer()
		{
			//IL_0088: 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 (Object.op_Implicit((Object)(object)Player.m_localPlayer) && ((Character)Player.m_localPlayer).m_nview.IsValid() && Object.op_Implicit((Object)(object)InventoryGui.instance))
			{
				Container currentContainer = InventoryGui.instance.m_currentContainer;
				if (Object.op_Implicit((Object)(object)currentContainer) && currentContainer.m_nview.IsValid())
				{
					((Character)Player.m_localPlayer).m_nview.GetZDO().Set("accessed-container", currentContainer.m_nview.GetZDO().m_uid);
				}
				else
				{
					((Character)Player.m_localPlayer).m_nview.GetZDO().Set("accessed-container", ZDOID.None);
				}
			}
		}
	}
	public static class PackageHandler
	{
		private static readonly Dictionary<int, IPackage> Packages = new Dictionary<int, IPackage>();

		private static readonly Random Random = new Random();

		private static int total;

		public static int AddPackage(IPackage package)
		{
			int randomId = GetRandomId();
			Packages.Add(randomId, package);
			return randomId;
		}

		public static void RemovePackage(int id)
		{
			Packages.Remove(id);
		}

		private static int GetRandomId()
		{
			return Random.Next(int.MinValue, int.MaxValue);
		}

		public static bool GetPackage<T>(int id, out T package) where T : IPackage
		{
			if (Packages.TryGetValue(id, out var value))
			{
				package = (T)value;
				return true;
			}
			package = default(T);
			return false;
		}

		public static T GetPackage<T>(int id) where T : IPackage
		{
			if (Packages.TryGetValue(id, out var value))
			{
				return (T)value;
			}
			return default(T);
		}
	}
}
namespace MultiUserChest.Patches
{
	[HarmonyPatch]
	public static class ContainerPatch
	{
		public const string ItemMoveRPC = "MUC_RequestItemMove";

		public const string ItemMoveResponseRPC = "MUC_RequestItemMoveResponse";

		public const string ItemAddRPC = "MUC_RequestItemAdd";

		public const string ItemAddResponseRPC = "MUC_RequestItemAddResponse";

		public const string ItemRemoveRPC = "MUC_RequestItemRemove";

		public const string ItemRemoveResponseRPC = "MUC_RequestItemRemoveResponse";

		public const string ItemConsumeRPC = "MUC_RequestItemConsume";

		public const string ItemConsumeResponseRPC = "MUC_RequestItemConsumeResponse";

		public const string ItemDropRPC = "MUC_RequestItemDrop";

		public const string ItemDropResponseRPC = "MUC_RequestItemDropResponse";

		[HarmonyPatch(typeof(Container), "Awake")]
		[HarmonyPostfix]
		public static void ContainerAwakePatch(Container __instance)
		{
			((Component)__instance).gameObject.AddComponent<ContainerExtend>();
			if (!__instance.IsOdinShipContainer() && !Object.op_Implicit((Object)(object)__instance.m_nview))
			{
				__instance.m_nview = (Object.op_Implicit((Object)(object)__instance.m_rootObjectOverride) ? ((Component)__instance.m_rootObjectOverride).GetComponent<ZNetView>() : ((Component)__instance).GetComponent<ZNetView>());
			}
		}

		[HarmonyPatch(typeof(Container), "RPC_RequestOpen")]
		[HarmonyPrefix]
		public static bool ContainerRPC_RequestOpenPatch(Container __instance, long uid, long playerID)
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			if (__instance.IsOdinShipContainer() || !__instance.m_nview.IsOwner())
			{
				return true;
			}
			if (!__instance.CheckAccess(playerID))
			{
				__instance.m_nview.InvokeRPC(uid, "OpenRespons", new object[1] { false });
				return false;
			}
			if (IsContainerInUse(__instance, uid))
			{
				__instance.m_nview.InvokeRPC(uid, "OpenRespons", new object[1] { true });
				return false;
			}
			ZDOMan.instance.ForceSendZDO(uid, __instance.m_nview.GetZDO().m_uid);
			__instance.m_nview.GetZDO().SetOwner(uid);
			__instance.m_nview.InvokeRPC(uid, "OpenRespons", new object[1] { true });
			return false;
		}

		[HarmonyPatch(typeof(Container), "RPC_RequestStack")]
		[HarmonyPrefix]
		public static bool ContainerRPC_RequestStackPatch(Container __instance, long uid, long playerID)
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			if (__instance.IsOdinShipContainer() || !__instance.m_nview.IsOwner())
			{
				return true;
			}
			if (!__instance.CheckAccess(playerID))
			{
				__instance.m_nview.InvokeRPC(uid, "RPC_StackResponse", new object[1] { false });
				return false;
			}
			if (IsContainerInUse(__instance, uid))
			{
				__instance.m_nview.InvokeRPC(uid, "RPC_StackResponse", new object[1] { true });
				return false;
			}
			ZDOMan.instance.ForceSendZDO(uid, __instance.m_nview.GetZDO().m_uid);
			__instance.m_nview.GetZDO().SetOwner(uid);
			__instance.m_nview.InvokeRPC(uid, "RPC_StackResponse", new object[1] { true });
			return false;
		}

		private static bool IsContainerInUse(Container container, long playerId)
		{
			bool flag = container.IsInUse();
			bool flag2 = Object.op_Implicit((Object)(object)container.m_wagon) && container.m_wagon.InUse();
			bool flag3 = playerId == ZNet.GetUID();
			if (flag || flag2)
			{
				return !flag3;
			}
			return false;
		}

		[HarmonyPatch(typeof(Container), "UpdateUseVisual")]
		[HarmonyPostfix]
		public static void ContainerUpdateUseVisualPatch(Container __instance)
		{
			if (!__instance.IsOdinShipContainer() && __instance.m_nview.IsValid() && Object.op_Implicit((Object)(object)Player.m_localPlayer) && Object.op_Implicit((Object)(object)InventoryGui.instance))
			{
				bool flag = (Object)(object)__instance == (Object)(object)InventoryGui.instance.m_currentContainer || IsContainerInUse(__instance);
				if (Object.op_Implicit((Object)(object)__instance.m_open))
				{
					__instance.m_open.SetActive(flag);
				}
				if (Object.op_Implicit((Object)(object)__instance.m_closed))
				{
					__instance.m_closed.SetActive(!flag);
				}
			}
		}

		private static bool IsContainerInUse(Container container)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			ZDOID containerId = container.m_nview.GetZDO().m_uid;
			return Player.GetAllPlayers().Any((Player p) => (Object)(object)p != (Object)(object)Player.m_localPlayer && ((Character)p).m_nview.IsValid() && ((Character)p).m_nview.GetZDO().GetZDOID("accessed-container") == containerId);
		}
	}
	[HarmonyPatch]
	public static class GamePatches
	{
		[HarmonyPatch(typeof(Game), "Start")]
		[HarmonyPostfix]
		public static void GameStartPatch()
		{
			RegisterRPCs();
		}

		public static void RegisterRPCs()
		{
			ZRoutedRpc.instance.Register<ZDOID, ZPackage>("MUC_RequestItemMove", (Action<long, ZDOID, ZPackage>)ContainerRPCHandler.RPC_RequestItemMove);
			ZRoutedRpc.instance.Register<ZDOID, ZPackage>("MUC_RequestItemAdd", (Action<long, ZDOID, ZPackage>)ContainerRPCHandler.RPC_RequestItemAdd);
			ZRoutedRpc.instance.Register<ZDOID, ZPackage>("MUC_RequestItemRemove", (Action<long, ZDOID, ZPackage>)ContainerRPCHandler.RPC_RequestItemRemove);
			ZRoutedRpc.instance.Register<ZDOID, ZPackage>("MUC_RequestItemConsume", (Action<long, ZDOID, ZPackage>)ContainerRPCHandler.RPC_RequestItemConsume);
			ZRoutedRpc.instance.Register<ZDOID, ZPackage>("MUC_RequestItemDrop", (Action<long, ZDOID, ZPackage>)ContainerRPCHandler.RPC_RequestDrop);
			ZRoutedRpc.instance.Register<ZDOID, ZPackage>("MUC_RequestItemMoveResponse", (Action<long, ZDOID, ZPackage>)InventoryHandler.RPC_RequestItemMoveResponse);
			ZRoutedRpc.instance.Register<ZDOID, ZPackage>("MUC_RequestItemAddResponse", (Action<long, ZDOID, ZPackage>)InventoryHandler.RPC_RequestItemAddResponse);
			ZRoutedRpc.instance.Register<ZDOID, ZPackage>("MUC_RequestItemRemoveResponse", (Action<long, ZDOID, ZPackage>)InventoryHandler.RPC_RequestItemRemoveResponse);
			ZRoutedRpc.instance.Register<ZDOID, ZPackage>("MUC_RequestItemConsumeResponse", (Action<long, ZDOID, ZPackage>)InventoryHandler.RPC_RequestItemConsumeResponse);
			ZRoutedRpc.instance.Register<ZDOID, ZPackage>("MUC_RequestItemDropResponse", (Action<long, ZDOID, ZPackage>)InventoryHandler.RPC_RequestDropResponse);
		}

		public static void InvokeRPC(ZNetView netView, string rpc, IPackage package)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			ZRoutedRpc.instance.InvokeRoutedRPC(netView.m_zdo.GetOwner(), rpc, new object[2]
			{
				netView.m_zdo.m_uid,
				package.WriteToPackage()
			});
		}
	}
	[HarmonyPatch]
	public static class HumanoidPatch
	{
		[HarmonyPatch(typeof(Humanoid), "Awake")]
		[HarmonyPostfix]
		public static void HumanoidAwakePatch(Humanoid __instance)
		{
			((Component)__instance).gameObject.AddComponent<HumanoidExtend>();
		}
	}
	[HarmonyPatch]
	public static class InventoryGuiPatch
	{
		[HarmonyPatch(typeof(InventoryGui), "Update")]
		[HarmonyPostfix]
		public static void InventoryGuiUpdatePatch(InventoryGui __instance)
		{
			if (Object.op_Implicit((Object)(object)__instance.m_currentContainer) && Object.op_Implicit((Object)(object)__instance.m_currentContainer.m_nview) && __instance.m_currentContainer.m_nview.IsValid())
			{
				__instance.m_currentContainer.CheckForChanges();
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "OnRightClickItem")]
		[HarmonyPrefix]
		public static bool InventoryGuiOnRightClickItemPatch(InventoryGui __instance, InventoryGrid grid, ItemData item)
		{
			Player localPlayer = Player.m_localPlayer;
			if (item == null || !Object.op_Implicit((Object)(object)localPlayer))
			{
				return true;
			}
			if (grid.GetInventory() == ((Humanoid)localPlayer).GetInventory())
			{
				return true;
			}
			if (!Object.op_Implicit((Object)(object)__instance.m_currentContainer) || __instance.m_currentContainer.IsOwner())
			{
				return true;
			}
			if (InventoryBlock.Get(((Humanoid)localPlayer).GetInventory()).BlockConsume)
			{
				return false;
			}
			if (((Humanoid)localPlayer).CanConsumeItem(item, false))
			{
				InventoryBlock.Get(((Humanoid)localPlayer).GetInventory()).BlockConsume = true;
				RequestConsume package = new RequestConsume(item);
				GamePatches.InvokeRPC(__instance.m_currentContainer.m_nview, "MUC_RequestItemConsume", package);
			}
			return false;
		}

		[HarmonyPatch(typeof(InventoryGui), "UpdateContainer")]
		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> ChangeOwnerCheck(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected O, but got Unknown
			return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(true, (CodeMatch[])(object)new CodeMatch[3]
			{
				new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Ldfld && ((FieldInfo)i.operand).Name == "m_currentContainer"), (string)null),
				new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Callvirt && ((MethodInfo)i.operand).Name == "IsOwner"), (string)null)
			}).RemoveInstructions(1).Insert((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(InventoryGuiPatch), "CanOpenContainer", (Type[])null, (Type[])null))
			})
				.InstructionEnumeration();
		}

		public static bool CanOpenContainer(Container container)
		{
			if (container.IsOdinShipContainer())
			{
				return container.IsOwner();
			}
			return true;
		}

		[HarmonyPatch(typeof(InventoryGui), "OnDropOutside")]
		[HarmonyPrefix]
		public static void InventoryGuiOnDropOutsidePatch(InventoryGui __instance, ref bool __runOriginal)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			if (!__runOriginal || !Object.op_Implicit((Object)(object)__instance.m_dragGo))
			{
				return;
			}
			if (((Humanoid)Player.m_localPlayer).GetInventory().GetInventories().Contains(__instance.m_dragInventory))
			{
				Log.LogDebug("Drop item from own inventory");
				return;
			}
			bool flag = Object.op_Implicit((Object)(object)__instance.m_currentContainer) && __instance.m_currentContainer.IsOwner();
			if (!(!Object.op_Implicit((Object)(object)__instance.m_currentContainer) || flag))
			{
				RequestDrop package = new RequestDrop(__instance.m_dragItem.m_gridPos, __instance.m_dragAmount, ((Character)Player.m_localPlayer).GetZDOID());
				GamePatches.InvokeRPC(__instance.m_currentContainer.m_nview, "MUC_RequestItemDrop", package);
				__instance.SetupDragItem((ItemData)null, (Inventory)null, 1);
				__runOriginal = false;
			}
		}

		[HarmonyPatch(typeof(Inventory), "Load")]
		[HarmonyPostfix]
		public static void InventorySelectSameItemAfterLoad(Inventory __instance)
		{
			if (Object.op_Implicit((Object)(object)InventoryGui.instance) && InventoryGui.instance.m_dragItem != null && Object.op_Implicit((Object)(object)InventoryGui.instance.m_currentContainer) && InventoryGui.instance.m_currentContainer.GetInventory() == __instance && InventoryGui.instance.m_dragInventory != null && InventoryGui.instance.m_dragInventory == __instance)
			{
				ItemData dragItem = InventoryGui.instance.m_dragItem;
				ItemData itemAt = __instance.GetItemAt(dragItem.m_gridPos.x, dragItem.m_gridPos.y);
				if (itemAt == null)
				{
					InventoryGui.instance.SetupDragItem((ItemData)null, (Inventory)null, 1);
					return;
				}
				int dragAmount = Mathf.Min(itemAt.m_stack, InventoryGui.instance.m_dragAmount);
				InventoryGui.instance.m_dragAmount = dragAmount;
				InventoryGui.instance.m_dragItem = itemAt;
			}
		}

		[HarmonyPatch(typeof(InventoryGrid), "UpdateInventory")]
		[HarmonyPostfix]
		public static void InventoryGridUpdateInventoryPatch(InventoryGrid __instance)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (!InventoryPreview.GetChanges(__instance.m_inventory, out var preview))
			{
				return;
			}
			foreach (Element element in __instance.m_elements)
			{
				if (preview.GetSlot(element.m_pos, out var item))
				{
					if (item == null)
					{
						ShowNoItem(element);
					}
					else
					{
						ShowItem(__instance, element, item);
					}
				}
			}
		}

		private static void ShowItem(InventoryGrid inventoryGrid, Element element, ItemData item)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Invalid comparison between Unknown and I4
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ad: Unknown result type (might be due to invalid IL or missing references)
			if (item?.m_shared == null)
			{
				return;
			}
			int stack = item.m_stack;
			int maxStackSize = item.m_shared.m_maxStackSize;
			((Behaviour)element.m_icon).enabled = stack > 0;
			element.m_icon.sprite = item.GetIcon();
			((Graphic)element.m_icon).color = Color.white;
			((Behaviour)element.m_amount).enabled = stack > 0 && maxStackSize > 1;
			element.m_amount.text = $"{stack}/{maxStackSize}";
			bool flag = item.m_shared.m_useDurability && item.m_durability < item.GetMaxDurability();
			((Component)element.m_durability).gameObject.SetActive(flag);
			if (flag)
			{
				if ((double)item.m_durability <= 0.0)
				{
					element.m_durability.SetValue(1f);
					element.m_durability.SetColor((Color)(((double)Mathf.Sin(Time.time * 10f) > 0.0) ? Color.red : new Color(0f, 0f, 0f, 0f)));
				}
				else
				{
					element.m_durability.SetValue(item.GetDurabilityPercentage());
					element.m_durability.ResetColor();
				}
			}
			((Behaviour)element.m_equiped).enabled = false;
			((Behaviour)element.m_queued).enabled = false;
			((Behaviour)element.m_noteleport).enabled = !item.m_shared.m_teleportable && !ZoneSystem.instance.GetGlobalKey((GlobalKeys)29);
			if ((int)item.m_shared.m_itemType == 2 && ((double)item.m_shared.m_food > 0.0 || (double)item.m_shared.m_foodStamina > 0.0 || (double)item.m_shared.m_foodEitr > 0.0))
			{
				((Behaviour)element.m_food).enabled = true;
				if ((double)item.m_shared.m_food < (double)item.m_shared.m_foodEitr / 2.0 && (double)item.m_shared.m_foodStamina < (double)item.m_shared.m_foodEitr / 2.0)
				{
					((Graphic)element.m_food).color = inventoryGrid.m_foodEitrColor;
				}
				else if ((double)item.m_shared.m_foodStamina < (double)item.m_shared.m_food / 2.0)
				{
					((Graphic)element.m_food).color = inventoryGrid.m_foodHealthColor;
				}
				else if ((double)item.m_shared.m_food < (double)item.m_shared.m_foodStamina / 2.0)
				{
					((Graphic)element.m_food).color = inventoryGrid.m_foodStaminaColor;
				}
				else
				{
					((Graphic)element.m_food).color = Color.white;
				}
			}
			else
			{
				((Behaviour)element.m_food).enabled = false;
			}
			((Behaviour)element.m_quality).enabled = item.m_shared.m_maxQuality > 1;
			if (item.m_shared.m_maxQuality > 1)
			{
				element.m_quality.text = item.m_quality.ToString();
			}
		}

		private static void ShowNoItem(Element element)
		{
			((Component)element.m_durability).gameObject.SetActive(false);
			((Behaviour)element.m_icon).enabled = false;
			((Behaviour)element.m_amount).enabled = false;
			((Behaviour)element.m_quality).enabled = false;
			((Behaviour)element.m_equiped).enabled = false;
			((Behaviour)element.m_queued).enabled = false;
			((Behaviour)element.m_noteleport).enabled = false;
			((Behaviour)element.m_food).enabled = false;
			element.m_tooltip.m_text = "";
			element.m_tooltip.m_topic = "";
		}
	}
	[HarmonyPatch]
	public static class InventoryPatch
	{
		public static readonly ConditionalWeakTable<ItemData, Inventory> InventoryOfItem = new ConditionalWeakTable<ItemData, Inventory>();

		private static readonly WeakReference<ItemData> LastRemovedItem = new WeakReference<ItemData>(null);

		private static bool allowItemSwap = true;

		[HarmonyPatch(typeof(Inventory), "AddItem", new Type[]
		{
			typeof(ItemData),
			typeof(int),
			typeof(int),
			typeof(int)
		})]
		[HarmonyPrefix]
		[HarmonyPriority(100)]
		public static void AddItem1Prefix(Inventory __instance, ref bool __runOriginal, ItemData item, int amount, int x, int y, ref bool __result)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			if (__runOriginal && InterceptAddItem(__instance, item, amount, new Vector2i(x, y), out var successfulAdded))
			{
				__result = successfulAdded;
				__runOriginal = false;
			}
		}

		[HarmonyPatch(typeof(Inventory), "AddItem", new Type[] { typeof(ItemData) })]
		[HarmonyPrefix]
		[HarmonyPriority(100)]
		public static void AddItem2Prefix(Inventory __instance, ref bool __runOriginal, ItemData item, ref bool __result)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			if (__runOriginal && InterceptAddItem(__instance, item, item.m_stack, new Vector2i(-1, -1), out var successfulAdded))
			{
				__result = successfulAdded;
				__runOriginal = false;
			}
		}

		[HarmonyPatch(typeof(Inventory), "RemoveItem", new Type[] { typeof(ItemData) })]
		[HarmonyPrefix]
		[HarmonyPriority(100)]
		public static void RemoveItemPrefix(Inventory __instance, ref bool __runOriginal, ref bool __result)
		{
			if (__runOriginal)
			{
				InventoryOwner owner = InventoryOwner.GetOwner(__instance);
				if (owner != null && owner.IsValid() && !owner.ZNetView.IsOwner())
				{
					__result = false;
					__runOriginal = false;
				}
			}
		}

		[HarmonyPatch(typeof(Inventory), "RemoveItem", new Type[] { typeof(ItemData) })]
		[HarmonyPostfix]
		public static void RemoveItemPostfix(Inventory __instance, ItemData item, ref bool __result)
		{
			if (__result)
			{
				LastRemovedItem.SetTarget(item);
			}
			else
			{
				LastRemovedItem.SetTarget(null);
			}
		}

		[HarmonyPatch(typeof(Inventory), "MoveAll")]
		[HarmonyPrefix]
		[HarmonyPriority(800)]
		public static void MoveAllPrefix()
		{
			allowItemSwap = false;
		}

		[HarmonyPatch(typeof(Inventory), "MoveAll")]
		[HarmonyPostfix]
		[HarmonyPriority(0)]
		public static void MoveAllPostfix()
		{
			allowItemSwap = true;
		}

		[HarmonyPatch(typeof(Inventory), "Changed")]
		[HarmonyPostfix]
		public static void AddItemPostfix(Inventory __instance)
		{
			foreach (Inventory inventory in __instance.GetInventories())
			{
				AssignItemsOfInventory(inventory);
			}
			if (LastRemovedItem.TryGetTarget(out var target) && InventoryOwner.GetOwner(target)?.Inventory == __inst