Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ChestItemsHoverDisplay v0.2.0
CDEV.ChestItemsHoverDisplay.dll
Decompiled 4 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("CDEV.ChestItemsHoverDisplay")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.2.0.0")] [assembly: AssemblyInformationalVersion("0.2.0")] [assembly: AssemblyProduct("CDEV.ChestItemsHoverDisplay")] [assembly: AssemblyTitle("CDEV.ChestItemsHoverDisplay")] [assembly: AssemblyVersion("0.2.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.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 CDEV.ChestItemsHoverDisplay { internal class HoverInventoryPanel : MonoBehaviour { private struct SlotView { public GameObject Go; public Image Icon; public Text Count; } private RectTransform _root; private RectTransform _gridRoot; private GridLayoutGroup _grid; private Text _title; private List<SlotView> _slots; private Font _font; private Container _current; private Inventory _trackedInventory; private int _gridW; private int _gridH; private bool _dirty = true; private bool _built; private static readonly string[] s_stackCache = BuildStackCache(128); private static string[] BuildStackCache(int n) { string[] array = new string[n + 1]; for (int i = 0; i <= n; i++) { array[i] = "x" + i; } return array; } private void Awake() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown _root = (RectTransform)((Component)this).transform; _slots = new List<SlotView>(32); Build(); } private void OnDestroy() { UnsubscribeCurrent(); } private void Build() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_007f: 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_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Expected O, but got Unknown //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Expected O, but got Unknown //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Expected O, but got Unknown //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Expected O, but got Unknown if (!_built) { _built = true; _font = FindValheimFont(); _root.anchorMin = new Vector2(0.5f, 0.5f); _root.anchorMax = new Vector2(0.5f, 0.5f); _root.pivot = new Vector2(0.5f, 1f); _root.anchoredPosition = new Vector2(0f, (float)Plugin.CfgVerticalOffset.Value); Image obj = ((Component)this).gameObject.AddComponent<Image>(); ((Graphic)obj).color = new Color(0f, 0f, 0f, 0.66f); ((Graphic)obj).raycastTarget = false; ContentSizeFitter obj2 = ((Component)this).gameObject.AddComponent<ContentSizeFitter>(); obj2.horizontalFit = (FitMode)2; obj2.verticalFit = (FitMode)2; VerticalLayoutGroup obj3 = ((Component)this).gameObject.AddComponent<VerticalLayoutGroup>(); ((LayoutGroup)obj3).padding = new RectOffset(6, 6, 5, 6); ((HorizontalOrVerticalLayoutGroup)obj3).spacing = 5f; ((LayoutGroup)obj3).childAlignment = (TextAnchor)0; ((HorizontalOrVerticalLayoutGroup)obj3).childControlWidth = false; ((HorizontalOrVerticalLayoutGroup)obj3).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandHeight = false; GameObject val = new GameObject("Title", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(((Component)this).transform, false); _title = val.AddComponent<Text>(); _title.font = _font; _title.fontSize = 16; _title.fontStyle = (FontStyle)1; ((Graphic)_title).color = Color.white; _title.alignment = (TextAnchor)3; _title.horizontalOverflow = (HorizontalWrapMode)1; _title.verticalOverflow = (VerticalWrapMode)1; ((Graphic)_title).raycastTarget = false; Outline obj4 = val.AddComponent<Outline>(); ((Shadow)obj4).effectColor = Color.black; ((Shadow)obj4).effectDistance = new Vector2(1f, -1f); LayoutElement obj5 = val.AddComponent<LayoutElement>(); obj5.minHeight = _title.fontSize; obj5.preferredHeight = _title.fontSize; GameObject val2 = new GameObject("Grid", new Type[1] { typeof(RectTransform) }); val2.transform.SetParent(((Component)this).transform, false); _gridRoot = (RectTransform)val2.transform; ContentSizeFitter obj6 = val2.AddComponent<ContentSizeFitter>(); obj6.horizontalFit = (FitMode)2; obj6.verticalFit = (FitMode)2; _grid = val2.AddComponent<GridLayoutGroup>(); ApplyCellSettings(); ((Component)this).gameObject.SetActive(false); } } private void ApplyCellSettings() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown int value = Plugin.CfgCellSize.Value; _grid.cellSize = new Vector2((float)value, (float)value); _grid.spacing = new Vector2(2f, 2f); ((LayoutGroup)_grid).padding = new RectOffset(0, 0, 0, 0); _grid.startCorner = (Corner)0; _grid.startAxis = (Axis)0; ((LayoutGroup)_grid).childAlignment = (TextAnchor)0; _grid.constraint = (Constraint)1; if (_gridW > 0) { _grid.constraintCount = _gridW; } } private static Font FindValheimFont() { Font[] array = Resources.FindObjectsOfTypeAll<Font>(); Font val = null; foreach (Font val2 in array) { if (!((Object)(object)val2 == (Object)null)) { if (((Object)val2).name.IndexOf("AveriaSerifLibre-Bold", StringComparison.OrdinalIgnoreCase) >= 0) { return val2; } if ((Object)(object)val == (Object)null) { val = val2; } } } return val; } private SlotView CreateSlot(int idx) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: 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_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Slot" + idx, new Type[1] { typeof(RectTransform) }); val.transform.SetParent((Transform)(object)_gridRoot, false); Image obj = val.AddComponent<Image>(); ((Graphic)obj).color = new Color(1f, 1f, 1f, 0.08f); ((Graphic)obj).raycastTarget = false; GameObject val2 = new GameObject("Icon", new Type[1] { typeof(RectTransform) }); val2.transform.SetParent(val.transform, false); RectTransform val3 = (RectTransform)val2.transform; val3.anchorMin = Vector2.zero; val3.anchorMax = Vector2.one; val3.offsetMin = Vector2.zero; val3.offsetMax = Vector2.zero; Image val4 = val2.AddComponent<Image>(); ((Graphic)val4).raycastTarget = false; val4.preserveAspect = true; GameObject val5 = new GameObject("Count", new Type[1] { typeof(RectTransform) }); val5.transform.SetParent(val.transform, false); RectTransform val6 = (RectTransform)val5.transform; val6.anchorMin = Vector2.zero; val6.anchorMax = Vector2.one; val6.offsetMin = new Vector2(0f, 0f); val6.offsetMax = new Vector2(-2f, 0f); Text val7 = val5.AddComponent<Text>(); ((Graphic)val7).raycastTarget = false; val7.alignment = (TextAnchor)8; val7.font = _font; val7.fontSize = 14; ((Graphic)val7).color = Color.white; val7.resizeTextForBestFit = false; val7.horizontalOverflow = (HorizontalWrapMode)1; val7.verticalOverflow = (VerticalWrapMode)1; Outline obj2 = val5.AddComponent<Outline>(); ((Shadow)obj2).effectColor = Color.black; ((Shadow)obj2).effectDistance = new Vector2(1f, -1f); SlotView result = default(SlotView); result.Go = val; result.Icon = val4; result.Count = val7; return result; } public void Hide() { if (_built) { if (((Component)this).gameObject.activeSelf) { ((Component)this).gameObject.SetActive(false); } UnsubscribeCurrent(); } } private void UnsubscribeCurrent() { if (_trackedInventory != null) { Inventory trackedInventory = _trackedInventory; trackedInventory.m_onChanged = (Action)Delegate.Remove(trackedInventory.m_onChanged, new Action(OnInventoryChanged)); _trackedInventory = null; } _current = null; _dirty = true; } private void OnInventoryChanged() { _dirty = true; } public void Show(Container c) { //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) if (!_built) { Build(); } if ((Object)(object)c != (Object)(object)_current) { UnsubscribeCurrent(); _current = c; _trackedInventory = c.GetInventory(); if (_trackedInventory != null) { Inventory trackedInventory = _trackedInventory; trackedInventory.m_onChanged = (Action)Delegate.Combine(trackedInventory.m_onChanged, new Action(OnInventoryChanged)); } if ((Object)(object)_title != (Object)null) { string text = c.m_name ?? string.Empty; _title.text = ((Localization.instance != null) ? Localization.instance.Localize(text) : text); } _dirty = true; } if (_trackedInventory == null) { Hide(); return; } if ((int)_grid.cellSize.x != Plugin.CfgCellSize.Value) { ApplyCellSettings(); _dirty = true; } int num = Mathf.Max(1, _trackedInventory.GetWidth()); int num2 = Mathf.Max(1, _trackedInventory.GetHeight()); if (num != _gridW || num2 != _gridH) { _gridW = num; _gridH = num2; _grid.constraintCount = num; _dirty = true; } int value = Plugin.CfgVerticalOffset.Value; if ((int)_root.anchoredPosition.y != value) { _root.anchoredPosition = new Vector2(0f, (float)value); } bool flag = false; if (_dirty) { Rebuild(); flag = true; } if (Plugin.CfgHideWhenEmpty.Value && _trackedInventory.NrOfItems() == 0) { if (((Component)this).gameObject.activeSelf) { ((Component)this).gameObject.SetActive(false); } return; } if (!((Component)this).gameObject.activeSelf) { ((Component)this).gameObject.SetActive(true); } if (flag) { LayoutRebuilder.ForceRebuildLayoutImmediate(_root); } } private void Rebuild() { //IL_00ae: Unknown result type (might be due to invalid IL or missing references) _dirty = false; int num = _gridW * _gridH; while (_slots.Count < num) { _slots.Add(CreateSlot(_slots.Count)); } for (int i = 0; i < _slots.Count; i++) { SlotView slotView = _slots[i]; if (i < num) { int num2 = i % _gridW; int num3 = i / _gridW; ItemData itemAt = _trackedInventory.GetItemAt(num2, num3); Sprite val = PickIcon(itemAt); slotView.Icon.sprite = val; ((Behaviour)slotView.Icon).enabled = (Object)(object)val != (Object)null; ((Graphic)slotView.Icon).color = Color.white; int num4 = itemAt?.m_stack ?? 0; if (num4 > 1 || (itemAt != null && itemAt.m_shared != null && itemAt.m_shared.m_maxStackSize > 1)) { slotView.Count.text = ((num4 >= 0 && num4 < s_stackCache.Length) ? s_stackCache[num4] : ("x" + num4)); ((Behaviour)slotView.Count).enabled = true; } else { ((Behaviour)slotView.Count).enabled = false; } if (!slotView.Go.activeSelf) { slotView.Go.SetActive(true); } } else if (slotView.Go.activeSelf) { slotView.Go.SetActive(false); } } } private static Sprite PickIcon(ItemData it) { if (it == null || it.m_shared == null) { return null; } Sprite[] icons = it.m_shared.m_icons; if (icons == null || icons.Length == 0) { return null; } int num = it.m_variant; if (num < 0) { num = 0; } if (num >= icons.Length) { num = icons.Length - 1; } return icons[num]; } } [BepInPlugin("cdev.valheim.chestitemshoverdisplay", "CDEV.ChestItemsHoverDisplay", "0.2.0")] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "cdev.valheim.chestitemshoverdisplay"; public const string PluginName = "CDEV.ChestItemsHoverDisplay"; public const string PluginVersion = "0.2.0"; internal static ManualLogSource Log; internal static Plugin Instance; internal static HoverInventoryPanel Panel; internal static ConfigEntry<bool> CfgEnabled; internal static ConfigEntry<int> CfgCellSize; internal static ConfigEntry<bool> CfgHideWhenEmpty; internal static ConfigEntry<bool> CfgRespectPrivateChests; internal static ConfigEntry<KeyCode> CfgHoldKey; internal static ConfigEntry<int> CfgVerticalOffset; private Harmony _harmony; private void Awake() { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Expected O, but got Unknown //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; CfgEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Display", "Enabled", true, "Master toggle for the hover inventory panel."); CfgCellSize = ((BaseUnityPlugin)this).Config.Bind<int>("Display", "CellSize", 40, new ConfigDescription("Pixel size of each grid cell.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(24, 96), Array.Empty<object>())); CfgHideWhenEmpty = ((BaseUnityPlugin)this).Config.Bind<bool>("Display", "HideWhenEmpty", true, "Hide the panel when the hovered container is empty."); CfgRespectPrivateChests = ((BaseUnityPlugin)this).Config.Bind<bool>("Display", "RespectPrivateChests", true, "Hide preview for private chests the local player cannot access, or chests inside wards the local player is not permitted in."); CfgHoldKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Display", "HoldKeyToShow", (KeyCode)0, "Optional key that must be held to show the panel. None = always show while hovering."); CfgVerticalOffset = ((BaseUnityPlugin)this).Config.Bind<int>("Display", "VerticalOffset", -80, new ConfigDescription("Vertical pixel offset from screen center (negative = below crosshair).", (AcceptableValueBase)(object)new AcceptableValueRange<int>(-400, 400), Array.Empty<object>())); _harmony = new Harmony("cdev.valheim.chestitemshoverdisplay"); _harmony.PatchAll(typeof(Plugin).Assembly); Log.LogInfo((object)"CDEV.ChestItemsHoverDisplay 0.2.0 loaded."); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } if ((Object)(object)Panel != (Object)null) { Object.Destroy((Object)(object)((Component)Panel).gameObject); } Panel = null; } internal static HoverInventoryPanel GetOrCreatePanel() { //IL_003a: 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) if ((Object)(object)Panel != (Object)null) { return Panel; } if ((Object)(object)Hud.instance == (Object)null) { return null; } GameObject val = new GameObject("CDEV_HoverInventoryPanel", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(((Component)Hud.instance).transform, false); Panel = val.AddComponent<HoverInventoryPanel>(); return Panel; } } [HarmonyPatch(typeof(Hud), "UpdateCrosshair")] internal static class HudUpdateCrosshairPatch { private static readonly Func<Container, long, bool> s_checkAccess = AccessTools.MethodDelegate<Func<Container, long, bool>>(AccessTools.Method(typeof(Container), "CheckAccess", new Type[1] { typeof(long) }, (Type[])null), (object)null, true); private static void Postfix(Player player) { //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) HoverInventoryPanel panel = Plugin.Panel; if (!Plugin.CfgEnabled.Value) { panel?.Hide(); return; } if ((Object)(object)player == (Object)null) { panel?.Hide(); return; } GameObject hoverObject = ((Humanoid)player).GetHoverObject(); if ((Object)(object)hoverObject == (Object)null) { panel?.Hide(); return; } Container componentInParent = hoverObject.GetComponentInParent<Container>(); if ((Object)(object)componentInParent == (Object)null) { panel?.Hide(); return; } ZNetView component = ((Component)componentInParent).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { panel?.Hide(); return; } if (Plugin.CfgRespectPrivateChests.Value) { if (s_checkAccess != null && !s_checkAccess(componentInParent, player.GetPlayerID())) { panel?.Hide(); return; } if (!PrivateArea.CheckAccess(((Component)componentInParent).transform.position, 0f, false, false)) { panel?.Hide(); return; } } if ((int)Plugin.CfgHoldKey.Value != 0 && !Input.GetKey(Plugin.CfgHoldKey.Value)) { panel?.Hide(); } else { Plugin.GetOrCreatePanel()?.Show(componentInParent); } } } }