Decompiled source of ChestHeim v0.5.3

plugins/ChestHeim.dll

Decompiled 20 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("ChestHeim")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+63c9d87e9f288373aa8fe5d8c63375bfddd82693")]
[assembly: AssemblyProduct("ChestHeim")]
[assembly: AssemblyTitle("ChestHeim")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.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 ChestHeim
{
	[BepInPlugin("mbaya.ChestHeim", "ChestHeim", "0.5.3")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	public class ChestHeimPlugin : BaseUnityPlugin
	{
		public const string Guid = "mbaya.ChestHeim";

		public const string Name = "ChestHeim";

		public const string Version = "0.5.3";

		private const string BasePiece = "piece_chest_blackmetal";

		internal static ManualLogSource Log;

		internal static ConfigEntry<bool> OthersCanDeposit;

		internal static ConfigEntry<float> SyncSeconds;

		internal static ConfigEntry<bool> LabelsEnabled;

		internal static ConfigEntry<LabelSide> LabelSideSetting;

		internal static ConfigEntry<float> PanelOffsetX;

		internal static ConfigEntry<float> PanelOffsetY;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Expected O, but got Unknown
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Expected O, but got Unknown
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Expected O, but got Unknown
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			OthersCanDeposit = ((BaseUnityPlugin)this).Config.Bind<bool>("Echo", "OthersCanDeposit", true, "Other players can open your echo chests and put things in, but only you can take things out. If false, only you can open them. (The take-out rule is enforced in each player's game.)");
			SyncSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Echo", "SyncSeconds", 2f, new ConfigDescription("How often the server copies an echo chest's contents to the player's other echo chests. (Server setting.)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 30f), Array.Empty<object>()));
			LabelsEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Labels", "ShowLabels", true, "Show the labels written on chests (Shift+E on a chest to write one).");
			LabelSideSetting = ((BaseUnityPlugin)this).Config.Bind<LabelSide>("Labels", "Side", LabelSide.Front, "Which side of a chest its label is on. If it appears on the wrong side, try another.");
			PanelOffsetX = ((BaseUnityPlugin)this).Config.Bind<float>("Panel", "PanelOffsetX", 0f, new ConfigDescription("Where you dragged the Restock panel (saved automatically).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-3000f, 3000f), Array.Empty<object>()));
			PanelOffsetY = ((BaseUnityPlugin)this).Config.Bind<float>("Panel", "PanelOffsetY", 0f, new ConfigDescription("Where you dragged the Restock panel (saved automatically).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-3000f, 3000f), Array.Empty<object>()));
			PrefabManager.OnVanillaPrefabsAvailable += AddChest;
			_harmony = new Harmony("mbaya.ChestHeim");
			SafePatch.All(_harmony, typeof(ChestHeimPlugin).Assembly, Log);
			Log.LogInfo((object)"ChestHeim 0.5.3 loaded");
		}

		private void Update()
		{
			VaultServer.Tick();
			VaultPanel.Update();
		}

		private void OnGUI()
		{
			ChestWindow.Draw();
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private void AddChest()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Expected O, but got Unknown
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected O, but got Unknown
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Expected O, but got Unknown
			PrefabManager.OnVanillaPrefabsAvailable -= AddChest;
			PieceConfig val = new PieceConfig();
			val.Name = "Echo Chest";
			val.Description = "A chest that holds the same things as every other Echo Chest you have built, wherever they are. Anyone can put things in; only its builder can take them out.";
			val.PieceTable = PieceTables.Hammer;
			val.Category = PieceCategories.Furniture;
			val.Requirements = (RequirementConfig[])(object)new RequirementConfig[3]
			{
				new RequirementConfig("FineWood", 10, 0, true),
				new RequirementConfig("Iron", 10, 0, true),
				new RequirementConfig("SurtlingCore", 5, 0, true)
			};
			CustomPiece val2 = new CustomPiece("ChestHeim_EchoChest", "piece_chest_blackmetal", val);
			GameObject piecePrefab = val2.PiecePrefab;
			if ((Object)(object)piecePrefab == (Object)null)
			{
				Log.LogError((object)"Could not create the Echo Chest.");
				return;
			}
			ClanChest.AddKey();
			VaultChest.Customise(piecePrefab);
			PieceManager.Instance.AddPiece(val2);
		}
	}
	internal enum LabelSide
	{
		Front,
		Right,
		Back,
		Left
	}
	internal struct LabelData
	{
		public string Text;

		public string Icon;

		public string TextColor;

		public string IconColor;

		public bool Empty
		{
			get
			{
				if (string.IsNullOrEmpty(Text))
				{
					return string.IsNullOrEmpty(Icon);
				}
				return false;
			}
		}

		public string Signature => Text + "|" + Icon + "|" + TextColor + "|" + IconColor;
	}
	internal static class ChestLabel
	{
		private static readonly int KeyText = StringExtensionMethods.GetStableHashCode("ch_ltext");

		private static readonly int KeyIcon = StringExtensionMethods.GetStableHashCode("ch_licon");

		private static readonly int KeyTextColor = StringExtensionMethods.GetStableHashCode("ch_lcolor");

		private static readonly int KeyIconColor = StringExtensionMethods.GetStableHashCode("ch_licolor");

		private static readonly Dictionary<string, Sprite> Sprites = new Dictionary<string, Sprite>();

		public static bool Labelable(Container chest)
		{
			if ((Object)(object)chest != (Object)null && (Object)(object)chest.m_nview != (Object)null && chest.m_nview.IsValid() && (Object)(object)((Component)chest).GetComponent<Piece>() != (Object)null)
			{
				return Utils.GetPrefabName(((Component)chest).gameObject).ToLowerInvariant().Contains("chest");
			}
			return false;
		}

		public static LabelData Read(Container chest)
		{
			ZDO zDO = chest.m_nview.GetZDO();
			return new LabelData
			{
				Text = zDO.GetString(KeyText, ""),
				Icon = zDO.GetString(KeyIcon, ""),
				TextColor = zDO.GetString(KeyTextColor, ""),
				IconColor = zDO.GetString(KeyIconColor, "")
			};
		}

		public static void Write(Container chest, LabelData data)
		{
			if (Labelable(chest))
			{
				chest.m_nview.ClaimOwnership();
				ZDO zDO = chest.m_nview.GetZDO();
				zDO.Set(KeyText, data.Text ?? "");
				zDO.Set(KeyIcon, data.Icon ?? "");
				zDO.Set(KeyTextColor, data.TextColor ?? "");
				zDO.Set(KeyIconColor, data.IconColor ?? "");
			}
		}

		public static Color ParseColor(string hex, Color fallback)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			Color result = default(Color);
			if (string.IsNullOrEmpty(hex) || !ColorUtility.TryParseHtmlString(hex.StartsWith("#") ? hex : ("#" + hex), ref result))
			{
				return fallback;
			}
			return result;
		}

		public static string Plain(string text)
		{
			return Regex.Replace(text ?? "", "<[^>]+>", "");
		}

		public static Sprite SpriteOf(string prefab)
		{
			if (string.IsNullOrEmpty(prefab))
			{
				return null;
			}
			if (Sprites.TryGetValue(prefab, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			Sprite val = null;
			GameObject val2 = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(prefab) : null);
			ItemDrop val3 = (((Object)(object)val2 != (Object)null) ? val2.GetComponent<ItemDrop>() : null);
			if ((Object)(object)val3 != (Object)null && val3.m_itemData.m_shared.m_icons != null && val3.m_itemData.m_shared.m_icons.Length != 0)
			{
				val = val3.m_itemData.m_shared.m_icons[0];
			}
			if ((Object)(object)val == (Object)null && (Object)(object)ZNetScene.instance != (Object)null)
			{
				GameObject prefab2 = ZNetScene.instance.GetPrefab(prefab);
				Piece val4 = (((Object)(object)prefab2 != (Object)null) ? prefab2.GetComponent<Piece>() : null);
				if ((Object)(object)val4 != (Object)null)
				{
					val = val4.m_icon;
				}
			}
			if ((Object)(object)val != (Object)null)
			{
				Sprites[prefab] = val;
			}
			return val;
		}

		public static string NameOf(string prefab)
		{
			GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(prefab) : null);
			ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null);
			if (!((Object)(object)val2 != (Object)null))
			{
				return prefab;
			}
			return Localization.instance.Localize(val2.m_itemData.m_shared.m_name);
		}
	}
	internal class ChestLabelView : MonoBehaviour
	{
		private Container _chest;

		private string _signature;

		private GameObject _root;

		private float _next;

		private TextMesh _fitText;

		private float _fitWidth;

		private float _fitHeight;

		private int _fitTries;

		private void Awake()
		{
			_chest = ((Component)this).GetComponent<Container>();
		}

		private void Update()
		{
			if ((Object)(object)_fitText != (Object)null)
			{
				TryFit();
			}
			if (!(Time.time < _next))
			{
				_next = Time.time + 0.5f;
				Refresh();
			}
		}

		private void Clear()
		{
			if ((Object)(object)_root != (Object)null)
			{
				Object.Destroy((Object)(object)_root);
			}
			_root = null;
			_fitText = null;
		}

		private void OnDestroy()
		{
			Clear();
		}

		private void Refresh()
		{
			if ((Object)(object)_chest == (Object)null || (Object)(object)_chest.m_nview == (Object)null || !_chest.m_nview.IsValid() || !ChestHeimPlugin.LabelsEnabled.Value)
			{
				_signature = null;
				Clear();
				return;
			}
			LabelData data = ChestLabel.Read(_chest);
			string text = data.Signature + "|" + ChestHeimPlugin.LabelSideSetting.Value;
			if (!(text == _signature))
			{
				_signature = text;
				Clear();
				if (!data.Empty)
				{
					Build(data);
				}
			}
		}

		private void Build(LabelData data)
		{
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: 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_0138: 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_006c: 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_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: 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_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: 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_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Expected O, but got Unknown
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_0299: Unknown result type (might be due to invalid IL or missing references)
			//IL_029a: Unknown result type (might be due to invalid IL or missing references)
			//IL_029f: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_0328: Unknown result type (might be due to invalid IL or missing references)
			//IL_032d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			//IL_033e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0342: Unknown result type (might be due to invalid IL or missing references)
			//IL_034e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0353: Unknown result type (might be due to invalid IL or missing references)
			//IL_0357: Unknown result type (might be due to invalid IL or missing references)
			//IL_0368: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0382: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
			Bounds? val = null;
			Renderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<Renderer>();
			foreach (Renderer val2 in componentsInChildren)
			{
				if (val2 is TrailRenderer || val2 is LineRenderer || ((object)val2).GetType().Name.Contains("Particle"))
				{
					continue;
				}
				Bounds bounds = val2.bounds;
				for (int j = 0; j < 8; j++)
				{
					Vector3 val3 = ((Bounds)(ref bounds)).center + Vector3.Scale(((Bounds)(ref bounds)).extents, new Vector3((float)(j & 1), (float)((j >> 1) & 1), (float)((j >> 2) & 1)) * 2f - Vector3.one);
					Vector3 val4 = ((Component)this).transform.InverseTransformPoint(val3);
					if (!val.HasValue)
					{
						val = new Bounds(val4, Vector3.zero);
						continue;
					}
					Bounds value = val.Value;
					((Bounds)(ref value)).Encapsulate(val4);
					val = value;
				}
			}
			if (val.HasValue)
			{
				Bounds value2 = val.Value;
				LabelSide value3 = ChestHeimPlugin.LabelSideSetting.Value;
				Vector3 val5 = (Vector3)(value3 switch
				{
					LabelSide.Right => Vector3.right, 
					LabelSide.Back => Vector3.back, 
					LabelSide.Front => Vector3.forward, 
					_ => Vector3.left, 
				});
				bool flag = value3 == LabelSide.Front || value3 == LabelSide.Back;
				float num = ((!flag) ? ((val5.x > 0f) ? ((Bounds)(ref value2)).max.x : (0f - ((Bounds)(ref value2)).min.x)) : ((val5.z > 0f) ? ((Bounds)(ref value2)).max.z : (0f - ((Bounds)(ref value2)).min.z)));
				Vector3 val6 = default(Vector3);
				((Vector3)(ref val6))..ctor(((Bounds)(ref value2)).center.x, ((Bounds)(ref value2)).min.y + ((Bounds)(ref value2)).size.y * 0.42f, ((Bounds)(ref value2)).center.z);
				val6 += val5 * (num + 0.015f);
				float num2 = Mathf.Max(0.3f, (flag ? ((Bounds)(ref value2)).size.x : ((Bounds)(ref value2)).size.z) * 0.85f);
				float num3 = Mathf.Clamp(num2 * 0.3f, 0.12f, 0.3f);
				_root = new GameObject("ChestLabel");
				_root.transform.SetParent(((Component)this).transform, false);
				_root.transform.localPosition = val6;
				_root.transform.localRotation = Quaternion.LookRotation(-val5, Vector3.up);
				AddPlate(_root.transform, num2, num3 + 0.06f);
				Sprite val7 = ChestLabel.SpriteOf(data.Icon);
				float left = (0f - num2) / 2f + 0.03f;
				if ((Object)(object)val7 != (Object)null)
				{
					GameObject val8 = new GameObject("Icon");
					val8.transform.SetParent(_root.transform, false);
					SpriteRenderer obj = val8.AddComponent<SpriteRenderer>();
					obj.sprite = val7;
					obj.color = ChestLabel.ParseColor(data.IconColor, Color.white);
					Bounds bounds2 = val7.bounds;
					float x = ((Bounds)(ref bounds2)).size.x;
					bounds2 = val7.bounds;
					float num4 = Mathf.Max(x, ((Bounds)(ref bounds2)).size.y);
					val8.transform.localScale = Vector3.one * (num3 / Mathf.Max(0.0001f, num4));
					val8.transform.localPosition = new Vector3((0f - num2) / 2f + num3 / 2f + 0.03f, 0f, -0.004f);
					left = (0f - num2) / 2f + num3 + 0.07f;
				}
				if (!string.IsNullOrEmpty(data.Text))
				{
					AddText(_root.transform, data, (Object)(object)val7 != (Object)null, left, num2, num3);
				}
			}
		}

		private static void AddPlate(Transform parent, float width, float height)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//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_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_0061: 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_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: 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_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Expected O, but got Unknown
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Plate");
			val.transform.SetParent(parent, false);
			Mesh val2 = new Mesh
			{
				name = "ChestLabelPlate"
			};
			val2.vertices = (Vector3[])(object)new Vector3[4]
			{
				new Vector3(-0.5f, -0.5f, 0f),
				new Vector3(0.5f, -0.5f, 0f),
				new Vector3(-0.5f, 0.5f, 0f),
				new Vector3(0.5f, 0.5f, 0f)
			};
			val2.triangles = new int[6] { 0, 2, 3, 0, 3, 1 };
			val2.uv = (Vector2[])(object)new Vector2[4]
			{
				Vector2.zero,
				Vector2.right,
				Vector2.up,
				Vector2.one
			};
			val2.RecalculateNormals();
			val.AddComponent<MeshFilter>().sharedMesh = val2;
			MeshRenderer obj = val.AddComponent<MeshRenderer>();
			((Renderer)obj).sharedMaterial = new Material(Shader.Find("Sprites/Default"))
			{
				color = new Color(0.07f, 0.05f, 0.04f, 0.82f)
			};
			((Renderer)obj).shadowCastingMode = (ShadowCastingMode)0;
			val.transform.localScale = new Vector3(width, height, 1f);
		}

		private void AddText(Transform parent, LabelData data, bool hasIcon, float left, float width, float row)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Text");
			val.transform.SetParent(parent, false);
			TextMesh val2 = val.AddComponent<TextMesh>();
			val2.font = ((GUIManager.Instance != null) ? GUIManager.Instance.AveriaSerifBold : Resources.GetBuiltinResource<Font>("Arial.ttf"));
			val2.richText = true;
			val2.text = data.Text;
			val2.fontSize = 64;
			val2.characterSize = 0.01f;
			val2.color = ChestLabel.ParseColor(data.TextColor, Color.white);
			val2.anchor = (TextAnchor)(hasIcon ? 3 : 4);
			val2.alignment = (TextAlignment)(!hasIcon);
			((Renderer)val.GetComponent<MeshRenderer>()).sharedMaterial = val2.font.material;
			((Renderer)val.GetComponent<MeshRenderer>()).shadowCastingMode = (ShadowCastingMode)0;
			float fitWidth = (hasIcon ? (width / 2f - 0.03f - left) : (width - 0.06f));
			val.transform.localPosition = new Vector3(hasIcon ? left : 0f, 0f, -0.004f);
			_fitText = val2;
			_fitWidth = fitWidth;
			_fitHeight = row * (float)Mathf.Max(1, data.Text.Split('\n').Length);
			_fitTries = 0;
		}

		private void TryFit()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: 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_001f: 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_0093: 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)
			Bounds bounds = ((Renderer)((Component)_fitText).GetComponent<MeshRenderer>()).bounds;
			Vector3 size = ((Bounds)(ref bounds)).size;
			float num = Mathf.Max(size.x, size.z);
			float y = size.y;
			if ((!(num <= 0.0001f) && !(y <= 0.0001f)) || ++_fitTries >= 20)
			{
				if (num > 0.0001f && y > 0.0001f)
				{
					float num2 = Mathf.Min(_fitWidth / num, _fitHeight * 0.85f / y);
					((Component)_fitText).transform.localScale = Vector3.one * num2;
				}
				_fitText = null;
			}
		}
	}
	[HarmonyPatch(typeof(Container), "Awake")]
	internal static class ChestLabelAwakePatch
	{
		private static void Postfix(Container __instance)
		{
			if (!((Object)(object)((Component)__instance).GetComponent<ChestLabelView>() != (Object)null) && !((Object)(object)((Component)__instance).GetComponent<Piece>() == (Object)null) && Utils.GetPrefabName(((Component)__instance).gameObject).ToLowerInvariant().Contains("chest"))
			{
				((Component)__instance).gameObject.AddComponent<ChestLabelView>();
			}
		}
	}
	[HarmonyPatch(typeof(Container), "GetHoverText")]
	internal static class ChestLabelHoverPatch
	{
		private static void Postfix(Container __instance, ref string __result)
		{
			if (!ChestHeimPlugin.LabelsEnabled.Value || !ChestLabel.Labelable(__instance))
			{
				return;
			}
			string text = ChestLabel.Plain(ChestLabel.Read(__instance).Text).Replace("\n", " ").Trim();
			if (text.Length != 0)
			{
				string text2 = Localization.instance.Localize(__instance.m_name);
				int num = __result.IndexOf(text2, StringComparison.Ordinal);
				if (num >= 0)
				{
					__result = __result.Substring(0, num) + text + __result.Substring(num + text2.Length);
				}
			}
		}
	}
	internal static class ChestWindow
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static WindowFunction <0>__DrawWindow;
		}

		private const int WindowId = 31249;

		private static readonly Color[] Swatches = (Color[])(object)new Color[10]
		{
			Color.white,
			new Color(1f, 0.32f, 0.32f),
			new Color(1f, 0.72f, 0.3f),
			new Color(1f, 0.93f, 0.35f),
			new Color(0.61f, 0.8f, 0.39f),
			new Color(0.3f, 0.82f, 0.88f),
			new Color(0.39f, 0.71f, 0.96f),
			new Color(0.73f, 0.41f, 0.78f),
			new Color(0.55f, 0.43f, 0.39f),
			Color.black
		};

		private static readonly string[] CommonIcons = new string[23]
		{
			"Wood", "FineWood", "Stone", "Coal", "Copper", "Tin", "Bronze", "Iron", "BlackMetal", "Silver",
			"Flametal", "SurtlingCore", "Resin", "LeatherScraps", "DeerHide", "Feathers", "Flint", "Honey", "MeadHealthMinor", "CookedMeat",
			"ArrowWood", "Coins", "Hammer"
		};

		private static Container _chest;

		private static Rect _rect;

		private static int _tab;

		private static string _text = "";

		private static string _icon = "";

		private static string _textColor = "";

		private static string _iconColor = "";

		private static string _message = "";

		private static string _clanText = "";

		private static bool _picking;

		private static string _query = "";

		private static Vector2 _scroll;

		private static List<(string prefab, string label)> _results = new List<(string, string)>();

		private static CursorLockMode _lockBefore;

		private static bool _visibleBefore;

		private static GUIStyle _preview;

		public static bool IsOpen => (Object)(object)_chest != (Object)null;

		private static float Scale => Mathf.Clamp((float)Screen.height / 1080f, 0.8f, 2.5f);

		private static bool ClanAvailable
		{
			get
			{
				if ((Object)(object)_chest != (Object)null && VaultRules.IsBuilder(_chest))
				{
					return ClanChest.HasKey(Player.m_localPlayer);
				}
				return false;
			}
		}

		public static void Open(Container chest)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: 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_00c5: Unknown result type (might be due to invalid IL or missing references)
			_chest = chest;
			LabelData labelData = ChestLabel.Read(chest);
			_text = labelData.Text;
			_icon = labelData.Icon;
			_textColor = labelData.TextColor;
			_iconColor = labelData.IconColor;
			_clanText = ClanChest.MyClan;
			_message = "";
			_tab = 0;
			_picking = false;
			_query = "";
			_results = Search("");
			_lockBefore = Cursor.lockState;
			_visibleBefore = Cursor.visible;
			float scale = Scale;
			_rect = new Rect(((float)Screen.width - 540f * scale) / 2f, ((float)Screen.height - 560f * scale) / 2f, 540f * scale, 560f * scale);
		}

		public static void Close()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_chest == (Object)null))
			{
				_chest = null;
				Cursor.lockState = _lockBefore;
				Cursor.visible = _visibleBefore;
			}
		}

		public static void Draw()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Invalid comparison between Unknown and I4
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Invalid comparison between Unknown and I4
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: 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_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Expected O, but got Unknown
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: 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_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Expected O, but got Unknown
			if ((Object)(object)_chest == (Object)null)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead() || Vector3.Distance(((Component)localPlayer).transform.position, ((Component)_chest).transform.position) > 8f)
			{
				Close();
				return;
			}
			Cursor.lockState = (CursorLockMode)0;
			Cursor.visible = true;
			Event current = Event.current;
			if ((int)current.type == 4 && (int)current.keyCode == 27)
			{
				current.Use();
				if (_picking)
				{
					_picking = false;
				}
				else
				{
					Close();
				}
				return;
			}
			float scale = Scale;
			GUI.skin.label.fontSize = Mathf.RoundToInt(16f * scale);
			GUI.skin.button.fontSize = Mathf.RoundToInt(16f * scale);
			GUI.skin.textField.fontSize = Mathf.RoundToInt(16f * scale);
			GUI.skin.textArea.fontSize = Mathf.RoundToInt(16f * scale);
			GUI.skin.toggle.fontSize = Mathf.RoundToInt(16f * scale);
			if (_preview == null)
			{
				_preview = new GUIStyle(GUI.skin.label)
				{
					richText = true,
					alignment = (TextAnchor)3
				};
			}
			_preview.fontSize = Mathf.RoundToInt(22f * scale);
			GUI.Box(_rect, GUIContent.none);
			Rect rect = _rect;
			object obj = <>O.<0>__DrawWindow;
			if (obj == null)
			{
				WindowFunction val = DrawWindow;
				<>O.<0>__DrawWindow = val;
				obj = (object)val;
			}
			_rect = GUI.Window(31249, rect, (WindowFunction)obj, "Chest");
		}

		private static void DrawWindow(int id)
		{
			float scale = Scale;
			GUILayout.Space(6f * scale);
			if (ClanAvailable)
			{
				_tab = GUILayout.Toolbar(_tab, new string[2] { "Label", "Clan" }, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f * scale) });
				GUILayout.Space(4f * scale);
			}
			else
			{
				_tab = 0;
			}
			if (_tab == 1)
			{
				DrawClan(scale);
			}
			else if (_picking)
			{
				DrawPicker(scale);
			}
			else
			{
				DrawLabel(scale);
			}
			GUILayout.FlexibleSpace();
			if (_message.Length > 0)
			{
				GUILayout.Label(_message, Array.Empty<GUILayoutOption>());
			}
			if (!_picking && GUILayout.Button("Close (Esc)", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f * scale) }))
			{
				Close();
			}
			GUI.DragWindow();
		}

		private static void DrawLabel(float s)
		{
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: 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_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.Label("Text. Colours: <color=#ff5252>red</color> is written <color=#ff5252>…</color> with tags, and <b>, <i> work too:", Array.Empty<GUILayoutOption>());
			_text = GUILayout.TextArea(_text, 80, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(58f * s) });
			GUILayout.Space(2f * s);
			GUILayout.Label("Text colour (used where the text has no colour tag of its own):", Array.Empty<GUILayoutOption>());
			SwatchRow(s, ref _textColor);
			GUILayout.Space(6f * s);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			Sprite val = ChestLabel.SpriteOf(_icon);
			Rect rect = GUILayoutUtility.GetRect(40f * s, 40f * s, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(40f * s) });
			if ((Object)(object)val != (Object)null)
			{
				DrawSprite(rect, val, ChestLabel.ParseColor(_iconColor, Color.white));
			}
			GUILayout.Label(((Object)(object)val != (Object)null) ? ("Icon: " + ChestLabel.NameOf(_icon)) : "No icon", Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("Choose icon...", (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(150f * s),
				GUILayout.Height(30f * s)
			}))
			{
				_picking = true;
				_results = Search(_query);
			}
			if (GUILayout.Button("No icon", (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(90f * s),
				GUILayout.Height(30f * s)
			}))
			{
				_icon = "";
			}
			GUILayout.EndHorizontal();
			GUILayout.Label("Icon colour:", Array.Empty<GUILayoutOption>());
			SwatchRow(s, ref _iconColor);
			GUILayout.Space(8f * s);
			GUILayout.Label("Preview:", Array.Empty<GUILayoutOption>());
			Color contentColor = ChestLabel.ParseColor(_textColor, Color.white);
			GUILayout.BeginHorizontal(GUI.skin.box, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(46f * s) });
			Rect rect2 = GUILayoutUtility.GetRect(36f * s, 36f * s, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(36f * s) });
			if ((Object)(object)val != (Object)null)
			{
				DrawSprite(rect2, val, ChestLabel.ParseColor(_iconColor, Color.white));
			}
			Color contentColor2 = GUI.contentColor;
			GUI.contentColor = contentColor;
			GUILayout.Label(_text, _preview, Array.Empty<GUILayoutOption>());
			GUI.contentColor = contentColor2;
			GUILayout.EndHorizontal();
			GUILayout.Space(8f * s);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("Save label", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(32f * s) }))
			{
				ChestLabel.Write(_chest, new LabelData
				{
					Text = _text.Trim(),
					Icon = _icon,
					TextColor = _textColor,
					IconColor = _iconColor
				});
				_message = "Saved.";
			}
			if (GUILayout.Button("Remove label", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(32f * s) }))
			{
				ChestLabel.Write(_chest, default(LabelData));
				_text = (_icon = (_textColor = (_iconColor = "")));
				_message = "Label removed.";
			}
			GUILayout.EndHorizontal();
		}

		private static void SwatchRow(float s, ref string hex)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			Color color = GUI.color;
			Color[] swatches = Swatches;
			foreach (Color val in swatches)
			{
				Rect rect = GUILayoutUtility.GetRect(26f * s, 22f * s, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(26f * s) });
				GUI.color = val;
				if (GUI.Button(rect, GUIContent.none))
				{
					hex = "#" + ColorUtility.ToHtmlStringRGB(val);
				}
			}
			GUI.color = color;
			hex = GUILayout.TextField(hex ?? "", 9, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f * s) });
			GUILayout.EndHorizontal();
		}

		private static void DrawSprite(Rect rect, Sprite sprite, Color tint)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			Texture2D texture = sprite.texture;
			if (!((Object)(object)texture == (Object)null))
			{
				Rect textureRect = sprite.textureRect;
				Color color = GUI.color;
				GUI.color = tint;
				GUI.DrawTextureWithTexCoords(rect, (Texture)(object)texture, new Rect(((Rect)(ref textureRect)).x / (float)((Texture)texture).width, ((Rect)(ref textureRect)).y / (float)((Texture)texture).height, ((Rect)(ref textureRect)).width / (float)((Texture)texture).width, ((Rect)(ref textureRect)).height / (float)((Texture)texture).height));
				GUI.color = color;
			}
		}

		private static List<(string prefab, string label)> Search(string query)
		{
			List<(string, string)> list = new List<(string, string)>();
			query = (query ?? "").Trim();
			if ((Object)(object)ObjectDB.instance == (Object)null)
			{
				return list;
			}
			if (query.Length < 2)
			{
				string[] commonIcons = CommonIcons;
				foreach (string text in commonIcons)
				{
					if ((Object)(object)ChestLabel.SpriteOf(text) != (Object)null)
					{
						list.Add((text, ChestLabel.NameOf(text)));
					}
				}
				return list;
			}
			foreach (GameObject item in ObjectDB.instance.m_items)
			{
				if (list.Count >= 40)
				{
					break;
				}
				ItemDrop val = (((Object)(object)item != (Object)null) ? item.GetComponent<ItemDrop>() : null);
				if (!((Object)(object)val == (Object)null) && val.m_itemData.m_shared.m_icons != null && val.m_itemData.m_shared.m_icons.Length != 0)
				{
					string text2 = Localization.instance.Localize(val.m_itemData.m_shared.m_name);
					if (text2.IndexOf(query, StringComparison.CurrentCultureIgnoreCase) >= 0 || ((Object)item).name.IndexOf(query, StringComparison.CurrentCultureIgnoreCase) >= 0)
					{
						list.Add((((Object)item).name, text2));
					}
				}
			}
			return list;
		}

		private static void DrawPicker(float s)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.Label("Search the game's items by name:", Array.Empty<GUILayoutOption>());
			string query = _query;
			_query = GUILayout.TextField(_query, 30, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f * s) });
			if (_query != query)
			{
				_results = Search(_query);
			}
			_scroll = GUILayout.BeginScrollView(_scroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(340f * s) });
			foreach (var (text, text2) in _results)
			{
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				Sprite val = ChestLabel.SpriteOf(text);
				Rect rect = GUILayoutUtility.GetRect(32f * s, 32f * s, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(32f * s) });
				if ((Object)(object)val != (Object)null)
				{
					DrawSprite(rect, val, Color.white);
				}
				if (GUILayout.Button(text2, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(32f * s) }))
				{
					_icon = text;
					_picking = false;
				}
				GUILayout.EndHorizontal();
			}
			if (_results.Count == 0)
			{
				GUILayout.Label("Nothing matches that.", Array.Empty<GUILayoutOption>());
			}
			GUILayout.EndScrollView();
			if (GUILayout.Button("Back", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f * s) }))
			{
				_picking = false;
			}
		}

		private static void DrawClan(float s)
		{
			string text = ClanChest.ClanOf(_chest);
			bool flag = VaultChest.IsVault(_chest);
			GUILayout.Label("Your clan (saved on this character):", Array.Empty<GUILayoutOption>());
			_clanText = GUILayout.TextField(_clanText, 24, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f * s) });
			GUILayout.Space(6f * s);
			GUILayout.Label((text.Length > 0) ? ("This chest is shared with the clan \"" + text + "\".") : "This chest isn't shared.", Array.Empty<GUILayoutOption>());
			if (flag)
			{
				GUILayout.Label("An Echo Chest set to a clan shows the same things as every other Echo Chest set to that clan. Its own contents are replaced by theirs.", Array.Empty<GUILayoutOption>());
			}
			GUILayout.Space(6f * s);
			bool enabled = (GUI.enabled = _clanText.Trim().Length > 0);
			if (GUILayout.Button(flag ? "Link this chest with my clan" : "Share this chest with my clan", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(32f * s) }))
			{
				ClanChest.MyClan = _clanText;
				ClanChest.SetClan(_chest, _clanText);
				_message = "Shared with " + _clanText.Trim() + ". Anyone whose clan is set to that name can open it.";
			}
			GUI.enabled = text.Length > 0;
			if (GUILayout.Button(flag ? "Back to my own echo chests" : "Stop sharing", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(32f * s) }))
			{
				ClanChest.SetClan(_chest, "");
				_message = "No longer shared.";
			}
			GUI.enabled = enabled;
			if (GUILayout.Button("Just save my clan name", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(28f * s) }))
			{
				ClanChest.MyClan = _clanText;
				_message = "Saved.";
			}
			GUI.enabled = true;
		}
	}
	[HarmonyPatch(typeof(Player), "TakeInput")]
	internal static class ChestWindowTakeInputPatch
	{
		private static void Postfix(ref bool __result)
		{
			if (ChestWindow.IsOpen)
			{
				__result = false;
			}
		}
	}
	[HarmonyPatch(typeof(PlayerController), "TakeInput")]
	internal static class ChestWindowControllerInputPatch
	{
		private static void Postfix(ref bool __result)
		{
			if (ChestWindow.IsOpen)
			{
				__result = false;
			}
		}
	}
	[HarmonyPatch(typeof(GameCamera), "UpdateMouseCapture")]
	internal static class KeepCursorPatch
	{
		private static void Postfix()
		{
			if (ChestWindow.IsOpen)
			{
				Cursor.lockState = (CursorLockMode)0;
				Cursor.visible = true;
			}
		}
	}
	internal static class ClanChest
	{
		public const string KeyItem = "ChestHeim_ClanKey";

		private const string ClanKey = "VH.Clan";

		public static readonly int KeyClan = StringExtensionMethods.GetStableHashCode("vh_clan");

		public static string MyClan
		{
			get
			{
				Player localPlayer = Player.m_localPlayer;
				if (!((Object)(object)localPlayer != (Object)null) || !localPlayer.m_customData.TryGetValue("VH.Clan", out var value))
				{
					return "";
				}
				return value;
			}
			set
			{
				Player localPlayer = Player.m_localPlayer;
				if ((Object)(object)localPlayer != (Object)null)
				{
					localPlayer.m_customData["VH.Clan"] = (value ?? "").Trim();
				}
			}
		}

		public static string ClanOf(Container chest)
		{
			if (!((Object)(object)chest != (Object)null) || !((Object)(object)chest.m_nview != (Object)null) || !chest.m_nview.IsValid())
			{
				return "";
			}
			return chest.m_nview.GetZDO().GetString(KeyClan, "");
		}

		public static bool SameClan(string a, string b)
		{
			if (a.Length > 0 && b.Length > 0)
			{
				return string.Equals(a.Trim(), b.Trim(), StringComparison.CurrentCultureIgnoreCase);
			}
			return false;
		}

		public static bool HasKey(Player player)
		{
			if ((Object)(object)player != (Object)null)
			{
				return ((Humanoid)player).GetInventory().GetAllItems().Any((ItemData i) => (Object)(object)i.m_dropPrefab != (Object)null && ((Object)i.m_dropPrefab).name == "ChestHeim_ClanKey");
			}
			return false;
		}

		public static void SetClan(Container chest, string clan)
		{
			if (!((Object)(object)chest == (Object)null) && !((Object)(object)chest.m_nview == (Object)null) && chest.m_nview.IsValid())
			{
				chest.m_nview.ClaimOwnership();
				ZDO zDO = chest.m_nview.GetZDO();
				zDO.Set(KeyClan, (clan ?? "").Trim());
				if (VaultChest.IsVault(zDO))
				{
					zDO.Set(VaultChest.KeyJoined, 0, false);
				}
			}
		}

		public static void AddKey()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Expected O, but got Unknown
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Expected O, but got Unknown
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			ItemConfig val = new ItemConfig();
			val.Name = "Clan Key";
			val.Description = "Carry it and press Shift+E on a chest you built to share it with your clan.";
			val.CraftingStation = CraftingStations.Workbench;
			val.MinStationLevel = 1;
			val.Amount = 1;
			val.Requirements = (RequirementConfig[])(object)new RequirementConfig[2]
			{
				new RequirementConfig("Bronze", 2, 0, true),
				new RequirementConfig("FineWood", 2, 0, true)
			};
			CustomItem val2 = new CustomItem("ChestHeim_ClanKey", "Ruby", val);
			if ((Object)(object)val2.ItemDrop != (Object)null)
			{
				val2.ItemDrop.m_itemData.m_shared.m_maxStackSize = 1;
			}
			ItemManager.Instance.AddItem(val2);
		}
	}
	[HarmonyPatch(typeof(Container), "CheckAccess")]
	internal static class ClanAccessPatch
	{
		private static void Postfix(Container __instance, long playerID, ref bool __result)
		{
			string text = ClanChest.ClanOf(__instance);
			if (text.Length != 0 && !VaultChest.IsVault(__instance))
			{
				bool flag = __instance.m_nview.GetZDO().GetLong(ZDOVars.s_creator, 0L) == playerID;
				__result = flag || ClanChest.SameClan(text, ClanChest.MyClan);
			}
		}
	}
	[HarmonyPatch(typeof(Container), "Interact")]
	internal static class ChestWindowInteractPatch
	{
		private static bool Prefix(Container __instance, Humanoid character, bool hold, bool alt, ref bool __result)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			if (hold || !alt || (Object)(object)character != (Object)(object)Player.m_localPlayer || !ChestLabel.Labelable(__instance))
			{
				return true;
			}
			Player val = (Player)character;
			if (VaultChest.IsVault(__instance) ? (!VaultRules.CanTake(__instance)) : (!__instance.CheckAccess(val.GetPlayerID())))
			{
				return true;
			}
			ChestWindow.Open(__instance);
			__result = true;
			return false;
		}
	}
	[HarmonyPatch(typeof(Container), "GetHoverText")]
	internal static class ClanHoverPatch
	{
		private static void Postfix(Container __instance, ref string __result)
		{
			string text = ClanChest.ClanOf(__instance);
			if (text.Length > 0)
			{
				__result = __result + "\n<color=#b39ddb>Clan chest: " + text + "</color>";
			}
			if (ChestLabel.Labelable(__instance))
			{
				__result = __result + "\n[<color=yellow><b>Shift+E</b></color>] Label" + ((VaultRules.IsBuilder(__instance) && ClanChest.HasKey(Player.m_localPlayer)) ? " / clan" : "");
			}
		}
	}
	internal class PanelDrag : MonoBehaviour, IBeginDragHandler, IEventSystemHandler, IDragHandler, IEndDragHandler, IPointerClickHandler
	{
		public RectTransform Target;

		public Action<Vector2> Moved;

		public Action Dropped;

		public Action Reset;

		public void OnBeginDrag(PointerEventData eventData)
		{
		}

		public void OnDrag(PointerEventData eventData)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)Target == (Object)null) && !((Object)(object)((Transform)Target).parent == (Object)null))
			{
				float num = Mathf.Max(0.0001f, ((Transform)Target).parent.lossyScale.x);
				Moved?.Invoke(eventData.delta / num);
			}
		}

		public void OnEndDrag(PointerEventData eventData)
		{
			Dropped?.Invoke();
		}

		public void OnPointerClick(PointerEventData eventData)
		{
			if (eventData.clickCount >= 2)
			{
				Reset?.Invoke();
			}
		}
	}
	internal static class SafePatch
	{
		public static void All(Harmony harmony, Assembly assembly, ManualLogSource log)
		{
			Type[] typesFromAssembly = AccessTools.GetTypesFromAssembly(assembly);
			foreach (Type type in typesFromAssembly)
			{
				if (type.GetCustomAttributes(typeof(HarmonyPatch), inherit: true).Length != 0)
				{
					try
					{
						harmony.PatchAll(type);
					}
					catch (Exception ex)
					{
						log.LogError((object)("Couldn't apply the patch " + type.Name + "; the rest are fine. " + ex.Message));
					}
				}
			}
		}
	}
	internal static class VaultChest
	{
		public const string PrefabName = "ChestHeim_EchoChest";

		public static readonly int PrefabHash = StringExtensionMethods.GetStableHashCode("ChestHeim_EchoChest");

		public static readonly int KeyJoined = StringExtensionMethods.GetStableHashCode("vh_joined");

		public static readonly int KeyStamp = StringExtensionMethods.GetStableHashCode("vh_stamp");

		public static readonly int KeyCount = StringExtensionMethods.GetStableHashCode("vh_count");

		public static readonly int KeyBusy = StringExtensionMethods.GetStableHashCode("vh_busy");

		public static bool IsVault(ZDO zdo)
		{
			if (zdo != null)
			{
				return zdo.GetPrefab() == PrefabHash;
			}
			return false;
		}

		public static bool IsVault(Container container)
		{
			if ((Object)(object)container != (Object)null && (Object)(object)container.m_nview != (Object)null && container.m_nview.IsValid())
			{
				return IsVault(container.m_nview.GetZDO());
			}
			return false;
		}

		public static void Customise(GameObject prefab)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: 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_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Expected O, but got Unknown
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			Container component = prefab.GetComponent<Container>();
			if ((Object)(object)component != (Object)null)
			{
				component.m_name = "Echo Chest";
				component.m_width = 5;
				component.m_height = 10;
				component.m_privacy = (PrivacySetting)2;
				component.m_autoDestroyEmpty = false;
				component.m_checkGuardStone = false;
			}
			Color val = default(Color);
			((Color)(ref val))..ctor(0.55f, 0.4f, 1f);
			Renderer[] componentsInChildren = prefab.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val2 in componentsInChildren)
			{
				Material[] sharedMaterials = val2.sharedMaterials;
				for (int j = 0; j < sharedMaterials.Length; j++)
				{
					if (!((Object)(object)sharedMaterials[j] == (Object)null) && sharedMaterials[j].HasProperty("_Color"))
					{
						Material val3 = new Material(sharedMaterials[j])
						{
							name = ((Object)sharedMaterials[j]).name + "_Vault"
						};
						val3.color = Color.Lerp(val3.color, val, 0.55f);
						sharedMaterials[j] = val3;
					}
				}
				val2.sharedMaterials = sharedMaterials;
			}
			GameObject val4 = new GameObject("VaultGlow");
			val4.transform.SetParent(prefab.transform, false);
			val4.transform.localPosition = new Vector3(0f, 0.6f, 0f);
			Light obj = val4.AddComponent<Light>();
			obj.type = (LightType)2;
			obj.color = new Color(0.6f, 0.45f, 1f);
			obj.range = 3f;
			obj.intensity = 0.7f;
			obj.shadows = (LightShadows)0;
		}
	}
	internal static class VaultPanel
	{
		private const string TargetsKey = "VH.Restock";

		private const float Width = 400f;

		private const float RowHeight = 34f;

		private const float Zoom = 1.3f;

		private const int MaxRows = 10;

		private const int MaxResults = 5;

		private static GameObject _panel;

		private static GameObject _close;

		private static InputField _search;

		private static string _query = "";

		private static string _status = "";

		private static Container _chest;

		private static bool _blocking;

		private static Vector2 _offset;

		private static List<KeyValuePair<string, int>> Targets()
		{
			List<KeyValuePair<string, int>> list = new List<KeyValuePair<string, int>>();
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || !localPlayer.m_customData.TryGetValue("VH.Restock", out var value) || string.IsNullOrEmpty(value))
			{
				return list;
			}
			string[] array = value.Split(';');
			for (int i = 0; i < array.Length; i++)
			{
				string[] array2 = array[i].Split('=');
				if (array2.Length == 2 && int.TryParse(array2[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result) && result > 0)
				{
					list.Add(new KeyValuePair<string, int>(array2[0], result));
				}
			}
			return list;
		}

		private static void SaveTargets(IEnumerable<KeyValuePair<string, int>> targets)
		{
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null))
			{
				localPlayer.m_customData["VH.Restock"] = string.Join(";", from t in targets
					where t.Value > 0
					select t.Key + "=" + t.Value.ToString(CultureInfo.InvariantCulture));
			}
		}

		private static void Adjust(string prefab, int delta)
		{
			List<KeyValuePair<string, int>> list = Targets();
			int num = list.FindIndex((KeyValuePair<string, int> t) => t.Key == prefab);
			int num2 = Mathf.Max(0, ((num >= 0) ? list[num].Value : 0) + delta);
			if (num >= 0)
			{
				list.RemoveAt(num);
			}
			if (num2 > 0)
			{
				list.Add(new KeyValuePair<string, int>(prefab, num2));
			}
			SaveTargets(list);
			Rebuild();
		}

		private static SharedData SharedOf(string prefab)
		{
			GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(prefab) : null);
			ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null);
			if (!((Object)(object)val2 != (Object)null))
			{
				return null;
			}
			return val2.m_itemData.m_shared;
		}

		private static string NameOf(string prefab)
		{
			SharedData val = SharedOf(prefab);
			if (val == null)
			{
				return prefab;
			}
			return Localization.instance.Localize(val.m_name);
		}

		private static int Carried(Inventory inventory, string prefab)
		{
			return (from i in inventory.GetAllItems()
				where (Object)(object)i.m_dropPrefab != (Object)null && ((Object)i.m_dropPrefab).name == prefab
				select i).Sum((ItemData i) => i.m_stack);
		}

		private static void Remember()
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return;
			}
			Dictionary<string, int> dictionary = new Dictionary<string, int>();
			foreach (ItemData allItem in ((Humanoid)localPlayer).GetInventory().GetAllItems())
			{
				if (!((Object)(object)allItem.m_dropPrefab == (Object)null) && !allItem.m_equipped)
				{
					string name = ((Object)allItem.m_dropPrefab).name;
					dictionary[name] = (dictionary.TryGetValue(name, out var value) ? value : 0) + allItem.m_stack;
				}
			}
			SaveTargets(dictionary);
			_status = "Remembered what you're carrying.";
			Rebuild();
		}

		private static void Restock()
		{
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || (Object)(object)_chest == (Object)null)
			{
				return;
			}
			Inventory inventory = ((Humanoid)localPlayer).GetInventory();
			Inventory inventory2 = _chest.GetInventory();
			int num = 0;
			int num2 = 0;
			foreach (KeyValuePair<string, int> target in Targets())
			{
				int num3 = target.Value - Carried(inventory, target.Key);
				if (num3 <= 0)
				{
					continue;
				}
				foreach (ItemData item in (from i in inventory2.GetAllItems()
					where (Object)(object)i.m_dropPrefab != (Object)null && ((Object)i.m_dropPrefab).name == target.Key
					select i).ToList())
				{
					if (num3 <= 0)
					{
						break;
					}
					int num4 = Mathf.Min(num3, item.m_stack);
					ItemData val = item.Clone();
					val.m_stack = num4;
					if (!inventory.CanAddItem(val, -1) || !inventory.AddItem(val))
					{
						break;
					}
					inventory2.RemoveItem(item, num4);
					num3 -= num4;
					num += num4;
				}
				if (num3 > 0)
				{
					num2++;
				}
			}
			_status = ((num == 0) ? "Nothing to take." : (string.Format("Took {0} item{1}.", num, (num == 1) ? "" : "s") + ((num2 > 0) ? $" {num2} short." : "")));
			Rebuild();
		}

		public static void Show(Container chest)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			_chest = chest;
			_query = "";
			_status = "";
			_offset = new Vector2(ChestHeimPlugin.PanelOffsetX.Value, ChestHeimPlugin.PanelOffsetY.Value);
			Rebuild();
		}

		public static void Hide()
		{
			if ((Object)(object)_panel != (Object)null)
			{
				Object.Destroy((Object)(object)_panel);
			}
			if ((Object)(object)_close != (Object)null)
			{
				Object.Destroy((Object)(object)_close);
			}
			_panel = null;
			_close = null;
			_search = null;
			_chest = null;
			SetBlock(block: false);
		}

		public static void Update()
		{
			if (!((Object)(object)_panel == (Object)null))
			{
				RectTransform val = (((Object)(object)InventoryGui.instance != (Object)null) ? InventoryGui.instance.m_container : null);
				RectTransform component = _panel.GetComponent<RectTransform>();
				if ((Object)(object)val != (Object)null && (Object)(object)((Transform)component).parent != (Object)(object)val)
				{
					Attach();
				}
				SetBlock((Object)(object)_search != (Object)null && _search.isFocused);
			}
		}

		private static void SetBlock(bool block)
		{
			if (block != _blocking)
			{
				_blocking = block;
				GUIManager.BlockInput(block);
			}
		}

		private static void Attach()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			RectTransform component = _panel.GetComponent<RectTransform>();
			RectTransform val = (((Object)(object)InventoryGui.instance != (Object)null) ? InventoryGui.instance.m_container : null);
			((Transform)component).localScale = Vector3.one * 1.3f;
			if (!((Object)(object)val == (Object)null))
			{
				((Transform)component).SetParent((Transform)(object)val, false);
				Vector2 val2 = default(Vector2);
				((Vector2)(ref val2))..ctor(1f, 1f);
				component.anchorMax = val2;
				component.anchorMin = val2;
				component.pivot = new Vector2(0f, 1f);
				component.anchoredPosition = new Vector2(6f, 0f) + _offset;
			}
		}

		private static void CloseChest()
		{
			if ((Object)(object)InventoryGui.instance != (Object)null && (Object)(object)InventoryGui.instance.m_currentContainer != (Object)null)
			{
				InventoryGui.instance.CloseContainer();
			}
		}

		private static void Rebuild()
		{
			//IL_0094: 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_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_026b: Unknown result type (might be due to invalid IL or missing references)
			//IL_029b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0479: Unknown result type (might be due to invalid IL or missing references)
			//IL_0488: Unknown result type (might be due to invalid IL or missing references)
			//IL_0494: Unknown result type (might be due to invalid IL or missing references)
			//IL_0354: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_chest == (Object)null || (Object)(object)GUIManager.CustomGUIFront == (Object)null)
			{
				Hide();
				return;
			}
			if ((Object)(object)_panel != (Object)null)
			{
				Object.Destroy((Object)(object)_panel);
			}
			List<KeyValuePair<string, int>> list = Targets();
			List<KeyValuePair<string, string>> list2 = SearchResults(list);
			int num = Mathf.Max(1, Mathf.Min(list.Count, 10));
			float num2 = 230f + (float)num * 34f + (float)(list2.Count + 1) * 34f;
			GUIManager instance = GUIManager.Instance;
			_panel = instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(-230f, 0f), 400f, num2, false);
			PanelDrag panelDrag = _panel.AddComponent<PanelDrag>();
			panelDrag.Target = _panel.GetComponent<RectTransform>();
			panelDrag.Moved = delegate(Vector2 delta)
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				//IL_000b: Unknown result type (might be due to invalid IL or missing references)
				_offset += delta;
				Attach();
			};
			panelDrag.Dropped = delegate
			{
				ChestHeimPlugin.PanelOffsetX.Value = _offset.x;
				ChestHeimPlugin.PanelOffsetY.Value = _offset.y;
			};
			panelDrag.Reset = delegate
			{
				//IL_0000: Unknown result type (might be due to invalid IL or missing references)
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				_offset = Vector2.zero;
				Attach();
				ChestHeimPlugin.PanelOffsetX.Value = 0f;
				ChestHeimPlugin.PanelOffsetY.Value = 0f;
			};
			Attach();
			Button("X", 166f, -24f, 44f, CloseChest);
			float num3 = -28f;
			Text("Restock", 0f, num3, 24, instance.ValheimOrange, 300f, (TextAnchor)4);
			num3 -= 34f;
			Text("Set what you like to carry, then click Restock.", 0f, num3, 14, Color.gray, 360f, (TextAnchor)4);
			num3 -= 40f;
			Button("Restock", -95f, num3, 190f, Restock);
			Button("Remember what I carry", 110f, num3, 200f, Remember);
			num3 -= 38f;
			if (_status.Length > 0)
			{
				Text(_status, 0f, num3, 14, instance.ValheimBeige, 360f, (TextAnchor)4);
			}
			num3 -= 34f;
			if (list.Count == 0)
			{
				Text("Nothing yet. Add items below.", 0f, num3, 14, Color.gray, 360f, (TextAnchor)4);
				num3 -= 34f;
			}
			Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory();
			foreach (KeyValuePair<string, int> item in list.Take(10))
			{
				int num4 = Carried(inventory, item.Key);
				string text = ((num4 >= item.Value) ? "#9ccc65" : "#ffb74d");
				Text($"{NameOf(item.Key)}  <color={text}>{num4}/{item.Value}</color>", -180f, num3, 16, Color.white, 230f, (TextAnchor)3);
				string prefab = item.Key;
				int step = (((SharedOf(prefab)?.m_maxStackSize ?? 1) < 50) ? 1 : 10);
				step = ((Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303)) ? (step * 10) : step);
				Button("-", 85f, num3, 34f, delegate
				{
					Adjust(prefab, -step);
				});
				Button("+", 123f, num3, 34f, delegate
				{
					Adjust(prefab, step);
				});
				Button("x", 161f, num3, 34f, delegate
				{
					Adjust(prefab, -1073741823);
				});
				num3 -= 34f;
			}
			num3 -= 10f;
			_search = instance.CreateInputField(_panel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, num3), (ContentType)0, "Add an item: type part of a name, press Enter", 16, 350f, 30f).GetComponent<InputField>();
			_search.text = _query;
			((UnityEvent<string>)(object)_search.onEndEdit).AddListener((UnityAction<string>)delegate(string query)
			{
				_query = query;
				Rebuild();
			});
			num3 -= 38f;
			foreach (KeyValuePair<string, string> item2 in list2)
			{
				string prefab2 = item2.Key;
				int amount = Mathf.Min(SharedOf(prefab2)?.m_maxStackSize ?? 1, 10);
				Button("+ " + item2.Value, 0f, num3, 350f, delegate
				{
					Adjust(prefab2, amount);
					_query = "";
					Rebuild();
				});
				num3 -= 34f;
			}
		}

		private static List<KeyValuePair<string, string>> SearchResults(List<KeyValuePair<string, int>> targets)
		{
			List<KeyValuePair<string, string>> list = new List<KeyValuePair<string, string>>();
			string text = (_query ?? "").Trim();
			if (text.Length < 2 || (Object)(object)ObjectDB.instance == (Object)null)
			{
				return list;
			}
			foreach (GameObject go in ObjectDB.instance.m_items)
			{
				ItemDrop val = (((Object)(object)go != (Object)null) ? go.GetComponent<ItemDrop>() : null);
				if ((Object)(object)val == (Object)null || targets.Any((KeyValuePair<string, int> t) => t.Key == ((Object)go).name))
				{
					continue;
				}
				SharedData shared = val.m_itemData.m_shared;
				if (shared.m_icons == null || shared.m_icons.Length == 0)
				{
					continue;
				}
				string text2 = Localization.instance.Localize(shared.m_name);
				if (text2.IndexOf(text, StringComparison.CurrentCultureIgnoreCase) >= 0)
				{
					list.Add(new KeyValuePair<string, string>(((Object)go).name, text2));
					if (list.Count >= 5)
					{
						break;
					}
				}
			}
			return list;
		}

		private static void Text(string text, float x, float y, int size, Color color, float width, TextAnchor anchor)
		{
			//IL_001a: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Invalid comparison between Unknown and I4
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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)
			Text component = GUIManager.Instance.CreateText(text, _panel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(x + (((int)anchor == 3) ? (width / 2f) : 0f), y), GUIManager.Instance.AveriaSerifBold, size, color, true, Color.black, width, 32f, false).GetComponent<Text>();
			component.alignment = anchor;
			component.supportRichText = true;
		}

		private static void Button(string label, float x, float y, float width, Action onClick)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			((UnityEvent)GUIManager.Instance.CreateButton(label, _panel.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(x, y), width, 30f).GetComponent<Button>().onClick).AddListener((UnityAction)delegate
			{
				onClick();
			});
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "Show")]
	internal static class PanelShowPatch
	{
		private static void Postfix(Container container)
		{
			if ((Object)(object)container != (Object)null && VaultChest.IsVault(container) && VaultRules.CanTake(container))
			{
				VaultPanel.Show(container);
			}
			else
			{
				VaultPanel.Hide();
			}
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "Hide")]
	internal static class PanelHidePatch
	{
		private static void Postfix()
		{
			VaultPanel.Hide();
		}
	}
	internal static class VaultRules
	{
		public static bool Quiet;

		public static bool IsBuilder(Container chest)
		{
			if ((Object)(object)Player.m_localPlayer != (Object)null)
			{
				return chest.m_nview.GetZDO().GetLong(ZDOVars.s_creator, 0L) == Player.m_localPlayer.GetPlayerID();
			}
			return false;
		}

		public static bool CanTake(Container chest)
		{
			if (!IsBuilder(chest))
			{
				return ClanChest.SameClan(ClanChest.ClanOf(chest), ClanChest.MyClan);
			}
			return true;
		}

		public static void Say(string text)
		{
			Player localPlayer = Player.m_localPlayer;
			if (localPlayer != null)
			{
				((Character)localPlayer).Message((MessageType)2, text, 0, (Sprite)null, false);
			}
		}

		public static long Now()
		{
			if (!((Object)(object)ZNet.instance != (Object)null))
			{
				return 0L;
			}
			return (long)(ZNet.instance.GetTimeSeconds() * 1000.0);
		}
	}
	[HarmonyPatch(typeof(Container), "Save")]
	internal static class SavePatch
	{
		private static void Postfix(Container __instance)
		{
			if (!VaultRules.Quiet && VaultChest.IsVault(__instance))
			{
				ZDO zDO = __instance.m_nview.GetZDO();
				if (zDO.GetInt(VaultChest.KeyJoined, 0) == 1)
				{
					zDO.Set(VaultChest.KeyStamp, VaultRules.Now());
				}
			}
		}
	}
	[HarmonyPatch(typeof(Container), "Interact")]
	internal static class OpenPatch
	{
		private static bool Prefix(Container __instance, bool hold, ref bool __result)
		{
			if (hold || !VaultChest.IsVault(__instance))
			{
				return true;
			}
			string text = ClanChest.ClanOf(__instance);
			if (text.Length > 0 && !VaultRules.CanTake(__instance))
			{
				VaultRules.Say("This chest belongs to a clan");
				__result = true;
				return false;
			}
			if (text.Length == 0 && !ChestHeimPlugin.OthersCanDeposit.Value && !VaultRules.IsBuilder(__instance))
			{
				VaultRules.Say("This vault is private");
				__result = true;
				return false;
			}
			if (__instance.m_nview.GetZDO().GetInt(VaultChest.KeyBusy, 0) > 0)
			{
				VaultRules.Say("This vault is open in another chest");
				__result = true;
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Container), "OnDestroyed")]
	internal static class DestroyPatch
	{
		private static bool Prefix(Container __instance)
		{
			if (!VaultChest.IsVault(__instance))
			{
				return true;
			}
			if (__instance.m_nview.GetZDO().GetInt(VaultChest.KeyCount, 0) < 2)
			{
				return true;
			}
			VaultRules.Quiet = true;
			try
			{
				__instance.m_inventory.RemoveAll();
			}
			finally
			{
				VaultRules.Quiet = false;
			}
			return false;
		}
	}
	internal static class TakeRule
	{
		public static bool OtherPlayersVault(out Container chest)
		{
			chest = (((Object)(object)InventoryGui.instance != (Object)null) ? InventoryGui.instance.m_currentContainer : null);
			if ((Object)(object)chest != (Object)null && VaultChest.IsVault(chest))
			{
				return !VaultRules.CanTake(chest);
			}
			return false;
		}

		public static void Refuse()
		{
			VaultRules.Say("Only its builder can take things out of this chest");
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "OnTakeAll")]
	internal static class TakeAllPatch
	{
		private static bool Prefix()
		{
			if (!TakeRule.OtherPlayersVault(out var _))
			{
				return true;
			}
			TakeRule.Refuse();
			return false;
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "OnRightClickItem")]
	internal static class RightClickPatch
	{
		private static bool Prefix(InventoryGrid grid)
		{
			if (!TakeRule.OtherPlayersVault(out var chest) || grid.GetInventory() != chest.GetInventory())
			{
				return true;
			}
			TakeRule.Refuse();
			return false;
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "OnSelectedItem")]
	internal static class SelectPatch
	{
		private static bool Prefix(InventoryGui __instance, InventoryGrid grid, ItemData item)
		{
			if (!TakeRule.OtherPlayersVault(out var chest) || grid.GetInventory() != chest.GetInventory())
			{
				return true;
			}
			if (!((Object)(object)__instance.m_dragGo != (Object)null) || __instance.m_dragItem == null)
			{
				if (item == null)
				{
					return true;
				}
				TakeRule.Refuse();
				return false;
			}
			if (item == null)
			{
				return true;
			}
			ItemData dragItem = __instance.m_dragItem;
			if (item.m_shared.m_name == dragItem.m_shared.m_name && item.m_quality == dragItem.m_quality && item.m_stack < item.m_shared.m_maxStackSize)
			{
				return true;
			}
			TakeRule.Refuse();
			return false;
		}
	}
	internal static class VaultServer
	{
		private static float _nextSync;

		public static bool IsServer
		{
			get
			{
				if ((Object)(object)ZNet.instance != (Object)null)
				{
					return ZNet.instance.IsServer();
				}
				return false;
			}
		}

		public static void Tick()
		{
			if (!IsServer || ZDOMan.instance == null || Time.time < _nextSync)
			{
				return;
			}
			_nextSync = Time.time + ChestHeimPlugin.SyncSeconds.Value;
			Dictionary<string, List<ZDO>> dictionary = new Dictionary<string, List<ZDO>>();
			foreach (ZDO value2 in ZDOMan.instance.m_objectsByID.Values)
			{
				if (VaultChest.IsVault(value2))
				{
					string text = value2.GetString(ClanChest.KeyClan, "").Trim().ToLowerInvariant();
					string key = ((text.Length > 0) ? ("c:" + text) : ("b:" + value2.GetLong(ZDOVars.s_creator, 0L)));
					if (!dictionary.TryGetValue(key, out var value))
					{
						value = (dictionary[key] = new List<ZDO>());
					}
					value.Add(value2);
				}
			}
			foreach (List<ZDO> value3 in dictionary.Values)
			{
				SyncGroup(value3);
			}
		}

		private static bool IsOpen(ZDO zdo)
		{
			return zdo.GetInt(ZDOVars.s_inUse, 0) == 1;
		}

		private static void SetIfChanged(ZDO zdo, int key, int value)
		{
			if (zdo.GetInt(key, 0) != value)
			{
				zdo.Set(key, value, false);
			}
		}

		private static void SyncGroup(List<ZDO> chests)
		{
			int num = chests.Count(IsOpen);
			foreach (ZDO chest in chests)
			{
				SetIfChanged(chest, VaultChest.KeyCount, chests.Count);
				SetIfChanged(chest, VaultChest.KeyBusy, num - (IsOpen(chest) ? 1 : 0));
			}
			ZDO val = null;
			long num2 = -1L;
			foreach (ZDO chest2 in chests)
			{
				if (chest2.GetInt(VaultChest.KeyJoined, 0) == 1)
				{
					long num3 = chest2.GetLong(VaultChest.KeyStamp, 0L);
					if (num3 > num2)
					{
						num2 = num3;
						val = chest2;
					}
				}
			}
			if (val == null)
			{
				foreach (ZDO chest3 in chests)
				{
					Join(chest3, 0L);
				}
				return;
			}
			byte[] byteArray = val.GetByteArray(ZDOVars.s_items, (byte[])null);
			foreach (ZDO chest4 in chests)
			{
				if (chest4 != val && !IsOpen(chest4) && (chest4.GetInt(VaultChest.KeyJoined, 0) != 1 || chest4.GetLong(VaultChest.KeyStamp, 0L) < num2))
				{
					Copy(chest4, byteArray, num2);
				}
			}
		}

		private static void Join(ZDO chest, long stamp)
		{
			if (chest.GetInt(VaultChest.KeyJoined, 0) != 1)
			{
				Write(chest, null, stamp);
			}
		}

		private static void Copy(ZDO chest, byte[] items, long stamp)
		{
			Write(chest, items, stamp);
		}

		private static void Write(ZDO chest, byte[] items, long stamp)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			chest.SetOwner(ZDOMan.GetSessionID());
			if (items != null && items.Length != 0)
			{
				chest.Set(ZDOVars.s_items, items);
			}
			chest.Set(VaultChest.KeyJoined, 1, false);
			chest.Set(VaultChest.KeyStamp, stamp);
			chest.SetOwner(0L);
			ZDOMan.instance.ForceSendZDO(chest.m_uid);
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}