Decompiled source of ItemDrawers Ymiron v0.5.0

ItemDrawers.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using ItemDrawers.Visuals;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.UI;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ItemDrawers
{
	internal static class BuildCategory
	{
		internal const string JotunnGuid = "com.jotunn.jotunn";

		private static PieceCategory? _custom;

		private static string _customName;

		internal static PieceCategory Get()
		{
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Expected I4, but got Unknown
			string text = (ModConfig.HammerTab.Value ?? string.Empty).Trim();
			if (text.Length == 0)
			{
				return (PieceCategory)4;
			}
			if (_customName == text)
			{
				return (PieceCategory)(((??)_custom) ?? 4);
			}
			_customName = text;
			_custom = null;
			try
			{
				Type? obj = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((Assembly a) => a.GetName().Name == "Jotunn")?.GetType("Jotunn.Managers.PieceManager");
				object obj2 = obj?.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public)?.GetValue(null);
				MethodInfo methodInfo = obj?.GetMethod("AddPieceCategory", new Type[1] { typeof(string) });
				if (obj2 == null || methodInfo == null)
				{
					ItemDrawersPlugin.Log.LogInfo((object)"Jotunn is not installed: the drawers are in the Furniture tab of the hammer.");
					return (PieceCategory)4;
				}
				_custom = (PieceCategory)methodInfo.Invoke(obj2, new object[1] { text });
				ItemDrawersPlugin.Log.LogInfo((object)$"Hammer tab '{text}' added through Jotunn (category {(int)_custom.Value}).");
			}
			catch (Exception ex)
			{
				ItemDrawersPlugin.Log.LogWarning((object)("Could not add the hammer tab '" + text + "' through Jotunn, using Furniture: " + ex.GetBaseException().Message));
			}
			return (PieceCategory)(((??)_custom) ?? 4);
		}
	}
	internal class ConfigSync : MonoBehaviour
	{
		private const string RpcRequest = "ymiron_itemdrawers_config_request";

		private const string RpcValues = "ymiron_itemdrawers_config";

		private const float RequestInterval = 10f;

		private const int MaxRequests = 6;

		private static ConfigSync s_instance;

		private ZPackage _serverValues;

		private float _requestTimer = 3f;

		private int _requests;

		private bool _registered;

		internal static bool Synced
		{
			get
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Expected O, but got Unknown
				if ((Object)s_instance != (Object)null)
				{
					return s_instance._serverValues != null;
				}
				return false;
			}
		}

		private void Awake()
		{
			s_instance = this;
		}

		private void Update()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			if (ZRoutedRpc.instance == null || (Object)ZNet.instance == (Object)null)
			{
				return;
			}
			if (!_registered)
			{
				_registered = true;
				ZRoutedRpc.instance.Register("ymiron_itemdrawers_config_request", (Action<long>)RPC_Request);
				ZRoutedRpc.instance.Register<ZPackage>("ymiron_itemdrawers_config", (Action<long, ZPackage>)RPC_Values);
			}
			if (ZNet.instance.IsServer() || _serverValues != null || _requests >= 6 || ZNet.instance.GetServerPeer() == null)
			{
				return;
			}
			_requestTimer -= Time.deltaTime;
			if (!(_requestTimer > 0f))
			{
				_requestTimer = 10f;
				_requests++;
				ZRoutedRpc.instance.InvokeRoutedRPC("ymiron_itemdrawers_config_request", Array.Empty<object>());
				if (_requests == 6)
				{
					ItemDrawersPlugin.Log.LogWarning((object)"The server does not send its ItemDrawers-Ymiron settings (no mod there?): each player uses their own config file.");
				}
			}
		}

		private static void RPC_Request(long sender)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			if (!((Object)ZNet.instance == (Object)null) && ZNet.instance.IsServer())
			{
				ZRoutedRpc.instance.InvokeRoutedRPC(sender, "ymiron_itemdrawers_config", new object[1] { Pack() });
			}
		}

		internal static void ServerConfigChanged()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			if ((Object)ZNet.instance != (Object)null && ZNet.instance.IsServer() && ZRoutedRpc.instance != null)
			{
				ZRoutedRpc.instance.InvokeRoutedRPC(0L, "ymiron_itemdrawers_config", new object[1] { Pack() });
			}
		}

		private static ZPackage Pack()
		{
			//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();
			List<ConfigDefinition> list = ModConfig.File.Keys.Where((ConfigDefinition d) => !ModConfig.IsLocalOnly(d)).ToList();
			val.Write(list.Count);
			foreach (ConfigDefinition item in list)
			{
				val.Write(item.Section);
				val.Write(item.Key);
				val.Write(ModConfig.File[item].GetSerializedValue());
			}
			return val;
		}

		private void RPC_Values(long sender, ZPackage package)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected O, but got Unknown
			if (!((Object)ZNet.instance == (Object)null) && !ZNet.instance.IsServer())
			{
				_serverValues = new ZPackage(package.GetArray());
				int num = Apply(_serverValues);
				DrawerPrefabs.TryFinalize();
				DrawerNetwork.Invalidate();
				ItemDrawersPlugin.Log.LogInfo((object)$"ItemDrawers-Ymiron settings received from the server: {num} applied (your file is unchanged).");
			}
		}

		internal static void Reapply()
		{
			if (Synced)
			{
				Apply(s_instance._serverValues);
			}
		}

		private static int Apply(ZPackage package)
		{
			package.SetPos(0);
			ConfigFile file = ModConfig.File;
			file.SaveOnConfigSet = false;
			int num = 0;
			try
			{
				int num2 = package.ReadInt();
				for (int i = 0; i < num2; i++)
				{
					string section = package.ReadString();
					string key = package.ReadString();
					string text = package.ReadString();
					ConfigDefinition val = ((IEnumerable<ConfigDefinition>)file.Keys).FirstOrDefault((Func<ConfigDefinition, bool>)((ConfigDefinition d) => d.Section == section && d.Key == key));
					if (!(val == (ConfigDefinition)null) && !ModConfig.IsLocalOnly(val))
					{
						ConfigEntryBase val2 = file[val];
						if (val2.GetSerializedValue() != text)
						{
							val2.SetSerializedValue(text);
						}
						num++;
					}
				}
			}
			catch (Exception ex)
			{
				ItemDrawersPlugin.Log.LogWarning((object)("ItemDrawers-Ymiron settings from the server not fully applied: " + ex.Message));
			}
			return num;
		}

		private void OnDestroy()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//IL_0015: Expected O, but got Unknown
			if ((Object)s_instance == (Object)this)
			{
				s_instance = null;
			}
			if (_serverValues != null)
			{
				_serverValues = null;
				ModConfig.File.SaveOnConfigSet = true;
				ModConfig.File.Reload();
				DrawerPrefabs.TryFinalize();
				DrawerNetwork.Invalidate();
				ItemDrawersPlugin.Log.LogInfo((object)"Left the server: ItemDrawers-Ymiron uses your own settings again.");
			}
		}
	}
	internal static class CraftContext
	{
		private static int _depth;

		internal static bool Active
		{
			get
			{
				if (_depth > 0)
				{
					return ModConfig.CraftFromDrawers.Value;
				}
				return false;
			}
		}

		internal static bool Enter(Player player)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_000f: 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_0023: Expected O, but got Unknown
			//IL_0023: Expected O, but got Unknown
			if ((Object)player == (Object)null || (Object)player != (Object)Player.m_localPlayer)
			{
				return false;
			}
			_depth++;
			return true;
		}

		internal static void Exit(bool entered)
		{
			if (entered && _depth > 0)
			{
				_depth--;
			}
		}

		internal static void Without(Action action)
		{
			int depth = _depth;
			_depth = 0;
			try
			{
				action();
			}
			finally
			{
				_depth = depth;
			}
		}

		internal static bool IsLocalInventory(Inventory inventory)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			if ((Object)Player.m_localPlayer != (Object)null)
			{
				return inventory == ((Humanoid)Player.m_localPlayer).GetInventory();
			}
			return false;
		}
	}
	internal enum Delivery
	{
		Inventory,
		Return,
		DropHere,
		Discard
	}
	public class Drawer : MonoBehaviour
	{
		private enum Op
		{
			Add,
			Remove,
			Clear
		}

		public int m_tier = 1;

		public int m_layout;

		public Transform[] m_faces;

		public Vector2 m_cellSize = new Vector2(0.8f, 0.8f);

		public float m_scale = 1f;

		internal static readonly List<Drawer> All = new List<Drawer>();

		private const string RpcChange = "ymiron_drawer_change";

		private const string RpcGive = "ymiron_drawer_give";

		private const int MaxSlots = 4;

		private static readonly int[] ItemKeys = (from i in Enumerable.Range(0, 4)
			select StringExtensionMethods.GetStableHashCode($"ymiron_drawer_item{i}")).ToArray();

		private static readonly int[] CountKeys = (from i in Enumerable.Range(0, 4)
			select StringExtensionMethods.GetStableHashCode($"ymiron_drawer_count{i}")).ToArray();

		private static readonly int[] DataKeys = (from i in Enumerable.Range(0, 4)
			select StringExtensionMethods.GetStableHashCode($"ymiron_drawer_data{i}")).ToArray();

		private ZNetView _nview;

		private Piece _piece;

		private DrawerFace[] _faceViews;

		private uint _shownRevision = uint.MaxValue;

		private int _shownStacks = -1;

		private int _frontVersion;

		internal TierDef Tier => TierDef.All[Mathf.Clamp(m_tier - 1, 0, TierDef.All.Length - 1)];

		internal LayoutDef Layout => LayoutDef.All[Mathf.Clamp(m_layout, 0, LayoutDef.All.Length - 1)];

		internal int Slots => Layout.Slots;

		internal bool IsValid
		{
			get
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Expected O, but got Unknown
				if ((Object)_nview != (Object)null)
				{
					return _nview.IsValid();
				}
				return false;
			}
		}

		internal string DisplayName
		{
			get
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Expected O, but got Unknown
				if (!((Object)_piece != (Object)null))
				{
					return Layout.DisplayName(Tier);
				}
				return _piece.m_name;
			}
		}

		internal int StacksPerSlot => Mathf.Max(1, ModConfig.Tier(Tier).Stacks.Value / Slots);

		private void Awake()
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Expected O, but got Unknown
			_nview = ((Component)this).GetComponent<ZNetView>();
			_piece = ((Component)this).GetComponent<Piece>();
			if (!((Object)_nview == (Object)null) && _nview.GetZDO() != null)
			{
				All.Add(this);
				_nview.Register<ZPackage>("ymiron_drawer_change", (Action<long, ZPackage>)RPC_Change);
				_nview.Register<ZPackage>("ymiron_drawer_give", (Action<long, ZPackage>)RPC_Give);
				WearNTear component = ((Component)this).GetComponent<WearNTear>();
				if ((Object)component != (Object)null)
				{
					component.m_onDestroyed = (Action)Delegate.Combine(component.m_onDestroyed, new Action(OnDestroyed));
				}
				BuildFaces();
			}
		}

		private void OnDestroy()
		{
			All.Remove(this);
		}

		private void Update()
		{
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Expected O, but got Unknown
			if (!IsValid || _faceViews == null)
			{
				return;
			}
			if (_frontVersion != ModConfig.FrontVersion)
			{
				DrawerFace[] faceViews = _faceViews;
				for (int i = 0; i < faceViews.Length; i++)
				{
					faceViews[i]?.Destroy();
				}
				BuildFaces();
				_shownRevision = uint.MaxValue;
			}
			uint dataRevision = _nview.GetZDO().DataRevision;
			int stacksPerSlot = StacksPerSlot;
			if (dataRevision != _shownRevision || stacksPerSlot != _shownStacks)
			{
				_shownRevision = dataRevision;
				_shownStacks = stacksPerSlot;
				for (int j = 0; j < _faceViews.Length; j++)
				{
					ItemDrop val = ItemInfo.Get(GetItem(j));
					_faceViews[j]?.Show(val, GetCount(j), ((Object)val != (Object)null) ? CapacityFor(val) : 0);
				}
			}
		}

		internal static void Resize(GameObject root, float size)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//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_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Expected O, but got Unknown
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			Transform val = root.transform.Find("model");
			if ((Object)val != (Object)null)
			{
				val.localScale = Vector3.one * size;
			}
			foreach (Transform item in root.transform)
			{
				Transform val2 = item;
				if (!(((Object)val2).name != "_snappoint"))
				{
					Vector3 localPosition = val2.localPosition;
					val2.localPosition = new Vector3(Mathf.Sign(localPosition.x) * 1f * 0.5f * size, (localPosition.y > 0.001f) ? (1f * size) : 0f, Mathf.Sign(localPosition.z) * 0.5f * 0.5f * size);
				}
			}
			Drawer component = root.GetComponent<Drawer>();
			if ((Object)component != (Object)null)
			{
				component.m_scale = size;
				component._frontVersion = int.MinValue;
			}
		}

		internal string GetItem(int slot)
		{
			if (!IsValid || slot < 0 || slot >= Slots)
			{
				return string.Empty;
			}
			return _nview.GetZDO().GetString(ItemKeys[slot], "");
		}

		internal string GetData(int slot)
		{
			if (!IsValid || slot < 0 || slot >= Slots)
			{
				return string.Empty;
			}
			return _nview.GetZDO().GetString(DataKeys[slot], "");
		}

		internal int GetCount(int slot)
		{
			if (!IsValid || slot < 0 || slot >= Slots)
			{
				return 0;
			}
			return _nview.GetZDO().GetInt(CountKeys[slot], 0);
		}

		internal bool IsFree(int slot)
		{
			return string.IsNullOrEmpty(GetItem(slot));
		}

		internal bool Holds(int slot, string prefabName, string data)
		{
			if (!IsFree(slot) && GetItem(slot) == prefabName)
			{
				return GetData(slot) == (data ?? string.Empty);
			}
			return false;
		}

		internal int CapacityFor(ItemDrop drop)
		{
			return StacksPerSlot * drop.m_itemData.m_shared.m_maxStackSize;
		}

		internal int RoomFor(int slot, string prefabName, string data)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			ItemDrop val = ItemInfo.Get(prefabName);
			if ((Object)val == (Object)null)
			{
				return 0;
			}
			if (IsFree(slot))
			{
				return CapacityFor(val);
			}
			if (!Holds(slot, prefabName, data))
			{
				return 0;
			}
			return Mathf.Max(0, CapacityFor(val) - GetCount(slot));
		}

		internal int RequestAdd(int slot, string prefabName, string data, int amount, Delivery overflow)
		{
			int num = Mathf.Min(amount, RoomFor(slot, prefabName, data));
			if (num > 0)
			{
				Send(Op.Add, slot, prefabName, data, num, overflow);
			}
			return num;
		}

		internal int RequestRemove(int slot, int amount, Delivery delivery)
		{
			int num = Mathf.Min(amount, GetCount(slot));
			if (num > 0)
			{
				Send(Op.Remove, slot, GetItem(slot), GetData(slot), num, delivery);
			}
			return num;
		}

		internal void RequestClear(int slot)
		{
			Send(Op.Clear, slot, string.Empty, string.Empty, 0, Delivery.Discard);
		}

		private void Send(Op op, int slot, string prefabName, string data, int amount, Delivery delivery)
		{
			//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((int)op);
			val.Write(slot);
			val.Write(prefabName ?? string.Empty);
			val.Write(data ?? string.Empty);
			val.Write(amount);
			val.Write((int)delivery);
			if (!_nview.IsOwner())
			{
				long owner = _nview.GetZDO().GetOwner();
				if (owner != 0L && ModNetwork.HasMod(owner))
				{
					_nview.InvokeRPC(owner, "ymiron_drawer_change", new object[1] { val });
					return;
				}
				_nview.ClaimOwnership();
			}
			val.SetPos(0);
			Apply(ZDOMan.GetSessionID(), val);
		}

		private void RPC_Change(long sender, ZPackage pkg)
		{
			Apply(sender, pkg);
		}

		private void Apply(long sender, ZPackage pkg)
		{
			if (!IsValid)
			{
				return;
			}
			Op op = (Op)pkg.ReadInt();
			int num = pkg.ReadInt();
			string prefabName = pkg.ReadString();
			string data = pkg.ReadString();
			int num2 = pkg.ReadInt();
			Delivery delivery = (Delivery)pkg.ReadInt();
			if (num < 0 || num >= Slots)
			{
				return;
			}
			if (!_nview.IsOwner())
			{
				_nview.ClaimOwnership();
			}
			switch (op)
			{
			case Op.Add:
			{
				int num3 = Add(num, prefabName, data, num2);
				if (num3 < num2)
				{
					Reply(sender, prefabName, data, num2 - num3, delivery);
				}
				break;
			}
			case Op.Remove:
			{
				int num4 = (Holds(num, prefabName, data) ? Remove(num, num2) : 0);
				if (num4 > 0 && delivery != Delivery.Discard)
				{
					Reply(sender, prefabName, data, num4, delivery);
				}
				break;
			}
			case Op.Clear:
				if (GetCount(num) <= 0)
				{
					Write(num, string.Empty, string.Empty, 0);
				}
				break;
			}
		}

		private int Add(int slot, string prefabName, string data, int amount)
		{
			int num = Mathf.Min(amount, RoomFor(slot, prefabName, data));
			if (num <= 0)
			{
				return 0;
			}
			int num2 = ((!IsFree(slot)) ? GetCount(slot) : 0);
			Write(slot, prefabName, data, num2 + num);
			return num;
		}

		private int Remove(int slot, int amount)
		{
			int count = GetCount(slot);
			int num = Mathf.Min(amount, count);
			if (num <= 0)
			{
				return 0;
			}
			Write(slot, GetItem(slot), GetData(slot), count - num);
			return num;
		}

		private void Write(int slot, string prefabName, string data, int count)
		{
			ZDO zDO = _nview.GetZDO();
			zDO.Set(ItemKeys[slot], prefabName ?? string.Empty);
			zDO.Set(DataKeys[slot], string.IsNullOrEmpty(prefabName) ? string.Empty : (data ?? string.Empty));
			zDO.Set(CountKeys[slot], Mathf.Max(0, count), false);
			DrawerNetwork.Invalidate();
		}

		private void Reply(long target, string prefabName, string data, int amount, Delivery delivery)
		{
			//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(prefabName);
			val.Write(data);
			val.Write(amount);
			val.Write((int)delivery);
			if (target == ZDOMan.GetSessionID())
			{
				val.SetPos(0);
				Receive(val);
			}
			else
			{
				_nview.InvokeRPC(target, "ymiron_drawer_give", new object[1] { val });
			}
		}

		private void RPC_Give(long sender, ZPackage pkg)
		{
			Receive(pkg);
		}

		private void Receive(ZPackage pkg)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: 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)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			ItemDrop val = ItemInfo.Get(pkg.ReadString());
			string data = pkg.ReadString();
			int num = pkg.ReadInt();
			Delivery delivery = (Delivery)pkg.ReadInt();
			if ((Object)val == (Object)null || num <= 0 || delivery == Delivery.Discard)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if (delivery == Delivery.DropHere || (Object)localPlayer == (Object)null)
			{
				DropStacks(val, data, num, ((Component)this).transform.position + ((Component)this).transform.forward * (0.4f * m_scale) + Vector3.up * 0.3f);
				return;
			}
			Inventory inventory = ((Humanoid)localPlayer).GetInventory();
			int num2 = Mathf.Min(num, ItemInfo.Room(inventory, val));
			ItemInfo.Give(inventory, val, num2, data);
			if (num > num2)
			{
				DropStacks(val, data, num - num2, ((Component)localPlayer).transform.position + Vector3.up);
			}
			string name = val.m_itemData.m_shared.m_name;
			if (delivery == Delivery.Inventory)
			{
				((Character)localPlayer).Message((MessageType)1, "$msg_added " + name, num, val.m_itemData.GetIcon(), false);
			}
			else
			{
				((Character)localPlayer).Message((MessageType)1, "No room in the drawer: " + name + " back", num, val.m_itemData.GetIcon(), false);
			}
		}

		private static void DropStacks(ItemDrop drop, string data, int amount, Vector3 position)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			int maxStackSize = drop.m_itemData.m_shared.m_maxStackSize;
			while (amount > 0)
			{
				int num = Mathf.Min(amount, maxStackSize);
				amount -= num;
				ItemDrop.DropItem(ItemInfo.NewStack(drop, num, data), num, position + Random.insideUnitSphere * 0.2f, Quaternion.Euler(0f, Random.Range(0f, 360f), 0f));
			}
		}

		internal string GetHoverText(int slot)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			if (!IsValid)
			{
				return string.Empty;
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append(DisplayName);
			ItemDrop val = ItemInfo.Get(GetItem(slot));
			if ((Object)val == (Object)null)
			{
				stringBuilder.Append("\n<color=#a0a0a0>Empty</color>");
				stringBuilder.Append("\n[<color=yellow><b>1-8</b></color>] Store the hotbar item here");
				return ItemInfo.Localize(stringBuilder.ToString());
			}
			int count = GetCount(slot);
			int num = CapacityFor(val);
			string text = KeyName(ModConfig.TakeOneKey.Value);
			stringBuilder.Append($"\n<color=orange>{val.m_itemData.m_shared.m_name}</color>  {count} / {num}");
			if (count > 0)
			{
				stringBuilder.Append("\n[<color=yellow><b>$KEY_Use</b></color>] Take a stack");
				stringBuilder.Append("\n[<color=yellow><b>" + text + " + $KEY_Use</b></color>] Take one");
			}
			stringBuilder.Append("\n[<color=yellow><b>$KEY_AltPlace + $KEY_Use</b></color>] Store all from the inventory");
			if (count <= 0)
			{
				stringBuilder.Append("\n[<color=yellow><b>" + text + " + $KEY_Use</b></color>] Free it for another item");
			}
			return ItemInfo.Localize(stringBuilder.ToString());
		}

		internal bool Interact(int slot, Humanoid user, bool hold, bool alt)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			if (!hold && IsValid)
			{
				Player val = (Player)((user is Player) ? user : null);
				if (val != null && PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false))
				{
					if (IsFree(slot))
					{
						((Character)val).Message((MessageType)2, "Empty: use an item from the hotbar on it to choose what it holds", 0, (Sprite)null, false);
						return false;
					}
					if (alt)
					{
						return StoreFromInventory(slot, val, GetItem(slot), GetData(slot));
					}
					bool flag = (int)ModConfig.TakeOneKey.Value != 0 && Input.GetKey(ModConfig.TakeOneKey.Value);
					if (flag && GetCount(slot) <= 0)
					{
						RequestClear(slot);
						((Character)val).Message((MessageType)2, "The drawer is free for another item", 0, (Sprite)null, false);
						return true;
					}
					return Take(slot, val, flag ? 1 : (-1));
				}
			}
			return false;
		}

		internal bool UseItem(int slot, Humanoid user, ItemData item)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (IsValid)
			{
				Player val = (Player)((user is Player) ? user : null);
				if (val != null && item != null && PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false))
				{
					if (!ItemInfo.CanStore(item))
					{
						((Character)val).Message((MessageType)2, item.m_equipped ? "Unequip it first" : "Drawers only take stackable items", 0, (Sprite)null, false);
						return true;
					}
					string name = ((Object)item.m_dropPrefab).name;
					string data = ItemInfo.DataKey(item);
					if (!IsFree(slot) && !Holds(slot, name, data))
					{
						((Character)val).Message((MessageType)2, "This drawer holds something else", 0, (Sprite)null, false);
						return true;
					}
					StoreFromInventory(slot, val, name, data);
					return true;
				}
			}
			return false;
		}

		private bool Take(int slot, Player player, int amount)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			ItemDrop val = ItemInfo.Get(GetItem(slot));
			if ((Object)val == (Object)null)
			{
				return false;
			}
			if (GetCount(slot) <= 0)
			{
				((Character)player).Message((MessageType)2, "No " + val.m_itemData.m_shared.m_name + " left", 0, (Sprite)null, false);
				return false;
			}
			if (amount < 0)
			{
				amount = val.m_itemData.m_shared.m_maxStackSize;
			}
			int num = Mathf.Min(amount, ItemInfo.Room(((Humanoid)player).GetInventory(), val));
			if (num <= 0)
			{
				((Character)player).Message((MessageType)2, "$inventory_full", 0, (Sprite)null, false);
				return false;
			}
			return RequestRemove(slot, num, Delivery.Inventory) > 0;
		}

		internal bool StoreFromInventory(int slot, Player player, string prefabName, string data)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			ItemDrop val = ItemInfo.Get(prefabName);
			if ((Object)val == (Object)null)
			{
				return false;
			}
			Inventory inventory = ((Humanoid)player).GetInventory();
			List<ItemData> list = ItemInfo.Matching(inventory, prefabName, data);
			if (list.Count == 0)
			{
				((Character)player).Message((MessageType)2, "No " + val.m_itemData.m_shared.m_name + " in your inventory", 0, (Sprite)null, false);
				return false;
			}
			int num = RoomFor(slot, prefabName, data);
			if (num <= 0)
			{
				((Character)player).Message((MessageType)2, "This drawer is full", 0, (Sprite)null, false);
				return false;
			}
			int num2 = 0;
			foreach (ItemData item in list)
			{
				int num3 = Mathf.Min(num - num2, item.m_stack);
				if (num3 <= 0)
				{
					break;
				}
				inventory.RemoveItem(item, num3);
				num2 += num3;
			}
			RequestAdd(slot, prefabName, data, num2, Delivery.Return);
			((Character)player).Message((MessageType)1, "Stored " + val.m_itemData.m_shared.m_name, num2, val.m_itemData.GetIcon(), false);
			return true;
		}

		private unsafe static string KeyName(KeyCode key)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected I4, but got Unknown
			switch (key - 303)
			{
			case 2:
			case 3:
				return "Ctrl";
			case 4:
			case 5:
				return "Alt";
			case 0:
			case 1:
				return "Shift";
			default:
				return ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString();
			}
		}

		private void OnDestroyed()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Expected O, but got Unknown
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: 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_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Expected O, but got Unknown
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			if (!IsValid || !_nview.IsOwner())
			{
				return;
			}
			GameObject val = (((Object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab("CargoCrate") : null);
			Inventory val2 = null;
			for (int i = 0; i < Slots; i++)
			{
				ItemDrop val3 = ItemInfo.Get(GetItem(i));
				int num = GetCount(i);
				string data = GetData(i);
				if ((Object)val3 == (Object)null || num <= 0)
				{
					continue;
				}
				int maxStackSize = val3.m_itemData.m_shared.m_maxStackSize;
				while (num > 0)
				{
					int num2 = Mathf.Min(num, maxStackSize);
					num -= num2;
					ItemData val4 = ItemInfo.NewStack(val3, num2, data);
					Vector3 val5 = ((Component)this).transform.position + Vector3.up * 0.6f * m_scale + Random.insideUnitSphere * 0.4f;
					if ((Object)val == (Object)null)
					{
						ItemDrop.DropItem(val4, num2, val5, Quaternion.Euler(0f, Random.Range(0f, 360f), 0f));
					}
					else if (val2 == null || !val2.AddItem(val4))
					{
						Container component = Object.Instantiate<GameObject>(val, val5, Random.rotation).GetComponent<Container>();
						val2 = ((component != null) ? component.GetInventory() : null);
						if (val2 == null || !val2.AddItem(val4))
						{
							ItemDrop.DropItem(val4, num2, val5, Quaternion.identity);
						}
					}
				}
				Write(i, string.Empty, string.Empty, 0);
			}
		}

		private void BuildFaces()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Invalid comparison between Unknown and I4
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			if (m_faces == null || (int)SystemInfo.graphicsDeviceType == 4)
			{
				return;
			}
			_frontVersion = ModConfig.FrontVersion;
			_faceViews = new DrawerFace[m_faces.Length];
			for (int i = 0; i < m_faces.Length; i++)
			{
				if ((Object)m_faces[i] != (Object)null)
				{
					_faceViews[i] = DrawerFace.Create(m_faces[i], m_cellSize, m_scale);
				}
			}
		}
	}
	internal sealed class DrawerFace
	{
		private static Sprite _white;

		private static Material _outlined;

		private static TMP_FontAsset _outlinedFor;

		private static bool _loggedError;

		private GameObject _root;

		private SpriteRenderer _icon;

		private TextMeshPro _count;

		private SpriteRenderer _label;

		private SpriteRenderer _barBack;

		private SpriteRenderer _barFill;

		private float _iconSize;

		private float _barWidth;

		private float _barHeight;

		private static Sprite White
		{
			get
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Expected O, but got Unknown
				//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_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_004c: Unknown result type (might be due to invalid IL or missing references)
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_006a: Expected O, but got Unknown
				if ((Object)_white == (Object)null)
				{
					Texture2D val = new Texture2D(4, 4, (TextureFormat)4, false);
					val.SetPixels(Enumerable.Repeat<Color>(Color.white, 16).ToArray());
					val.Apply();
					_white = Sprite.Create(val, new Rect(0f, 0f, 4f, 4f), new Vector2(0f, 0.5f), 4f);
				}
				return _white;
			}
		}

		private static Material Outlined(TMP_FontAsset font)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_004a: Expected O, but got Unknown
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)font == (Object)null || (Object)((TMP_Asset)font).material == (Object)null)
			{
				return null;
			}
			if ((Object)_outlined == (Object)null || (Object)_outlinedFor != (Object)font)
			{
				_outlinedFor = font;
				_outlined = new Material(((TMP_Asset)font).material)
				{
					name = "ymd_count_outlined"
				};
				_outlined.EnableKeyword(ShaderUtilities.Keyword_Outline);
				SetIfPresent(_outlined, ShaderUtilities.ID_OutlineWidth, 0.28f);
				SetIfPresent(_outlined, ShaderUtilities.ID_FaceDilate, 0.15f);
				if (_outlined.HasProperty(ShaderUtilities.ID_OutlineColor))
				{
					_outlined.SetColor(ShaderUtilities.ID_OutlineColor, new Color(0.05f, 0.03f, 0.02f, 1f));
				}
			}
			return _outlined;
		}

		private static void SetIfPresent(Material material, int property, float value)
		{
			if (material.HasProperty(property))
			{
				material.SetFloat(property, value);
			}
		}

		internal static DrawerFace Create(Transform anchor, Vector2 cell, float scale)
		{
			//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_0029: Expected O, but got Unknown
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Expected O, but got Unknown
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Expected O, but got Unknown
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_032a: Unknown result type (might be due to invalid IL or missing references)
			//IL_032f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0330: Unknown result type (might be due to invalid IL or missing references)
			//IL_035c: Unknown result type (might be due to invalid IL or missing references)
			//IL_037e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0383: Unknown result type (might be due to invalid IL or missing references)
			//IL_0384: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Expected O, but got Unknown
			DrawerFace drawerFace = new DrawerFace();
			int layer = ((Component)anchor).gameObject.layer;
			drawerFace._root = new GameObject("front")
			{
				layer = layer
			};
			drawerFace._root.transform.SetParent(anchor, false);
			Transform transform = drawerFace._root.transform;
			Quaternion rotation = Quaternion.Euler(0f, 180f, 0f);
			float x = cell.x;
			float y = cell.y;
			float num = ModConfig.FrontDistance.Value / 100f / Mathf.Max(scale, 0.1f);
			float num2 = Mathf.Max(0.002f, num - 0.004f);
			float num3 = num;
			float num4 = num + 0.002f;
			drawerFace._iconSize = Mathf.Min(x, y) * ModConfig.PictureSize.Value;
			drawerFace._icon = Child(transform, "icon", layer, new Vector3(0f, y * ModConfig.PictureY.Value, num3), rotation).AddComponent<SpriteRenderer>();
			((Renderer)drawerFace._icon).sortingOrder = 1;
			float value = ModConfig.PictureBrightness.Value;
			drawerFace._icon.color = new Color(value, value, value, 1f);
			((Renderer)drawerFace._icon).enabled = false;
			float num5 = x * ModConfig.LabelWidth.Value;
			float num6 = y * ModConfig.LabelHeight.Value;
			float num7 = y * ModConfig.LabelY.Value;
			drawerFace._label = Rect(transform, "label", layer, new Vector3(num5 * 0.5f, num7, num2), rotation, new Color(0.06f, 0.045f, 0.035f, ModConfig.LabelOpacity.Value), 0);
			((Component)drawerFace._label).transform.localScale = new Vector3(num5, num6, 1f);
			((Renderer)drawerFace._label).enabled = false;
			GameObject obj = Child(transform, "count", layer, new Vector3(0f, num7, num4), rotation);
			obj.SetActive(false);
			TextMeshPro val = obj.AddComponent<TextMeshPro>();
			TMP_FontAsset numbers = Fonts.Numbers;
			if ((Object)numbers != (Object)null)
			{
				((TMP_Text)val).font = numbers;
			}
			obj.SetActive(true);
			if ((Object)numbers != (Object)null)
			{
				Material val2 = Outlined(numbers);
				if ((Object)val2 != (Object)null)
				{
					((TMP_Text)val).fontSharedMaterial = val2;
				}
			}
			((TMP_Text)val).rectTransform.sizeDelta = new Vector2(num5 * 0.92f, num6 * ModConfig.NumberSize.Value);
			((TMP_Text)val).enableAutoSizing = true;
			((TMP_Text)val).fontSizeMin = 0.05f;
			((TMP_Text)val).fontSizeMax = 6f;
			((TMP_Text)val).alignment = (TextAlignmentOptions)514;
			((TMP_Text)val).fontStyle = (FontStyles)1;
			((Graphic)val).color = Palette.CountText;
			((TMP_Text)val).textWrappingMode = (TextWrappingModes)0;
			((TMP_Text)val).text = string.Empty;
			val.renderer.sortingOrder = 3;
			drawerFace._count = val;
			drawerFace._barWidth = num5;
			drawerFace._barHeight = Mathf.Max(0.008f, y * ModConfig.BarHeight.Value);
			float num8 = y * ModConfig.BarY.Value;
			drawerFace._barBack = Rect(transform, "bar_back", layer, new Vector3(drawerFace._barWidth * 0.5f, num8, num2), rotation, Palette.BarBack, 1);
			((Component)drawerFace._barBack).transform.localScale = new Vector3(drawerFace._barWidth, drawerFace._barHeight, 1f);
			drawerFace._barFill = Rect(transform, "bar_fill", layer, new Vector3(drawerFace._barWidth * 0.5f, num8, num4), rotation, Palette.BarFill, 2);
			((Renderer)drawerFace._barBack).enabled = false;
			((Renderer)drawerFace._barFill).enabled = false;
			return drawerFace;
		}

		internal void Destroy()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Expected O, but got Unknown
			if ((Object)_root != (Object)null)
			{
				Object.Destroy((Object)_root);
			}
			_root = null;
		}

		internal void Show(ItemDrop drop, int count, int capacity)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			//IL_007a: Expected O, but got Unknown
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Expected O, but got Unknown
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//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)
			//IL_00ac: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Expected O, but got Unknown
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: 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)
			try
			{
				if ((Object)drop == (Object)null)
				{
					((Renderer)_icon).enabled = false;
					((Renderer)_label).enabled = false;
					((TMP_Text)_count).text = string.Empty;
					((Renderer)_barBack).enabled = false;
					((Renderer)_barFill).enabled = false;
					return;
				}
				Sprite icon = drop.m_itemData.GetIcon();
				if ((Object)_icon.sprite != (Object)icon)
				{
					_icon.sprite = icon;
					float num;
					if (!((Object)icon != (Object)null))
					{
						num = 1f;
					}
					else
					{
						Bounds bounds = icon.bounds;
						float x = ((Bounds)(ref bounds)).size.x;
						bounds = icon.bounds;
						num = Mathf.Max(x, ((Bounds)(ref bounds)).size.y);
					}
					float num2 = num;
					((Component)_icon).transform.localScale = Vector3.one * (_iconSize / Mathf.Max(num2, 0.0001f));
				}
				float value = ModConfig.PictureBrightness.Value;
				_icon.color = ((count > 0) ? new Color(value, value, value, 1f) : new Color(value, value, value, 0.35f));
				((Renderer)_icon).enabled = (Object)icon != (Object)null;
				((Renderer)_label).enabled = ModConfig.LabelOpacity.Value > 0f;
				((TMP_Text)_count).text = ItemInfo.ShortCount(count);
				bool value2 = ModConfig.ShowBar.Value;
				float num3 = ((capacity > 0) ? Mathf.Clamp01((float)count / (float)capacity) : 0f);
				((Renderer)_barBack).enabled = value2;
				((Renderer)_barFill).enabled = value2 && num3 > 0f;
				_barFill.color = ((num3 >= 1f) ? Palette.BarFull : Palette.BarFill);
				((Component)_barFill).transform.localScale = new Vector3(_barWidth * num3, _barHeight, 1f);
			}
			catch (Exception arg)
			{
				if (!_loggedError)
				{
					_loggedError = true;
					ItemDrawersPlugin.Log.LogError((object)string.Format("Drawer front for '{0}' x{1} failed: {2}", ((Object)drop != (Object)null) ? ((Object)drop).name : "?", count, arg));
				}
			}
		}

		private static GameObject Child(Transform parent, string name, int layer, Vector3 position, Quaternion rotation)
		{
			//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_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			GameObject val = new GameObject(name)
			{
				layer = layer
			};
			val.transform.SetParent(parent, false);
			val.transform.localPosition = position;
			val.transform.localRotation = rotation;
			return val;
		}

		private static SpriteRenderer Rect(Transform parent, string name, int layer, Vector3 position, Quaternion rotation, Color color, int order)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: 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)
			SpriteRenderer obj = Child(parent, name, layer, position, rotation).AddComponent<SpriteRenderer>();
			obj.sprite = White;
			obj.color = color;
			((Renderer)obj).sortingOrder = order;
			return obj;
		}
	}
	internal sealed class DrawerKind
	{
		internal TierDef Tier;

		internal LayoutDef Layout;

		internal string PrefabName => "ymiron_drawer_" + Tier.Key + "_" + Layout.Suffix;

		internal string Name => Layout.DisplayName(Tier);

		internal static DrawerKind[] All()
		{
			List<DrawerKind> list = new List<DrawerKind>();
			TierDef[] all = TierDef.All;
			foreach (TierDef tier in all)
			{
				LayoutDef[] all2 = LayoutDef.All;
				foreach (LayoutDef layout in all2)
				{
					list.Add(new DrawerKind
					{
						Tier = tier,
						Layout = layout
					});
				}
			}
			return list.ToArray();
		}
	}
	internal static class DrawerNetwork
	{
		private static readonly Dictionary<string, int> CraftCounts = new Dictionary<string, int>();

		private static int _craftFrame = -1;

		private static int _version;

		private static int _craftVersion = -1;

		internal static void Invalidate()
		{
			_version++;
		}

		internal static List<SlotRef> Slots(Vector3 center, float range, bool accessible)
		{
			//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_00f1: Unknown result type (might be due to invalid IL or missing references)
			List<SlotRef> list = new List<SlotRef>();
			float rangeSq = range * range;
			foreach (Drawer item in from t in Drawer.All.Where((Drawer d) => (Object)d != (Object)null && d.IsValid).Select(delegate(Drawer d)
				{
					//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_0011: Unknown result type (might be due to invalid IL or missing references)
					//IL_0016: Unknown result type (might be due to invalid IL or missing references)
					Vector3 val = ((Component)d).transform.position - center;
					return (Drawer: d, DistSq: ((Vector3)(ref val)).sqrMagnitude);
				})
				where t.DistSq <= rangeSq
				orderby t.DistSq
				select t.Drawer)
			{
				if (!accessible || PrivateArea.CheckAccess(((Component)item).transform.position, 0f, false, false))
				{
					for (int num = 0; num < item.Slots; num++)
					{
						list.Add(new SlotRef(item, num));
					}
				}
			}
			return list;
		}

		internal static int CraftCount(string sharedName)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)localPlayer == (Object)null || string.IsNullOrEmpty(sharedName) || !ModConfig.CraftFromDrawers.Value)
			{
				return 0;
			}
			if (_craftFrame != Time.frameCount || _craftVersion != _version)
			{
				_craftFrame = Time.frameCount;
				_craftVersion = _version;
				CraftCounts.Clear();
				foreach (SlotRef item in Slots(((Component)localPlayer).transform.position, ModConfig.CraftRange.Value, accessible: true))
				{
					int count = item.Count;
					string text = ((count > 0) ? ItemInfo.SharedName(item.Item) : null);
					if (text != null)
					{
						CraftCounts.TryGetValue(text, out var value);
						CraftCounts[text] = value + count;
					}
				}
			}
			if (!CraftCounts.TryGetValue(sharedName, out var value2))
			{
				return 0;
			}
			return value2;
		}

		internal static int TakeForCraft(string sharedName, int amount)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if ((Object)localPlayer == (Object)null || amount <= 0)
			{
				return 0;
			}
			int num = 0;
			foreach (SlotRef item in Slots(((Component)localPlayer).transform.position, ModConfig.CraftRange.Value, accessible: true))
			{
				if (num >= amount)
				{
					break;
				}
				if (item.Count > 0 && ItemInfo.SharedName(item.Item) == sharedName)
				{
					num += item.Drawer.RequestRemove(item.Slot, amount - num, Delivery.Discard);
				}
			}
			return num;
		}

		internal static List<StockEntry> Stock(Vector3 center, float range, out int drawers, out int freeSlots)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Expected O, but got Unknown
			Dictionary<string, StockEntry> dictionary = new Dictionary<string, StockEntry>();
			List<SlotRef> list = Slots(center, range, accessible: true);
			drawers = list.Select((SlotRef s) => s.Drawer).Distinct().Count();
			freeSlots = 0;
			foreach (SlotRef item2 in list)
			{
				if (item2.IsFree)
				{
					freeSlots++;
					continue;
				}
				int count = item2.Count;
				if (count <= 0)
				{
					continue;
				}
				string item = item2.Item;
				string data = item2.Data;
				string key = item + "\n" + data;
				if (!dictionary.TryGetValue(key, out var value))
				{
					ItemDrop val = ItemInfo.Get(item);
					if ((Object)val == (Object)null)
					{
						continue;
					}
					StockEntry stockEntry = (dictionary[key] = new StockEntry
					{
						Prefab = item,
						Data = data,
						Drop = val,
						LocalName = ItemInfo.Localize(val.m_itemData.m_shared.m_name)
					});
					value = stockEntry;
				}
				value.Count += count;
				value.Compartments++;
			}
			return dictionary.Values.OrderBy<StockEntry, string>((StockEntry e) => e.LocalName, StringComparer.CurrentCultureIgnoreCase).ToList();
		}

		internal static int Withdraw(string prefab, string data, int amount, Vector3 center, float range)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			foreach (SlotRef item in Slots(center, range, accessible: true).Where(delegate(SlotRef s)
			{
				SlotRef slotRef = s;
				if (slotRef.Holds(prefab, data))
				{
					slotRef = s;
					return slotRef.Count > 0;
				}
				return false;
			}).OrderBy(delegate(SlotRef s)
			{
				SlotRef slotRef = s;
				return slotRef.Count;
			}))
			{
				if (num >= amount)
				{
					break;
				}
				num += item.Drawer.RequestRemove(item.Slot, amount - num, Delivery.Inventory);
			}
			return num;
		}

		internal static int Deposit(string prefab, string data, int amount, Vector3 center, float range, bool useFree, Delivery overflow)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			List<SlotRef> source = Slots(center, range, accessible: true);
			int num = 0;
			foreach (SlotRef item in source.Where(delegate(SlotRef s)
			{
				SlotRef slotRef = s;
				return slotRef.Holds(prefab, data);
			}).OrderByDescending(delegate(SlotRef s)
			{
				SlotRef slotRef = s;
				return slotRef.Count;
			}))
			{
				if (num >= amount)
				{
					return num;
				}
				num += item.Drawer.RequestAdd(item.Slot, prefab, data, amount - num, overflow);
			}
			if (useFree)
			{
				foreach (SlotRef item2 in source.Where((SlotRef s) => s.IsFree))
				{
					if (num >= amount)
					{
						break;
					}
					num += item2.Drawer.RequestAdd(item2.Slot, prefab, data, amount - num, overflow);
				}
			}
			return num;
		}
	}
	internal sealed class DrawerPickup : MonoBehaviour
	{
		private static readonly FieldInfo InstancesField = AccessTools.Field(typeof(ItemDrop), "s_instances");

		private static readonly MethodInfo SaveMethod = AccessTools.Method(typeof(ItemDrop), "Save", (Type[])null, (Type[])null);

		private static bool _loggedError;

		private float _timer;

		private void Update()
		{
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Expected O, but got Unknown
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			_timer -= Time.deltaTime;
			if (_timer > 0f)
			{
				return;
			}
			_timer = ModConfig.PickupInterval.Value;
			if (!ModConfig.PickupEnabled.Value || Drawer.All.Count == 0 || (Object)Player.m_localPlayer == (Object)null || !(InstancesField?.GetValue(null) is List<ItemDrop> source))
			{
				return;
			}
			foreach (ItemDrop item in source.ToList())
			{
				try
				{
					TryStore(item);
				}
				catch (Exception arg)
				{
					if (!_loggedError)
					{
						_loggedError = true;
						ItemDrawersPlugin.Log.LogError((object)string.Format("Pickup of '{0}' failed: {1}", ((Object)item != (Object)null) ? ((Object)item).name : "?", arg));
					}
				}
			}
		}

		private static void TryStore(ItemDrop drop)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Expected O, but got Unknown
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)drop == (Object)null || drop.IsPiece())
			{
				return;
			}
			ZNetView component = ((Component)drop).GetComponent<ZNetView>();
			if ((Object)component == (Object)null || !component.IsValid() || !component.IsOwner() || !drop.CanPickup(true))
			{
				return;
			}
			drop.Load();
			ItemData itemData = drop.m_itemData;
			if (itemData == null || itemData.m_stack <= 0 || !ItemInfo.CanStore(itemData))
			{
				return;
			}
			int num = DrawerNetwork.Deposit(((Object)itemData.m_dropPrefab).name, ItemInfo.DataKey(itemData), itemData.m_stack, ((Component)drop).transform.position, ModConfig.PickupRange.Value, useFree: false, Delivery.DropHere);
			if (num > 0)
			{
				if (num >= itemData.m_stack)
				{
					component.Destroy();
					return;
				}
				itemData.m_stack -= num;
				SaveMethod?.Invoke(drop, null);
			}
		}
	}
	internal static class DrawerPrefabs
	{
		internal const string LedgerPrefabName = "ymiron_drawer_ledger";

		private const string FallbackSource = "piece_chest_wood";

		private static readonly FieldInfo NamedPrefabsField = typeof(ZNetScene).GetField("m_namedPrefabs", BindingFlags.Instance | BindingFlags.NonPublic);

		private static readonly List<(DrawerKind Kind, GameObject Prefab)> Drawers = new List<(DrawerKind, GameObject)>();

		private static GameObject _ledger;

		private static GameObject _holder;

		private static ZNetScene _scene;

		internal static void Build(ZNetScene scene)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Expected O, but got Unknown
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Expected O, but got Unknown
			_scene = scene;
			Drawers.Clear();
			_ledger = null;
			ModelKit.ReleaseCreated();
			if ((Object)_holder != (Object)null)
			{
				Object.Destroy((Object)_holder);
			}
			_holder = new GameObject("ItemDrawers_Holder");
			_holder.SetActive(false);
			Object.DontDestroyOnLoad((Object)_holder);
			DrawerKind[] array = DrawerKind.All();
			foreach (DrawerKind drawerKind in array)
			{
				try
				{
					GameObject val = BuildDrawer(scene, drawerKind);
					if ((Object)val != (Object)null)
					{
						RegisterInScene(scene, val);
						Drawers.Add((drawerKind, val));
					}
				}
				catch (Exception arg)
				{
					ItemDrawersPlugin.Log.LogError((object)$"Building the {drawerKind.Name} failed: {arg}");
				}
			}
			try
			{
				_ledger = BuildLedger(scene);
				if ((Object)_ledger != (Object)null)
				{
					RegisterInScene(scene, _ledger);
				}
			}
			catch (Exception arg2)
			{
				ItemDrawersPlugin.Log.LogError((object)$"Building the Drawer Ledger failed: {arg2}");
			}
			ItemDrawersPlugin.Log.LogInfo((object)string.Format("{0} drawers and {1} ledger created.", Drawers.Count, ((Object)_ledger != (Object)null) ? "the" : "no"));
			TryFinalize();
		}

		private static GameObject Source(ZNetScene scene, string name)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Expected O, but got Unknown
			GameObject prefab = scene.GetPrefab(name);
			if ((Object)prefab == (Object)null || (Object)prefab.GetComponent<Piece>() == (Object)null || (Object)prefab.GetComponent<WearNTear>() == (Object)null)
			{
				prefab = scene.GetPrefab("piece_chest_wood");
			}
			if (!((Object)prefab != (Object)null) || !((Object)prefab.GetComponent<Piece>() != (Object)null) || !((Object)prefab.GetComponent<WearNTear>() != (Object)null))
			{
				return null;
			}
			return prefab;
		}

		private static GameObject StrippedClone(GameObject source, string name, float health, MaterialType material, out Transform model)
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Expected O, but got Unknown
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Expected O, but got Unknown
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(source, _holder.transform, false);
			((Object)val).name = name;
			Transform transform = val.transform;
			MonoBehaviour[] components = val.GetComponents<MonoBehaviour>();
			foreach (MonoBehaviour val2 in components)
			{
				if (!(val2 is ZNetView) && !(val2 is Piece) && !(val2 is WearNTear))
				{
					Object.DestroyImmediate((Object)val2);
				}
			}
			for (int num = transform.childCount - 1; num >= 0; num--)
			{
				Object.DestroyImmediate((Object)((Component)transform.GetChild(num)).gameObject);
			}
			Collider[] components2 = val.GetComponents<Collider>();
			for (int j = 0; j < components2.Length; j++)
			{
				Object.DestroyImmediate((Object)components2[j]);
			}
			WearNTear component = val.GetComponent<WearNTear>();
			component.m_new = null;
			component.m_worn = null;
			component.m_broken = null;
			component.m_wet = null;
			component.m_snow = null;
			component.m_snowWorn = null;
			component.m_snowBroken = null;
			component.m_fragmentRoots = null;
			component.m_nonSolidRenderers?.Clear();
			component.m_health = health;
			component.m_materialType = material;
			Piece component2 = val.GetComponent<Piece>();
			component2.m_enabled = true;
			component2.m_category = (PieceCategory)4;
			component2.m_comfort = 0;
			component2.m_comfortGroup = (ComfortGroup)0;
			model = new GameObject("model")
			{
				layer = val.layer
			}.transform;
			model.SetParent(transform, false);
			return val;
		}

		private static GameObject BuildDrawer(ZNetScene scene, DrawerKind kind)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			//IL_025c: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Source(scene, kind.Tier.SourcePrefab);
			if ((Object)val == (Object)null)
			{
				ItemDrawersPlugin.Log.LogError((object)("No vanilla chest to build the " + kind.Name + " from."));
				return null;
			}
			Transform model;
			GameObject val2 = StrippedClone(val, kind.PrefabName, kind.Tier.Health, kind.Tier.Material, out model);
			val2.GetComponent<WearNTear>().m_supports = true;
			float value = ModConfig.DrawerSize.Value;
			model.localScale = Vector3.one * value;
			List<DrawerModel.Cell> list = DrawerModel.Build(scene, model, kind.Tier, kind.Layout);
			ModelKit.AddBoxCollider(model, new Vector3(0f, 0.5f, -0.01f), new Vector3(1f, 1f, 0.46f), Quaternion.identity);
			for (int i = 0; i < list.Count; i++)
			{
				GameObject val3 = new GameObject($"compartment{i}")
				{
					layer = val2.layer
				};
				val3.transform.SetParent(model, false);
				val3.transform.localPosition = new Vector3(list[i].Center.x, list[i].Center.y, 0.235f);
				val3.AddComponent<BoxCollider>().size = new Vector3(list[i].Size.x, list[i].Size.y, 0.03f);
				val3.AddComponent<DrawerSlot>().m_slot = i;
			}
			AddSnapPoints(val2.transform, value);
			Piece component = val2.GetComponent<Piece>();
			component.m_name = kind.Name;
			component.m_description = ((kind.Layout.Slots == 1) ? "Holds a great many of one item. Its front shows what is inside and how much." : $"{kind.Layout.Slots} compartments, each holding a great many of one item.");
			Drawer drawer = val2.AddComponent<Drawer>();
			drawer.m_tier = kind.Tier.Number;
			drawer.m_layout = kind.Layout.Index;
			drawer.m_faces = list.Select((DrawerModel.Cell c) => c.Face).ToArray();
			drawer.m_cellSize = list[0].Size;
			drawer.m_scale = value;
			return val2;
		}

		private static GameObject BuildLedger(ZNetScene scene)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Source(scene, "piece_chest_wood");
			if ((Object)val == (Object)null)
			{
				return null;
			}
			Transform model;
			GameObject obj = StrippedClone(val, "ymiron_drawer_ledger", 400f, (MaterialType)0, out model);
			LedgerModel.Build(scene, model);
			ModelKit.AddBoxCollider(model, LedgerModel.ColliderCenter, LedgerModel.ColliderSize, Quaternion.identity);
			Piece component = obj.GetComponent<Piece>();
			component.m_name = "Drawer Ledger";
			component.m_description = "The book of everything kept in the drawers around it: browse it, search it, take from it, and put things away from one place.";
			obj.AddComponent<Ledger>();
			return obj;
		}

		private static void AddSnapPoints(Transform root, float scale)
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
			float num = 0.5f * scale;
			float num2 = 0.25f * scale;
			float[] array = new float[2]
			{
				0f,
				1f * scale
			};
			foreach (float num3 in array)
			{
				float[] array2 = new float[2]
				{
					0f - num,
					num
				};
				foreach (float num4 in array2)
				{
					float[] array3 = new float[2]
					{
						0f - num2,
						num2
					};
					foreach (float num5 in array3)
					{
						GameObject val = new GameObject("_snappoint")
						{
							layer = ((Component)root).gameObject.layer,
							tag = "snappoint"
						};
						val.transform.SetParent(root, false);
						val.transform.localPosition = new Vector3(num4, num3, num5);
					}
				}
			}
		}

		internal static void TryFinalize()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected O, but got Unknown
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Expected O, but got Unknown
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Expected O, but got Unknown
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Expected O, but got Unknown
			if (Drawers.Count == 0 && (Object)_ledger == (Object)null)
			{
				return;
			}
			ObjectDB instance = ObjectDB.instance;
			if ((Object)instance == (Object)null || instance.m_items.Count == 0)
			{
				return;
			}
			GameObject itemPrefab = instance.GetItemPrefab("Hammer");
			PieceTable table = ((!((Object)itemPrefab != (Object)null)) ? null : itemPrefab.GetComponent<ItemDrop>()?.m_itemData?.m_shared?.m_buildPieces);
			if ((Object)table == (Object)null)
			{
				return;
			}
			HashSet<string> ours = new HashSet<string>(Drawers.Select(((DrawerKind Kind, GameObject Prefab) d) => ((Object)d.Prefab).name)) { "ymiron_drawer_ledger" };
			table.m_pieces.RemoveAll((GameObject p) => (Object)p == (Object)null || ours.Contains(((Object)p).name));
			PieceCategory category = BuildCategory.Get();
			foreach (GameObject item3 in from p in Drawers.Select(((DrawerKind Kind, GameObject Prefab) d) => d.Prefab).Concat((IEnumerable<GameObject>)(object)new GameObject[1] { _ledger })
				where (Object)p != (Object)null
				select p)
			{
				item3.GetComponent<Piece>().m_category = category;
			}
			int num = new string[3] { "piece_chest_blackmetal", "piece_chest", "piece_chest_wood" }.Select((string name) => table.m_pieces.FindIndex((GameObject p) => ((Object)p).name == name)).DefaultIfEmpty(-1).Max();
			num = ((num >= 0) ? (num + 1) : table.m_pieces.Count);
			if ((Object)_ledger != (Object)null)
			{
				Piece component = _ledger.GetComponent<Piece>();
				component.m_resources = ParseRequirements(instance, ModConfig.LedgerRequirements.Value, "Wood:10,LeatherScraps:4,Resin:4", "Drawer Ledger");
				component.m_craftingStation = FindStation(ModConfig.LedgerStation.Value, "Drawer Ledger");
				table.m_pieces.Insert(num++, _ledger);
			}
			foreach (var drawer in Drawers)
			{
				DrawerKind item = drawer.Kind;
				GameObject item2 = drawer.Prefab;
				TierConfig tierConfig = ModConfig.Tier(item.Tier);
				Piece component2 = item2.GetComponent<Piece>();
				bool flag = item.Layout == LayoutDef.Single;
				string text = item.Tier.Requirements[item.Layout.Index];
				component2.m_resources = ParseRequirements(instance, flag ? tierConfig.Requirements.Value : text, text, item.Name);
				component2.m_craftingStation = FindStation(tierConfig.Station.Value, item.Name);
				if (flag && tierConfig.Enabled.Value)
				{
					table.m_pieces.Insert(num++, item2);
				}
			}
		}

		internal static void ApplySize()
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			float value = ModConfig.DrawerSize.Value;
			foreach (var drawer in Drawers)
			{
				GameObject item = drawer.Prefab;
				if ((Object)item != (Object)null)
				{
					Drawer.Resize(item, value);
				}
			}
			foreach (Drawer item2 in Drawer.All.Where((Drawer d) => (Object)d != (Object)null).ToList())
			{
				Drawer.Resize(((Component)item2).gameObject, value);
			}
		}

		internal static void RenderIcons()
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Expected O, but got Unknown
			foreach (GameObject item in from p in Drawers.Select(((DrawerKind Kind, GameObject Prefab) d) => d.Prefab).Concat((IEnumerable<GameObject>)(object)new GameObject[1] { _ledger })
				where (Object)p != (Object)null
				select p)
			{
				Sprite val = IconRenderer.Render(item);
				if ((Object)val != (Object)null)
				{
					item.GetComponent<Piece>().m_icon = val;
				}
			}
		}

		private static CraftingStation FindStation(string name, string what)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Expected O, but got Unknown
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			name = (name ?? string.Empty).Trim();
			if (name.Length == 0)
			{
				return null;
			}
			object obj;
			if (!((Object)_scene != (Object)null))
			{
				obj = null;
			}
			else
			{
				GameObject prefab = _scene.GetPrefab(name);
				obj = ((prefab != null) ? prefab.GetComponent<CraftingStation>() : null);
			}
			if ((Object)obj == (Object)null)
			{
				ItemDrawersPlugin.Log.LogWarning((object)(what + ": crafting station '" + name + "' not found, none required."));
			}
			return (CraftingStation)obj;
		}

		private static Requirement[] ParseRequirements(ObjectDB odb, string raw, string fallback, string what)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			List<Requirement> list = Parse(odb, raw, what);
			if (list.Count == 0 && raw != fallback)
			{
				ItemDrawersPlugin.Log.LogWarning((object)(what + ": no valid requirements, using the default cost."));
				list = Parse(odb, fallback, what);
			}
			if (list.Count == 0)
			{
				list.Add(new Requirement
				{
					m_resItem = odb.GetItemPrefab("Wood").GetComponent<ItemDrop>(),
					m_amount = 10,
					m_recover = true
				});
			}
			return list.ToArray();
		}

		private static List<Requirement> Parse(ObjectDB odb, string raw, string what)
		{
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Expected O, but got Unknown
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Expected O, but got Unknown
			List<Requirement> list = new List<Requirement>();
			string[] array = (raw ?? string.Empty).Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries);
			foreach (string text in array)
			{
				string[] array2 = text.Trim().Split(':');
				if (array2.Length != 2 || !int.TryParse(array2[1].Trim(), out var result) || result <= 0)
				{
					ItemDrawersPlugin.Log.LogWarning((object)(what + ": invalid requirement '" + text + "'. Expected format Prefab:Amount."));
					continue;
				}
				GameObject itemPrefab = odb.GetItemPrefab(array2[0].Trim());
				ItemDrop val = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null);
				if ((Object)val == (Object)null)
				{
					ItemDrawersPlugin.Log.LogWarning((object)(what + ": item '" + array2[0].Trim() + "' not found in ObjectDB, skipped."));
					continue;
				}
				list.Add(new Requirement
				{
					m_resItem = val,
					m_amount = result,
					m_recover = true
				});
			}
			return list;
		}

		private static void RegisterInScene(ZNetScene scene, GameObject prefab)
		{
			scene.m_prefabs.RemoveAll((GameObject p) => (Object)p == (Object)null || ((Object)p != (Object)prefab && ((Object)p).name == ((Object)prefab).name));
			if (!scene.m_prefabs.Contains(prefab))
			{
				scene.m_prefabs.Add(prefab);
			}
			if (NamedPrefabsField?.GetValue(scene) is Dictionary<int, GameObject> dictionary)
			{
				dictionary[StringExtensionMethods.GetStableHashCode(((Object)prefab).name)] = prefab;
			}
			else
			{
				ItemDrawersPlugin.Log.LogError((object)("Cannot access ZNetScene.m_namedPrefabs: '" + ((Object)prefab).name + "' will not be buildable."));
			}
		}
	}
	public class DrawerSlot : MonoBehaviour, Hoverable, Interactable
	{
		public int m_slot;

		private Drawer _drawer;

		private Drawer Owner
		{
			get
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Expected O, but got Unknown
				if ((Object)_drawer == (Object)null)
				{
					_drawer = ((Component)this).GetComponentInParent<Drawer>();
				}
				return _drawer;
			}
		}

		public string GetHoverText()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			if (!((Object)Owner != (Object)null))
			{
				return string.Empty;
			}
			return Owner.GetHoverText(m_slot);
		}

		public string GetHoverName()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			if (!((Object)Owner != (Object)null))
			{
				return string.Empty;
			}
			return Owner.DisplayName;
		}

		public float GetHoverOffset()
		{
			return 0f;
		}

		public bool Interact(Humanoid user, bool hold, bool alt)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			if ((Object)Owner != (Object)null)
			{
				return Owner.Interact(m_slot, user, hold, alt);
			}
			return false;
		}

		public bool UseItem(Humanoid user, ItemData item)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			if ((Object)Owner != (Object)null)
			{
				return Owner.UseItem(m_slot, user, item);
			}
			return false;
		}
	}
	internal static class Fonts
	{
		private static TMP_FontAsset _numbers;

		internal static TMP_FontAsset Numbers
		{
			get
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Expected O, but got Unknown
				//IL_0078: Unknown result type (might be due to invalid IL or missing references)
				//IL_0083: Expected O, but got Unknown
				if ((Object)_numbers != (Object)null)
				{
					return _numbers;
				}
				TMP_FontAsset[] source = Resources.FindObjectsOfTypeAll<TMP_FontAsset>();
				_numbers = ((IEnumerable<TMP_FontAsset>)source).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset f) => ((Object)f).name.IndexOf("Norse", StringComparison.OrdinalIgnoreCase) >= 0 && ((Object)f).name.IndexOf("Bold", StringComparison.OrdinalIgnoreCase) >= 0)) ?? ((IEnumerable<TMP_FontAsset>)source).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset f) => ((Object)f).name.IndexOf("Norse", StringComparison.OrdinalIgnoreCase) >= 0)) ?? (((Object)InventoryGui.instance != (Object)null) ? InventoryGui.instance.m_containerName.font : null) ?? ((IEnumerable<TMP_FontAsset>)source).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset f) => ((Object)f).name.IndexOf("Averia", StringComparison.OrdinalIgnoreCase) >= 0)) ?? source.FirstOrDefault();
				return _numbers;
			}
		}
	}
	[HarmonyPatch(typeof(Game), "Start")]
	internal static class Game_Start_Patch
	{
		private static void Postfix(Game __instance)
		{
			((Component)__instance).gameObject.AddComponent<DrawerPickup>();
			((Component)__instance).gameObject.AddComponent<ModNetwork>();
			((Component)__instance).gameObject.AddComponent<ConfigSync>();
			DrawerPrefabs.RenderIcons();
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "Hide")]
	internal static class InventoryGui_Hide_Patch
	{
		private static void Postfix()
		{
			LedgerPanel.Close();
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "OnSelectedItem")]
	internal static class InventoryGui_OnSelectedItem_Patch
	{
		private static bool Prefix(InventoryGui __instance, InventoryGrid grid, ItemData item, Modifier mod, GameObject ___m_dragGo)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Invalid comparison between Unknown and I4
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Expected O, but got Unknown
			//IL_0033: Expected O, but got Unknown
			if (!LedgerPanel.IsOpen || (int)mod != 2 || item == null || (Object)___m_dragGo != (Object)null || (Object)grid != (Object)__instance.m_playerGrid)
			{
				return true;
			}
			LedgerPanel.StoreStack(item);
			return false;
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "SetupRequirement")]
	internal static class InventoryGui_SetupRequirement_Patch
	{
		private static void Prefix(Player player, out bool __state)
		{
			__state = CraftContext.Enter(player);
		}

		private static void Postfix(Transform elementRoot, Requirement req, Player player, bool __result, bool __state)
		{
			StockDisplay value = ModConfig.ShowStock.Value;
			if (!__state || !__result || value == StockDisplay.Off || (Object)(object)req?.m_resItem == (Object)null)
			{
				return;
			}
			Transform val = elementRoot.Find("res_amount");
			TMP_Text val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<TMP_Text>() : null);
			if (!((Object)(object)val2 == (Object)null) && int.TryParse(val2.text, out var result))
			{
				string name = req.m_resItem.m_itemData.m_shared.m_name;
				int inInventory = 0;
				CraftContext.Without(delegate
				{
					inInventory = ((Humanoid)player).GetInventory().CountItems(name, -1, true);
				});
				int num = DrawerNetwork.CraftCount(name);
				string text = ((value == StockDisplay.Total || num <= 0) ? Compact(inInventory + num) : (Compact(inInventory) + "+" + Compact(num)));
				FitToBox(val2);
				val2.text = result + "/" + text;
			}
		}

		private static Exception Finalizer(Exception __exception, bool __state)
		{
			CraftContext.Exit(__state);
			return __exception;
		}

		private static string Compact(int count)
		{
			if (count >= 1000000)
			{
				return count / 1000000 + "M";
			}
			if (count >= 10000)
			{
				return count / 1000 + "k";
			}
			return count.ToString();
		}

		private static void FitToBox(TMP_Text text)
		{
			if (!text.enableAutoSizing)
			{
				text.fontSizeMax = text.fontSize;
				text.fontSizeMin = text.fontSize * 0.5f;
				text.textWrappingMode = (TextWrappingModes)0;
				text.enableAutoSizing = true;
			}
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "Show")]
	internal static class InventoryGui_Show_Patch
	{
		private static void Postfix(Container container)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			if ((Object)container != (Object)null)
			{
				LedgerPanel.Close();
			}
		}
	}
	[HarmonyPatch(typeof(Inventory), "CountItems")]
	internal static class Inventory_CountItems_Patch
	{
		private static void Postfix(Inventory __instance, string name, int quality, ref int __result)
		{
			if (CraftContext.Active && name != null && quality <= 1 && CraftContext.IsLocalInventory(__instance))
			{
				__result += DrawerNetwork.CraftCount(name);
			}
		}
	}
	[HarmonyPatch(typeof(Inventory), "HaveItem", new Type[]
	{
		typeof(string),
		typeof(bool)
	})]
	internal static class Inventory_HaveItem_Patch
	{
		private static void Postfix(Inventory __instance, string name, ref bool __result)
		{
			if (!__result && CraftContext.Active && name != null && CraftContext.IsLocalInventory(__instance))
			{
				__result = DrawerNetwork.CraftCount(name) > 0;
			}
		}
	}
	[BepInPlugin("ymiron.valheim.itemdrawers", "ItemDrawers-Ymiron", "0.5.0")]
	[BepInProcess("valheim.exe")]
	[BepInProcess("valheim_server.exe")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class ItemDrawersPlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "ymiron.valheim.itemdrawers";

		public const string PluginName = "ItemDrawers-Ymiron";

		public const string PluginVersion = "0.5.0";

		private Harmony _harmony;

		private FileSystemWatcher _watcher;

		private volatile bool _configChanged;

		internal static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			ModConfig.Bind(((BaseUnityPlugin)this).Config);
			_harmony = new Harmony("ymiron.valheim.itemdrawers");
			Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(typeof(ItemDrawersPlugin).Assembly);
			foreach (Type type in typesFromAssembly)
			{
				try
				{
					_harmony.CreateClassProcessor(type).Patch();
				}
				catch (Exception ex)
				{
					Log.LogError((object)("Patch " + type.Name + " failed: " + ex.Message));
				}
			}
			WatchConfigFile();
			Log.LogInfo((object)"ItemDrawers-Ymiron 0.5.0 loaded.");
		}

		private void WatchConfigFile()
		{
			_watcher = new FileSystemWatcher(Path.GetDirectoryName(((BaseUnityPlugin)this).Config.ConfigFilePath), Path.GetFileName(((BaseUnityPlugin)this).Config.ConfigFilePath))
			{
				NotifyFilter = (NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite),
				IncludeSubdirectories = false
			};
			_watcher.Changed += delegate
			{
				_configChanged = true;
			};
			_watcher.Created += delegate
			{
				_configChanged = true;
			};
			_watcher.Renamed += delegate
			{
				_configChanged = true;
			};
			_watcher.EnableRaisingEvents = true;
		}

		private void Update()
		{
			if (!_configChanged)
			{
				return;
			}
			_configChanged = false;
			try
			{
				((BaseUnityPlugin)this).Config.Reload();
				ConfigSync.ServerConfigChanged();
				ConfigSync.Reapply();
				Log.LogInfo((object)(ConfigSync.Synced ? "Config reloaded: the server's settings still apply, only your personal ones (fronts, keys) changed." : "Config reloaded (drawer health changes on the next world load)."));
				DrawerPrefabs.TryFinalize();
				DrawerNetwork.Invalidate();
			}
			catch (IOException)
			{
				_configChanged = true;
			}
		}

		private void OnDestroy()
		{
			_watcher?.Dispose();
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	internal static class ItemInfo
	{
		private static readonly Dictionary<string, ItemDrop> Cache = new Dictionary<string, ItemDrop>();

		private static ObjectDB _cachedFor;

		internal static ItemDrop Get(string prefabName)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			//IL_0035: Expected O, but got Unknown
			if (string.IsNullOrEmpty(prefabName) || (Object)ObjectDB.instance == (Object)null)
			{
				return null;
			}
			if ((Object)_cachedFor != (Object)ObjectDB.instance)
			{
				Cache.Clear();
				_cachedFor = ObjectDB.instance;
			}
			if (!Cache.TryGetValue(prefabName, out var value))
			{
				GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(prefabName);
				value = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null);
				Cache[prefabName] = value;
			}
			return value;
		}

		internal static string SharedName(string prefabName)
		{
			return Get(prefabName)?.m_itemData?.m_shared?.m_name;
		}

		internal static bool CanStore(ItemData item)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			if (item == null || (Object)item.m_dropPrefab == (Object)null || item.m_shared == null)
			{
				return false;
			}
			if (item.m_shared.m_maxStackSize > 1 && item.m_quality <= 1 && !item.m_shared.m_questItem && !item.m_equipped && !ModConfig.IsBlacklisted(((Object)item.m_dropPrefab).name))
			{
				return (Object)Get(((Object)item.m_dropPrefab).name) != (Object)null;
			}
			return false;
		}

		internal static string DataKey(ItemData item)
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			List<KeyValuePair<string, string>> list = item?.m_customData?.Where((KeyValuePair<string, string> p) => !string.IsNullOrEmpty(p.Value)).OrderBy<KeyValuePair<string, string>, string>((KeyValuePair<string, string> p) => p.Key, StringComparer.Ordinal).ToList();
			if (list == null || list.Count == 0)
			{
				return string.Empty;
			}
			ZPackage val = new ZPackage();
			val.Write(list.Count);
			foreach (KeyValuePair<string, string> item2 in list)
			{
				val.Write(item2.Key);
				val.Write(item2.Value);
			}
			return val.GetBase64();
		}

		internal static Dictionary<string, string> ReadData(string key)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			if (string.IsNullOrEmpty(key))
			{
				return dictionary;
			}
			try
			{
				ZPackage val = new ZPackage(key);
				int num = val.ReadInt();
				for (int i = 0; i < num; i++)
				{
					string key2 = val.ReadString();
					dictionary[key2] = val.ReadString();
				}
			}
			catch (Exception ex)
			{
				ItemDrawersPlugin.Log.LogWarning((object)("Unreadable custom data in a drawer: " + ex.Message));
			}
			return dictionary;
		}

		internal static ItemData NewStack(ItemDrop drop, int amount, string data)
		{
			ItemData obj = drop.m_itemData.Clone();
			obj.m_dropPrefab = ((Component)drop).gameObject;
			obj.m_stack = amount;
			obj.m_quality = 1;
			obj.m_worldLevel = (byte)Game.m_worldLevel;
			obj.m_customData = ReadData(data);
			return obj;
		}

		internal static int Room(Inventory inventory, ItemDrop drop)
		{
			SharedData shared = drop.m_itemData.m_shared;
			return inventory.FindFreeStackSpace(shared.m_name, (float)Game.m_worldLevel) + inventory.GetEmptySlots() * shared.m_maxStackSize;
		}

		internal static void Give(Inventory inventory, ItemDrop drop, int amount, string data)
		{
			int maxStackSize = drop.m_itemData.m_shared.m_maxStackSize;
			while (amount > 0)
			{
				int num = Mathf.Min(amount, maxStackSize);
				if (!inventory.AddItem(NewStack(drop, num, data)))
				{
					ItemDrawersPlugin.Log.LogWarning((object)$"Could not add {num} {((Object)drop).name} to the inventory.");
					break;
				}
				amount -= num;
			}
		}

		internal static List<ItemData> Matching(Inventory inventory, string prefabName, string data)
		{
			return (from i in inventory.GetAllItems()
				where CanStore(i) && ((Object)i.m_dropPrefab).name == prefabName && DataKey(i) == data
				select i).ToList();
		}

		internal static string Localize(string text)
		{
			if (Localization.instance == null)
			{
				return text;
			}
			return Localization.instance.Localize(text);
		}

		internal static string ShortCount(int count)
		{
			if (count < 10000)
			{
				return count.ToString();
			}
			if (count < 1000000)
			{
				return ((float)count / 1000f).ToString((count < 100000) ? "0.#" : "0") + "k";
			}
			return ((float)count / 1000000f).ToString("0.#") + "M";
		}
	}
	internal sealed class LayoutDef
	{
		internal int Index;

		internal int Rows;

		internal int Columns;

		internal string Suffix;

		internal static readonly LayoutDef Single = new LayoutDef
		{
			Index = 0,
			Rows = 1,
			Columns = 1,
			Suffix = "x1"
		};

		internal static readonly LayoutDef Double = new LayoutDef
		{
			Index = 1,
			Rows = 2,
			Columns = 1,
			Suffix = "x2"
		};

		internal static readonly LayoutDef Quad = new LayoutDef
		{
			Index = 2,
			Rows = 2,
			Columns = 2,
			Suffix = "x4"
		};

		internal static readonly LayoutDef[] All = new LayoutDef[3] { Single, Double, Quad };

		internal int Slots => Rows * Columns;

		internal string DisplayName(TierDef tier)
		{
			if (Slots != 1)
			{
				return $"{tier.Name} ({Slots} compartments)";
			}
			return tier.Name;
		}
	}
	public class Ledger : MonoBehaviour, Hoverable, Interactable
	{
		private ZNetView _nview;

		private Piece _piece;

		internal string DisplayName
		{
			get
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Expected O, but got Unknown
				if (!((Object)_piece != (Object)null))
				{
					return "Drawer Ledger";
				}
				return _piece.m_name;
			}
		}

		private void Awake()
		{
			_nview = ((Component)this).GetComponent<ZNetView>();
			_piece = ((Component)this).GetComponent<Piece>();
		}

		public string GetHoverText()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			if ((Object)_nview == (Object)null || !_nview.IsValid())
			{
				return string.Empty;
			}
			float range = ModConfig.LedgerRange.Value;
			int num = Drawer.All.Count((Drawer d) => (Object)d != (Object)null && d.IsValid && Vector3.Distance(((Component)d).transform.position, ((Component)this).transform.position) <= range);
			return ItemInfo.Localize($"{DisplayName}\n<color=#a0a0a0>{num} drawers within {range:0} m</color>\n" + "[<color=yellow><b>$KEY_Use</b></color>] Open");
		}

		public string GetHoverName()
		{
			return DisplayName;
		}

		public float GetHoverOffset()
		{
			return 0f;
		}

		public bool Interact(Humanoid user, bool hold, bool alt)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			//IL_0039: 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_004d: Expected O, but got Unknown
			//IL_004d: Expected O, but got Unknown
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if (!hold && !((Object)_nview == (Object)null) && _nview.IsValid())
			{
				Player val = (Player)((user is Player) ? user : null);
				if (val != null && !((Object)val != (Object)Player.m_localPlayer))
				{
					if (!PrivateArea.CheckAccess(((Component)this).transform.position, 0f, true, false))
					{
						return true;
					}
					LedgerPanel.Open(this);
					return true;
				}
			}
			return false;
		}

		public bool UseItem(Humanoid user, ItemData item)
		{
			return false;
		}
	}
	internal sealed class LedgerPanel : MonoBehaviour
	{
		private sealed class Tile
		{
			internal GameObject Go;

			internal InventoryElement Element;

			internal StockEntry Entry;
		}

		private const float Margin = 12f;

		private const float HeaderHeight = 58f;

		private const float FooterHeight = 20f;

		private const float RefreshInterval = 0.5f;

		private const float CloseDistance = 5f;

		private static LedgerPanel _instance;

		private Ledger _ledger;

		private TMP_Text _title;

		private TMP_Text _status;

		private TMP_Text _empty;

		private TMP_InputField _search;

		private RectTransform _content;

		private GameObject _elementPrefab;

		private readonly List<Tile> _tiles = new List<Tile>();

		private float _refreshTimer;

		private bool _dirty;

		internal static bool IsOpen
		{
			get
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Expected O, but got Unknown
				//IL_001c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0027: Expected O, but got Unknown
				if ((Object)_instance != (Object)null && (Object)_instance._ledger != (Object)null)
				{
					return ((Component)_instance).gameObject.activeSelf;
				}
				return false;
			}
		}

		internal static bool SearchFocused { get; private set; }

		private Vector3 Center
		{
			get
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_0011: Expected O, but got Unknown
				//IL_0024: 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)
				if (!((Object)_ledger != (Object)null))
				{
					return Vector3.zero;
				}
				return ((Component)_ledger).transform.position;
			}
		}

		internal static void Open(Ledger ledger)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			InventoryGui instance = InventoryGui.instance;
			if ((Object)instance == (Object)null)
			{
				return;
			}
			if ((Object)_instance == (Object)null)
			{
				try
				{
					_instance = Create(instance);
				}
				catch (Exception arg)
				{
					ItemDrawersPlugin.Log.LogError((object)$"Could not build the ledger panel: {arg}");
					return;
				}
			}
			_instance._ledger = ledger;
			((Component)_instance).gameObject.SetActive(true);
			((Component)_instance).transform.SetAsLastSibling();
			_instance._search.text = strin