Decompiled source of Chest List v1.0.0

Chest_List.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Chest_List.UI;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
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: IgnoresAccessChecksTo("assembly_valheim")]
[assembly: AssemblyCompany("ModdedWolf")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Shows a chest contents overlay when looking at chests.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Chest_List")]
[assembly: AssemblyTitle("Chest_List")]
[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 Chest_List
{
	internal static class ChestListConfig
	{
		internal static ConfigEntry<bool> EnableWorldGeneratedChests;

		internal static ConfigEntry<bool> CombineStacks;

		internal static ConfigEntry<float> UiPositionX;

		internal static ConfigEntry<float> UiPositionY;

		internal static ConfigEntry<float> UiAlpha;

		internal static ConfigEntry<bool> ShowItemImages;

		internal static ConfigEntry<float> MinPanelWidth;

		internal static ConfigEntry<float> MaxPanelWidth;

		internal static void Init(ConfigFile config)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Expected O, but got Unknown
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Expected O, but got Unknown
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Expected O, but got Unknown
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: Expected O, but got Unknown
			EnableWorldGeneratedChests = config.Bind<bool>("General", "EnableWorldGeneratedChests", false, "When enabled, also show contents for world/dungeon loot chests. Player-placed chests are always shown. Off by default.");
			CombineStacks = config.Bind<bool>("General", "CombineStacks", false, "When enabled, merge identical items into one row with a total count (same name, quality, and variant). When disabled, each inventory stack is listed separately. Off by default.");
			UiPositionX = config.Bind<float>("UI", "PositionX", 0.72f, new ConfigDescription("Horizontal screen position of the overlay (0 = left edge, 1 = right edge). Anchor is the panel center.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			UiPositionY = config.Bind<float>("UI", "PositionY", 0.55f, new ConfigDescription("Vertical screen position of the overlay (0 = bottom edge, 1 = top edge). Anchor is the panel center.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			UiAlpha = config.Bind<float>("UI", "Alpha", 0.92f, new ConfigDescription("Overlay transparency (0 = invisible, 1 = fully opaque).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
			ShowItemImages = config.Bind<bool>("UI", "ShowItemImages", true, "When enabled, show item icons to the left of each name/count. On by default.");
			MinPanelWidth = config.Bind<float>("UI", "MinPanelWidth", 300f, new ConfigDescription("Minimum overlay panel width in UI pixels. Panel grows with the longest row up to MaxPanelWidth.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(200f, 600f), Array.Empty<object>()));
			MaxPanelWidth = config.Bind<float>("UI", "MaxPanelWidth", 470f, new ConfigDescription("Maximum overlay panel width in UI pixels. Longer item names are clipped beyond this.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(250f, 800f), Array.Empty<object>()));
		}
	}
	[BepInPlugin("ModdedWolf.Chest_List", "Chest_List", "1.0.0")]
	public class ChestListPlugin : BaseUnityPlugin
	{
		public const string GUID = "ModdedWolf.Chest_List";

		public const string NAME = "Chest_List";

		public const string VERSION = "1.0.0";

		internal static ChestListPlugin Instance;

		internal static ManualLogSource Log;

		private Harmony _harmony;

		private GameObject _overlayRoot;

		private void Awake()
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			ChestListConfig.Init(((BaseUnityPlugin)this).Config);
			_harmony = new Harmony("ModdedWolf.Chest_List");
			_harmony.PatchAll();
			_overlayRoot = new GameObject("Chest_List_Overlay");
			_overlayRoot.AddComponent<ChestListOverlay>();
			Object.DontDestroyOnLoad((Object)(object)_overlayRoot);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Chest_List v1.0.0 loaded.");
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			_harmony = null;
			if ((Object)(object)_overlayRoot != (Object)null)
			{
				Object.Destroy((Object)(object)_overlayRoot);
				_overlayRoot = null;
			}
			Instance = null;
		}
	}
	internal static class ChestTarget
	{
		internal static Container Current { get; private set; }

		internal static void SetFromHoverObject(GameObject hover)
		{
			Current = ResolveContainer(hover);
		}

		internal static void Clear()
		{
			Current = null;
		}

		internal static Container ResolveContainer(GameObject hover)
		{
			if ((Object)(object)hover == (Object)null)
			{
				return null;
			}
			Container componentInParent = hover.GetComponentInParent<Container>();
			if ((Object)(object)componentInParent == (Object)null || !IsValidContainer(componentInParent))
			{
				return null;
			}
			if (!ShouldShow(componentInParent))
			{
				return null;
			}
			return componentInParent;
		}

		internal static bool IsValidContainer(Container container)
		{
			if ((Object)(object)container == (Object)null)
			{
				return false;
			}
			ZNetView nview = container.m_nview;
			if ((Object)(object)nview != (Object)null && !nview.IsValid())
			{
				return false;
			}
			return container.GetInventory() != null;
		}

		internal static bool IsPlayerPlaced(Container container)
		{
			if ((Object)(object)container == (Object)null)
			{
				return false;
			}
			Piece val = container.m_piece;
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)container).GetComponent<Piece>();
			}
			if ((Object)(object)val == (Object)null)
			{
				val = ((Component)container).GetComponentInParent<Piece>();
			}
			if ((Object)(object)val != (Object)null)
			{
				return val.IsPlacedByPlayer();
			}
			return false;
		}

		internal static bool ShouldShow(Container container)
		{
			if (IsPlayerPlaced(container))
			{
				return true;
			}
			return ChestListConfig.EnableWorldGeneratedChests.Value;
		}

		internal static bool CanPreview(Container container, Player player)
		{
			if ((Object)(object)container == (Object)null || (Object)(object)player == (Object)null)
			{
				return false;
			}
			if (!IsValidContainer(container))
			{
				return false;
			}
			if (!ShouldShow(container))
			{
				return false;
			}
			try
			{
				if (!container.CheckAccess(player.GetPlayerID()))
				{
					return false;
				}
			}
			catch
			{
				return false;
			}
			return true;
		}
	}
}
namespace Chest_List.UI
{
	internal sealed class ChestListOverlay : MonoBehaviour
	{
		private sealed class DisplayEntry
		{
			public ItemData Item;

			public int Stack;
		}

		private sealed class RowWidgets
		{
			public GameObject Root;

			public RectTransform Rect;

			public LayoutElement Layout;

			public Image Icon;

			public TextMeshProUGUI Label;
		}

		private readonly struct InvisibleMeasureScope : IDisposable
		{
			private readonly ChestListOverlay _owner;

			private readonly bool _restoreAlpha;

			private readonly float _previousAlpha;

			public InvisibleMeasureScope(ChestListOverlay owner, bool restoreAlpha, float previousAlpha)
			{
				_owner = owner;
				_restoreAlpha = restoreAlpha;
				_previousAlpha = previousAlpha;
			}

			public void Dispose()
			{
				if (!((Object)(object)_owner == (Object)null) && _restoreAlpha && Alive((Object)(object)_owner._canvasGroup))
				{
					_owner._canvasGroup.alpha = _previousAlpha;
				}
			}
		}

		private const float DefaultMinPanelWidth = 300f;

		private const float DefaultMaxPanelWidth = 470f;

		private const float ContentRightPad = 28f;

		private const float TitleHeight = 34f;

		private const float TitleGap = 4f;

		private const float RowHeight = 31f;

		private const float IconSize = 27f;

		private const float TitleFontSize = 25f;

		private const float ItemFontSize = 21f;

		private const float MaxPanelHeight = 450f;

		private const float MinPad = 16f;

		private const float InnerPad = 4f;

		private const float ScrollSensitivity = 40f;

		private Canvas _canvas;

		private CanvasGroup _canvasGroup;

		private RectTransform _panel;

		private Image _panelImage;

		private RectTransform _content;

		private RectTransform _titleRt;

		private TextMeshProUGUI _title;

		private RectTransform _scrollRt;

		private RectTransform _viewport;

		private ScrollRect _scrollRect;

		private RectTransform _listRoot;

		private readonly List<RowWidgets> _rows = new List<RowWidgets>(64);

		private readonly List<DisplayEntry> _displayEntries = new List<DisplayEntry>(64);

		private readonly Dictionary<string, int> _mergeIndexByKey = new Dictionary<string, int>(64);

		private readonly StringBuilder _labelBuilder = new StringBuilder(64);

		private readonly StringBuilder _keyBuilder = new StringBuilder(64);

		private Container _boundContainer;

		private int _boundRevision = -1;

		private bool _boundShowIcons;

		private bool _boundCombineStacks;

		private float _boundMinPanelWidth = -1f;

		private float _boundMaxPanelWidth = -1f;

		private bool _uiBuilt;

		private float _panelWidth = 300f;

		private int _remeasureAfterFrame = -1;

		private float _remeasurePanelHeight;

		private float _padL = 16f;

		private float _padR = 16f;

		private float _padT = 16f;

		private float _padB = 16f;

		private static TMP_FontAsset _cachedFont;

		private static Material _cachedFontMaterial;

		private static float _cachedFontSize = 16f;

		private static Color _cachedFontColor = new Color(1f, 0.984f, 0.875f, 1f);

		private static Sprite _cachedPanelSprite;

		private static Material _cachedPanelMaterial;

		private static Color _cachedPanelColor = Color.white;

		private static Type _cachedPanelType = (Type)1;

		private void Update()
		{
			try
			{
				Tick();
			}
			catch (Exception arg)
			{
				ManualLogSource log = ChestListPlugin.Log;
				if (log != null)
				{
					log.LogError((object)$"ChestListOverlay tick failed: {arg}");
				}
				SafeHide();
			}
		}

		private void Tick()
		{
			if (!_uiBuilt)
			{
				if (!TryResolveGameFont(out var _, out var material, out var _, out var color) || !TryResolveInventoryPanelStyle(out var _, out material, out color, out var _))
				{
					return;
				}
				BuildUi();
				_uiBuilt = true;
				SafeHide();
			}
			if (!Alive((Object)(object)_canvas) || !Alive((Object)(object)_panel) || !Alive((Object)(object)_canvasGroup))
			{
				_uiBuilt = false;
				return;
			}
			if (!TryGetPreviewTarget(out var container, out var inventory))
			{
				SafeHide();
				return;
			}
			ApplyLayoutAndAlpha();
			RefreshContents(container, inventory);
			TryDeferredWidthRemeasure();
			HandleMouseWheelScroll();
			SafeShow();
		}

		private void OnDestroy()
		{
			_rows.Clear();
			_uiBuilt = false;
			_boundContainer = null;
		}

		private static bool TryGetPreviewTarget(out Container container, out Inventory inventory)
		{
			container = null;
			inventory = null;
			Player localPlayer = Player.m_localPlayer;
			if (!Alive((Object)(object)localPlayer))
			{
				return false;
			}
			if (ShouldHideForMenus())
			{
				return false;
			}
			container = ChestTarget.Current;
			if (!ChestTarget.CanPreview(container, localPlayer))
			{
				GameObject val = null;
				try
				{
					val = ((Humanoid)localPlayer).GetHoverObject();
				}
				catch
				{
					return false;
				}
				container = ChestTarget.ResolveContainer(val);
				if (!ChestTarget.CanPreview(container, localPlayer))
				{
					return false;
				}
			}
			if (!Alive((Object)(object)container))
			{
				return false;
			}
			try
			{
				inventory = container.GetInventory();
			}
			catch
			{
				return false;
			}
			return inventory != null;
		}

		private static bool ShouldHideForMenus()
		{
			try
			{
				if (InventoryGui.IsVisible())
				{
					return true;
				}
				if (Menu.IsVisible())
				{
					return true;
				}
				if (Alive((Object)(object)TextViewer.instance) && TextViewer.instance.IsVisible())
				{
					return true;
				}
				if (Console.IsVisible())
				{
					return true;
				}
				if (Alive((Object)(object)Chat.instance) && Chat.instance.HasFocus())
				{
					return true;
				}
				if (StoreGui.IsVisible())
				{
					return true;
				}
			}
			catch
			{
				return true;
			}
			return false;
		}

		private void BuildUi()
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Expected O, but got Unknown
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Expected O, but got Unknown
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f5: Expected O, but got Unknown
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_0329: Unknown result type (might be due to invalid IL or missing references)
			//IL_0343: Unknown result type (might be due to invalid IL or missing references)
			//IL_0353: Unknown result type (might be due to invalid IL or missing references)
			//IL_036d: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b2: Expected O, but got Unknown
			//IL_040d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0414: Expected O, but got Unknown
			//IL_0444: Unknown result type (might be due to invalid IL or missing references)
			//IL_045e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0478: Unknown result type (might be due to invalid IL or missing references)
			//IL_0488: Unknown result type (might be due to invalid IL or missing references)
			//IL_0498: Unknown result type (might be due to invalid IL or missing references)
			//IL_04db: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e5: Expected O, but got Unknown
			_canvas = ((Component)this).gameObject.AddComponent<Canvas>();
			_canvas.renderMode = (RenderMode)0;
			_canvas.sortingOrder = 80;
			CanvasScaler obj = ((Component)this).gameObject.AddComponent<CanvasScaler>();
			obj.uiScaleMode = (ScaleMode)1;
			obj.referenceResolution = new Vector2(1920f, 1080f);
			obj.matchWidthOrHeight = 0.5f;
			((Behaviour)((Component)this).gameObject.AddComponent<GraphicRaycaster>()).enabled = false;
			_canvasGroup = ((Component)this).gameObject.AddComponent<CanvasGroup>();
			_canvasGroup.blocksRaycasts = false;
			_canvasGroup.interactable = false;
			GameObject val = new GameObject("Panel", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val.transform.SetParent(((Component)this).transform, false);
			_panel = val.GetComponent<RectTransform>();
			_panel.anchorMin = new Vector2(0.5f, 0.5f);
			_panel.anchorMax = new Vector2(0.5f, 0.5f);
			_panel.pivot = new Vector2(0.5f, 0.5f);
			_panel.sizeDelta = new Vector2(_panelWidth, 120f);
			_panelImage = val.GetComponent<Image>();
			ApplyInventoryPanelStyle(_panelImage);
			((Graphic)_panelImage).raycastTarget = false;
			ResolvePaddingFromSprite(_panelImage.sprite);
			GameObject val2 = new GameObject("Content", new Type[1] { typeof(RectTransform) });
			val2.transform.SetParent((Transform)(object)_panel, false);
			_content = val2.GetComponent<RectTransform>();
			ApplyContentInsets();
			_title = CreateGameTmp("Title", (Transform)(object)_content, isTitle: true);
			_titleRt = ((TMP_Text)_title).rectTransform;
			_titleRt.anchorMin = new Vector2(0f, 1f);
			_titleRt.anchorMax = new Vector2(1f, 1f);
			_titleRt.pivot = new Vector2(0.5f, 1f);
			_titleRt.anchoredPosition = Vector2.zero;
			_titleRt.sizeDelta = new Vector2(0f, 34f);
			((TMP_Text)_title).alignment = (TextAlignmentOptions)514;
			((Graphic)_title).raycastTarget = false;
			((MaskableGraphic)_title).maskable = false;
			((TMP_Text)_title).overflowMode = (TextOverflowModes)0;
			((TMP_Text)_title).textWrappingMode = (TextWrappingModes)0;
			((TMP_Text)_title).enableAutoSizing = false;
			((TMP_Text)_title).text = "Chest";
			((Component)_title).gameObject.SetActive(true);
			GameObject val3 = new GameObject("Scroll", new Type[2]
			{
				typeof(RectTransform),
				typeof(ScrollRect)
			});
			val3.transform.SetParent((Transform)(object)_content, false);
			_scrollRt = val3.GetComponent<RectTransform>();
			_scrollRt.anchorMin = Vector2.zero;
			_scrollRt.anchorMax = Vector2.one;
			_scrollRt.pivot = new Vector2(0.5f, 1f);
			_scrollRt.offsetMin = Vector2.zero;
			_scrollRt.offsetMax = new Vector2(0f, -38f);
			((TMP_Text)_title).transform.SetAsFirstSibling();
			GameObject val4 = new GameObject("Viewport", new Type[2]
			{
				typeof(RectTransform),
				typeof(RectMask2D)
			});
			val4.transform.SetParent(val3.transform, false);
			_viewport = val4.GetComponent<RectTransform>();
			StretchFull(_viewport);
			GameObject val5 = new GameObject("List", new Type[3]
			{
				typeof(RectTransform),
				typeof(VerticalLayoutGroup),
				typeof(ContentSizeFitter)
			});
			val5.transform.SetParent(val4.transform, false);
			_listRoot = val5.GetComponent<RectTransform>();
			_listRoot.anchorMin = new Vector2(0f, 1f);
			_listRoot.anchorMax = new Vector2(1f, 1f);
			_listRoot.pivot = new Vector2(0.5f, 1f);
			_listRoot.anchoredPosition = Vector2.zero;
			_listRoot.sizeDelta = Vector2.zero;
			VerticalLayoutGroup component = val5.GetComponent<VerticalLayoutGroup>();
			((LayoutGroup)component).childAlignment = (TextAnchor)0;
			((HorizontalOrVerticalLayoutGroup)component).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)component).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)component).childForceExpandWidth = true;
			((HorizontalOrVerticalLayoutGroup)component).childForceExpandHeight = false;
			((HorizontalOrVerticalLayoutGroup)component).spacing = 0f;
			((LayoutGroup)component).padding = new RectOffset(0, 0, 0, 0);
			ContentSizeFitter component2 = val5.GetComponent<ContentSizeFitter>();
			component2.horizontalFit = (FitMode)0;
			component2.verticalFit = (FitMode)2;
			_scrollRect = val3.GetComponent<ScrollRect>();
			_scrollRect.content = _listRoot;
			_scrollRect.viewport = _viewport;
			_scrollRect.horizontal = false;
			_scrollRect.vertical = true;
			_scrollRect.movementType = (MovementType)2;
			_scrollRect.inertia = true;
			_scrollRect.decelerationRate = 0.135f;
			_scrollRect.scrollSensitivity = 40f;
			_scrollRect.verticalScrollbar = null;
			_scrollRect.horizontalScrollbar = null;
			ApplyPanelSize(_panelWidth, GetMinPanelHeight());
		}

		private float GetTitleBlockHeight()
		{
			return 38f;
		}

		private float GetBorderChromeHeight()
		{
			return _padT + _padB;
		}

		private float GetMinPanelHeight()
		{
			return GetBorderChromeHeight() + GetTitleBlockHeight() + 31f;
		}

		private float GetMaxPanelHeight()
		{
			return Mathf.Max(450f, GetMinPanelHeight());
		}

		private float GetMinPanelWidth()
		{
			float num = 300f;
			try
			{
				if (ChestListConfig.MinPanelWidth != null)
				{
					num = ChestListConfig.MinPanelWidth.Value;
				}
			}
			catch
			{
			}
			return Mathf.Clamp(num, 200f, 600f);
		}

		private float GetMaxPanelWidth()
		{
			float num = 470f;
			try
			{
				if (ChestListConfig.MaxPanelWidth != null)
				{
					num = ChestListConfig.MaxPanelWidth.Value;
				}
			}
			catch
			{
			}
			num = Mathf.Clamp(num, 250f, 800f);
			return Mathf.Max(num, GetMinPanelWidth());
		}

		private void ApplyLayoutAndAlpha()
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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_006c: 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_007c: 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_00b9: 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)
			float num = Mathf.Clamp01(ChestListConfig.UiPositionX.Value);
			float num2 = Mathf.Clamp01(ChestListConfig.UiPositionY.Value);
			float alpha = Mathf.Clamp01(ChestListConfig.UiAlpha.Value);
			Transform parent = ((Transform)_panel).parent;
			RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null);
			? val2;
			if (!((Object)(object)val != (Object)null))
			{
				val2 = new Vector2((float)Screen.width, (float)Screen.height);
			}
			else
			{
				Rect rect = val.rect;
				val2 = ((Rect)(ref rect)).size;
			}
			Vector2 val3 = (Vector2)val2;
			if (val3.x <= 1f || val3.y <= 1f)
			{
				((Vector2)(ref val3))..ctor((float)Screen.width, (float)Screen.height);
			}
			_panel.anchoredPosition = new Vector2((num - 0.5f) * val3.x, (num2 - 0.5f) * val3.y);
			if (Alive((Object)(object)_canvasGroup))
			{
				_canvasGroup.alpha = alpha;
			}
		}

		private void RefreshContents(Container container, Inventory inventory)
		{
			//IL_037a: 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_034a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: 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)
			if (!Alive((Object)(object)container) || inventory == null || !Alive((Object)(object)_title) || !Alive((Object)(object)_listRoot) || !Alive((Object)(object)_scrollRect))
			{
				return;
			}
			int num;
			try
			{
				num = inventory.NrOfItems();
			}
			catch
			{
				return;
			}
			bool value = ChestListConfig.ShowItemImages.Value;
			bool value2 = ChestListConfig.CombineStacks.Value;
			float minPanelWidth = GetMinPanelWidth();
			float maxPanelWidth = GetMaxPanelWidth();
			if (container == _boundContainer && num == _boundRevision && value == _boundShowIcons && value2 == _boundCombineStacks && Mathf.Approximately(minPanelWidth, _boundMinPanelWidth) && Mathf.Approximately(maxPanelWidth, _boundMaxPanelWidth))
			{
				return;
			}
			_boundContainer = container;
			_boundRevision = num;
			_boundShowIcons = value;
			_boundCombineStacks = value2;
			_boundMinPanelWidth = minPanelWidth;
			_boundMaxPanelWidth = maxPanelWidth;
			List<ItemData> list;
			try
			{
				list = inventory.GetAllItemsInGridOrder();
			}
			catch
			{
				return;
			}
			if (list == null)
			{
				list = new List<ItemData>();
			}
			BuildDisplayEntries(list, value2);
			float borderChromeHeight = GetBorderChromeHeight();
			float titleBlockHeight = GetTitleBlockHeight();
			float minPanelHeight = GetMinPanelHeight();
			float num2 = GetMaxPanelHeight() - borderChromeHeight - titleBlockHeight;
			if (num2 < 31f)
			{
				num2 = 31f;
			}
			int count = _displayEntries.Count;
			float num3 = (float)count * 31f;
			float num4 = Mathf.Min(Mathf.Max(num3, 31f), num2);
			float num5 = borderChromeHeight + titleBlockHeight + num4;
			if (num5 < minPanelHeight)
			{
				num5 = minPanelHeight;
				num4 = num5 - borderChromeHeight - titleBlockHeight;
			}
			if (Alive((Object)(object)_title))
			{
				if (Alive((Object)(object)((Component)_title).gameObject) && !((Component)_title).gameObject.activeSelf)
				{
					((Component)_title).gameObject.SetActive(true);
				}
				((TMP_Text)_title).text = GetContainerTitle(container);
			}
			EnsureRowCount(count);
			for (int i = 0; i < _rows.Count; i++)
			{
				RowWidgets rowWidgets = _rows[i];
				if (!Alive((Object)(object)rowWidgets.Root))
				{
					continue;
				}
				if (i >= count)
				{
					rowWidgets.Root.SetActive(false);
					continue;
				}
				rowWidgets.Root.SetActive(true);
				if (Alive((Object)(object)rowWidgets.Layout))
				{
					rowWidgets.Layout.preferredHeight = 31f;
					rowWidgets.Layout.minHeight = 31f;
				}
				((TMP_Text)rowWidgets.Label).fontStyle = (FontStyles)0;
				DisplayEntry displayEntry = _displayEntries[i];
				ItemData val = displayEntry?.Item;
				if (val == null || val.m_shared == null)
				{
					((Component)rowWidgets.Icon).gameObject.SetActive(false);
					((TMP_Text)rowWidgets.Label).margin = Vector4.zero;
					((TMP_Text)rowWidgets.Label).text = string.Empty;
					continue;
				}
				if (value)
				{
					Sprite val2 = null;
					try
					{
						val2 = val.GetIcon();
					}
					catch
					{
						val2 = null;
					}
					bool flag = (Object)(object)val2 != (Object)null;
					((Behaviour)rowWidgets.Icon).enabled = flag;
					rowWidgets.Icon.sprite = val2;
					((Component)rowWidgets.Icon).gameObject.SetActive(flag);
					if (flag && Alive((Object)(object)((Graphic)rowWidgets.Icon).rectTransform))
					{
						((Graphic)rowWidgets.Icon).rectTransform.sizeDelta = new Vector2(27f, 27f);
					}
					((TMP_Text)rowWidgets.Label).margin = (Vector4)(flag ? new Vector4(35f, 0f, 0f, 0f) : Vector4.zero);
				}
				else
				{
					((Component)rowWidgets.Icon).gameObject.SetActive(false);
					((TMP_Text)rowWidgets.Label).margin = Vector4.zero;
				}
				((TMP_Text)rowWidgets.Label).text = FormatItemLabel(val, displayEntry.Stack);
			}
			RelayoutPanelWidth(value, count, num5, scheduleDeferredRemeasure: true);
			bool enabled = num3 > num4 + 0.5f;
			if (Alive((Object)(object)_scrollRect))
			{
				((Behaviour)_scrollRect).enabled = enabled;
				_scrollRect.verticalNormalizedPosition = 1f;
			}
			ApplyLayoutAndAlpha();
		}

		private float RelayoutPanelWidth(bool showIcons, int total, float panelHeight, bool scheduleDeferredRemeasure)
		{
			EnsureFontsAppliedForMeasure(total);
			using (BeginInvisibleMeasureScope())
			{
				Canvas.ForceUpdateCanvases();
				float num = MeasurePanelWidth(showIcons, total);
				Canvas.ForceUpdateCanvases();
				num = Mathf.Max(num, MeasurePanelWidth(showIcons, total));
				ApplyPanelSize(num, panelHeight);
				if (Alive((Object)(object)_listRoot))
				{
					LayoutRebuilder.ForceRebuildLayoutImmediate(_listRoot);
				}
				if (scheduleDeferredRemeasure)
				{
					_remeasurePanelHeight = panelHeight;
					_remeasureAfterFrame = Time.frameCount + 1;
				}
				return num;
			}
		}

		private void TryDeferredWidthRemeasure()
		{
			if (_remeasureAfterFrame >= 0 && Time.frameCount >= _remeasureAfterFrame)
			{
				_remeasureAfterFrame = -1;
				if (Alive((Object)(object)_panel) && Alive((Object)(object)((Component)_panel).gameObject) && ((Component)_panel).gameObject.activeSelf)
				{
					int count = _displayEntries.Count;
					RelayoutPanelWidth(_boundShowIcons, count, _remeasurePanelHeight, scheduleDeferredRemeasure: false);
				}
			}
		}

		private InvisibleMeasureScope BeginInvisibleMeasureScope()
		{
			float previousAlpha = (Alive((Object)(object)_canvasGroup) ? _canvasGroup.alpha : 1f);
			bool num = Alive((Object)(object)_panel) && ((Component)_panel).gameObject.activeSelf;
			bool flag = Alive((Object)(object)_canvas) && ((Behaviour)_canvas).enabled;
			if (!num || !flag)
			{
				if (Alive((Object)(object)_canvasGroup))
				{
					_canvasGroup.alpha = 0f;
				}
				if (Alive((Object)(object)_canvas) && !((Behaviour)_canvas).enabled)
				{
					((Behaviour)_canvas).enabled = true;
				}
				if (Alive((Object)(object)_panel) && !((Component)_panel).gameObject.activeSelf)
				{
					((Component)_panel).gameObject.SetActive(true);
				}
				return new InvisibleMeasureScope(this, restoreAlpha: true, previousAlpha);
			}
			return new InvisibleMeasureScope(this, restoreAlpha: false, previousAlpha);
		}

		private void EnsureFontsAppliedForMeasure(int total)
		{
			if (!TryResolveGameFont(out var _, out var _, out var _, out var _))
			{
				return;
			}
			if (Alive((Object)(object)_title) && (!Alive((Object)(object)((TMP_Text)_title).font) || IsLiberation(((TMP_Text)_title).font)))
			{
				ApplyGameFont(_title, isTitle: true);
			}
			for (int i = 0; i < total && i < _rows.Count; i++)
			{
				TextMeshProUGUI label = _rows[i].Label;
				if (Alive((Object)(object)label) && (!Alive((Object)(object)((TMP_Text)label).font) || IsLiberation(((TMP_Text)label).font)))
				{
					ApplyGameFont(label, isTitle: false);
				}
			}
		}

		private float MeasurePanelWidth(bool showIcons, int total)
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			float num = 0f;
			float minPanelWidth = GetMinPanelWidth();
			float maxPanelWidth = GetMaxPanelWidth();
			if (Alive((Object)(object)_title) && !string.IsNullOrEmpty(((TMP_Text)_title).text))
			{
				PrepareTmpForMeasure(_title);
				num = Mathf.Max(num, ((TMP_Text)_title).GetPreferredValues(((TMP_Text)_title).text).x);
			}
			for (int i = 0; i < total && i < _rows.Count; i++)
			{
				RowWidgets rowWidgets = _rows[i];
				if (Alive((Object)(object)rowWidgets.Label) && !string.IsNullOrEmpty(((TMP_Text)rowWidgets.Label).text))
				{
					Vector4 margin = ((TMP_Text)rowWidgets.Label).margin;
					((TMP_Text)rowWidgets.Label).margin = Vector4.zero;
					PrepareTmpForMeasure(rowWidgets.Label);
					float x = ((TMP_Text)rowWidgets.Label).GetPreferredValues(((TMP_Text)rowWidgets.Label).text).x;
					((TMP_Text)rowWidgets.Label).margin = margin;
					float num2 = 0f;
					if (showIcons && Alive((Object)(object)rowWidgets.Icon) && ((Component)rowWidgets.Icon).gameObject.activeSelf)
					{
						num2 = 35f;
					}
					num = Mathf.Max(num, num2 + x);
				}
			}
			if (num <= 0.5f)
			{
				return minPanelWidth;
			}
			return Mathf.Clamp(num + _padL + _padR + 28f, minPanelWidth, maxPanelWidth);
		}

		private static void PrepareTmpForMeasure(TextMeshProUGUI tmp)
		{
			if (Alive((Object)(object)tmp))
			{
				((TMP_Text)tmp).ForceMeshUpdate(true, false);
			}
		}

		private void ApplyPanelSize(float panelWidth, float panelHeight)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			if (Alive((Object)(object)_panel) && Alive((Object)(object)_content))
			{
				panelHeight = Mathf.Max(panelHeight, GetMinPanelHeight());
				panelWidth = Mathf.Clamp(panelWidth, GetMinPanelWidth(), GetMaxPanelWidth());
				_panelWidth = panelWidth;
				_panel.sizeDelta = new Vector2(panelWidth, panelHeight);
				ApplyContentInsets();
			}
		}

		private void ApplyContentInsets()
		{
			//IL_0014: 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_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			if (Alive((Object)(object)_content))
			{
				_content.anchorMin = Vector2.zero;
				_content.anchorMax = Vector2.one;
				_content.offsetMin = new Vector2(_padL, _padB);
				_content.offsetMax = new Vector2(0f - _padR, 0f - _padT);
			}
		}

		private void ResolvePaddingFromSprite(Sprite sprite)
		{
			//IL_0021: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			float num = 16f;
			float num2 = 16f;
			float num3 = 16f;
			float num4 = 16f;
			if (Alive((Object)(object)sprite))
			{
				Vector4 border = sprite.border;
				float pixelsPerUnit = ((sprite.pixelsPerUnit > 0.01f) ? sprite.pixelsPerUnit : 1f);
				num = BorderToPad(border.x, pixelsPerUnit);
				num2 = BorderToPad(border.y, pixelsPerUnit);
				num3 = BorderToPad(border.z, pixelsPerUnit);
				num4 = BorderToPad(border.w, pixelsPerUnit);
			}
			_padL = num + 4f;
			_padR = num3 + 4f;
			_padT = num4 + 4f;
			_padB = num2 + 4f;
		}

		private static float BorderToPad(float borderPixels, float pixelsPerUnit)
		{
			float num = borderPixels / pixelsPerUnit;
			if (num < 4f && borderPixels >= 16f)
			{
				num = borderPixels;
			}
			return Mathf.Max(16f, num);
		}

		private void EnsureRowCount(int count)
		{
			while (_rows.Count < count)
			{
				_rows.Add(CreateRow(_rows.Count));
			}
		}

		private RowWidgets CreateRow(int index)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: 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_00e0: 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_0100: 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_011e: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject($"Row_{index}", new Type[2]
			{
				typeof(RectTransform),
				typeof(LayoutElement)
			});
			val.transform.SetParent((Transform)(object)_listRoot, false);
			val.SetActive(false);
			RectTransform component = val.GetComponent<RectTransform>();
			LayoutElement component2 = val.GetComponent<LayoutElement>();
			component2.preferredHeight = 31f;
			component2.minHeight = 31f;
			component2.flexibleWidth = 1f;
			GameObject val2 = new GameObject("Icon", new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val2.transform.SetParent(val.transform, false);
			RectTransform component3 = val2.GetComponent<RectTransform>();
			component3.anchorMin = new Vector2(0f, 0.5f);
			component3.anchorMax = new Vector2(0f, 0.5f);
			component3.pivot = new Vector2(0f, 0.5f);
			component3.anchoredPosition = Vector2.zero;
			component3.sizeDelta = new Vector2(27f, 27f);
			Image component4 = val2.GetComponent<Image>();
			component4.preserveAspect = true;
			((Graphic)component4).raycastTarget = false;
			((MaskableGraphic)component4).maskable = true;
			val2.SetActive(false);
			TextMeshProUGUI val3 = CreateGameTmp("Label", val.transform, isTitle: false);
			StretchFull(((TMP_Text)val3).rectTransform);
			((TMP_Text)val3).alignment = (TextAlignmentOptions)4097;
			((Graphic)val3).raycastTarget = false;
			((MaskableGraphic)val3).maskable = true;
			((TMP_Text)val3).overflowMode = (TextOverflowModes)0;
			((TMP_Text)val3).textWrappingMode = (TextWrappingModes)0;
			((Component)val3).gameObject.SetActive(true);
			val.SetActive(true);
			return new RowWidgets
			{
				Root = val,
				Rect = component,
				Layout = component2,
				Icon = component4,
				Label = val3
			};
		}

		private void BuildDisplayEntries(List<ItemData> items, bool combineStacks)
		{
			_displayEntries.Clear();
			_mergeIndexByKey.Clear();
			if (items == null || items.Count == 0)
			{
				return;
			}
			if (!combineStacks)
			{
				for (int i = 0; i < items.Count; i++)
				{
					ItemData val = items[i];
					if (val != null)
					{
						_displayEntries.Add(new DisplayEntry
						{
							Item = val,
							Stack = val.m_stack
						});
					}
				}
				return;
			}
			for (int j = 0; j < items.Count; j++)
			{
				ItemData val2 = items[j];
				if (val2 != null && val2.m_shared != null)
				{
					string key = BuildMergeKey(val2);
					if (_mergeIndexByKey.TryGetValue(key, out var value))
					{
						_displayEntries[value].Stack += val2.m_stack;
						continue;
					}
					_mergeIndexByKey[key] = _displayEntries.Count;
					_displayEntries.Add(new DisplayEntry
					{
						Item = val2,
						Stack = val2.m_stack
					});
				}
			}
		}

		private string BuildMergeKey(ItemData item)
		{
			_keyBuilder.Length = 0;
			string text = ((item.m_shared != null) ? item.m_shared.m_name : string.Empty);
			_keyBuilder.Append(text ?? string.Empty);
			_keyBuilder.Append('|');
			_keyBuilder.Append(item.m_quality);
			_keyBuilder.Append('|');
			_keyBuilder.Append(item.m_variant);
			_keyBuilder.Append('|');
			_keyBuilder.Append(item.m_worldLevel);
			return _keyBuilder.ToString();
		}

		private static string GetContainerTitle(Container container)
		{
			if (!Alive((Object)(object)container))
			{
				return "Chest";
			}
			try
			{
				if (container != null)
				{
					string hoverName = ((Hoverable)container).GetHoverName();
					if (!string.IsNullOrEmpty(hoverName))
					{
						return Localize(hoverName);
					}
				}
			}
			catch
			{
			}
			string name = container.m_name;
			if (!string.IsNullOrEmpty(name))
			{
				return Localize(name);
			}
			try
			{
				Inventory inventory = container.GetInventory();
				if (inventory != null)
				{
					string name2 = inventory.GetName();
					if (!string.IsNullOrEmpty(name2))
					{
						return Localize(name2);
					}
				}
			}
			catch
			{
			}
			try
			{
				Piece val = container.m_piece;
				if (!Alive((Object)(object)val))
				{
					val = ((Component)container).GetComponentInParent<Piece>();
				}
				if (Alive((Object)(object)val) && !string.IsNullOrEmpty(val.m_name))
				{
					return Localize(val.m_name);
				}
			}
			catch
			{
			}
			return "Chest";
		}

		private string FormatItemLabel(ItemData item, int stack)
		{
			_labelBuilder.Length = 0;
			if (item == null || item.m_shared == null)
			{
				return string.Empty;
			}
			string value = Localize(item.m_shared.m_name);
			_labelBuilder.Append(value);
			if (stack > 1)
			{
				_labelBuilder.Append("  x").Append(stack);
			}
			if (item.m_quality > 1)
			{
				_labelBuilder.Append("  [Q").Append(item.m_quality).Append(']');
			}
			return _labelBuilder.ToString();
		}

		private static string Localize(string token)
		{
			if (string.IsNullOrEmpty(token))
			{
				return string.Empty;
			}
			if (Localization.instance != null)
			{
				return Localization.instance.Localize(token);
			}
			return token;
		}

		private static void ApplyInventoryPanelStyle(Image target)
		{
			//IL_0021: 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)
			if (Alive((Object)(object)target) && TryResolveInventoryPanelStyle(out var sprite, out var material, out var color, out var type))
			{
				target.sprite = sprite;
				target.type = type;
				((Graphic)target).color = color;
				if (Alive((Object)(object)material))
				{
					((Graphic)target).material = material;
				}
				target.preserveAspect = false;
				target.fillCenter = true;
			}
		}

		private static bool TryResolveInventoryPanelStyle(out Sprite sprite, out Material material, out Color color, out Type type)
		{
			//IL_0007: 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_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected I4, but got Unknown
			//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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected I4, but got Unknown
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: 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_0136: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			sprite = null;
			material = null;
			color = _cachedPanelColor;
			type = (Type)(int)_cachedPanelType;
			if (Alive((Object)(object)_cachedPanelSprite))
			{
				sprite = _cachedPanelSprite;
				material = (Alive((Object)(object)_cachedPanelMaterial) ? _cachedPanelMaterial : null);
				color = _cachedPanelColor;
				type = (Type)(int)_cachedPanelType;
				return true;
			}
			_cachedPanelSprite = null;
			_cachedPanelMaterial = null;
			InventoryGui instance = InventoryGui.instance;
			if (!Alive((Object)(object)instance))
			{
				return false;
			}
			Image best = null;
			int bestScore = int.MinValue;
			if (Alive((Object)(object)instance.m_player))
			{
				ScorePanelImages((Component)(object)instance.m_player, preferPlayer: true, ref best, ref bestScore);
			}
			if (Alive((Object)(object)instance.m_container))
			{
				ScorePanelImages((Component)(object)instance.m_container, preferPlayer: false, ref best, ref bestScore);
			}
			if (Alive((Object)(object)instance.m_inventoryRoot))
			{
				ScorePanelImages((Component)(object)instance.m_inventoryRoot, preferPlayer: false, ref best, ref bestScore);
			}
			if (!Alive((Object)(object)best) || !Alive((Object)(object)best.sprite))
			{
				return false;
			}
			sprite = best.sprite;
			material = (Alive((Object)(object)((Graphic)best).material) ? ((Graphic)best).material : null);
			color = ((((Graphic)best).color.a > 0.01f) ? ((Graphic)best).color : Color.white);
			type = (Type)(((int)best.type == 0) ? 1 : ((int)best.type));
			Vector4 border = sprite.border;
			if (((Vector4)(ref border)).sqrMagnitude < 1f)
			{
				type = (Type)1;
			}
			CachePanelStyle(sprite, material, color, type);
			return true;
		}

		private static void ScorePanelImages(Component root, bool preferPlayer, ref Image best, ref int bestScore)
		{
			if (Alive((Object)(object)root))
			{
				ConsiderPanelImage(root.GetComponent<Image>(), preferPlayer, isRoot: true, ref best, ref bestScore);
				Image[] componentsInChildren = root.GetComponentsInChildren<Image>(true);
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					ConsiderPanelImage(componentsInChildren[i], preferPlayer, isRoot: false, ref best, ref bestScore);
				}
			}
		}

		private static void ConsiderPanelImage(Image img, bool preferPlayer, bool isRoot, ref Image best, ref int bestScore)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Invalid comparison between Unknown and I4
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Invalid comparison between Unknown and I4
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: 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_0164: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			if (!Alive((Object)(object)img) || !Alive((Object)(object)img.sprite) || !((Behaviour)img).enabled)
			{
				return;
			}
			RectTransform rectTransform = ((Graphic)img).rectTransform;
			Rect rect = rectTransform.rect;
			float num = Mathf.Abs(((Rect)(ref rect)).width);
			rect = rectTransform.rect;
			float num2 = Mathf.Abs(((Rect)(ref rect)).height);
			if (num > 1f && num2 > 1f && (num < 80f || num2 < 80f) && !isRoot && (int)img.type != 1)
			{
				return;
			}
			string value = ((Object)((Component)img).gameObject).name ?? string.Empty;
			string value2 = ((Object)img.sprite).name ?? string.Empty;
			if (!ContainsAny(value, "icon", "button", "slot", "selected", "glow", "arrow", "tab", "drag") && !ContainsAny(value2, "icon", "button", "slot", "arrow", "tab"))
			{
				int num3 = 0;
				if (preferPlayer)
				{
					num3 += 50;
				}
				if (isRoot)
				{
					num3 += 40;
				}
				if ((int)img.type == 1)
				{
					num3 += 80;
				}
				Vector4 border = img.sprite.border;
				float num4 = border.x + border.y + border.z + border.w;
				if (num4 >= 8f)
				{
					num3 += 60;
				}
				else if (num4 >= 1f)
				{
					num3 += 20;
				}
				if (ContainsAny(value, "bkg", "bg", "back", "panel", "wood", "inventory") || ContainsAny(value2, "bkg", "bg", "panel", "wood", "inventory", "chest"))
				{
					num3 += 100;
				}
				num3 += Mathf.Clamp(Mathf.RoundToInt((num + num2) * 0.05f), 0, 40);
				if (num3 > bestScore)
				{
					bestScore = num3;
					best = img;
				}
			}
		}

		private static void CachePanelStyle(Sprite sprite, Material material, Color color, Type type)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			_cachedPanelSprite = sprite;
			_cachedPanelMaterial = (Alive((Object)(object)material) ? material : null);
			_cachedPanelColor = color;
			_cachedPanelType = type;
			ManualLogSource log = ChestListPlugin.Log;
			if (log != null)
			{
				log.LogInfo((object)$"Using inventory panel sprite '{((Object)sprite).name}' type={type} border={sprite.border}");
			}
		}

		private static bool ContainsAny(string value, params string[] tokens)
		{
			if (string.IsNullOrEmpty(value))
			{
				return false;
			}
			for (int i = 0; i < tokens.Length; i++)
			{
				if (value.IndexOf(tokens[i], StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return true;
				}
			}
			return false;
		}

		private static TextMeshProUGUI CreateGameTmp(string name, Transform parent, bool isTitle)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) });
			val.SetActive(false);
			val.transform.SetParent(parent, false);
			TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>();
			ApplyGameFont(val2, isTitle);
			if (!Alive((Object)(object)((TMP_Text)val2).font) || IsLiberation(((TMP_Text)val2).font))
			{
				ApplyGameFont(val2, isTitle);
			}
			return val2;
		}

		private static void ApplyGameFont(TextMeshProUGUI text, bool isTitle)
		{
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			if (!Alive((Object)(object)text) || !TryResolveGameFont(out var font, out var material, out var _, out var color) || IsLiberation(font) || !Alive((Object)(object)font))
			{
				return;
			}
			((TMP_Text)text).font = font;
			if (Alive((Object)(object)material))
			{
				((TMP_Text)text).fontSharedMaterial = material;
			}
			else if (Alive((Object)(object)((TMP_Asset)font).material))
			{
				((TMP_Text)text).fontSharedMaterial = ((TMP_Asset)font).material;
			}
			if (Alive((Object)(object)((TMP_Text)text).font) && IsLiberation(((TMP_Text)text).font))
			{
				((TMP_Text)text).font = font;
				if (Alive((Object)(object)material))
				{
					((TMP_Text)text).fontSharedMaterial = material;
				}
			}
			((TMP_Text)text).fontSize = (isTitle ? 25f : 21f);
			((Graphic)text).color = (Color)(isTitle ? new Color(1f, 0.92f, 0.7f, 1f) : color);
			((TMP_Text)text).fontStyle = (FontStyles)0;
		}

		private void HandleMouseWheelScroll()
		{
			//IL_0048: 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_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			if (!Alive((Object)(object)_scrollRect) || !((Behaviour)_scrollRect).enabled || !Alive((Object)(object)_listRoot) || !Alive((Object)(object)_viewport) || !Alive((Object)(object)_panel))
			{
				return;
			}
			Rect rect = _listRoot.rect;
			float num = Mathf.Abs(((Rect)(ref rect)).height);
			rect = _viewport.rect;
			float num2 = Mathf.Abs(((Rect)(ref rect)).height);
			if (!(num <= num2 + 0.5f) && RectTransformUtility.RectangleContainsScreenPoint(_panel, Vector2.op_Implicit(Input.mousePosition), (Camera)null))
			{
				float axis = Input.GetAxis("Mouse ScrollWheel");
				if (!(Mathf.Abs(axis) < 0.0001f))
				{
					float num3 = num - num2;
					float num4 = axis * 40f / num3;
					_scrollRect.verticalNormalizedPosition = Mathf.Clamp01(_scrollRect.verticalNormalizedPosition + num4);
				}
			}
		}

		private static bool TryResolveGameFont(out TMP_FontAsset font, out Material material, out float size, out Color color)
		{
			//IL_000e: 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_00dd: 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_0057: 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)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			font = null;
			material = null;
			size = _cachedFontSize;
			color = _cachedFontColor;
			if (Alive((Object)(object)_cachedFont))
			{
				font = _cachedFont;
				material = (Alive((Object)(object)_cachedFontMaterial) ? _cachedFontMaterial : ((TMP_Asset)_cachedFont).material);
				size = _cachedFontSize;
				color = _cachedFontColor;
				return !IsLiberation(font);
			}
			_cachedFont = null;
			_cachedFontMaterial = null;
			InventoryGui instance = InventoryGui.instance;
			if (Alive((Object)(object)instance) && (TryTakeFont(instance.m_containerName, ref font, ref material, ref size, ref color) || TryTakeFont(instance.m_weight, ref font, ref material, ref size, ref color) || TryTakeFont(instance.m_containerWeight, ref font, ref material, ref size, ref color) || TryTakeFont(instance.m_playerName, ref font, ref material, ref size, ref color) || TryTakeFontFromChildren(((Component)instance).gameObject, ref font, ref material, ref size, ref color)))
			{
				CacheGameFont(font, material, size, color);
				return true;
			}
			if (Alive((Object)(object)Hud.instance) && TryTakeFontFromChildren(((Component)Hud.instance).gameObject, ref font, ref material, ref size, ref color))
			{
				CacheGameFont(font, material, size, color);
				return true;
			}
			TMP_FontAsset[] array = Resources.FindObjectsOfTypeAll<TMP_FontAsset>();
			foreach (TMP_FontAsset val in array)
			{
				if (Alive((Object)(object)val) && !string.IsNullOrEmpty(((Object)val).name) && !IsLiberation(val))
				{
					string name = ((Object)val).name;
					if (name.IndexOf("Norse", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Averia", StringComparison.OrdinalIgnoreCase) >= 0 || name.IndexOf("Valheim", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						font = val;
						material = ((TMP_Asset)val).material;
						CacheGameFont(font, material, size, color);
						return true;
					}
				}
			}
			foreach (TMP_FontAsset val2 in array)
			{
				if (Alive((Object)(object)val2) && !string.IsNullOrEmpty(((Object)val2).name) && !IsLiberation(val2))
				{
					font = val2;
					material = ((TMP_Asset)val2).material;
					CacheGameFont(font, material, size, color);
					return true;
				}
			}
			return false;
		}

		private static bool TryTakeFont(TMP_Text source, ref TMP_FontAsset font, ref Material material, ref float size, ref Color color)
		{
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			if (!Alive((Object)(object)source) || !Alive((Object)(object)source.font) || IsLiberation(source.font))
			{
				return false;
			}
			font = source.font;
			material = (Alive((Object)(object)source.fontSharedMaterial) ? source.fontSharedMaterial : ((TMP_Asset)source.font).material);
			size = ((source.fontSize > 1f) ? source.fontSize : 16f);
			color = ((Graphic)source).color;
			return true;
		}

		private static bool TryTakeFontFromChildren(GameObject root, ref TMP_FontAsset font, ref Material material, ref float size, ref Color color)
		{
			if (!Alive((Object)(object)root))
			{
				return false;
			}
			TextMeshProUGUI[] componentsInChildren = root.GetComponentsInChildren<TextMeshProUGUI>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				if (TryTakeFont((TMP_Text)(object)componentsInChildren[i], ref font, ref material, ref size, ref color))
				{
					return true;
				}
			}
			return false;
		}

		private static void CacheGameFont(TMP_FontAsset font, Material material, float size, Color color)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			_cachedFont = font;
			_cachedFontMaterial = (Alive((Object)(object)material) ? material : (((Object)(object)font != (Object)null) ? ((TMP_Asset)font).material : null));
			_cachedFontSize = ((size > 1f) ? size : 16f);
			_cachedFontColor = color;
		}

		private static bool IsLiberation(TMP_FontAsset font)
		{
			if (!Alive((Object)(object)font) || string.IsNullOrEmpty(((Object)font).name))
			{
				return true;
			}
			return ((Object)font).name.IndexOf("Liberation", StringComparison.OrdinalIgnoreCase) >= 0;
		}

		private static void StretchFull(RectTransform rt)
		{
			//IL_0001: 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_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			rt.anchorMin = Vector2.zero;
			rt.anchorMax = Vector2.one;
			rt.offsetMin = Vector2.zero;
			rt.offsetMax = Vector2.zero;
		}

		private static bool Alive(Object obj)
		{
			return obj != (Object)null;
		}

		private void SafeShow()
		{
			if (_uiBuilt)
			{
				if (Alive((Object)(object)_canvas) && !((Behaviour)_canvas).enabled)
				{
					((Behaviour)_canvas).enabled = true;
				}
				if (Alive((Object)(object)_panel) && !((Component)_panel).gameObject.activeSelf)
				{
					((Component)_panel).gameObject.SetActive(true);
				}
			}
		}

		private void SafeHide()
		{
			_boundContainer = null;
			_boundRevision = -1;
			_boundShowIcons = false;
			_boundCombineStacks = false;
			_boundMinPanelWidth = -1f;
			_boundMaxPanelWidth = -1f;
			_remeasureAfterFrame = -1;
			if (_uiBuilt && Alive((Object)(object)_panel) && ((Component)_panel).gameObject.activeSelf)
			{
				((Component)_panel).gameObject.SetActive(false);
			}
		}
	}
}
namespace Chest_List.Patches
{
	[HarmonyPatch(typeof(Player), "UpdateHover")]
	internal static class PlayerUpdateHoverPatch
	{
		private static void Postfix(Player __instance)
		{
			if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
			{
				ChestTarget.SetFromHoverObject(((Humanoid)__instance).GetHoverObject());
			}
		}
	}
	[HarmonyPatch(typeof(Player), "OnDestroy")]
	internal static class PlayerOnDestroyPatch
	{
		private static void Prefix(Player __instance)
		{
			if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer)
			{
				ChestTarget.Clear();
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}