Decompiled source of QStore v1.0.8

BepInEx/plugins/QStore.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("QStore")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("QStore")]
[assembly: AssemblyTitle("QStore")]
[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 QStore
{
	[BepInPlugin("Zancho.QStore", "Q Store", "1.0.8")]
	public class QStorePlugin : BaseUnityPlugin
	{
		internal static ConfigEntry<KeyCode> StoreKey;

		private MethodInfo _inventoryChanged;

		private MethodInfo _containerSave;

		private MethodInfo _getHoverObject;

		private void Awake()
		{
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			StoreKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "Store Key", (KeyCode)113, "Press this key while hovering a container to store matching inventory items without opening it.");
			_inventoryChanged = typeof(Inventory).GetMethod("Changed", BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[2]
			{
				typeof(bool),
				typeof(bool)
			}, null);
			_containerSave = typeof(Container).GetMethod("Save", BindingFlags.Instance | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
			_getHoverObject = typeof(Player).GetMethod("GetHoverObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
			FavoriteSlotService.Initialize();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Q Store 1.0.8 loaded. Q stores matching items without opening the chest.");
			new Harmony("Zancho.QStore").PatchAll(typeof(QStorePlugin).Assembly);
		}

		private void Update()
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			Player localPlayer = Player.m_localPlayer;
			if (!((Object)(object)localPlayer == (Object)null) && (!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()))
			{
				FavoriteSlotUi.HandleFavoriteInput();
				FavoriteSlotUi.UpdateHelpTooltip(((Object)(object)InventoryGui.instance != (Object)null) ? InventoryGui.instance.m_playerGrid : null);
				if (Input.GetKeyDown(StoreKey.Value))
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)"Q Store: Q detected.");
					StoreHoveredContainer(localPlayer);
				}
			}
		}

		private void StoreHoveredContainer(Player player)
		{
			GameObject val = null;
			if (_getHoverObject != null)
			{
				try
				{
					object? obj = _getHoverObject.Invoke(player, null);
					val = (GameObject)((obj is GameObject) ? obj : null);
				}
				catch (Exception ex)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Q Store: GetHoverObject failed: " + ex.Message));
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				FieldInfo field = typeof(Player).GetField("m_hovering", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null)
				{
					object? value = field.GetValue(player);
					val = (GameObject)((value is GameObject) ? value : null);
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Q Store: Q detected, but Valheim is not hovering a container.");
				return;
			}
			Container val2 = val.GetComponentInParent<Container>();
			if ((Object)(object)val2 == (Object)null)
			{
				val2 = val.GetComponentInChildren<Container>();
			}
			if ((Object)(object)val2 == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)("Q Store: hovered object '" + ((Object)val).name + "' is not a Container."));
				return;
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)("Q Store: hovered container found: '" + ((Object)((Component)val2).gameObject).name + "'."));
			Inventory inventory = val2.GetInventory();
			Inventory inventory2 = ((Humanoid)player).GetInventory();
			if (inventory == null || inventory2 == null)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)"Q Store: Could not get the chest or player inventory.");
				return;
			}
			List<ItemData> list = new List<ItemData>(inventory2.GetAllItems());
			int num = 0;
			HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			foreach (ItemData item in list)
			{
				if (item == null || item.m_shared == null || item.m_stack <= 0 || FavoriteSlotService.IsFavorite(item.m_gridPos.x, item.m_gridPos.y))
				{
					continue;
				}
				string name = item.m_shared.m_name;
				if (inventory.CountItems(name, -1, true) <= 0)
				{
					continue;
				}
				int stack = item.m_stack;
				if (stack <= 0)
				{
					continue;
				}
				ItemData val3 = item.Clone();
				val3.m_stack = stack;
				if (inventory.AddItem(val3))
				{
					if (!inventory2.RemoveItem(item, stack))
					{
						inventory.RemoveItem(val3);
						continue;
					}
					num += stack;
					hashSet.Add(name);
				}
			}
			if (num <= 0)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Q Store: hovered chest found, but there were no matching items with free space.");
				return;
			}
			_inventoryChanged?.Invoke(inventory2, new object[2] { false, false });
			_inventoryChanged?.Invoke(inventory, new object[2] { false, false });
			_containerSave?.Invoke(val2, Array.Empty<object>());
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"Q Store: moved {num} items across {hashSet.Count} item type(s) into '{((Object)((Component)val2).gameObject).name}' without opening it.");
			if ((Object)(object)MessageHud.instance != (Object)null)
			{
				int count = hashSet.Count;
				string text = ((count == 1) ? "1 item type stored" : (count + " item types stored"));
				MessageHud.instance.ShowMessage((MessageType)2, text, 0, (Sprite)null, false, true);
			}
		}
	}
	internal static class FavoriteSlotService
	{
		private const string FileName = "QStore.favorite-slots.txt";

		private static readonly HashSet<string> FavoriteSlots = new HashSet<string>(StringComparer.Ordinal);

		private static string _characterKey;

		private static bool _loaded;

		private static string FilePath => Path.Combine(Paths.ConfigPath, "QStore.favorite-slots.txt");

		internal static void Initialize()
		{
			Load();
		}

		internal static bool IsFavorite(int x, int y)
		{
			EnsureLoaded();
			return FavoriteSlots.Contains(MakeKey(x, y));
		}

		internal static bool Toggle(int x, int y)
		{
			EnsureLoaded();
			string item = MakeKey(x, y);
			bool result;
			if (FavoriteSlots.Contains(item))
			{
				FavoriteSlots.Remove(item);
				result = false;
			}
			else
			{
				FavoriteSlots.Add(item);
				result = true;
			}
			Save();
			return result;
		}

		private static string MakeKey(int x, int y)
		{
			return _characterKey + "|" + x + "|" + y;
		}

		private static void EnsureLoaded()
		{
			string characterKey = GetCharacterKey();
			if (!_loaded || !string.Equals(_characterKey, characterKey, StringComparison.Ordinal))
			{
				Load();
			}
		}

		private static string GetCharacterKey()
		{
			try
			{
				if ((Object)(object)Game.instance != (Object)null)
				{
					PlayerProfile playerProfile = Game.instance.GetPlayerProfile();
					if (playerProfile != null)
					{
						long playerID = playerProfile.GetPlayerID();
						if (playerID != 0L)
						{
							return playerID.ToString();
						}
					}
				}
			}
			catch
			{
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer != (Object)null)
			{
				return "name:" + localPlayer.GetPlayerName();
			}
			return "unknown";
		}

		private static void Load()
		{
			_characterKey = GetCharacterKey();
			FavoriteSlots.Clear();
			if (File.Exists(FilePath))
			{
				string[] array = File.ReadAllLines(FilePath);
				foreach (string text in array)
				{
					if (!string.IsNullOrWhiteSpace(text))
					{
						string[] array2 = text.Split(new char[1] { '|' });
						if (array2.Length == 3 && string.Equals(array2[0], _characterKey, StringComparison.Ordinal) && int.TryParse(array2[1], out var result) && int.TryParse(array2[2], out var result2))
						{
							FavoriteSlots.Add(MakeKey(result, result2));
						}
					}
				}
			}
			_loaded = true;
		}

		private static void Save()
		{
			Directory.CreateDirectory(Paths.ConfigPath);
			List<string> list = new List<string>();
			if (File.Exists(FilePath))
			{
				string[] array = File.ReadAllLines(FilePath);
				foreach (string text in array)
				{
					if (!string.IsNullOrWhiteSpace(text) && !text.StartsWith(_characterKey + "|", StringComparison.Ordinal))
					{
						list.Add(text);
					}
				}
			}
			foreach (string favoriteSlot in FavoriteSlots)
			{
				if (favoriteSlot.Split(new char[1] { '|' }).Length == 3)
				{
					list.Add(favoriteSlot);
				}
			}
			list.Sort(StringComparer.Ordinal);
			File.WriteAllLines(FilePath, list.ToArray());
		}
	}
	internal static class FavoriteSlotUi
	{
		private const string StarName = "QStoreFavoriteStar";

		private const string HelpButtonName = "QStoreFavoriteHelpButton";

		private const float StarSize = 14f;

		private const float StarOffset = 2f;

		private const float ShieldGap = 3f;

		private const float HelpButtonSize = 34f;

		private static readonly FieldInfo ElementsField = AccessTools.Field(typeof(InventoryGrid), "m_elements");

		private static readonly FieldInfo WeightIconField = AccessTools.Field(typeof(InventoryGui), "m_weightIcon");

		private static Sprite _starSprite;

		private static GameObject _helpButton;

		private static Text _helpTooltipText;

		private static Image _helpTooltipBackground;

		private static RectTransform _helpTooltipRect;

		private static Font _helpTooltipFont;

		private const float TargetScreenXAt1920 = 642f;

		private const float TargetScreenYFromTopAt1080 = 47f;

		internal static void HandleFavoriteInput()
		{
			//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_0075: 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)
			//IL_0097: 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)
			if (!Input.GetMouseButtonDown(2) || (Object)(object)InventoryGui.instance == (Object)null || (Object)(object)InventoryGui.instance.m_playerGrid == (Object)null)
			{
				return;
			}
			InventoryGrid playerGrid = InventoryGui.instance.m_playerGrid;
			Inventory val = (((Object)(object)Player.m_localPlayer != (Object)null) ? ((Humanoid)Player.m_localPlayer).GetInventory() : null);
			if (val == null || playerGrid.GetInventory() != val)
			{
				return;
			}
			InventoryElement val2 = FindHoveredElement(playerGrid);
			if ((Object)(object)val2 == (Object)null)
			{
				return;
			}
			Vector2i position = val2.Position;
			ItemData itemAt = val.GetItemAt(position.x, position.y);
			if (itemAt != null && itemAt.m_stack > 0)
			{
				bool flag = FavoriteSlotService.Toggle(position.x, position.y);
				Refresh(playerGrid);
				if ((Object)(object)MessageHud.instance != (Object)null)
				{
					MessageHud.instance.ShowMessage((MessageType)1, flag ? "Inventory slot favorited" : "Inventory slot unfavorited", 0, (Sprite)null, false, true);
				}
			}
		}

		internal static InventoryElement FindHoveredElement(InventoryGrid grid)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: 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_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: 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_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: 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_0139: 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)
			if ((Object)(object)grid == (Object)null || !(ElementsField.GetValue(grid) is List<InventoryElement> list))
			{
				return null;
			}
			Vector2 val = Vector2.op_Implicit(Input.mousePosition);
			Vector2 val2 = default(Vector2);
			Vector2 val3 = default(Vector2);
			foreach (InventoryElement item in list)
			{
				if ((Object)(object)item == (Object)null || (Object)(object)item.m_icon == (Object)null)
				{
					continue;
				}
				RectTransform rectTransform = ((Graphic)item.m_icon).rectTransform;
				if (!((Object)(object)rectTransform == (Object)null))
				{
					Vector3[] array = (Vector3[])(object)new Vector3[4];
					rectTransform.GetWorldCorners(array);
					((Vector2)(ref val2))..ctor(float.MaxValue, float.MaxValue);
					((Vector2)(ref val3))..ctor(float.MinValue, float.MinValue);
					for (int i = 0; i < 4; i++)
					{
						val2 = Vector2.Min(val2, new Vector2(array[i].x, array[i].y));
						val3 = Vector2.Max(val3, new Vector2(array[i].x, array[i].y));
					}
					if (val.x >= val2.x && val.x <= val3.x && val.y >= val2.y && val.y <= val3.y)
					{
						return item;
					}
				}
			}
			return null;
		}

		internal static void Refresh(InventoryGrid grid)
		{
			//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)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: 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_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: 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_0186: 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)
			if ((Object)(object)grid == (Object)null || grid.GetInventory() == null || (Object)(object)Player.m_localPlayer == (Object)null || grid.GetInventory() != ((Humanoid)Player.m_localPlayer).GetInventory() || !(ElementsField.GetValue(grid) is List<InventoryElement> list))
			{
				return;
			}
			EnsureHelpButton(grid);
			foreach (InventoryElement item in list)
			{
				if ((Object)(object)item == (Object)null || (Object)(object)item.m_icon == (Object)null)
				{
					continue;
				}
				Transform parent = ((Component)item.m_icon).transform.parent;
				if ((Object)(object)parent == (Object)null)
				{
					continue;
				}
				Vector2i position = item.Position;
				bool num = FavoriteSlotService.IsFavorite(position.x, position.y);
				Transform val = parent.Find("QStoreFavoriteStar");
				if (!num)
				{
					if ((Object)(object)val != (Object)null)
					{
						Object.Destroy((Object)(object)((Component)val).gameObject);
					}
				}
				else if ((Object)(object)val == (Object)null)
				{
					GameObject val2 = new GameObject("QStoreFavoriteStar", new Type[2]
					{
						typeof(RectTransform),
						typeof(Image)
					});
					RectTransform component = val2.GetComponent<RectTransform>();
					((Transform)component).SetParent(parent, false);
					component.anchorMin = new Vector2(1f, 1f);
					component.anchorMax = new Vector2(1f, 1f);
					component.pivot = new Vector2(1f, 1f);
					component.anchoredPosition = new Vector2(-2f, 2f);
					component.sizeDelta = new Vector2(14f, 14f);
					Image component2 = val2.GetComponent<Image>();
					component2.sprite = GetStarSprite();
					((Graphic)component2).raycastTarget = false;
					((Graphic)component2).color = new Color(1f, 0.82f, 0.15f, 0.98f);
				}
				else
				{
					((Component)val).gameObject.SetActive(true);
				}
			}
		}

		private static void EnsureHelpButton(InventoryGrid grid)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Expected O, but got Unknown
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: 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_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: 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_0178: 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_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_helpButton != (Object)null)
			{
				if (!_helpButton.activeSelf)
				{
					_helpButton.SetActive(true);
				}
				PositionHelpButton(grid);
				return;
			}
			Image val = FindNativeButtonImage();
			if ((Object)(object)val == (Object)null)
			{
				Debug.LogWarning((object)"Q Store: could not find a native Valheim button image for the favorite help button.");
				return;
			}
			_helpButton = new GameObject("QStoreFavoriteHelpButton", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			_helpButton.transform.SetParent(((Component)grid).transform, false);
			RectTransform component = _helpButton.GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0.5f, 0.5f);
			component.anchorMax = new Vector2(0.5f, 0.5f);
			component.pivot = new Vector2(0.5f, 0.5f);
			component.sizeDelta = new Vector2(34f, 34f);
			((Transform)component).localScale = Vector3.one;
			Image component2 = _helpButton.GetComponent<Image>();
			component2.sprite = val.sprite;
			component2.type = val.type;
			component2.preserveAspect = false;
			((Graphic)component2).color = Color.white;
			((Graphic)component2).raycastTarget = false;
			GameObject val2 = new GameObject("QStoreHelpStar", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			RectTransform component3 = val2.GetComponent<RectTransform>();
			((Transform)component3).SetParent(_helpButton.transform, false);
			component3.anchorMin = new Vector2(0.5f, 0.5f);
			component3.anchorMax = new Vector2(0.5f, 0.5f);
			component3.pivot = new Vector2(0.5f, 0.5f);
			component3.anchoredPosition = Vector2.zero;
			component3.sizeDelta = new Vector2(21f, 21f);
			Image component4 = val2.GetComponent<Image>();
			component4.sprite = GetStarSprite();
			((Graphic)component4).color = new Color(1f, 0.82f, 0.15f, 1f);
			((Graphic)component4).raycastTarget = false;
			EnsureHelpTooltip(grid);
			PositionHelpButton(grid);
		}

		private static string GetHierarchyName(Transform transform)
		{
			if ((Object)(object)transform == (Object)null)
			{
				return string.Empty;
			}
			string text = ((Object)transform).name ?? string.Empty;
			Transform parent = transform.parent;
			int num = 0;
			while ((Object)(object)parent != (Object)null && num++ < 32)
			{
				if (!string.IsNullOrEmpty(((Object)parent).name))
				{
					text = ((Object)parent).name + "/" + text;
				}
				parent = parent.parent;
			}
			return text;
		}

		private static Image FindNativeButtonImage()
		{
			if ((Object)(object)InventoryGui.instance == (Object)null)
			{
				return null;
			}
			Button[] componentsInChildren = ((Component)InventoryGui.instance).GetComponentsInChildren<Button>(true);
			Image result = null;
			Button[] array = componentsInChildren;
			foreach (Button val in array)
			{
				if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).gameObject == (Object)(object)_helpButton)
				{
					continue;
				}
				Image val2 = ((Component)val).GetComponent<Image>();
				if ((Object)(object)val2 == (Object)null)
				{
					Graphic targetGraphic = ((Selectable)val).targetGraphic;
					Image val3 = (Image)(object)((targetGraphic is Image) ? targetGraphic : null);
					if (val3 != null)
					{
						val2 = val3;
					}
				}
				if ((Object)(object)val2 == (Object)null || (Object)(object)val2.sprite == (Object)null)
				{
					continue;
				}
				string text = GetHierarchyName(((Component)val).transform).ToLowerInvariant();
				Text[] componentsInChildren2 = ((Component)val).GetComponentsInChildren<Text>(true);
				foreach (Text val4 in componentsInChildren2)
				{
					if ((Object)(object)val4 != (Object)null && !string.IsNullOrEmpty(val4.text) && val4.text.Trim().Equals("Trash", StringComparison.OrdinalIgnoreCase))
					{
						return val2;
					}
				}
				if (text.Contains("trash"))
				{
					return val2;
				}
				if (text.Contains("pin") && !text.Contains("pincursor"))
				{
					result = val2;
				}
			}
			return result;
		}

		private static RectTransform FindShieldOrTrashRect()
		{
			if ((Object)(object)InventoryGui.instance == (Object)null)
			{
				return null;
			}
			Button[] componentsInChildren = ((Component)InventoryGui.instance).GetComponentsInChildren<Button>(true);
			foreach (Button val in componentsInChildren)
			{
				if ((Object)(object)val == (Object)null)
				{
					continue;
				}
				string text = GetHierarchyName(((Component)val).transform).ToLowerInvariant();
				Text[] componentsInChildren2 = ((Component)val).GetComponentsInChildren<Text>(true);
				foreach (Text val2 in componentsInChildren2)
				{
					if ((Object)(object)val2 != (Object)null && !string.IsNullOrEmpty(val2.text) && val2.text.Trim().Equals("Trash", StringComparison.OrdinalIgnoreCase))
					{
						return ((Component)val).GetComponent<RectTransform>();
					}
				}
				if (text.Contains("trash"))
				{
					return ((Component)val).GetComponent<RectTransform>();
				}
			}
			if (WeightIconField != null)
			{
				try
				{
					object value = WeightIconField.GetValue(InventoryGui.instance);
					RectTransform val3 = (RectTransform)((value is RectTransform) ? value : null);
					if (val3 != null)
					{
						return val3;
					}
					Component val4 = (Component)((value is Component) ? value : null);
					if (val4 != null)
					{
						return val4.GetComponent<RectTransform>();
					}
					GameObject val5 = (GameObject)((value is GameObject) ? value : null);
					if (val5 != null)
					{
						return val5.GetComponent<RectTransform>();
					}
				}
				catch
				{
				}
			}
			return null;
		}

		private static void PositionHelpButton(InventoryGrid grid)
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: 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_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_helpButton == (Object)null) && !((Object)(object)grid == (Object)null))
			{
				RectTransform component = _helpButton.GetComponent<RectTransform>();
				RectTransform component2 = ((Component)grid).GetComponent<RectTransform>();
				if (!((Object)(object)component == (Object)null) && !((Object)(object)component2 == (Object)null))
				{
					((Transform)component).SetParent(((Component)grid).transform, false);
					float num = 642f * (float)Screen.width / 1920f;
					float num2 = 47f * (float)Screen.height / 1080f;
					Vector2 val = default(Vector2);
					((Vector2)(ref val))..ctor(num, (float)Screen.height - num2);
					Vector3 val2 = ((Transform)component2).InverseTransformPoint(new Vector3(val.x, val.y, 0f));
					Vector2 anchoredPosition = default(Vector2);
					((Vector2)(ref anchoredPosition))..ctor(val2.x, val2.y);
					component.anchorMin = new Vector2(0.5f, 0.5f);
					component.anchorMax = new Vector2(0.5f, 0.5f);
					component.pivot = new Vector2(0.5f, 0.5f);
					component.anchoredPosition = anchoredPosition;
					component.sizeDelta = new Vector2(34f, 34f);
					((Transform)component).localScale = Vector3.one;
					((Transform)component).SetAsLastSibling();
					PositionHelpTooltip(grid);
				}
			}
		}

		private static void EnsureHelpTooltip(InventoryGrid grid)
		{
			//IL_0033: 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)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: 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_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: 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_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: 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_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)_helpTooltipRect != (Object)null))
			{
				_helpTooltipRect = new GameObject("QStoreFavoriteHelpTooltip", new Type[2]
				{
					typeof(RectTransform),
					typeof(Image)
				}).GetComponent<RectTransform>();
				((Transform)_helpTooltipRect).SetParent(((Component)grid).transform, false);
				_helpTooltipRect.anchorMin = new Vector2(0.5f, 0.5f);
				_helpTooltipRect.anchorMax = new Vector2(0.5f, 0.5f);
				_helpTooltipRect.pivot = new Vector2(0.5f, 0f);
				_helpTooltipRect.sizeDelta = new Vector2(360f, 72f);
				((Component)_helpTooltipRect).gameObject.SetActive(false);
				_helpTooltipBackground = ((Component)_helpTooltipRect).GetComponent<Image>();
				Image val = FindNativeButtonImage();
				if ((Object)(object)val != (Object)null)
				{
					_helpTooltipBackground.sprite = val.sprite;
					_helpTooltipBackground.type = val.type;
					((Graphic)_helpTooltipBackground).color = ((Graphic)val).color;
				}
				((Graphic)_helpTooltipBackground).raycastTarget = false;
				GameObject val2 = new GameObject("QStoreFavoriteHelpTooltipText", new Type[2]
				{
					typeof(RectTransform),
					typeof(Text)
				});
				RectTransform component = val2.GetComponent<RectTransform>();
				((Transform)component).SetParent((Transform)(object)_helpTooltipRect, false);
				component.anchorMin = Vector2.zero;
				component.anchorMax = Vector2.one;
				component.offsetMin = new Vector2(8f, 6f);
				component.offsetMax = new Vector2(-8f, -6f);
				_helpTooltipText = val2.GetComponent<Text>();
				_helpTooltipText.font = FindUiFont();
				_helpTooltipText.fontSize = 14;
				_helpTooltipText.alignment = (TextAnchor)4;
				_helpTooltipText.horizontalOverflow = (HorizontalWrapMode)0;
				_helpTooltipText.verticalOverflow = (VerticalWrapMode)0;
				((Graphic)_helpTooltipText).color = Color.white;
				((Graphic)_helpTooltipText).raycastTarget = false;
				_helpTooltipText.text = "Middle Mouse Button (MMB) on an inventory item slot\nFavorite / Unfavorite item slot";
			}
		}

		private static Font FindUiFont()
		{
			if ((Object)(object)_helpTooltipFont != (Object)null)
			{
				return _helpTooltipFont;
			}
			if ((Object)(object)InventoryGui.instance != (Object)null)
			{
				Text[] componentsInChildren = ((Component)InventoryGui.instance).GetComponentsInChildren<Text>(true);
				foreach (Text val in componentsInChildren)
				{
					if ((Object)(object)val != (Object)null && (Object)(object)val.font != (Object)null)
					{
						_helpTooltipFont = val.font;
						return _helpTooltipFont;
					}
				}
			}
			return Resources.GetBuiltinResource<Font>("Arial.ttf");
		}

		private static void PositionHelpTooltip(InventoryGrid grid)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_0073: 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_0076: 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)
			//IL_008b: 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_00a6: 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)
			if (!((Object)(object)_helpTooltipRect == (Object)null) && !((Object)(object)_helpButton == (Object)null))
			{
				RectTransform component = ((Component)grid).GetComponent<RectTransform>();
				RectTransform component2 = _helpButton.GetComponent<RectTransform>();
				if (!((Object)(object)component == (Object)null) && !((Object)(object)component2 == (Object)null))
				{
					Rect rect = component2.rect;
					float x = ((Rect)(ref rect)).center.x;
					rect = component2.rect;
					Vector3 val = ((Transform)component2).TransformPoint(new Vector3(x, ((Rect)(ref rect)).yMin, 0f));
					Vector3 val2 = ((Transform)component).InverseTransformPoint(val);
					_helpTooltipRect.pivot = new Vector2(0.5f, 1f);
					_helpTooltipRect.anchoredPosition = new Vector2(val2.x - 105f, val2.y - 8f);
				}
			}
		}

		internal static void UpdateHelpTooltip(InventoryGrid grid)
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: 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_00be: 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_00c8: 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_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_helpButton == (Object)null || (Object)(object)_helpTooltipRect == (Object)null)
			{
				return;
			}
			RectTransform component = _helpButton.GetComponent<RectTransform>();
			if (!((Object)(object)component == (Object)null))
			{
				Vector3[] array = (Vector3[])(object)new Vector3[4];
				component.GetWorldCorners(array);
				Vector2 val = default(Vector2);
				((Vector2)(ref val))..ctor(float.MaxValue, float.MaxValue);
				Vector2 val2 = default(Vector2);
				((Vector2)(ref val2))..ctor(float.MinValue, float.MinValue);
				for (int i = 0; i < array.Length; i++)
				{
					val = Vector2.Min(val, new Vector2(array[i].x, array[i].y));
					val2 = Vector2.Max(val2, new Vector2(array[i].x, array[i].y));
				}
				Vector2 val3 = Vector2.op_Implicit(Input.mousePosition);
				bool active = val3.x >= val.x && val3.x <= val2.x && val3.y >= val.y && val3.y <= val2.y;
				((Component)_helpTooltipRect).gameObject.SetActive(active);
			}
		}

		private static Sprite GetStarSprite()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: 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_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: 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_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_starSprite != (Object)null)
			{
				return _starSprite;
			}
			Texture2D val = new Texture2D(64, 64, (TextureFormat)4, false);
			((Texture)val).filterMode = (FilterMode)1;
			Color val2 = default(Color);
			((Color)(ref val2))..ctor(0f, 0f, 0f, 0f);
			Color val3 = default(Color);
			((Color)(ref val3))..ctor(1f, 0.82f, 0.15f, 1f);
			Color[] array = (Color[])(object)new Color[4096];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = val2;
			}
			Vector2 val4 = default(Vector2);
			((Vector2)(ref val4))..ctor(32f, 32f);
			float num = 25f;
			float num2 = 11f;
			Vector2[] array2 = (Vector2[])(object)new Vector2[10];
			for (int j = 0; j < 10; j++)
			{
				double num3 = -Math.PI / 2.0 + (double)j * Math.PI / 5.0;
				float num4 = ((j % 2 == 0) ? num : num2);
				array2[j] = val4 + new Vector2((float)Math.Cos(num3), (float)Math.Sin(num3)) * num4;
			}
			for (int k = 0; k < 64; k++)
			{
				for (int l = 0; l < 64; l++)
				{
					if (PointInPolygon(array2, new Vector2((float)l + 0.5f, (float)k + 0.5f)))
					{
						array[k * 64 + l] = val3;
					}
				}
			}
			val.SetPixels(array);
			val.Apply();
			_starSprite = Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f), 100f);
			((Object)_starSprite).name = "QStoreFavoriteStar";
			return _starSprite;
		}

		private static bool PointInPolygon(Vector2[] polygon, Vector2 point)
		{
			//IL_001b: 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_0039: 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)
			bool flag = false;
			int num = polygon.Length - 1;
			for (int i = 0; i < polygon.Length; i++)
			{
				if (polygon[i].y > point.y != polygon[num].y > point.y && point.x < (polygon[num].x - polygon[i].x) * (point.y - polygon[i].y) / (polygon[num].y - polygon[i].y) + polygon[i].x)
				{
					flag = !flag;
				}
				num = i;
			}
			return flag;
		}
	}
	[HarmonyPatch(typeof(InventoryGrid), "UpdateGui")]
	internal static class QStoreFavoriteUiPatch
	{
		private static void Postfix(InventoryGrid __instance)
		{
			try
			{
				FavoriteSlotUi.Refresh(__instance);
			}
			catch (Exception ex)
			{
				Debug.LogWarning((object)("Q Store: favorite-slot UI refresh failed: " + ex.Message));
			}
		}
	}
	[HarmonyPatch(typeof(Container), "GetHoverText")]
	internal static class QStoreContainerHoverPatch
	{
		private static void Postfix(Container __instance, ref string __result)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)__instance == (Object)null) && QStorePlugin.StoreKey != null)
			{
				string text = ((object)QStorePlugin.StoreKey.Value/*cast due to .constrained prefix*/).ToString();
				if (string.IsNullOrEmpty(text))
				{
					text = "Q";
				}
				if (__result == null)
				{
					__result = string.Empty;
				}
				__result = __result.Replace(" (Hold to stack)", string.Empty);
				if (__result.IndexOf("Store matching items", StringComparison.OrdinalIgnoreCase) < 0)
				{
					__result = __result + "\n[<color=yellow><b>" + text + "</b></color>] Store matching items";
				}
			}
		}
	}
}