Decompiled source of StorageSign v1.0.0

StorageSign.dll

Decompiled 5 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace StorageSign
{
	public class StorageSign : MonoBehaviour, Interactable
	{
		public float signRange = 12f;

		public float refreshInterval = 3f;

		public int maxLines = 6;

		private TextMeshProUGUI textWidget;

		private float nextScan;

		private void Awake()
		{
			textWidget = ((Component)this).GetComponentInChildren<TextMeshProUGUI>(true);
			nextScan = 0f;
		}

		private void Update()
		{
			if (!(Time.time < nextScan))
			{
				nextScan = Time.time + Mathf.Max(1f, refreshInterval);
				RefreshText();
			}
		}

		public void RefreshText()
		{
			if ((Object)(object)textWidget == (Object)null)
			{
				textWidget = ((Component)this).GetComponentInChildren<TextMeshProUGUI>(true);
				if ((Object)(object)textWidget == (Object)null)
				{
					return;
				}
			}
			((TMP_Text)textWidget).text = BuildSummary();
		}

		private string BuildSummary()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			List<Container> list = StorageUtil.FindContainers(((Component)this).transform.position, signRange);
			List<ItemEntry> list2 = StorageUtil.Aggregate(list);
			list2.Sort((ItemEntry a, ItemEntry b) => b.totalCount.CompareTo(a.totalCount));
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine(list.Count + ((list.Count == 1) ? " chest" : " chests"));
			int num = 0;
			foreach (ItemEntry item in list2)
			{
				if (num >= maxLines)
				{
					break;
				}
				stringBuilder.AppendLine(item.displayName + ": " + item.totalCount);
				num++;
			}
			return stringBuilder.ToString().TrimEnd();
		}

		public bool Interact(Humanoid user, bool hold, bool alt)
		{
			if ((Object)(object)StorageSignGUI.Instance != (Object)null)
			{
				StorageSignGUI.Instance.Open(this);
			}
			return true;
		}

		public bool UseItem(Humanoid user, ItemData item)
		{
			return false;
		}

		public string GetHoverText()
		{
			return "Storage Sign\n[<color=yellow>E</color>] Overview";
		}

		public string GetHoverName()
		{
			return "Storage Sign";
		}
	}
	public class StorageSignGUI : MonoBehaviour
	{
		public static StorageSignGUI Instance;

		private bool open;

		private bool busy;

		private StorageSign currentSign;

		private string status = "";

		private List<Container> chests = new List<Container>();

		private List<ItemEntry> items = new List<ItemEntry>();

		private int selectedItem = -1;

		private int selectedChest = -1;

		private SortMode sortMode;

		private Vector2 itemsScroll;

		private Vector2 chestsScroll;

		private Texture2D whiteTex;

		private readonly Dictionary<Sprite, Texture2D> iconCache = new Dictionary<Sprite, Texture2D>();

		public static bool IsOpen
		{
			get
			{
				if ((Object)(object)Instance != (Object)null)
				{
					return Instance.open;
				}
				return false;
			}
		}

		private void Awake()
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			whiteTex = new Texture2D(1, 1);
			whiteTex.SetPixel(0, 0, Color.white);
			whiteTex.Apply();
		}

		private void OnDestroy()
		{
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}

		public void Open(StorageSign sign)
		{
			currentSign = sign;
			sortMode = ((StorageSignPlugin.SortModeSetting != null) ? StorageSignPlugin.SortModeSetting.Value : SortMode.Name);
			selectedItem = -1;
			selectedChest = -1;
			status = "";
			open = true;
			RefreshData();
		}

		public void Close()
		{
			open = false;
			Cursor.visible = false;
			Cursor.lockState = (CursorLockMode)1;
		}

		private void Update()
		{
			//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)
			ConfigEntry<KeyboardShortcut> openHotkey = StorageSignPlugin.OpenHotkey;
			if (openHotkey != null)
			{
				KeyboardShortcut value = openHotkey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					if (open)
					{
						Close();
					}
					else
					{
						TryOpenNearest();
					}
				}
			}
			if (open && Input.GetKeyDown((KeyCode)27))
			{
				Close();
			}
		}

		private void TryOpenNearest()
		{
			//IL_0059: 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_0069: 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)
			if ((Object)(object)currentSign != (Object)null)
			{
				Open(currentSign);
				return;
			}
			StorageSign[] array = Object.FindObjectsByType<StorageSign>((FindObjectsSortMode)0);
			StorageSign storageSign = null;
			float num = float.MaxValue;
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer != (Object)null)
			{
				StorageSign[] array2 = array;
				foreach (StorageSign storageSign2 in array2)
				{
					if (!((Object)(object)storageSign2 == (Object)null))
					{
						Vector3 val = ((Component)storageSign2).transform.position - ((Component)localPlayer).transform.position;
						float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
						if (sqrMagnitude < num)
						{
							num = sqrMagnitude;
							storageSign = storageSign2;
						}
					}
				}
			}
			if ((Object)(object)storageSign != (Object)null)
			{
				Open(storageSign);
			}
		}

		private void RefreshData()
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)currentSign == (Object)null)
			{
				chests.Clear();
				items.Clear();
			}
			else
			{
				chests = StorageUtil.FindContainers(((Component)currentSign).transform.position, currentSign.signRange);
				items = StorageUtil.Aggregate(chests);
				SortItems();
			}
		}

		private void SortItems()
		{
			switch (sortMode)
			{
			case SortMode.Count:
				items.Sort((ItemEntry a, ItemEntry b) => b.totalCount.CompareTo(a.totalCount));
				break;
			case SortMode.Type:
				items.Sort(delegate(ItemEntry a, ItemEntry b)
				{
					//IL_0007: Unknown result type (might be due to invalid IL or missing references)
					ref ItemType itemType = ref a.itemType;
					object target = b.itemType;
					int num = ((Enum)Unsafe.As<ItemType, ItemType>(ref itemType)/*cast due to .constrained prefix*/).CompareTo(target);
					return (num != 0) ? num : string.Compare(a.displayName, b.displayName, StringComparison.OrdinalIgnoreCase);
				});
				break;
			default:
				items.Sort((ItemEntry a, ItemEntry b) => string.Compare(a.displayName, b.displayName, StringComparison.OrdinalIgnoreCase));
				break;
			}
		}

		private void OnGUI()
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			if (open)
			{
				Cursor.visible = true;
				Cursor.lockState = (CursorLockMode)0;
				GUI.color = new Color(0f, 0f, 0f, 0.72f);
				GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), (Texture)(object)whiteTex);
				GUI.color = Color.white;
				float num = (float)Screen.width * 0.86f;
				float num2 = (float)Screen.height * 0.86f;
				GUILayout.BeginArea(new Rect(((float)Screen.width - num) / 2f, ((float)Screen.height - num2) / 2f, num, num2), GUI.skin.box);
				DrawHeader();
				GUILayout.Space(4f);
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				DrawItemsColumn();
				DrawChestsColumn();
				GUILayout.EndHorizontal();
				GUILayout.Space(4f);
				DrawFooter();
				GUILayout.EndArea();
			}
		}

		private void DrawHeader()
		{
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			GUILayout.Label("Storage Overview", GUI.skin.box, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(24f) });
			GUILayout.Space(8f);
			DrawSortButton("Name", SortMode.Name);
			DrawSortButton("Type", SortMode.Type);
			DrawSortButton("Count", SortMode.Count);
			GUILayout.Space(12f);
			if (GUILayout.Button("Sort All", Array.Empty<GUILayoutOption>()))
			{
				DoSortAll();
			}
			if (GUILayout.Button("Consolidate", Array.Empty<GUILayoutOption>()))
			{
				DoConsolidate();
			}
			if (GUILayout.Button("Quick Stack", Array.Empty<GUILayoutOption>()))
			{
				DoQuickStack();
			}
			GUILayout.FlexibleSpace();
			if (GUILayout.Button("Close", Array.Empty<GUILayoutOption>()))
			{
				Close();
			}
			GUILayout.EndHorizontal();
			GUILayout.Label("Range: " + (((Object)(object)currentSign != (Object)null) ? currentSign.signRange.ToString("0.#") : "?") + "m   |   " + chests.Count + " chests   |   " + items.Count + " item types", Array.Empty<GUILayoutOption>());
		}

		private void DrawSortButton(string label, SortMode mode)
		{
			//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_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			Color backgroundColor = GUI.backgroundColor;
			if (sortMode == mode)
			{
				GUI.backgroundColor = new Color(0.3f, 0.6f, 1f);
			}
			if (GUILayout.Button(label, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(58f) }))
			{
				sortMode = mode;
				SortItems();
			}
			GUI.backgroundColor = backgroundColor;
		}

		private void DrawItemsColumn()
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: 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_007a: 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_017f: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.BeginVertical(GUI.skin.box, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width((float)Screen.width * 0.48f),
				GUILayout.ExpandHeight(true)
			});
			GUILayout.Label("All items", Array.Empty<GUILayoutOption>());
			itemsScroll = GUILayout.BeginScrollView(itemsScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) });
			for (int i = 0; i < items.Count; i++)
			{
				ItemEntry itemEntry = items[i];
				Color backgroundColor = GUI.backgroundColor;
				if (selectedItem == i)
				{
					GUI.backgroundColor = new Color(0.25f, 0.45f, 0.7f);
				}
				GUILayout.BeginHorizontal(GUI.skin.box, Array.Empty<GUILayoutOption>());
				GUILayout.Label((Texture)(object)Icon(itemEntry.icon), (GUILayoutOption[])(object)new GUILayoutOption[2]
				{
					GUILayout.Width(26f),
					GUILayout.Height(26f)
				});
				GUILayout.Label(itemEntry.displayName, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
				GUILayout.Label(itemEntry.totalCount.ToString(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(70f) });
				GUILayout.Label(itemEntry.perChest.Count + " chests", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) });
				if (GUILayout.Button("Select", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(64f) }))
				{
					selectedItem = i;
				}
				GUILayout.EndHorizontal();
				GUI.backgroundColor = backgroundColor;
			}
			GUILayout.EndScrollView();
			GUILayout.EndVertical();
		}

		private void DrawChestsColumn()
		{
			//IL_0038: 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_0051: 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)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.BeginVertical(GUI.skin.box, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.ExpandWidth(true),
				GUILayout.ExpandHeight(true)
			});
			GUILayout.Label("Chests", Array.Empty<GUILayoutOption>());
			chestsScroll = GUILayout.BeginScrollView(chestsScroll, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandHeight(true) });
			for (int i = 0; i < chests.Count; i++)
			{
				Container obj = chests[i];
				Inventory inventory = obj.GetInventory();
				int num = ((inventory != null) ? inventory.NrOfItems() : 0);
				int num2 = ((inventory != null) ? (inventory.GetWidth() * inventory.GetHeight()) : 0);
				Color backgroundColor = GUI.backgroundColor;
				if (selectedChest == i)
				{
					GUI.backgroundColor = new Color(0.25f, 0.45f, 0.7f);
				}
				GUILayout.BeginHorizontal(GUI.skin.box, Array.Empty<GUILayoutOption>());
				GUILayout.Label(StorageUtil.ChestName(obj), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
				GUILayout.Label(num + "/" + num2, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(90f) });
				if (GUILayout.Button("Select", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(64f) }))
				{
					selectedChest = i;
				}
				GUILayout.EndHorizontal();
				GUI.backgroundColor = backgroundColor;
			}
			GUILayout.EndScrollView();
			GUILayout.EndVertical();
		}

		private void DrawFooter()
		{
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (selectedItem >= 0 && selectedItem < items.Count)
			{
				GUILayout.Label("Selected: " + items[selectedItem].displayName, Array.Empty<GUILayoutOption>());
			}
			else
			{
				GUILayout.Label("Selected: (none)", Array.Empty<GUILayoutOption>());
			}
			GUILayout.FlexibleSpace();
			if (selectedItem >= 0 && selectedItem < items.Count && selectedChest >= 0 && selectedChest < chests.Count && GUILayout.Button("Move '" + items[selectedItem].displayName + "' to '" + StorageUtil.ChestName(chests[selectedChest]) + "'", Array.Empty<GUILayoutOption>()))
			{
				DoMoveToChest(items[selectedItem].key, chests[selectedChest]);
			}
			GUILayout.EndHorizontal();
			if (!string.IsNullOrEmpty(status))
			{
				GUILayout.Label(status, Array.Empty<GUILayoutOption>());
			}
		}

		private Texture2D Icon(Sprite sprite)
		{
			//IL_002c: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			if ((Object)(object)sprite == (Object)null || (Object)(object)sprite.texture == (Object)null)
			{
				return null;
			}
			if (iconCache.TryGetValue(sprite, out var value))
			{
				return value;
			}
			Rect textureRect = sprite.textureRect;
			Texture2D val = new Texture2D((int)((Rect)(ref textureRect)).width, (int)((Rect)(ref textureRect)).height);
			val.SetPixels(sprite.texture.GetPixels((int)((Rect)(ref textureRect)).x, (int)((Rect)(ref textureRect)).y, (int)((Rect)(ref textureRect)).width, (int)((Rect)(ref textureRect)).height));
			val.Apply();
			iconCache[sprite] = val;
			return val;
		}

		private void DoSortAll()
		{
			if (busy)
			{
				return;
			}
			busy = true;
			status = "Sorting...";
			((MonoBehaviour)this).StartCoroutine(CoClaimAndRun(new List<Container>(chests), delegate(List<Container> owned)
			{
				int num = 0;
				foreach (Container item in owned)
				{
					SortChest(item);
					num++;
				}
				status = Report("Sorted", num);
				RefreshData();
				busy = false;
			}));
		}

		private void DoConsolidate()
		{
			if (busy)
			{
				return;
			}
			busy = true;
			status = "Consolidating...";
			((MonoBehaviour)this).StartCoroutine(CoClaimAndRun(new List<Container>(chests), delegate(List<Container> owned)
			{
				int num = 0;
				for (int i = 0; i < owned.Count; i++)
				{
					for (int j = i + 1; j < owned.Count; j++)
					{
						num += owned[i].GetInventory().StackAll(owned[j].GetInventory(), false);
					}
				}
				status = "Consolidated " + num + " stack(s)." + ReportSkipped(owned.Count);
				RefreshData();
				busy = false;
			}));
		}

		private void DoQuickStack()
		{
			if (busy)
			{
				return;
			}
			busy = true;
			if ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				status = "No local player.";
				busy = false;
				return;
			}
			foreach (Container chest in chests)
			{
				chest.StackAll();
			}
			status = "Quick-stack requested for " + chests.Count + " chest(s).";
			((MonoBehaviour)this).StartCoroutine(CoRefreshAfter(1.2f));
		}

		private void DoMoveToChest(string key, Container target)
		{
			if (busy)
			{
				return;
			}
			busy = true;
			status = "Moving...";
			((MonoBehaviour)this).StartCoroutine(CoClaimAndRun(new List<Container>(chests), delegate(List<Container> owned)
			{
				int num = 0;
				Container val = null;
				foreach (Container item in owned)
				{
					if ((Object)(object)item == (Object)(object)target)
					{
						val = item;
					}
				}
				if ((Object)(object)val == (Object)null)
				{
					status = "Could not take ownership of the target chest.";
					RefreshData();
					busy = false;
				}
				else
				{
					Inventory inventory = val.GetInventory();
					foreach (Container item2 in owned)
					{
						if (!((Object)(object)item2 == (Object)(object)val))
						{
							Inventory inventory2 = item2.GetInventory();
							foreach (ItemData item3 in inventory2.GetAllItems().FindAll((ItemData it) => it != null && it.m_shared != null && it.m_shared.m_name == key))
							{
								inventory.MoveItemToThis(inventory2, item3);
								num += item3.m_stack;
							}
						}
					}
					status = "Moved " + num + " of '" + StorageUtil.Localize(key) + "' to '" + StorageUtil.ChestName(val) + "'.";
					RefreshData();
					busy = false;
				}
			}));
		}

		private string Report(string verb, int done)
		{
			return verb + " " + done + " chest(s)." + ReportSkipped(done);
		}

		private string ReportSkipped(int ownedCount)
		{
			int num = chests.Count - ownedCount;
			if (num <= 0)
			{
				return "";
			}
			return " (" + num + " chest(s) could not be taken ownership of)";
		}

		private IEnumerator CoRefreshAfter(float seconds)
		{
			yield return (object)new WaitForSeconds(seconds);
			RefreshData();
			busy = false;
		}

		private IEnumerator CoClaimAndRun(List<Container> containers, Action<List<Container>> mutate)
		{
			foreach (Container container in containers)
			{
				ZNetView component = ((Component)container).GetComponent<ZNetView>();
				if ((Object)(object)component != (Object)null && !component.IsOwner())
				{
					component.ClaimOwnership();
				}
			}
			yield return null;
			yield return null;
			yield return null;
			List<Container> list = new List<Container>();
			foreach (Container container2 in containers)
			{
				ZNetView component2 = ((Component)container2).GetComponent<ZNetView>();
				if ((Object)(object)component2 == (Object)null || component2.IsOwner())
				{
					list.Add(container2);
				}
			}
			mutate(list);
		}

		private static void SortChest(Container c)
		{
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			Inventory inventory = c.GetInventory();
			if (inventory == null)
			{
				return;
			}
			List<ItemData> allItems = inventory.GetAllItems();
			if (allItems.Count < 2)
			{
				return;
			}
			allItems.Sort(delegate(ItemData a, ItemData b)
			{
				//IL_0011: Unknown result type (might be due to invalid IL or missing references)
				ref ItemType itemType = ref a.m_shared.m_itemType;
				object target = b.m_shared.m_itemType;
				int num2 = ((Enum)Unsafe.As<ItemType, ItemType>(ref itemType)/*cast due to .constrained prefix*/).CompareTo(target);
				if (num2 != 0)
				{
					return num2;
				}
				int num3 = string.Compare(StorageUtil.Localize(a.m_shared.m_name), StorageUtil.Localize(b.m_shared.m_name), StringComparison.OrdinalIgnoreCase);
				return (num3 != 0) ? num3 : b.m_stack.CompareTo(a.m_stack);
			});
			int width = inventory.GetWidth();
			inventory.RemoveAll();
			for (int num = 0; num < allItems.Count; num++)
			{
				inventory.AddItem(allItems[num], new Vector2i(num % width, num / width));
			}
		}
	}
	public enum SortMode
	{
		Name,
		Type,
		Count
	}
	[BepInPlugin("com.storagesign.storagesign", "Storage Sign", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class StorageSignPlugin : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(PlayerController), "InInventoryEtc")]
		private static class InputBlockPatch
		{
			private static void Postfix(ref bool __result)
			{
				if (StorageSignGUI.IsOpen)
				{
					__result = true;
				}
			}
		}

		public const string PluginGUID = "com.storagesign.storagesign";

		public const string PluginName = "Storage Sign";

		public const string PluginVersion = "1.0.0";

		public const string PrefabName = "StorageSign";

		internal static bool PrefabRegistered;

		internal static ConfigEntry<bool> Enabled;

		internal static ConfigEntry<bool> AddBuildPiece;

		internal static ConfigEntry<float> SignRange;

		internal static ConfigEntry<float> RefreshInterval;

		internal static ConfigEntry<int> SignMaxLines;

		internal static ConfigEntry<SortMode> SortModeSetting;

		internal static ConfigEntry<KeyboardShortcut> OpenHotkey;

		private Harmony harmony;

		private void Awake()
		{
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Expected O, but got Unknown
			//IL_0136: 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_0141: Expected O, but got Unknown
			Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master toggle for StorageSign.");
			AddBuildPiece = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AddBuildPiece", true, "Add the 'Storage Sign' piece to the Hammer build menu. Requires a game restart.");
			SignRange = ((BaseUnityPlugin)this).Config.Bind<float>("General", "SignRange", 12f, "Radius (meters) around a sign that is scanned for chests.");
			RefreshInterval = ((BaseUnityPlugin)this).Config.Bind<float>("General", "RefreshInterval", 3f, "Seconds between sign-face text refreshes.");
			SignMaxLines = ((BaseUnityPlugin)this).Config.Bind<int>("General", "SignMaxLines", 6, "How many item lines the sign face shows.");
			SortModeSetting = ((BaseUnityPlugin)this).Config.Bind<SortMode>("General", "SortMode", SortMode.Name, "Default sort for the storage overview.");
			OpenHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Controls", "OpenHotkey", new KeyboardShortcut((KeyCode)111, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), "Hotkey to open the storage overview for the nearest sign.");
			harmony = new Harmony("com.storagesign.storagesign");
			harmony.PatchAll(typeof(InputBlockPatch));
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Storage Sign 1.0.0 loading...");
			GameObject val = new GameObject("StorageSignGUI");
			Object.DontDestroyOnLoad((Object)val);
			val.AddComponent<StorageSignGUI>();
			PrefabManager.OnVanillaPrefabsAvailable += OnVanillaPrefabsAvailable;
			PieceManager.OnPiecesRegistered += OnPiecesRegistered;
			if (IsVanillaPrefabReady())
			{
				OnVanillaPrefabsAvailable();
			}
		}

		private void OnDestroy()
		{
			PrefabManager.OnVanillaPrefabsAvailable -= OnVanillaPrefabsAvailable;
			PieceManager.OnPiecesRegistered -= OnPiecesRegistered;
		}

		private void OnVanillaPrefabsAvailable()
		{
			if (PrefabRegistered || !Enabled.Value || !AddBuildPiece.Value)
			{
				return;
			}
			try
			{
				GameObject val = FindBaseSignPrefab();
				if ((Object)(object)val == (Object)null)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)"StorageSign: could not find a vanilla sign prefab to clone. Build piece was not registered.");
					return;
				}
				GameObject val2 = PrefabManager.Instance.CreateClonedPrefab("StorageSign", val);
				if ((Object)(object)val2 == (Object)null)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("StorageSign: failed to clone sign prefab '" + ((Object)val).name + "'."));
					return;
				}
				Sign component = val2.GetComponent<Sign>();
				if ((Object)(object)component != (Object)null)
				{
					Object.Destroy((Object)(object)component);
				}
				StorageSign storageSign = val2.AddComponent<StorageSign>();
				storageSign.signRange = SignRange.Value;
				storageSign.refreshInterval = RefreshInterval.Value;
				storageSign.maxLines = SignMaxLines.Value;
				PrefabManager.Instance.AddPrefab(val2);
				PrefabRegistered = true;
				((BaseUnityPlugin)this).Logger.LogInfo((object)("StorageSign: registered 'StorageSign' cloned from '" + ((Object)val).name + "'."));
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("StorageSign: failed to register prefab: " + ex));
			}
		}

		private void OnPiecesRegistered()
		{
			//IL_0027: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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_0060: Expected O, but got Unknown
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			if (!PrefabRegistered)
			{
				return;
			}
			try
			{
				GameObject prefab = PrefabManager.Instance.GetPrefab("StorageSign");
				if (!((Object)(object)prefab == (Object)null))
				{
					PieceConfig val = new PieceConfig
					{
						Name = "Storage Sign",
						Description = "Shows everything stored in nearby chests. Interact for a full sorting overview.",
						PieceTable = "Hammer",
						Category = "Misc",
						Enabled = true
					};
					val.AddRequirement("Wood", 5, true);
					PieceManager.Instance.AddPiece(new CustomPiece(prefab, false, val));
					((BaseUnityPlugin)this).Logger.LogInfo((object)"StorageSign: added 'Storage Sign' build piece to the Hammer menu.");
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("StorageSign: failed to add build piece: " + ex));
			}
		}

		private static bool IsVanillaPrefabReady()
		{
			if ((Object)(object)ZNetScene.instance != (Object)null && ZNetScene.instance.m_prefabs != null)
			{
				return ZNetScene.instance.m_prefabs.Count > 0;
			}
			return false;
		}

		private static GameObject FindBaseSignPrefab()
		{
			if ((Object)(object)ZNetScene.instance != (Object)null && ZNetScene.instance.m_prefabs != null)
			{
				foreach (GameObject prefab in ZNetScene.instance.m_prefabs)
				{
					if ((Object)(object)prefab != (Object)null && (Object)(object)prefab.GetComponent<Sign>() != (Object)null)
					{
						return prefab;
					}
				}
			}
			string[] array = new string[3] { "sign", "piece_sign", "sign_notext" };
			foreach (string text in array)
			{
				GameObject val = ((PrefabManager.Instance != null) ? PrefabManager.Instance.GetPrefab(text) : null);
				if ((Object)(object)val != (Object)null && (Object)(object)val.GetComponent<Sign>() != (Object)null)
				{
					return val;
				}
			}
			return null;
		}
	}
	public class ItemEntry
	{
		public string key;

		public string displayName;

		public ItemType itemType;

		public Sprite icon;

		public int totalCount;

		public Dictionary<Container, int> perChest = new Dictionary<Container, int>();
	}
	public static class StorageUtil
	{
		public static List<Container> FindContainers(Vector3 center, float range)
		{
			//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_0052: 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_005d: 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)
			List<Container> list = new List<Container>();
			float num = range * range;
			Container[] array = Object.FindObjectsByType<Container>((FindObjectsSortMode)0);
			foreach (Container val in array)
			{
				if (!((Object)(object)val == (Object)null) && ((Behaviour)val).isActiveAndEnabled && !((Object)(object)((Component)val).GetComponentInParent<StorageSign>() != (Object)null))
				{
					Vector3 val2 = ((Component)val).transform.position - center;
					if (!(((Vector3)(ref val2)).sqrMagnitude > num))
					{
						list.Add(val);
					}
				}
			}
			list.Sort(delegate(Container a, Container b)
			{
				//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)
				//IL_0027: Unknown result type (might be due to invalid IL or missing references)
				//IL_002d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: 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)
				Vector3 val3 = ((Component)a).transform.position - center;
				float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude;
				val3 = ((Component)b).transform.position - center;
				return sqrMagnitude.CompareTo(((Vector3)(ref val3)).sqrMagnitude);
			});
			return list;
		}

		public static List<ItemEntry> Aggregate(IEnumerable<Container> containers)
		{
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<string, ItemEntry> dictionary = new Dictionary<string, ItemEntry>();
			foreach (Container container in containers)
			{
				Inventory inventory = container.GetInventory();
				if (inventory == null)
				{
					continue;
				}
				foreach (ItemData allItem in inventory.GetAllItems())
				{
					if (allItem == null || allItem.m_shared == null)
					{
						continue;
					}
					string name = allItem.m_shared.m_name;
					if (!string.IsNullOrEmpty(name))
					{
						if (!dictionary.TryGetValue(name, out var value))
						{
							value = (dictionary[name] = new ItemEntry
							{
								key = name,
								displayName = Localize(name),
								itemType = allItem.m_shared.m_itemType,
								icon = allItem.GetIcon()
							});
						}
						value.totalCount += allItem.m_stack;
						value.perChest.TryGetValue(container, out var value2);
						value.perChest[container] = value2 + allItem.m_stack;
					}
				}
			}
			return new List<ItemEntry>(dictionary.Values);
		}

		public static string Localize(string key)
		{
			if (string.IsNullOrEmpty(key))
			{
				return key;
			}
			if (Localization.instance != null)
			{
				string text = Localization.instance.Localize(key);
				if (!string.IsNullOrEmpty(text))
				{
					return text;
				}
			}
			if (!key.StartsWith("$"))
			{
				return key;
			}
			return key.Substring(1);
		}

		public static string ChestName(Container c)
		{
			if ((Object)(object)c == (Object)null)
			{
				return "?";
			}
			string name = c.m_name;
			if (string.IsNullOrEmpty(name))
			{
				Piece component = ((Component)c).GetComponent<Piece>();
				if ((Object)(object)component != (Object)null && !string.IsNullOrEmpty(component.m_name))
				{
					name = component.m_name;
				}
			}
			if (string.IsNullOrEmpty(name))
			{
				name = ((Object)((Component)c).gameObject).name;
			}
			return Localize(name);
		}
	}
}