Decompiled source of Chest List v1.0.2

Chest_List.dll

Decompiled 2 months 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.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2")]
[assembly: AssemblyProduct("Chest_List")]
[assembly: AssemblyTitle("Chest_List")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.2.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", true, "When enabled, merge identical items into one row with a total count (same name/world level; quality only when the item supports tiers; variant only when it has multiple variants). When disabled, each inventory stack is listed separately. On 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.2")]
	public class ChestListPlugin : BaseUnityPlugin
	{
		public const string GUID = "ModdedWolf.Chest_List";

		public const string NAME = "Chest_List";

		public const string VERSION = "1.0.2";

		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.2 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 MinRowHeight = 22f;

		private const float IconSize = 27f;

		private const float MinIconSize = 20f;

		private const float TitleFontSize = 25f;

		private const float ItemFontSize = 21f;

		private const float MinItemFontSize = 16f;

		private const float MinPad = 16f;

		private const float InnerPad = 4f;

		private const float ColumnGap = 14f;

		private const float ScreenEdgeMargin = 36f;

		private const float HudTopReserve = 88f;

		private const float HudBottomReserve = 100f;

		private const float ComfortableHeightFraction = 0.55f;

		private const int MaxColumns = 3;

		private Canvas _canvas;

		private CanvasGroup _canvasGroup;

		private RectTransform _panel;

		private Image _panelImage;

		private RectTransform _content;

		private RectTransform _titleRt;

		private TextMeshProUGUI _title;

		private RectTransform _listArea;

		private RectTransform _listRoot;

		private GridLayoutGroup _listGrid;

		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 int _boundStackRevision = -1;

		private bool _boundShowIcons;

		private bool _boundCombineStacks;

		private float _boundMinPanelWidth = -1f;

		private float _boundMaxPanelWidth = -1f;

		private bool _uiBuilt;

		private float _panelWidth = 300f;

		private float _listContentHeight;

		private int _layoutColumns = 1;

		private int _layoutRowsPerColumn = 1;

		private float _layoutRowHeight = 31f;

		private float _layoutIconSize = 27f;

		private float _layoutItemFontSize = 21f;

		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();
			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_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Expected O, but got Unknown
			//IL_00dd: 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_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Expected O, but got Unknown
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Expected O, but got Unknown
			//IL_02fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0325: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: Unknown result type (might be due to invalid IL or missing references)
			//IL_034f: Unknown result type (might be due to invalid IL or missing references)
			//IL_038e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0394: Expected O, but got Unknown
			//IL_03c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0406: Unknown result type (might be due to invalid IL or missing references)
			//IL_0420: Unknown result type (might be due to invalid IL or missing references)
			//IL_0446: Unknown result type (might be due to invalid IL or missing references)
			//IL_0460: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ba: 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;
			_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("ListArea", new Type[1] { typeof(RectTransform) });
			val3.transform.SetParent((Transform)(object)_content, false);
			_listArea = val3.GetComponent<RectTransform>();
			_listArea.anchorMin = Vector2.zero;
			_listArea.anchorMax = Vector2.one;
			_listArea.pivot = new Vector2(0.5f, 1f);
			_listArea.offsetMin = Vector2.zero;
			_listArea.offsetMax = new Vector2(0f, -38f);
			((TMP_Text)_title).transform.SetAsFirstSibling();
			GameObject val4 = new GameObject("List", new Type[2]
			{
				typeof(RectTransform),
				typeof(GridLayoutGroup)
			});
			val4.transform.SetParent(val3.transform, false);
			_listRoot = val4.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 = new Vector2(0f, 0f);
			_listGrid = val4.GetComponent<GridLayoutGroup>();
			_listGrid.cellSize = new Vector2(100f, 31f);
			_listGrid.spacing = new Vector2(14f, 0f);
			_listGrid.startCorner = (Corner)0;
			_listGrid.startAxis = (Axis)1;
			((LayoutGroup)_listGrid).childAlignment = (TextAnchor)0;
			_listGrid.constraint = (Constraint)1;
			_listGrid.constraintCount = 1;
			((LayoutGroup)_listGrid).padding = new RectOffset(0, 0, 0, 0);
			ApplyPanelSize(_panelWidth, GetMinPanelHeight());
		}

		private float GetTitleBlockHeight()
		{
			return 38f;
		}

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

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

		private float GetAvailableScreenHeight()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			Vector2 parentCanvasSize = GetParentCanvasSize();
			float num = Mathf.Max(1f, parentCanvasSize.y);
			float configuredPositionY = GetConfiguredPositionY();
			float num2 = num * (1f - configuredPositionY) - 88f;
			float num3 = num * configuredPositionY - 100f;
			float num4 = 2f * Mathf.Max(0f, Mathf.Min(num2, num3));
			float num5 = num * 0.55f;
			float num6 = num - 88f - 100f;
			float num7 = Mathf.Min(new float[3] { num4, num5, num6 });
			return Mathf.Max(140f, num7);
		}

		private static float GetConfiguredPositionY()
		{
			try
			{
				if (ChestListConfig.UiPositionY != null)
				{
					return Mathf.Clamp01(ChestListConfig.UiPositionY.Value);
				}
			}
			catch
			{
			}
			return 0.55f;
		}

		private Vector2 GetParentCanvasSize()
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: 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_003f: 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_004d: 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)
			RectTransform val = (RectTransform)(Alive((Object)(object)_panel) ? /*isinst with value type is only supported in some contexts*/: null);
			Vector2 val2;
			if (!((Object)(object)val != (Object)null))
			{
				val2 = Vector2.zero;
			}
			else
			{
				Rect rect = val.rect;
				val2 = ((Rect)(ref rect)).size;
			}
			Vector2 val3 = val2;
			if (val3.x <= 1f || val3.y <= 1f)
			{
				float num = 1080f;
				float num2 = 1920f;
				float num3 = Mathf.Max(1f, (float)Screen.width);
				float num4 = Mathf.Max(1f, (float)Screen.height);
				float num5 = Mathf.Log(num3 / num2, 2f);
				float num6 = Mathf.Log(num4 / num, 2f);
				float num7 = Mathf.Lerp(num5, num6, 0.5f);
				float num8 = Mathf.Pow(2f, num7);
				((Vector2)(ref val3))..ctor(num3 / num8, num4 / num8);
			}
			return val3;
		}

		private void ComputeFitToScreenLayout(int total)
		{
			int value = Mathf.Max(1, total);
			float availableScreenHeight = GetAvailableScreenHeight();
			float num = GetBorderChromeHeight() + GetTitleBlockHeight();
			float num2 = Mathf.Max(22f, availableScreenHeight - num);
			int num3 = 1;
			float num4 = 31f;
			for (int i = 1; i <= 3; i++)
			{
				int num5 = CeilDiv(value, i);
				float num6 = (float)num5 * 31f;
				if (num + num6 <= availableScreenHeight + 0.5f)
				{
					num3 = i;
					num4 = 31f;
					break;
				}
				num3 = i;
				if (i == 3)
				{
					num4 = Mathf.Clamp(num2 / (float)num5, 22f, 31f);
				}
			}
			int num7 = CeilDiv(value, num3);
			float num8 = (float)num7 * num4;
			if (num + num8 > availableScreenHeight + 0.5f)
			{
				num4 = Mathf.Max(22f, num2 / (float)Mathf.Max(1, num7));
			}
			_layoutColumns = num3;
			_layoutRowsPerColumn = num7;
			_layoutRowHeight = num4;
			if (Mathf.Approximately(num4, 31f))
			{
				_layoutIconSize = 27f;
				_layoutItemFontSize = 21f;
			}
			else
			{
				float num9 = Mathf.InverseLerp(22f, 31f, num4);
				_layoutIconSize = Mathf.Lerp(20f, 27f, num9);
				_layoutItemFontSize = Mathf.Lerp(16f, 21f, num9);
			}
		}

		private static int CeilDiv(int value, int divisor)
		{
			if (divisor <= 0)
			{
				return value;
			}
			return (value + divisor - 1) / divisor;
		}

		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 float GetMaxTotalPanelWidth()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			int num = Mathf.Max(1, _layoutColumns);
			float maxPanelWidth = GetMaxPanelWidth();
			float num2 = 14f * (float)Mathf.Max(0, num - 1);
			float num3 = maxPanelWidth * (float)num + num2;
			Vector2 parentCanvasSize = GetParentCanvasSize();
			float num4 = Mathf.Max(maxPanelWidth, parentCanvasSize.x - 72f);
			return Mathf.Min(num3, num4);
		}

		private void ApplyLayoutAndAlpha()
		{
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: 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_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Clamp01(ChestListConfig.UiPositionX.Value);
			float configuredPositionY = GetConfiguredPositionY();
			float alpha = Mathf.Clamp01(ChestListConfig.UiAlpha.Value);
			Vector2 parentCanvasSize = GetParentCanvasSize();
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor((num - 0.5f) * parentCanvasSize.x, (configuredPositionY - 0.5f) * parentCanvasSize.y);
			float num2 = (Alive((Object)(object)_panel) ? (_panel.sizeDelta.x * 0.5f) : (_panelWidth * 0.5f));
			float num3 = (Alive((Object)(object)_panel) ? (_panel.sizeDelta.y * 0.5f) : (GetMinPanelHeight() * 0.5f));
			float num4 = parentCanvasSize.x * 0.5f - num2 - 36f;
			float num5 = (0f - parentCanvasSize.x) * 0.5f + num2 + 36f;
			float num6 = parentCanvasSize.y * 0.5f - num3 - 88f;
			float num7 = (0f - parentCanvasSize.y) * 0.5f + num3 + 100f;
			if (num4 < num5)
			{
				val.x = 0f;
			}
			else
			{
				val.x = Mathf.Clamp(val.x, num5, num4);
			}
			if (num6 < num7)
			{
				val.y = 0f;
			}
			else
			{
				val.y = Mathf.Clamp(val.y, num7, num6);
			}
			_panel.anchoredPosition = val;
			if (Alive((Object)(object)_canvasGroup))
			{
				_canvasGroup.alpha = alpha;
			}
		}

		private void RefreshContents(Container container, Inventory inventory)
		{
			//IL_03f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_031b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0419: 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))
			{
				return;
			}
			int num;
			int num2;
			try
			{
				num = inventory.NrOfItems();
				num2 = inventory.NrOfItemsIncludingStacks();
			}
			catch
			{
				return;
			}
			bool value = ChestListConfig.ShowItemImages.Value;
			bool value2 = ChestListConfig.CombineStacks.Value;
			float minPanelWidth = GetMinPanelWidth();
			float maxPanelWidth = GetMaxPanelWidth();
			if (container == _boundContainer && num == _boundRevision && num2 == _boundStackRevision && value == _boundShowIcons && value2 == _boundCombineStacks && Mathf.Approximately(minPanelWidth, _boundMinPanelWidth) && Mathf.Approximately(maxPanelWidth, _boundMaxPanelWidth))
			{
				return;
			}
			int num3;
			List<ItemData> list;
			try
			{
				List<ItemData> allItems = inventory.GetAllItems();
				num3 = allItems?.Count ?? 0;
				list = BuildGridOrderedCopy(allItems);
			}
			catch
			{
				return;
			}
			if (list == null)
			{
				list = new List<ItemData>();
				num3 = 0;
			}
			BuildDisplayEntries(list, value2);
			_boundContainer = container;
			_boundRevision = num;
			_boundStackRevision = num2;
			_boundShowIcons = value;
			_boundCombineStacks = value2;
			_boundMinPanelWidth = minPanelWidth;
			_boundMaxPanelWidth = maxPanelWidth;
			float borderChromeHeight = GetBorderChromeHeight();
			float titleBlockHeight = GetTitleBlockHeight();
			int count = _displayEntries.Count;
			ComputeFitToScreenLayout(count);
			float minPanelHeight = GetMinPanelHeight();
			float num4 = Mathf.Max((float)_layoutRowsPerColumn * _layoutRowHeight, _layoutRowHeight);
			float num5 = borderChromeHeight + titleBlockHeight + num4;
			if (num5 < minPanelHeight)
			{
				num5 = minPanelHeight;
			}
			float availableScreenHeight = GetAvailableScreenHeight();
			if (num5 > availableScreenHeight)
			{
				num5 = availableScreenHeight;
				num4 = Mathf.Max(_layoutRowHeight, num5 - borderChromeHeight - titleBlockHeight);
				_layoutRowHeight = Mathf.Max(22f, num4 / (float)Mathf.Max(1, _layoutRowsPerColumn));
			}
			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 = _layoutRowHeight;
					rowWidgets.Layout.minHeight = _layoutRowHeight;
					rowWidgets.Layout.flexibleHeight = 0f;
				}
				((TMP_Text)rowWidgets.Label).fontStyle = (FontStyles)0;
				((TMP_Text)rowWidgets.Label).fontSize = _layoutItemFontSize;
				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(_layoutIconSize, _layoutIconSize);
					}
					((TMP_Text)rowWidgets.Label).margin = (Vector4)(flag ? new Vector4(_layoutIconSize + 8f, 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);
			}
			ApplyListContentSize(count);
			RelayoutPanelWidth(value, count, num5, scheduleDeferredRemeasure: true);
			ApplyListContentSize(count);
			if (!value2 && count != num3)
			{
				ManualLogSource log = ChestListPlugin.Log;
				if (log != null)
				{
					log.LogDebug((object)$"Chest list row count mismatch: shown={count}, inventory.GetAllItems()={num3}");
				}
			}
			ApplyLayoutAndAlpha();
		}

		private static List<ItemData> BuildGridOrderedCopy(List<ItemData> raw)
		{
			if (raw == null || raw.Count == 0)
			{
				return new List<ItemData>();
			}
			List<ItemData> list = new List<ItemData>(raw.Count);
			for (int i = 0; i < raw.Count; i++)
			{
				ItemData val = raw[i];
				if (val != null)
				{
					list.Add(val);
				}
			}
			list.Sort(CompareGridPos);
			return list;
		}

		private static int CompareGridPos(ItemData a, ItemData b)
		{
			if (a == b)
			{
				return 0;
			}
			if (a == null)
			{
				return 1;
			}
			if (b == null)
			{
				return -1;
			}
			int num = a.m_gridPos.y.CompareTo(b.m_gridPos.y);
			if (num != 0)
			{
				return num;
			}
			return a.m_gridPos.x.CompareTo(b.m_gridPos.x);
		}

		private void ApplyListContentSize(int rowCount)
		{
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: 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_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			int num = Mathf.Max(1, _layoutColumns);
			_listContentHeight = Mathf.Max(0f, (float)(_layoutRowsPerColumn = ((rowCount <= 0) ? 1 : Mathf.Max(1, CeilDiv(rowCount, num)))) * _layoutRowHeight);
			if (Alive((Object)(object)_listRoot))
			{
				if (Alive((Object)(object)_listGrid))
				{
					float num2 = Mathf.Max(1f, _panelWidth - _padL - _padR);
					float num3 = 14f * (float)Mathf.Max(0, num - 1);
					float num4 = Mathf.Max(1f, (num2 - num3) / (float)num);
					_listGrid.constraintCount = num;
					_listGrid.cellSize = new Vector2(num4, _layoutRowHeight);
					_listGrid.spacing = new Vector2((num > 1) ? 14f : 0f, 0f);
				}
				Vector2 sizeDelta = _listRoot.sizeDelta;
				sizeDelta.y = _listContentHeight;
				_listRoot.sizeDelta = sizeDelta;
				_listRoot.anchoredPosition = new Vector2(_listRoot.anchoredPosition.x, 0f);
				LayoutRebuilder.ForceRebuildLayoutImmediate(_listRoot);
			}
		}

		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);
				ApplyListContentSize(total);
				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);
					ApplyListContentSize(count);
				}
			}
		}

		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))
				{
					if (!Alive((Object)(object)((TMP_Text)label).font) || IsLiberation(((TMP_Text)label).font))
					{
						ApplyGameFont(label, isTitle: false);
					}
					((TMP_Text)label).fontSize = _layoutItemFontSize;
				}
			}
		}

		private float MeasurePanelWidth(bool showIcons, int total)
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			float num = 0f;
			float num2 = 0f;
			float minPanelWidth = GetMinPanelWidth();
			float maxPanelWidth = GetMaxPanelWidth();
			if (Alive((Object)(object)_title) && !string.IsNullOrEmpty(((TMP_Text)_title).text))
			{
				PrepareTmpForMeasure(_title);
				num2 = ((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 num3 = 0f;
					if (showIcons && Alive((Object)(object)rowWidgets.Icon) && ((Component)rowWidgets.Icon).gameObject.activeSelf)
					{
						num3 = _layoutIconSize + 8f;
					}
					num = Mathf.Max(num, num3 + x);
				}
			}
			int num4 = Mathf.Max(1, _layoutColumns);
			float maxTotalPanelWidth = GetMaxTotalPanelWidth();
			if (num <= 0.5f && num2 <= 0.5f)
			{
				return Mathf.Min(minPanelWidth * (float)num4 + 14f * (float)Mathf.Max(0, num4 - 1), maxTotalPanelWidth);
			}
			float num5 = Mathf.Max(num, num2) + _padL + _padR + 28f;
			num5 = Mathf.Clamp(num5, minPanelWidth, maxPanelWidth);
			if (num4 <= 1)
			{
				return num5;
			}
			float num6 = Mathf.Clamp(num + 28f, Mathf.Max(1f, minPanelWidth - _padL - _padR), Mathf.Max(1f, maxPanelWidth - _padL - _padR));
			float num7 = 14f * (float)(num4 - 1);
			float num8 = _padL + _padR + num6 * (float)num4 + num7;
			float num9 = num2 + _padL + _padR + 28f;
			return Mathf.Clamp(Mathf.Max(num8, Mathf.Min(num9, maxTotalPanelWidth)), minPanelWidth, maxTotalPanelWidth);
		}

		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_0050: 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());
				float minPanelWidth = GetMinPanelWidth();
				float maxTotalPanelWidth = GetMaxTotalPanelWidth();
				panelWidth = Mathf.Clamp(panelWidth, minPanelWidth, maxTotalPanelWidth);
				_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_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: 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_0131: 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.flexibleHeight = 0f;
			component2.flexibleWidth = 0f;
			component2.layoutPriority = 100;
			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;
			SharedData shared = item.m_shared;
			string text = ((shared != null) ? shared.m_name : string.Empty);
			_keyBuilder.Append(text ?? string.Empty);
			_keyBuilder.Append('|');
			_keyBuilder.Append(item.m_worldLevel);
			if (shared != null && shared.m_maxQuality > 1)
			{
				_keyBuilder.Append('|');
				_keyBuilder.Append('q');
				_keyBuilder.Append(item.m_quality);
			}
			if (shared != null && shared.m_variants > 1)
			{
				_keyBuilder.Append('|');
				_keyBuilder.Append('v');
				_keyBuilder.Append(item.m_variant);
			}
			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 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;
			_boundStackRevision = -1;
			_boundShowIcons = false;
			_boundCombineStacks = false;
			_boundMinPanelWidth = -1f;
			_boundMaxPanelWidth = -1f;
			_remeasureAfterFrame = -1;
			_listContentHeight = 0f;
			_layoutColumns = 1;
			_layoutRowsPerColumn = 1;
			_layoutRowHeight = 31f;
			_layoutIconSize = 27f;
			_layoutItemFontSize = 21f;
			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)
		{
		}
	}
}