Decompiled source of SharedStash v1.0.0

SharedStash.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mirror;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("Mirror")]
[assembly: AssemblyCompany("SharedStash")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("SharedStash")]
[assembly: AssemblyTitle("SharedStash")]
[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 SharedStash
{
	[BepInPlugin("com.stonewardsmods.sharedstash", "Shared Stash", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log;

		internal static FirstPersonController LocalPlayer;

		internal static ConfigEntry<KeyCode> ToggleKey;

		internal static ConfigEntry<string> ProximitySearchTerm;

		internal static ConfigEntry<float> ProximityRadius;

		internal static ConfigEntry<float> ProximityRefreshInterval;

		internal static ConfigEntry<string> NeverStoreItemIds;

		internal static ConfigEntry<float> PromptOffsetX;

		internal static ConfigEntry<float> PromptOffsetY;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			ToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "ToggleKey", (KeyCode)98, "Key to open/close the shared stash. Only works while near the King - it also auto-closes if you walk away.");
			ProximitySearchTerm = ((BaseUnityPlugin)this).Config.Bind<string>("General", "ProximitySearchTerm", "King", "The stash looks for the nearest scene object whose name contains this text (case-insensitive) and uses its distance to the player as the location check. Change this if the actual object isn't named exactly 'King'.");
			ProximityRadius = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ProximityRadius", 15f, "How close (in world units/meters) the player must be to the matched object for the stash to be usable.");
			ProximityRefreshInterval = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ProximityRefreshInterval", 2f, "How often (in seconds) to re-scan the scene for the King object. Lower = more responsive if he moves/despawns, higher = less overhead.");
			NeverStoreItemIds = ((BaseUnityPlugin)this).Config.Bind<string>("General", "NeverStoreItemIds", "PickaxeTool,Horn", "Comma-separated item IDs that can never be deposited into the stash (e.g. your starting tools). Not case-sensitive.");
			PromptOffsetX = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "PromptOffsetX", -140f, "Horizontal nudge (in pixels) for the 'Open Stash' prompt button from dead-center of the screen. 0 = perfectly centered; negative = left, positive = right.");
			PromptOffsetY = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "PromptOffsetY", 75f, "Distance in pixels from the BOTTOM edge of the screen to the 'Open Stash' prompt button. Higher = further up. Adjust this if it overlaps your health bar/hotbar.");
			_harmony = new Harmony("com.stonewardsmods.sharedstash");
			_harmony.PatchAll();
			Log.LogInfo((object)"Shared Stash loaded.");
		}

		private void Update()
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			bool flag = ProximityGate.IsPlayerNearAnchor();
			if (StashUI.IsOpen && !flag)
			{
				StashUI.Close();
				Log.LogInfo((object)"Left the area - stash closed.");
			}
			if (StashUI.IsOpen && Input.GetKeyDown((KeyCode)27))
			{
				StashUI.Close();
			}
			if (Input.GetKeyDown(ToggleKey.Value))
			{
				if (StashUI.IsOpen)
				{
					StashUI.Close();
				}
				else if (flag)
				{
					StashUI.Open();
				}
				else
				{
					Log.LogInfo((object)"The stash can only be opened near the King.");
				}
			}
		}

		private void OnGUI()
		{
			if (StashUI.IsOpen)
			{
				StashUI.Draw();
			}
			else if (ProximityGate.IsPlayerNearAnchor())
			{
				DrawOpenPrompt();
			}
		}

		private void DrawOpenPrompt()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: 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_0090: Unknown result type (might be due to invalid IL or missing references)
			StashUI.EnsureStyles();
			Rect val = default(Rect);
			((Rect)(ref val))..ctor((float)Screen.width / 2f - 90f + PromptOffsetX.Value, (float)Screen.height - PromptOffsetY.Value, 180f, 40f);
			Color color = GUI.color;
			GUI.color = new Color(1f, 1f, 1f, 0.8f);
			bool flag = GUI.Button(val, $"Open Stash ({ToggleKey.Value})", StashUI._buttonStyle);
			GUI.color = color;
			if (flag)
			{
				StashUI.Open();
			}
		}
	}
	internal static class ProximityGate
	{
		private static Transform _anchor;

		private static float _nextRefreshTime;

		internal static bool IsPlayerNearAnchor()
		{
			//IL_001c: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			FirstPersonController localPlayer = Plugin.LocalPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return false;
			}
			RefreshAnchorIfNeeded(((Component)localPlayer).transform.position);
			if ((Object)(object)_anchor == (Object)null)
			{
				return false;
			}
			float value = Plugin.ProximityRadius.Value;
			return Vector3.Distance(((Component)localPlayer).transform.position, _anchor.position) <= value;
		}

		private static void RefreshAnchorIfNeeded(Vector3 playerPosition)
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			if (!(Time.time < _nextRefreshTime) || !((Object)(object)_anchor != (Object)null))
			{
				_nextRefreshTime = Time.time + Plugin.ProximityRefreshInterval.Value;
				_anchor = FindClosestMatch(playerPosition);
			}
		}

		private static Transform FindClosestMatch(Vector3 playerPosition)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			string value = Plugin.ProximitySearchTerm.Value;
			if (string.IsNullOrEmpty(value))
			{
				return null;
			}
			Transform result = null;
			float num = float.MaxValue;
			Transform[] array = Object.FindObjectsByType<Transform>((FindObjectsSortMode)0);
			Transform[] array2 = array;
			foreach (Transform val in array2)
			{
				if (!((Object)(object)val == (Object)null) && ((Object)val).name != null && ((Object)val).name.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0)
				{
					float num2 = Vector3.Distance(playerPosition, val.position);
					if (num2 < num)
					{
						num = num2;
						result = val;
					}
				}
			}
			return result;
		}
	}
	public struct StashItemData
	{
		public string itemId;

		public int count;
	}
	[StructLayout(LayoutKind.Sequential, Size = 1)]
	public struct RequestStashSyncMessage : NetworkMessage
	{
	}
	public struct StashSyncMessage : NetworkMessage
	{
		public StashItemData[] items;
	}
	public struct DepositItemMessage : NetworkMessage
	{
		public string itemId;

		public int count;
	}
	public struct WithdrawItemMessage : NetworkMessage
	{
		public string itemId;

		public int count;
	}
	internal static class Networker
	{
		internal static void RegisterNetwork()
		{
			RegisterSerializers();
			if (NetworkServer.active)
			{
				RegisterServerHandlers();
			}
			if (NetworkClient.active)
			{
				RegisterClientHandlers();
			}
		}

		private static void RegisterSerializers()
		{
			Writer<StashItemData>.write = delegate(NetworkWriter writer, StashItemData data)
			{
				NetworkWriterExtensions.WriteString(writer, data.itemId);
				NetworkWriterExtensions.WriteInt(writer, data.count);
			};
			Reader<StashItemData>.read = (NetworkReader reader) => new StashItemData
			{
				itemId = NetworkReaderExtensions.ReadString(reader),
				count = NetworkReaderExtensions.ReadInt(reader)
			};
			Writer<RequestStashSyncMessage>.write = delegate
			{
			};
			Reader<RequestStashSyncMessage>.read = (NetworkReader reader) => default(RequestStashSyncMessage);
			Writer<StashSyncMessage>.write = delegate(NetworkWriter writer, StashSyncMessage msg)
			{
				StashItemData[] items = msg.items;
				int num = ((items != null) ? items.Length : 0);
				NetworkWriterExtensions.WriteInt(writer, num);
				for (int i = 0; i < num; i++)
				{
					Writer<StashItemData>.write(writer, msg.items[i]);
				}
			};
			Reader<StashSyncMessage>.read = delegate(NetworkReader reader)
			{
				int num = NetworkReaderExtensions.ReadInt(reader);
				StashItemData[] array = new StashItemData[num];
				for (int i = 0; i < num; i++)
				{
					array[i] = Reader<StashItemData>.read(reader);
				}
				return new StashSyncMessage
				{
					items = array
				};
			};
			Writer<DepositItemMessage>.write = delegate(NetworkWriter writer, DepositItemMessage msg)
			{
				NetworkWriterExtensions.WriteString(writer, msg.itemId);
				NetworkWriterExtensions.WriteInt(writer, msg.count);
			};
			Reader<DepositItemMessage>.read = (NetworkReader reader) => new DepositItemMessage
			{
				itemId = NetworkReaderExtensions.ReadString(reader),
				count = NetworkReaderExtensions.ReadInt(reader)
			};
			Writer<WithdrawItemMessage>.write = delegate(NetworkWriter writer, WithdrawItemMessage msg)
			{
				NetworkWriterExtensions.WriteString(writer, msg.itemId);
				NetworkWriterExtensions.WriteInt(writer, msg.count);
			};
			Reader<WithdrawItemMessage>.read = (NetworkReader reader) => new WithdrawItemMessage
			{
				itemId = NetworkReaderExtensions.ReadString(reader),
				count = NetworkReaderExtensions.ReadInt(reader)
			};
		}

		private static void RegisterServerHandlers()
		{
			NetworkServer.RegisterHandler<RequestStashSyncMessage>((Action<NetworkConnectionToClient, RequestStashSyncMessage>)OnRequestStashSync, true);
			NetworkServer.RegisterHandler<DepositItemMessage>((Action<NetworkConnectionToClient, DepositItemMessage>)OnDepositRequest, true);
			NetworkServer.RegisterHandler<WithdrawItemMessage>((Action<NetworkConnectionToClient, WithdrawItemMessage>)OnWithdrawRequest, true);
		}

		private static void RegisterClientHandlers()
		{
			NetworkClient.RegisterHandler<StashSyncMessage>((Action<StashSyncMessage>)OnStashSync, false);
		}

		private static void OnRequestStashSync(NetworkConnectionToClient conn, RequestStashSyncMessage msg)
		{
			((NetworkConnection)conn).Send<StashSyncMessage>(new StashSyncMessage
			{
				items = StashStorage.ToArray()
			}, 0);
		}

		private static void OnDepositRequest(NetworkConnectionToClient conn, DepositItemMessage msg)
		{
			if (!ItemBlocklist.IsBlocked(msg.itemId))
			{
				InventorySystem inventoryForConnection = GetInventoryForConnection(conn);
				if (!((Object)(object)inventoryForConnection == (Object)null) && RemoveFromPlayerInventory(inventoryForConnection, msg.itemId, msg.count))
				{
					StashStorage.Add(msg.itemId, msg.count);
					BroadcastStash();
				}
			}
		}

		private static void OnWithdrawRequest(NetworkConnectionToClient conn, WithdrawItemMessage msg)
		{
			InventorySystem inventoryForConnection = GetInventoryForConnection(conn);
			if ((Object)(object)inventoryForConnection == (Object)null || !StashStorage.TryRemove(msg.itemId, msg.count))
			{
				return;
			}
			ItemDataSO val = ItemLookup.Find(msg.itemId);
			if ((Object)(object)val == (Object)null)
			{
				StashStorage.Add(msg.itemId, msg.count);
				return;
			}
			int itemCount = inventoryForConnection.GetItemCount(msg.itemId);
			inventoryForConnection.ServerAddItem(val, msg.count);
			int itemCount2 = inventoryForConnection.GetItemCount(msg.itemId);
			int num = itemCount2 - itemCount;
			if (num < 0)
			{
				num = 0;
			}
			if (num > msg.count)
			{
				num = msg.count;
			}
			int num2 = msg.count - num;
			if (num2 > 0)
			{
				StashStorage.Add(msg.itemId, num2);
			}
			BroadcastStash();
		}

		private static InventorySystem GetInventoryForConnection(NetworkConnectionToClient conn)
		{
			if (conn == null || (Object)(object)((NetworkConnection)conn).identity == (Object)null)
			{
				return null;
			}
			FirstPersonController component = ((Component)((NetworkConnection)conn).identity).GetComponent<FirstPersonController>();
			return ((Object)(object)component != (Object)null) ? component.InventorySystem : null;
		}

		private static bool RemoveFromPlayerInventory(InventorySystem inv, string itemId, int count)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: 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)
			for (int i = 0; i < inv.InventoryEntries.Count; i++)
			{
				InventoryEntry val = inv.InventoryEntries[i];
				if (val.itemID == itemId && val.count >= count)
				{
					return inv.TryRemove(i, count);
				}
			}
			return false;
		}

		private static void BroadcastStash()
		{
			NetworkServer.SendToAll<StashSyncMessage>(new StashSyncMessage
			{
				items = StashStorage.ToArray()
			}, 0, false);
		}

		private static void OnStashSync(StashSyncMessage msg)
		{
			StashClientState.LastKnownStash = msg.items ?? new StashItemData[0];
		}

		internal static void RequestSync()
		{
			if (NetworkClient.isConnected)
			{
				NetworkClient.Send<RequestStashSyncMessage>(default(RequestStashSyncMessage), 0);
			}
		}

		internal static void SendDeposit(string itemId, int count)
		{
			if (NetworkClient.isConnected)
			{
				NetworkClient.Send<DepositItemMessage>(new DepositItemMessage
				{
					itemId = itemId,
					count = count
				}, 0);
			}
		}

		internal static void SendWithdraw(string itemId, int count)
		{
			if (NetworkClient.isConnected)
			{
				NetworkClient.Send<WithdrawItemMessage>(new WithdrawItemMessage
				{
					itemId = itemId,
					count = count
				}, 0);
			}
		}
	}
	internal static class StashStorage
	{
		private static readonly Dictionary<string, int> _contents = new Dictionary<string, int>();

		internal static void Add(string itemId, int count)
		{
			if (!_contents.ContainsKey(itemId))
			{
				_contents[itemId] = 0;
			}
			_contents[itemId] += count;
		}

		internal static bool TryRemove(string itemId, int count)
		{
			if (!_contents.TryGetValue(itemId, out var value) || value < count)
			{
				return false;
			}
			_contents[itemId] -= count;
			if (_contents[itemId] <= 0)
			{
				_contents.Remove(itemId);
			}
			return true;
		}

		internal static StashItemData[] ToArray()
		{
			List<StashItemData> list = new List<StashItemData>();
			foreach (KeyValuePair<string, int> content in _contents)
			{
				list.Add(new StashItemData
				{
					itemId = content.Key,
					count = content.Value
				});
			}
			return list.ToArray();
		}
	}
	internal static class StashClientState
	{
		internal static StashItemData[] LastKnownStash = new StashItemData[0];
	}
	internal static class ItemLookup
	{
		private static readonly Dictionary<string, ItemDataSO> _cache = new Dictionary<string, ItemDataSO>();

		internal static ItemDataSO Find(string itemId)
		{
			if (_cache.TryGetValue(itemId, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			ItemDataSO[] array = Resources.FindObjectsOfTypeAll<ItemDataSO>();
			ItemDataSO[] array2 = array;
			foreach (ItemDataSO val in array2)
			{
				if (val.itemID == itemId)
				{
					_cache[itemId] = val;
					return val;
				}
			}
			return null;
		}

		internal static string GetDisplayName(string itemId)
		{
			ItemDataSO val = Find(itemId);
			if ((Object)(object)val != (Object)null)
			{
				string localizedName = val.GetLocalizedName();
				if (!string.IsNullOrEmpty(localizedName))
				{
					return localizedName;
				}
			}
			return DisplayName.Format(itemId);
		}

		internal static string GetStatLine(string itemId)
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			ItemDataSO val = Find(itemId);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append(val.GetRarityLocalizedString(true));
			WeaponDataSO val2 = (WeaponDataSO)(object)((val is WeaponDataSO) ? val : null);
			if (val2 != null)
			{
				if (val2.weaponCategories != null && val2.weaponCategories.Count > 0)
				{
					List<string> list = new List<string>();
					foreach (WeaponCategory weaponCategory in val2.weaponCategories)
					{
						list.Add(FormatEnumName(((object)weaponCategory/*cast due to .constrained prefix*/).ToString()));
					}
					stringBuilder.Append("  •  ").Append(string.Join("/", list));
				}
				FirstPersonController localPlayer = Plugin.LocalPlayer;
				if ((Object)(object)localPlayer != (Object)null && (Object)(object)localPlayer.PlayerStats != (Object)null)
				{
					float num = localPlayer.PlayerStats.CalculatePreviewDamage(val2);
					stringBuilder.Append("  •  Damage ").Append(num.ToString("0.#"));
				}
				else
				{
					stringBuilder.Append("  •  Base Dmg ").Append(val2.BaseDamage.ToString("0.#"));
				}
			}
			return stringBuilder.ToString();
		}

		private static string FormatEnumName(string raw)
		{
			string text = raw.Replace('_', ' ').ToLowerInvariant();
			if (text.Length == 0)
			{
				return text;
			}
			return char.ToUpperInvariant(text[0]) + text.Substring(1);
		}

		internal static bool IsToolOrWeapon(string itemId, ItemDataSO itemData)
		{
			if (itemData is WeaponDataSO)
			{
				return true;
			}
			if (string.IsNullOrEmpty(itemId))
			{
				return false;
			}
			return itemId.IndexOf("tool", StringComparison.OrdinalIgnoreCase) >= 0 || itemId.IndexOf("arrow", StringComparison.OrdinalIgnoreCase) >= 0;
		}
	}
	internal static class DisplayName
	{
		private static readonly Dictionary<string, string> _cache = new Dictionary<string, string>();

		internal static string Format(string itemId)
		{
			if (string.IsNullOrEmpty(itemId))
			{
				return itemId;
			}
			if (_cache.TryGetValue(itemId, out var value))
			{
				return value;
			}
			string text = itemId.Replace('_', ' ');
			StringBuilder stringBuilder = new StringBuilder();
			for (int i = 0; i < text.Length; i++)
			{
				char c = text[i];
				if (i > 0 && char.IsUpper(c) && char.IsLower(text[i - 1]))
				{
					stringBuilder.Append(' ');
				}
				stringBuilder.Append(c);
			}
			string[] array = stringBuilder.ToString().Split(new char[1] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
			for (int j = 0; j < array.Length; j++)
			{
				string text2 = array[j];
				array[j] = char.ToUpperInvariant(text2[0]) + text2.Substring(1).ToLowerInvariant();
			}
			string text3 = string.Join(" ", array);
			_cache[itemId] = text3;
			return text3;
		}
	}
	internal static class ItemBlocklist
	{
		private static HashSet<string> _cached;

		private static string _cachedRaw;

		internal static bool IsBlocked(string itemId)
		{
			string text = Plugin.NeverStoreItemIds.Value ?? string.Empty;
			if (_cached == null || _cachedRaw != text)
			{
				_cachedRaw = text;
				_cached = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
				string[] array = text.Split(',');
				foreach (string text2 in array)
				{
					string text3 = text2.Trim();
					if (text3.Length > 0)
					{
						_cached.Add(text3);
					}
				}
			}
			return itemId != null && _cached.Contains(itemId);
		}
	}
	[HarmonyPatch(typeof(NetworkHelper), "OnStartClient")]
	internal static class NetworkStartupPatch
	{
		[HarmonyPostfix]
		private static void Postfix(NetworkHelper __instance)
		{
			Networker.RegisterNetwork();
		}
	}
	[HarmonyPatch(typeof(FirstPersonController), "OnStartLocalPlayer")]
	internal static class LocalPlayerTrackerPatch
	{
		[HarmonyPostfix]
		private static void Postfix(FirstPersonController __instance)
		{
			Plugin.LocalPlayer = __instance;
			Networker.RequestSync();
		}
	}
	internal static class StashUI
	{
		internal static bool IsOpen;

		private static Vector2 _stashScroll;

		private static Vector2 _invScroll;

		private static CursorLockMode _previousLockState;

		private static bool _previousCursorVisible;

		private static bool _stylesReady;

		private static Texture2D _panelTex;

		private static Texture2D _borderTex;

		private static Texture2D _accentTex;

		private static Texture2D _slotBorderTex;

		private static Texture2D _slotFillTex;

		private static GUIStyle _titleStyle;

		private static GUIStyle _headerStyle;

		private static GUIStyle _subHeaderStyle;

		private static GUIStyle _summaryStyle;

		private static GUIStyle _rowLabelStyle;

		internal static GUIStyle _buttonStyle;

		private static GUIStyle _statLabelStyle;

		private static GUIStyle _closeButtonStyle;

		internal static void Open()
		{
			//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)
			if (!IsOpen)
			{
				IsOpen = true;
				_previousLockState = Cursor.lockState;
				_previousCursorVisible = Cursor.visible;
				Cursor.lockState = (CursorLockMode)0;
				Cursor.visible = true;
				Networker.RequestSync();
			}
		}

		internal static void Close()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if (IsOpen)
			{
				IsOpen = false;
				Cursor.lockState = _previousLockState;
				Cursor.visible = _previousCursorVisible;
			}
		}

		private static void PlaySound(string soundId)
		{
			FirstPersonController localPlayer = Plugin.LocalPlayer;
			if ((Object)(object)localPlayer != (Object)null && (Object)(object)localPlayer.FPSAudioPlayer != (Object)null)
			{
				((NetworkedAudioPlayer)localPlayer.FPSAudioPlayer).PlaySound(soundId);
			}
		}

		internal static void EnsureStyles()
		{
			//IL_0029: 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_006f: 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_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Expected O, but got Unknown
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Expected O, but got Unknown
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Expected O, but got Unknown
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Expected O, but got Unknown
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0208: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Expected O, but got Unknown
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0241: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0252: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_025f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0269: Expected O, but got Unknown
			//IL_026f: Expected O, but got Unknown
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02df: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			//IL_0356: Unknown result type (might be due to invalid IL or missing references)
			//IL_035f: Unknown result type (might be due to invalid IL or missing references)
			//IL_036c: Expected O, but got Unknown
			//IL_0385: Unknown result type (might be due to invalid IL or missing references)
			//IL_039a: Unknown result type (might be due to invalid IL or missing references)
			//IL_039f: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bd: Expected O, but got Unknown
			//IL_03db: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_041e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0438: Unknown result type (might be due to invalid IL or missing references)
			//IL_0461: Unknown result type (might be due to invalid IL or missing references)
			//IL_047b: Unknown result type (might be due to invalid IL or missing references)
			if (!_stylesReady)
			{
				_stylesReady = true;
				_panelTex = MakeTex(new Color(0.05f, 0.05f, 0.07f, 0.97f));
				_borderTex = MakeTex(new Color(0.55f, 0.42f, 0.18f, 1f));
				_accentTex = MakeTex(new Color(0.75f, 0.6f, 0.25f, 0.95f));
				_slotBorderTex = MakeTex(new Color(0.85f, 0.83f, 0.75f, 1f));
				_slotFillTex = MakeTex(new Color(0.14f, 0.14f, 0.17f, 1f));
				_titleStyle = new GUIStyle(GUI.skin.label)
				{
					fontSize = 22,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)4
				};
				_titleStyle.normal.textColor = new Color(0.95f, 0.9f, 0.75f);
				_headerStyle = new GUIStyle(GUI.skin.label)
				{
					fontSize = 15,
					fontStyle = (FontStyle)1
				};
				_headerStyle.normal.textColor = new Color(0.9f, 0.85f, 0.6f);
				_subHeaderStyle = new GUIStyle(GUI.skin.label)
				{
					fontSize = 12,
					fontStyle = (FontStyle)1
				};
				_subHeaderStyle.normal.textColor = new Color(0.6f, 0.78f, 0.95f);
				_summaryStyle = new GUIStyle(GUI.skin.label)
				{
					fontSize = 11,
					fontStyle = (FontStyle)2
				};
				_summaryStyle.normal.textColor = new Color(0.65f, 0.65f, 0.6f);
				_rowLabelStyle = new GUIStyle(GUI.skin.label)
				{
					fontSize = 13,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)3
				};
				_rowLabelStyle.normal.textColor = Color.white;
				_buttonStyle = new GUIStyle(GUI.skin.button)
				{
					fontSize = 12,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)4,
					padding = new RectOffset(6, 6, 4, 4)
				};
				_buttonStyle.normal.background = MakeTex(new Color(0.24f, 0.19f, 0.1f, 1f));
				_buttonStyle.normal.textColor = new Color(0.95f, 0.9f, 0.75f);
				_buttonStyle.hover.background = MakeTex(new Color(0.33f, 0.26f, 0.13f, 1f));
				_buttonStyle.hover.textColor = Color.white;
				_buttonStyle.active.background = MakeTex(new Color(0.17f, 0.13f, 0.06f, 1f));
				_buttonStyle.active.textColor = Color.white;
				_statLabelStyle = new GUIStyle(GUI.skin.label)
				{
					fontSize = 11,
					richText = true
				};
				_statLabelStyle.normal.textColor = new Color(0.8f, 0.8f, 0.8f);
				_closeButtonStyle = new GUIStyle(GUI.skin.button)
				{
					fontSize = 14,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)4
				};
				_closeButtonStyle.normal.background = MakeTex(new Color(0.4f, 0.14f, 0.12f, 1f));
				_closeButtonStyle.normal.textColor = Color.white;
				_closeButtonStyle.hover.background = MakeTex(new Color(0.55f, 0.18f, 0.15f, 1f));
				_closeButtonStyle.hover.textColor = Color.white;
				_closeButtonStyle.active.background = MakeTex(new Color(0.3f, 0.1f, 0.08f, 1f));
				_closeButtonStyle.active.textColor = Color.white;
			}
		}

		private static Texture2D MakeTex(Color color)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(1, 1);
			val.SetPixel(0, 0, color);
			val.Apply();
			return val;
		}

		internal static void Draw()
		{
			//IL_0082: 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_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			if (IsOpen)
			{
				EnsureStyles();
				Rect val = default(Rect);
				((Rect)(ref val))..ctor((float)(Screen.width / 2 - 320), (float)(Screen.height / 2 - 225), 640f, 450f);
				Rect val2 = default(Rect);
				((Rect)(ref val2))..ctor(((Rect)(ref val)).x - 3f, ((Rect)(ref val)).y - 3f, ((Rect)(ref val)).width + 6f, ((Rect)(ref val)).height + 6f);
				GUI.DrawTexture(val2, (Texture)(object)_borderTex);
				GUI.DrawTexture(val, (Texture)(object)_panelTex);
				Rect val3 = default(Rect);
				((Rect)(ref val3))..ctor(((Rect)(ref val)).x, ((Rect)(ref val)).y + 10f, ((Rect)(ref val)).width, 28f);
				GUI.Label(val3, "Shared Stash", _titleStyle);
				Rect val4 = default(Rect);
				((Rect)(ref val4))..ctor(((Rect)(ref val)).x + 20f, ((Rect)(ref val)).y + 42f, ((Rect)(ref val)).width - 40f, 2f);
				GUI.DrawTexture(val4, (Texture)(object)_accentTex);
				Rect val5 = default(Rect);
				((Rect)(ref val5))..ctor(((Rect)(ref val)).xMax - 36f, ((Rect)(ref val)).y + 8f, 26f, 26f);
				if (GUI.Button(val5, "X", _closeButtonStyle))
				{
					Close();
				}
				DrawStashColumn(new Rect(((Rect)(ref val)).x + 20f, ((Rect)(ref val)).y + 54f, 280f, 378f));
				DrawInventoryColumn(new Rect(((Rect)(ref val)).x + ((Rect)(ref val)).width - 300f, ((Rect)(ref val)).y + 54f, 280f, 378f));
			}
		}

		private static void DrawStashColumn(Rect area)
		{
			//IL_0001: 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_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.BeginArea(area);
			GUILayout.Label("Stash Contents", _headerStyle, Array.Empty<GUILayoutOption>());
			StashItemData[] lastKnownStash = StashClientState.LastKnownStash;
			int num = 0;
			StashItemData[] array = lastKnownStash;
			for (int i = 0; i < array.Length; i++)
			{
				StashItemData stashItemData = array[i];
				num += stashItemData.count;
			}
			GUILayout.Label(string.Format("{0} item type{1}  •  {2} total", lastKnownStash.Length, (lastKnownStash.Length == 1) ? "" : "s", num), _summaryStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Space(4f);
			_stashScroll = GUILayout.BeginScrollView(_stashScroll, Array.Empty<GUILayoutOption>());
			List<StashItemData> list = new List<StashItemData>();
			List<StashItemData> list2 = new List<StashItemData>();
			StashItemData[] array2 = lastKnownStash;
			for (int j = 0; j < array2.Length; j++)
			{
				StashItemData item = array2[j];
				ItemDataSO itemData = ItemLookup.Find(item.itemId);
				if (ItemLookup.IsToolOrWeapon(item.itemId, itemData))
				{
					list.Add(item);
				}
				else
				{
					list2.Add(item);
				}
			}
			if (list.Count > 0)
			{
				GUILayout.Label("Tools & Weapons", _subHeaderStyle, Array.Empty<GUILayoutOption>());
				foreach (StashItemData item2 in list)
				{
					DrawStashRow(item2);
				}
				GUILayout.Space(6f);
			}
			if (list2.Count > 0)
			{
				GUILayout.Label("Resources", _subHeaderStyle, Array.Empty<GUILayoutOption>());
				foreach (StashItemData item3 in list2)
				{
					DrawStashRow(item3);
				}
			}
			GUILayout.EndScrollView();
			GUILayout.EndArea();
		}

		private static void DrawStashRow(StashItemData slot)
		{
			GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			DrawIcon(slot.itemId);
			GUILayout.Label($"{ItemLookup.GetDisplayName(slot.itemId)} x{slot.count}", _rowLabelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(128f) });
			if (GUILayout.Button("Take", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(48f) }))
			{
				Networker.SendWithdraw(slot.itemId, 1);
				PlaySound("PICKUP_ITEM");
			}
			bool flag = (GUI.enabled = slot.count > 1);
			if (GUILayout.Button("All", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(38f) }) && flag)
			{
				Networker.SendWithdraw(slot.itemId, slot.count);
				PlaySound("PICKUP_ITEM");
			}
			GUI.enabled = true;
			GUILayout.EndHorizontal();
			string statLine = ItemLookup.GetStatLine(slot.itemId);
			if (!string.IsNullOrEmpty(statLine))
			{
				GUILayout.Label(statLine, _statLabelStyle, Array.Empty<GUILayoutOption>());
			}
			GUILayout.EndVertical();
			GUILayout.Space(4f);
		}

		private static void DrawInventoryColumn(Rect area)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: 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_019e: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.BeginArea(area);
			GUILayout.Label("Your Inventory", _headerStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Space(19f);
			_invScroll = GUILayout.BeginScrollView(_invScroll, Array.Empty<GUILayoutOption>());
			FirstPersonController localPlayer = Plugin.LocalPlayer;
			if ((Object)(object)localPlayer != (Object)null && (Object)(object)localPlayer.InventorySystem != (Object)null)
			{
				SyncList<InventoryEntry> inventoryEntries = localPlayer.InventorySystem.InventoryEntries;
				List<InventoryEntry> list = new List<InventoryEntry>();
				List<InventoryEntry> list2 = new List<InventoryEntry>();
				for (int i = 0; i < inventoryEntries.Count; i++)
				{
					InventoryEntry val = inventoryEntries[i];
					if (!((InventoryEntry)(ref val)).IsEmpty && !ItemBlocklist.IsBlocked(val.itemID))
					{
						ItemDataSO itemData = ItemLookup.Find(val.itemID);
						if (ItemLookup.IsToolOrWeapon(val.itemID, itemData))
						{
							list.Add(val);
						}
						else
						{
							list2.Add(val);
						}
					}
				}
				if (list.Count > 0)
				{
					GUILayout.Label("Tools & Weapons", _subHeaderStyle, Array.Empty<GUILayoutOption>());
					foreach (InventoryEntry item in list)
					{
						DrawInventoryRow(item);
					}
					GUILayout.Space(6f);
				}
				if (list2.Count > 0)
				{
					GUILayout.Label("Resources", _subHeaderStyle, Array.Empty<GUILayoutOption>());
					foreach (InventoryEntry item2 in list2)
					{
						DrawInventoryRow(item2);
					}
				}
			}
			GUILayout.EndScrollView();
			GUILayout.EndArea();
		}

		private static void DrawInventoryRow(InventoryEntry entry)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: 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)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			DrawIcon(entry.itemID);
			GUILayout.Label($"{ItemLookup.GetDisplayName(entry.itemID)} x{entry.count}", _rowLabelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(128f) });
			if (GUILayout.Button("Store", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(48f) }))
			{
				Networker.SendDeposit(entry.itemID, 1);
				PlaySound("DROP_ITEM");
			}
			bool flag = (GUI.enabled = entry.count > 1);
			if (GUILayout.Button("All", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(38f) }) && flag)
			{
				Networker.SendDeposit(entry.itemID, entry.count);
				PlaySound("DROP_ITEM");
			}
			GUI.enabled = true;
			GUILayout.EndHorizontal();
			string statLine = ItemLookup.GetStatLine(entry.itemID);
			if (!string.IsNullOrEmpty(statLine))
			{
				GUILayout.Label(statLine, _statLabelStyle, Array.Empty<GUILayoutOption>());
			}
			GUILayout.EndVertical();
			GUILayout.Space(4f);
		}

		private static void DrawIcon(string itemId)
		{
			//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_004b: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: 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)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			ItemDataSO val = ItemLookup.Find(itemId);
			Sprite val2 = (((Object)(object)val != (Object)null) ? val.itemIcon : null);
			Rect rect = GUILayoutUtility.GetRect(28f, 28f, (GUILayoutOption[])(object)new GUILayoutOption[2]
			{
				GUILayout.Width(28f),
				GUILayout.Height(28f)
			});
			GUI.DrawTexture(rect, (Texture)(object)_slotBorderTex);
			Rect val3 = default(Rect);
			((Rect)(ref val3))..ctor(((Rect)(ref rect)).x + 2f, ((Rect)(ref rect)).y + 2f, ((Rect)(ref rect)).width - 4f, ((Rect)(ref rect)).height - 4f);
			GUI.DrawTexture(val3, (Texture)(object)_slotFillTex);
			if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2.texture == (Object)null))
			{
				Texture2D texture = val2.texture;
				Rect textureRect = val2.textureRect;
				float num = ((Rect)(ref textureRect)).x / (float)((Texture)texture).width;
				textureRect = val2.textureRect;
				float num2 = ((Rect)(ref textureRect)).y / (float)((Texture)texture).height;
				textureRect = val2.textureRect;
				float num3 = ((Rect)(ref textureRect)).width / (float)((Texture)texture).width;
				textureRect = val2.textureRect;
				Rect val4 = default(Rect);
				((Rect)(ref val4))..ctor(num, num2, num3, ((Rect)(ref textureRect)).height / (float)((Texture)texture).height);
				Rect val5 = default(Rect);
				((Rect)(ref val5))..ctor(((Rect)(ref val3)).x + 2f, ((Rect)(ref val3)).y + 2f, ((Rect)(ref val3)).width - 4f, ((Rect)(ref val3)).height - 4f);
				GUI.DrawTextureWithTexCoords(val5, (Texture)(object)texture, val4);
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		internal IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}