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 CheckMyStuff v1.0.2
plugins/CheckMyStuff/CheckMyStuff.dll
Decompiled 10 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using BepInEx; using BepInEx.Logging; using CheckMyStuff.Barrel; using CheckMyStuff.Classification; using CheckMyStuff.Routing; using CheckMyStuff.UI; using HarmonyLib; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Newtonsoft.Json; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("CheckMyStuff")] [assembly: AssemblyFileVersion("1.0.2")] [assembly: AssemblyCompany("R4V9N1")] [assembly: AssemblyProduct("CheckMyStuff")] [assembly: AssemblyDescription("Created by R4V9N1")] [assembly: AssemblyVersion("1.0.2.0")] namespace CheckMyStuff { [BepInPlugin("r4v9n1.checkmystuff", "CheckMyStuff", "1.0.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public sealed class CheckMyStuffPlugin : BaseUnityPlugin { public const string PluginGuid = "r4v9n1.checkmystuff"; public const string PluginName = "CheckMyStuff"; public const string PluginVersion = "1.0.2"; public const string CreatorCredit = "Created by R4V9N1"; internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; new Harmony("r4v9n1.checkmystuff").PatchAll(typeof(CheckMyStuffPlugin).Assembly); ItemDatabase.Initialize(typeof(CheckMyStuffPlugin).Assembly); ItemDatabase.ValidateCatalog(); ChestLabelManager.ValidateContract(); ChestLabelUi.ValidateContract(); PrefabManager.OnVanillaPrefabsAvailable += RegisterBarrelWhenReady; ((BaseUnityPlugin)this).Logger.LogInfo((object)("CheckMyStuff 1.0.2 loaded: " + ItemDatabase.Count + " classified items; category and exact-item routing active.")); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Waiting for Jotunn vanilla-prefab availability before registering the CheckMyStuff barrel."); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Created by R4V9N1."); } private void Update() { if ((Object)(object)ObjectDB.instance != (Object)null) { ItemTaxonomy.RefreshRuntimeItems(ObjectDB.instance); } ChestLabelUi.Draw(); BarrelUi.Draw(); SortingEngine.ProcessPendingRetry(); } private void RegisterBarrelWhenReady() { try { if (!BarrelRegistrar.Register()) { ((BaseUnityPlugin)this).Logger.LogError((object)"CheckMyStuff barrel registration did not complete. Chest labels remain available."); return; } PrefabManager.OnVanillaPrefabsAvailable -= RegisterBarrelWhenReady; ((BaseUnityPlugin)this).Logger.LogInfo((object)"CheckMyStuff barrel registered after vanilla prefabs became available."); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("CheckMyStuff barrel registration failed after vanilla prefabs became available: " + ex)); } } private void OnDestroy() { PrefabManager.OnVanillaPrefabsAvailable -= RegisterBarrelWhenReady; } } } namespace CheckMyStuff.UI { public static class BarrelUi { private const float PanelWidth = 360f; private const float PanelHeight = 454f; private const float MaxUseDistance = 5f; private static GameObject s_panel; private static RectTransform s_panelRect; private static GameObject s_confirmRoot; private static TMP_Text s_confirmText; private static TMP_Text s_statusText; private static BarrelController s_lastController; private static bool s_createFailureLogged; public static void Draw() { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) BarrelController active = BarrelController.Active; InventoryGui instance = InventoryGui.instance; if ((Object)(object)active == (Object)null) { HidePanel(); return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || (Object)(object)instance == (Object)null) { BarrelController.Close(); HidePanel(); } else if (!InventoryGui.IsVisible()) { BarrelController.Close(); HidePanel(); } else if (instance.IsContainerOpen()) { BarrelController.Close(); HidePanel(); } else if (Vector3.Distance(((Component)localPlayer).transform.position, ((Component)active).transform.position) > 5f) { CloseUi(); } else { if ((Object)(object)s_panel == (Object)null && !TryCreatePanel(instance)) { return; } if (active != s_lastController) { s_lastController = active; if ((Object)(object)s_statusText != (Object)null) { s_statusText.text = "Choose Store All or a category to store bag items."; } } SyncPanelPosition(instance); if (!s_panel.activeSelf) { s_panel.SetActive(true); } } } private static bool TryCreatePanel(InventoryGui gui) { //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019c: Expected O, but got Unknown //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0341: Unknown result type (might be due to invalid IL or missing references) //IL_0350: Unknown result type (might be due to invalid IL or missing references) //IL_0373: Unknown result type (might be due to invalid IL or missing references) //IL_039c: Unknown result type (might be due to invalid IL or missing references) //IL_03b0: Unknown result type (might be due to invalid IL or missing references) //IL_03d2: Unknown result type (might be due to invalid IL or missing references) //IL_03e1: Unknown result type (might be due to invalid IL or missing references) //IL_0404: Unknown result type (might be due to invalid IL or missing references) //IL_042a: Unknown result type (might be due to invalid IL or missing references) //IL_0439: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02c8: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Unknown result type (might be due to invalid IL or missing references) //IL_04c5: Unknown result type (might be due to invalid IL or missing references) //IL_04d4: Unknown result type (might be due to invalid IL or missing references) //IL_0515: Unknown result type (might be due to invalid IL or missing references) //IL_0524: Unknown result type (might be due to invalid IL or missing references) //IL_0547: Unknown result type (might be due to invalid IL or missing references) //IL_0571: Unknown result type (might be due to invalid IL or missing references) //IL_0580: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)gui == (Object)null || (Object)(object)gui.m_container == (Object)null || (Object)(object)gui.m_player == (Object)null) { LogCreateFailure("InventoryGui container/player panel unavailable."); return false; } RectTransform container = gui.m_container; RectTransform player = gui.m_player; Transform val = ((Transform)player).Find("Bkg"); Image val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<Image>() : null); Transform val3 = ((Transform)player).Find("sunken"); Image val4 = (((Object)(object)val3 != (Object)null) ? ((Component)val3).GetComponent<Image>() : null); TMP_FontAsset val5 = FindFont(gui, "Valheim-Norsebold"); TMP_FontAsset val6 = FindFont(gui, "Valheim-AveriaSansLibre"); TMP_FontAsset val7 = FindAnyNativeFont(gui); if ((Object)(object)val5 == (Object)null) { val5 = val7; } if ((Object)(object)val6 == (Object)null) { val6 = val7; } Button val8 = FindNativeButtonTemplate(gui); if ((Object)(object)val2 == (Object)null || (Object)(object)val5 == (Object)null || (Object)(object)val6 == (Object)null) { LogCreateFailure("Native barrel UI assets unavailable: background=" + ((Object)(object)val2 != (Object)null) + " titleFont=" + ((Object)(object)val5 != (Object)null) + " bodyFont=" + ((Object)(object)val6 != (Object)null) + " button=" + ((Object)(object)val8 != (Object)null)); return false; } GameObject val9 = new GameObject("CheckMyStuffBarrelPanel", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val9.transform.SetParent(((Transform)container).parent, false); val9.transform.SetSiblingIndex(Mathf.Min(((Transform)container).GetSiblingIndex() + 1, ((Transform)container).parent.childCount - 1)); SetLayerRecursively(val9, ((Component)gui).gameObject.layer); RectTransform component = val9.GetComponent<RectTransform>(); component.anchorMin = container.anchorMin; component.anchorMax = container.anchorMax; component.pivot = container.pivot; component.anchoredPosition = container.anchoredPosition; component.sizeDelta = new Vector2(360f, 454f); Image component2 = val9.GetComponent<Image>(); CopyImageStyle(val2, component2); ((Graphic)component2).color = Color.white; ((Graphic)component2).raycastTarget = true; if ((Object)(object)val4 != (Object)null) { GameObject obj = CreateImage("CheckMyStuffBarrelInset", (Transform)(object)component); RectTransform component3 = obj.GetComponent<RectTransform>(); component3.anchorMin = new Vector2(0f, 1f); component3.anchorMax = new Vector2(0f, 1f); component3.pivot = new Vector2(0f, 1f); component3.anchoredPosition = new Vector2(10f, -44f); component3.sizeDelta = new Vector2(340f, 392f); Image component4 = obj.GetComponent<Image>(); CopyImageStyle(val4, component4); ((Graphic)component4).color = new Color(1f, 1f, 1f, 0.72f); ((Graphic)component4).raycastTarget = false; obj.transform.SetAsFirstSibling(); } Shadow obj2 = ((Component)CreateNativeText(val5, (Transform)(object)component, "CheckMyStuffBarrelTitle", "CHECKMYSTUFF", new Vector2(12f, -8f), new Vector2(336f, 30f), 25f, (TextAlignmentOptions)514, new Color(1f, 0.718f, 0.36f, 1f))).gameObject.AddComponent<Shadow>(); obj2.effectColor = new Color(0f, 0f, 0f, 0.78f); obj2.effectDistance = new Vector2(2f, -2f); CreateNativeText(val6, (Transform)(object)component, "CheckMyStuffBarrelSubtitle", "STORE BAG ITEMS BY CATEGORY", new Vector2(14f, -48f), new Vector2(332f, 26f), 13f, (TextAlignmentOptions)514, new Color(0.88f, 0.76f, 0.57f, 1f)); CreateNativeButton(val8, val2, val6, (Transform)(object)component, "CheckMyStuffStoreAll", "Store All", new Vector2(14f, -86f), new Vector2(163f, 36f), ConfirmStoreAll); CheckMyStuffCategory[] selectableCategories = CheckMyStuffCategoryNames.GetSelectableCategories(); for (int i = 0; i < selectableCategories.Length; i++) { CheckMyStuffCategory checkMyStuffCategory = selectableCategories[i]; int num = i % 2; int num2 = i / 2; CheckMyStuffCategory capturedCategory = checkMyStuffCategory; CreateNativeButton(val8, val2, val6, (Transform)(object)component, "CheckMyStuffStore_" + checkMyStuffCategory, CheckMyStuffCategoryNames.ToDisplayName(checkMyStuffCategory), new Vector2(14f + (float)num * 169f, -130f - (float)num2 * 44f), new Vector2(163f, 36f), delegate { RouteCategory(capturedCategory); }); } s_statusText = CreateNativeText(val6, (Transform)(object)component, "CheckMyStuffBarrelStatus", "Choose Store All or a category to store bag items.", new Vector2(14f, -320f), new Vector2(332f, 52f), 12f, (TextAlignmentOptions)514, new Color(0.92f, 0.82f, 0.65f, 1f)); CreateNativeButton(val8, val2, val6, (Transform)(object)component, "CheckMyStuffBarrelClose", "Close", new Vector2(14f, -384f), new Vector2(332f, 38f), CloseUi); CreateConfirmDialog(component, val8, val2, val4, val5, val6); s_panel = val9; s_panelRect = component; val9.SetActive(false); s_createFailureLogged = false; if (CheckMyStuffPlugin.Log != null) { CheckMyStuffPlugin.Log.LogInfo((object)"CheckMyStuff barrel UI initialized on the native Valheim inventory layer at the container-panel position."); } return true; } private static void SyncPanelPosition(InventoryGui gui) { //IL_0032: 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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)gui == (Object)null) && !((Object)(object)gui.m_container == (Object)null) && !((Object)(object)s_panelRect == (Object)null)) { RectTransform container = gui.m_container; s_panelRect.anchorMin = container.anchorMin; s_panelRect.anchorMax = container.anchorMax; s_panelRect.pivot = container.pivot; s_panelRect.anchoredPosition = container.anchoredPosition; s_panelRect.sizeDelta = new Vector2(360f, 454f); } } private static void ConfirmStoreAll() { BarrelController active = BarrelController.Active; Player localPlayer = Player.m_localPlayer; if ((Object)(object)active == (Object)null || (Object)(object)localPlayer == (Object)null || (Object)(object)s_confirmRoot == (Object)null) { return; } int num = SortingEngine.CountStorable(localPlayer, ((Component)active).transform); if (num <= 0) { if ((Object)(object)s_statusText != (Object)null) { s_statusText.text = "Nothing to store: no bag items match an enabled labeled chest in range."; } return; } s_confirmText.text = "Are you sure you want to store " + num + " item" + ((num == 1) ? "" : "s") + "?"; s_confirmRoot.transform.SetAsLastSibling(); s_confirmRoot.SetActive(true); } private static void HideConfirm() { if ((Object)(object)s_confirmRoot != (Object)null && s_confirmRoot.activeSelf) { s_confirmRoot.SetActive(false); } } private static void CreateConfirmDialog(RectTransform panelRect, Button buttonTemplate, Image backgroundSource, Image sunkenSource, TMP_FontAsset titleFont, TMP_FontAsset bodyFont) { //IL_0013: 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_0033: 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_0049: 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_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: 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_00ef: 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_013b: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_024a: Unknown result type (might be due to invalid IL or missing references) GameObject obj = CreateImage("CheckMyStuffConfirm", (Transform)(object)panelRect); RectTransform component = obj.GetComponent<RectTransform>(); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.pivot = new Vector2(0.5f, 0.5f); component.anchoredPosition = Vector2.zero; component.sizeDelta = Vector2.zero; Image component2 = obj.GetComponent<Image>(); ((Graphic)component2).color = new Color(0f, 0f, 0f, 0.6f); ((Graphic)component2).raycastTarget = true; GameObject obj2 = CreateImage("CheckMyStuffConfirmBox", (Transform)(object)component); RectTransform component3 = obj2.GetComponent<RectTransform>(); component3.anchorMin = new Vector2(0f, 1f); component3.anchorMax = new Vector2(0f, 1f); component3.pivot = new Vector2(0f, 1f); component3.anchoredPosition = new Vector2(20f, -140f); component3.sizeDelta = new Vector2(320f, 170f); Image component4 = obj2.GetComponent<Image>(); CopyImageStyle(((Object)(object)sunkenSource != (Object)null) ? sunkenSource : backgroundSource, component4); ((Graphic)component4).color = Color.white; ((Graphic)component4).raycastTarget = true; CreateNativeText(titleFont, (Transform)(object)component3, "CheckMyStuffConfirmTitle", "Store All", new Vector2(10f, -10f), new Vector2(300f, 30f), 20f, (TextAlignmentOptions)514, new Color(1f, 0.718f, 0.36f, 1f)); s_confirmText = CreateNativeText(bodyFont, (Transform)(object)component3, "CheckMyStuffConfirmText", string.Empty, new Vector2(10f, -46f), new Vector2(300f, 52f), 15f, (TextAlignmentOptions)514, new Color(0.92f, 0.82f, 0.65f, 1f)); CreateNativeButton(buttonTemplate, backgroundSource, bodyFont, (Transform)(object)component3, "CheckMyStuffConfirmYes", "Yes", new Vector2(14f, -112f), new Vector2(140f, 40f), delegate { HideConfirm(); RouteCategory(null); }); CreateNativeButton(buttonTemplate, backgroundSource, bodyFont, (Transform)(object)component3, "CheckMyStuffConfirmNo", "No", new Vector2(166f, -112f), new Vector2(140f, 40f), HideConfirm); s_confirmRoot = obj; obj.SetActive(false); } private static void RouteCategory(CheckMyStuffCategory? category) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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) BarrelController active = BarrelController.Active; Player localPlayer = Player.m_localPlayer; if ((Object)(object)active == (Object)null || (Object)(object)localPlayer == (Object)null || !InventoryGui.IsVisible() || (Object)(object)InventoryGui.instance == (Object)null || InventoryGui.instance.IsContainerOpen()) { return; } Vector3 val = ((Component)localPlayer).transform.position - ((Component)active).transform.position; if (((Vector3)(ref val)).sqrMagnitude > 25f || !PrivateArea.CheckAccess(((Component)active).transform.position, 0f, false, false)) { return; } SortingResult sortingResult = (category.HasValue ? SortingEngine.SortCategory(localPlayer, ((Component)active).transform, category.Value) : SortingEngine.SortAll(localPlayer, ((Component)active).transform)); if (!((Object)(object)s_statusText == (Object)null)) { s_statusText.text = (category.HasValue ? CheckMyStuffCategoryNames.ToDisplayName(category.Value) : "Store All") + ": moved " + sortingResult.ItemsMoved + " item(s) from " + sortingResult.StacksTouched + " stack(s) into " + sortingResult.ChestsUsed + " chest(s)."; if (sortingResult.EligibleStacks > 0 && sortingResult.RemainingStacks > 0) { TMP_Text obj = s_statusText; obj.text = obj.text + " " + sortingResult.RemainingStacks + " stack(s) did not fit (matching chests full)."; } } } private static void CloseUi() { BarrelController.Close(); HidePanel(); if ((Object)(object)InventoryGui.instance != (Object)null && InventoryGui.IsVisible()) { InventoryGui.instance.Hide(); } } private static Button FindNativeButtonTemplate(InventoryGui gui) { if ((Object)(object)gui == (Object)null) { return null; } Button[] array = (Button[])(object)new Button[6] { gui.m_takeAllButton, gui.m_stackAllButton, gui.m_dropButton, gui.m_craftButton, gui.m_tabCraft, gui.m_tabUpgrade }; for (int i = 0; i < array.Length; i++) { if (IsUsableButtonTemplate(array[i])) { return array[i]; } } Button[] componentsInChildren = ((Component)gui).GetComponentsInChildren<Button>(true); for (int j = 0; j < componentsInChildren.Length; j++) { if (IsUsableButtonTemplate(componentsInChildren[j])) { return componentsInChildren[j]; } } return null; } private static bool IsUsableButtonTemplate(Button button) { if ((Object)(object)button == (Object)null) { return false; } Image component = ((Component)button).GetComponent<Image>(); if ((Object)(object)component != (Object)null) { return (Object)(object)component.sprite != (Object)null; } return false; } private static Button CreateNativeButton(Button template, Image fallbackImage, TMP_FontAsset font, Transform parent, string name, string label, Vector2 anchoredPosition, Vector2 size, Action action) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006d: 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_0094: 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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Expected O, but got Unknown //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_022d: 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_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_015f: 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) GameObject val = new GameObject(name, new Type[4] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Button) }) { layer = ((Component)parent).gameObject.layer }; val.transform.SetParent(parent, false); RectTransform component = val.GetComponent<RectTransform>(); component.anchorMin = new Vector2(0f, 1f); component.anchorMax = new Vector2(0f, 1f); component.pivot = new Vector2(0f, 1f); component.anchoredPosition = anchoredPosition; component.sizeDelta = size; Image component2 = val.GetComponent<Image>(); Image val2 = (((Object)(object)template != (Object)null) ? ((Component)template).GetComponent<Image>() : null); if ((Object)(object)val2 != (Object)null) { CopyImageStyle(val2, component2); ((Graphic)component2).color = ((Graphic)val2).color; } else if ((Object)(object)fallbackImage != (Object)null) { CopyImageStyle(fallbackImage, component2); ((Graphic)component2).color = new Color(0.44f, 0.3f, 0.2f, 0.96f); } Button component3 = val.GetComponent<Button>(); ((Selectable)component3).targetGraphic = (Graphic)(object)component2; if ((Object)(object)template != (Object)null) { ((Selectable)component3).transition = ((Selectable)template).transition; ((Selectable)component3).colors = ((Selectable)template).colors; ((Selectable)component3).spriteState = ((Selectable)template).spriteState; ((Selectable)component3).navigation = ((Selectable)template).navigation; } ((UnityEventBase)component3.onClick).RemoveAllListeners(); ((UnityEvent)component3.onClick).AddListener((UnityAction)delegate { action(); }); TMP_Text obj = CreateNativeText(font, (Transform)(object)component, name + "_Text", label, Vector2.zero, size, 14f, (TextAlignmentOptions)514, new Color(0.96f, 0.84f, 0.6f, 1f)); RectTransform rectTransform = obj.rectTransform; obj.enableAutoSizing = true; obj.fontSizeMin = 9f; obj.fontSizeMax = 14f; rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = Vector2.one; rectTransform.pivot = new Vector2(0.5f, 0.5f); rectTransform.anchoredPosition = Vector2.zero; rectTransform.sizeDelta = Vector2.zero; return component3; } private static TMP_Text CreateNativeText(TMP_FontAsset font, Transform parent, string name, string value, Vector2 anchoredPosition, Vector2 size, float fontSize, TextAlignmentOptions alignment, Color color) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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_0077: 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) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(TextMeshProUGUI) }) { layer = ((Component)parent).gameObject.layer }; val.transform.SetParent(parent, false); RectTransform component = val.GetComponent<RectTransform>(); component.anchorMin = new Vector2(0f, 1f); component.anchorMax = new Vector2(0f, 1f); component.pivot = new Vector2(0f, 1f); component.anchoredPosition = anchoredPosition; component.sizeDelta = size; TextMeshProUGUI component2 = val.GetComponent<TextMeshProUGUI>(); ((TMP_Text)component2).text = value; ((TMP_Text)component2).font = font; ((TMP_Text)component2).fontSize = fontSize; ((TMP_Text)component2).alignment = alignment; ((Graphic)component2).color = color; ((Graphic)component2).raycastTarget = false; ((TMP_Text)component2).overflowMode = (TextOverflowModes)1; return (TMP_Text)(object)component2; } private static TMP_FontAsset FindFont(InventoryGui gui, string fontName) { if ((Object)(object)gui == (Object)null) { return null; } TMP_Text[] componentsInChildren = ((Component)gui).GetComponentsInChildren<TMP_Text>(true); foreach (TMP_Text val in componentsInChildren) { if ((Object)(object)val != (Object)null && (Object)(object)val.font != (Object)null && string.Equals(((Object)val.font).name, fontName, StringComparison.Ordinal)) { return val.font; } } return null; } private static TMP_FontAsset FindAnyNativeFont(InventoryGui gui) { if ((Object)(object)gui == (Object)null) { return null; } TMP_Text[] componentsInChildren = ((Component)gui).GetComponentsInChildren<TMP_Text>(true); foreach (TMP_Text val in componentsInChildren) { if ((Object)(object)val != (Object)null && (Object)(object)val.font != (Object)null) { return val.font; } } return null; } private static GameObject CreateImage(string name, Transform parent) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown GameObject val = new GameObject(name, new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }) { layer = ((Component)parent).gameObject.layer }; val.transform.SetParent(parent, false); return val; } private static void CopyImageStyle(Image source, Image destination) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)source == (Object)null) && !((Object)(object)destination == (Object)null)) { destination.sprite = source.sprite; destination.overrideSprite = source.overrideSprite; destination.type = source.type; destination.preserveAspect = source.preserveAspect; destination.fillCenter = source.fillCenter; ((Graphic)destination).material = ((Graphic)source).material; destination.pixelsPerUnitMultiplier = source.pixelsPerUnitMultiplier; } } private static void SetLayerRecursively(GameObject root, int layer) { if (!((Object)(object)root == (Object)null)) { root.layer = layer; Transform transform = root.transform; for (int i = 0; i < transform.childCount; i++) { SetLayerRecursively(((Component)transform.GetChild(i)).gameObject, layer); } } } private static void HidePanel() { s_lastController = null; HideConfirm(); if ((Object)(object)s_panel != (Object)null && s_panel.activeSelf) { s_panel.SetActive(false); } } private static void LogCreateFailure(string message) { if (!s_createFailureLogged && CheckMyStuffPlugin.Log != null) { CheckMyStuffPlugin.Log.LogWarning((object)("CheckMyStuff native barrel UI could not initialize: " + message)); s_createFailureLogged = true; } } } public static class ChestLabelUi { private enum OptionsMode { None, Category, Subcategory } private const float PanelWidth = 350f; private const float CollapsedHeight = 232f; private const float ExpandedHeight = 525f; private const float PanelGap = 12f; private static readonly FieldInfo CurrentContainerField = typeof(InventoryGui).GetField("m_currentContainer", BindingFlags.Instance | BindingFlags.NonPublic); private static GameObject s_panel; private static RectTransform s_panelRect; private static RectTransform s_categoryOptionsRoot; private static RectTransform s_subcategoryOptionsRoot; private static Button s_categoryButton; private static Button s_subcategoryButton; private static Button s_enabledButton; private static TMP_Text s_categoryButtonText; private static TMP_Text s_subcategoryButtonText; private static TMP_Text s_enabledButtonText; private static TMP_Text s_statusText; private static Container s_lastContainer; private static OptionsMode s_optionsMode; private static bool s_createFailureLogged; private static Button s_buttonTemplate; private static Image s_backgroundSource; private static TMP_FontAsset s_bodyFont; private static CheckMyStuffCategory? s_subcategoryOptionsCategory; private static ItemTaxonomyPath s_taxonomyBrowsePath; private static int s_taxonomyPage; private const int TaxonomyPageSize = 8; private const float CheckboxSize = 18f; private static Container s_syncedContainer; private static uint s_syncedRevision; public static void ValidateContract() { if (CurrentContainerField == null || CurrentContainerField.FieldType != typeof(Container)) { throw new InvalidOperationException("InventoryGui.m_currentContainer contract is unavailable."); } } public static void Draw() { //IL_005c: Unknown result type (might be due to invalid IL or missing references) InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.m_container == (Object)null || (Object)(object)instance.m_player == (Object)null || !InventoryGui.IsVisible()) { HidePanel(); return; } Container currentContainer = GetCurrentContainer(instance); if ((Object)(object)currentContainer == (Object)null || !ChestLabelManager.IsSupportedChest(currentContainer)) { HidePanel(); } else if (!BarrelController.HasSorterInRange(((Component)currentContainer).transform.position)) { HidePanel(); } else if (!((Object)(object)s_panel == (Object)null) || TryCreatePanel(instance)) { if (currentContainer != s_lastContainer) { s_lastContainer = currentContainer; SetOptionsMode(OptionsMode.None); } ZNetView component = ((Component)currentContainer).GetComponent<ZNetView>(); uint num = (((Object)(object)component != (Object)null && component.IsValid() && component.GetZDO() != null) ? component.GetZDO().DataRevision : 0u); if (currentContainer != s_syncedContainer || num != s_syncedRevision || num == 0) { s_syncedContainer = currentContainer; s_syncedRevision = num; SyncState(currentContainer); } if (!s_panel.activeSelf) { s_panel.SetActive(true); } } } private static bool TryCreatePanel(InventoryGui gui) { //IL_010c: 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_011e: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Expected O, but got Unknown //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0143: 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_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02ba: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Unknown result type (might be due to invalid IL or missing references) //IL_0306: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_033c: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_036e: Unknown result type (might be due to invalid IL or missing references) //IL_0394: Unknown result type (might be due to invalid IL or missing references) //IL_03a3: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Unknown result type (might be due to invalid IL or missing references) //IL_03f9: Unknown result type (might be due to invalid IL or missing references) //IL_0408: Unknown result type (might be due to invalid IL or missing references) //IL_042b: Unknown result type (might be due to invalid IL or missing references) //IL_0451: 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_0519: Unknown result type (might be due to invalid IL or missing references) //IL_0528: Unknown result type (might be due to invalid IL or missing references) //IL_056b: Unknown result type (might be due to invalid IL or missing references) //IL_057a: Unknown result type (might be due to invalid IL or missing references) //IL_059d: Unknown result type (might be due to invalid IL or missing references) //IL_05e9: Unknown result type (might be due to invalid IL or missing references) //IL_05ef: Expected O, but got Unknown //IL_04f4: Unknown result type (might be due to invalid IL or missing references) RectTransform container = gui.m_container; RectTransform player = gui.m_player; Transform val = ((Transform)player).Find("Bkg"); Image val2 = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<Image>() : null); Transform val3 = ((Transform)player).Find("sunken"); Image val4 = (((Object)(object)val3 != (Object)null) ? ((Component)val3).GetComponent<Image>() : null); TMP_FontAsset val5 = FindFont(gui, "Valheim-Norsebold"); TMP_FontAsset val6 = FindFont(gui, "Valheim-AveriaSansLibre"); TMP_FontAsset val7 = FindAnyNativeFont(gui); if ((Object)(object)val5 == (Object)null) { val5 = val7; } if ((Object)(object)val6 == (Object)null) { val6 = val7; } Button val8 = FindNativeButtonTemplate(gui); if ((Object)(object)container == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val5 == (Object)null || (Object)(object)val6 == (Object)null) { LogCreateFailure(container, val2, val5, val6, val8); return false; } s_buttonTemplate = val8; s_backgroundSource = val2; s_bodyFont = val6; GameObject val9 = new GameObject("CheckMyStuffChestLabelPanel", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val9.transform.SetParent((Transform)(object)container, false); SetLayerRecursively(val9, ((Component)gui).gameObject.layer); RectTransform component = val9.GetComponent<RectTransform>(); component.anchorMin = new Vector2(1f, 1f); component.anchorMax = new Vector2(1f, 1f); component.pivot = new Vector2(0f, 1f); component.anchoredPosition = new Vector2(12f, 0f); component.sizeDelta = new Vector2(350f, 232f); Image component2 = val9.GetComponent<Image>(); CopyImageStyle(val2, component2); ((Graphic)component2).color = Color.white; ((Graphic)component2).raycastTarget = true; if ((Object)(object)val4 != (Object)null) { GameObject obj = CreateImage("CheckMyStuffNativeInset", (Transform)(object)component); RectTransform component3 = obj.GetComponent<RectTransform>(); component3.anchorMin = new Vector2(0f, 1f); component3.anchorMax = new Vector2(0f, 1f); component3.pivot = new Vector2(0f, 1f); component3.anchoredPosition = new Vector2(8f, -38f); component3.sizeDelta = new Vector2(334f, 184f); Image component4 = obj.GetComponent<Image>(); CopyImageStyle(val4, component4); ((Graphic)component4).color = new Color(1f, 1f, 1f, 0.78f); ((Graphic)component4).raycastTarget = false; obj.transform.SetAsFirstSibling(); } Shadow obj2 = ((Component)CreateNativeText(val5, (Transform)(object)component, "CheckMyStuffTitle", "CHECKMYSTUFF", new Vector2(12f, -7f), new Vector2(326f, 36f), 23f, (TextAlignmentOptions)514, new Color(1f, 0.718f, 0.36f, 1f))).gameObject.AddComponent<Shadow>(); obj2.effectColor = new Color(0f, 0f, 0f, 0.78f); obj2.effectDistance = new Vector2(2f, -2f); CreateNativeText(val6, (Transform)(object)component, "CheckMyStuffCategoryLabel", "Category", new Vector2(14f, -44f), new Vector2(220f, 18f), 13f, (TextAlignmentOptions)513, new Color(0.92f, 0.82f, 0.65f, 1f)); s_categoryButton = CreateNativeButton(val8, val2, val6, (Transform)(object)component, "CheckMyStuffCategoryButton", "Unassigned", new Vector2(12f, -63f), new Vector2(326f, 36f), delegate { ToggleOptions(OptionsMode.Category); }); s_categoryButtonText = ((Component)s_categoryButton).GetComponentInChildren<TMP_Text>(true); CreateNativeText(val6, (Transform)(object)component, "CheckMyStuffSubcategoryLabel", "Subcategory", new Vector2(14f, -98f), new Vector2(220f, 18f), 13f, (TextAlignmentOptions)513, new Color(0.92f, 0.82f, 0.65f, 1f)); s_subcategoryButton = CreateNativeButton(val8, val2, val6, (Transform)(object)component, "CheckMyStuffSubcategoryButton", "All Types", new Vector2(12f, -117f), new Vector2(326f, 36f), delegate { ToggleOptions(OptionsMode.Subcategory); }); s_subcategoryButtonText = ((Component)s_subcategoryButton).GetComponentInChildren<TMP_Text>(true); if ((Object)(object)s_subcategoryButtonText != (Object)null) { s_subcategoryButtonText.enableAutoSizing = false; s_subcategoryButtonText.fontSize = 13f; s_subcategoryButtonText.textWrappingMode = (TextWrappingModes)0; s_subcategoryButtonText.overflowMode = (TextOverflowModes)1; s_subcategoryButtonText.margin = new Vector4(8f, 0f, 8f, 0f); } s_enabledButton = CreateNativeButton(val8, val2, val6, (Transform)(object)component, "CheckMyStuffEnabledButton", "Enabled: OFF", new Vector2(12f, -155f), new Vector2(326f, 36f), ToggleEnabled); s_enabledButtonText = ((Component)s_enabledButton).GetComponentInChildren<TMP_Text>(true); s_statusText = CreateNativeText(val6, (Transform)(object)component, "CheckMyStuffStatus", "Choose a category to label this chest.", new Vector2(12f, -191f), new Vector2(326f, 32f), 11f, (TextAlignmentOptions)514, new Color(0.88f, 0.78f, 0.62f, 0.95f)); s_categoryOptionsRoot = CreateOptionsRoot((Transform)(object)component, "CheckMyStuffCategoryOptions", ((Component)gui).gameObject.layer); s_subcategoryOptionsRoot = CreateOptionsRoot((Transform)(object)component, "CheckMyStuffSubcategoryOptions", ((Component)gui).gameObject.layer); BuildCategoryOptions(); s_panel = val9; s_panelRect = component; SetOptionsMode(OptionsMode.None); val9.SetActive(false); s_createFailureLogged = false; if (CheckMyStuffPlugin.Log != null) { CheckMyStuffPlugin.Log.LogInfo((object)"CheckMyStuff chest label UI initialized with native Category + Subcategory + Enabled controls."); } return true; } private static RectTransform CreateOptionsRoot(Transform parent, string name, int layer) { //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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_003d: 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_0067: 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) //IL_0087: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); SetLayerRecursively(val, layer); RectTransform component = val.GetComponent<RectTransform>(); component.anchorMin = new Vector2(0f, 1f); component.anchorMax = new Vector2(0f, 1f); component.pivot = new Vector2(0f, 1f); component.anchoredPosition = Vector2.zero; component.sizeDelta = new Vector2(350f, 525f); return component; } private static void BuildCategoryOptions() { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)s_categoryOptionsRoot == (Object)null) { return; } CheckMyStuffCategory[] selectableCategories = CheckMyStuffCategoryNames.GetSelectableCategories(); for (int i = 0; i < selectableCategories.Length; i++) { CheckMyStuffCategory checkMyStuffCategory = selectableCategories[i]; int num = i % 2; int num2 = i / 2; CheckMyStuffCategory capturedCategory = checkMyStuffCategory; CreateNativeButton(s_buttonTemplate, s_backgroundSource, s_bodyFont, (Transform)(object)s_categoryOptionsRoot, "CheckMyStuffCategory_" + checkMyStuffCategory, CheckMyStuffCategoryNames.ToDisplayName(checkMyStuffCategory), new Vector2(12f + (float)num * 166f, -226f - (float)num2 * 40f), new Vector2(158f, 36f), delegate { SelectCategory(capturedCategory); }); } CreateNavigation(0, 1, delegate { SetOptionsMode(OptionsMode.None); }, null); } private static void RebuildSubcategoryOptions(CheckMyStuffCategory category) { if (!((Object)(object)s_subcategoryOptionsRoot == (Object)null)) { if (!s_subcategoryOptionsCategory.HasValue || s_subcategoryOptionsCategory.Value != category) { s_taxonomyBrowsePath = ItemTaxonomy.GetInitialBrowsePath(category); s_taxonomyPage = 0; } s_subcategoryOptionsCategory = category; RebuildTaxonomyOptions(category, s_taxonomyBrowsePath, s_taxonomyPage); } } private static void RebuildTaxonomyOptions(CheckMyStuffCategory category, ItemTaxonomyPath parent, int page) { //IL_01db: 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) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_037e: Unknown result type (might be due to invalid IL or missing references) //IL_038d: Unknown result type (might be due to invalid IL or missing references) //IL_032e: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Unknown result type (might be due to invalid IL or missing references) //IL_03cc: Unknown result type (might be due to invalid IL or missing references) //IL_03db: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)s_subcategoryOptionsRoot == (Object)null) { return; } ItemTaxonomyPath itemTaxonomyPath = parent ?? new ItemTaxonomyPath(null, null, null, null); if (ItemTaxonomy.IsFinalChoice(category, itemTaxonomyPath) && itemTaxonomyPath.Depth > ItemTaxonomy.GetInitialBrowsePath(category).Depth) { ItemTaxonomyPath parent2 = itemTaxonomyPath.Parent(); int val = ItemTaxonomy.GetChildren(category, parent2).IndexOf(itemTaxonomyPath.GetPart(itemTaxonomyPath.Depth - 1)); RebuildTaxonomyOptions(category, parent2, Math.Max(0, val) / 8); return; } ClearOptionButtons((Transform)(object)s_subcategoryOptionsRoot); s_subcategoryOptionsCategory = category; s_taxonomyBrowsePath = itemTaxonomyPath; List<string> children = ItemTaxonomy.GetChildren(category, s_taxonomyBrowsePath); ChestLabelState state = null; if ((Object)(object)s_lastContainer != (Object)null) { ChestLabelManager.TryRead(s_lastContainer, out state); } int num = Math.Max(1, (children.Count + 8 - 1) / 8); s_taxonomyPage = Math.Max(0, Math.Min(page, num - 1)); int num2 = s_taxonomyPage * 8; int num3 = Math.Min(children.Count, num2 + 8); for (int i = num2; i < num3; i++) { string value = children[i]; int num4 = i - num2; ItemTaxonomyPath childPath = s_taxonomyBrowsePath.WithChild(value); bool finalChoice = ItemTaxonomy.IsFinalChoice(category, childPath); Button val2 = CreateNativeButton(s_buttonTemplate, s_backgroundSource, s_bodyFont, (Transform)(object)s_subcategoryOptionsRoot, "CheckMyStuffTaxonomy_" + s_taxonomyPage + "_" + num4, ItemTaxonomy.GetOptionDisplayName(value), new Vector2(12f + (float)(num4 % 2) * 166f, -270f - (float)(num4 / 2) * 40f), new Vector2(158f, 36f), delegate { if (finalChoice) { SelectTaxonomyPath(childPath); } else { RebuildTaxonomyOptions(category, childPath, 0); } }); TMP_Text componentInChildren = ((Component)val2).GetComponentInChildren<TMP_Text>(true); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.rectTransform.anchoredPosition = new Vector2(13f, 0f); componentInChildren.rectTransform.sizeDelta = new Vector2(-26f, 0f); } CreateNativeButton(s_buttonTemplate, s_backgroundSource, s_bodyFont, ((Component)val2).transform, "CheckMyStuffTick_" + s_taxonomyPage + "_" + num4, IsTicked(state, childPath) ? "X" : string.Empty, new Vector2(4f, -9f), new Vector2(18f, 18f), delegate { ToggleTaxonomyPath(category, childPath); }); } UpdateBrowseIndicator(category, s_taxonomyBrowsePath); ItemTaxonomyPath selectedPath = s_taxonomyBrowsePath; if (selectedPath.Depth == 0) { CreateNativeButton(s_buttonTemplate, s_backgroundSource, s_bodyFont, (Transform)(object)s_subcategoryOptionsRoot, "CheckMyStuffTaxonomyAllTypes", "All Types", new Vector2(12f, -226f), new Vector2(158f, 36f), SelectAllTypes); } else { CreateNativeButton(s_buttonTemplate, s_backgroundSource, s_bodyFont, (Transform)(object)s_subcategoryOptionsRoot, "CheckMyStuffTaxonomyUse", "All Types", new Vector2(12f, -226f), new Vector2(158f, 36f), delegate { SelectTaxonomyPath(selectedPath); }); } CreateNativeButton(s_buttonTemplate, s_backgroundSource, s_bodyFont, (Transform)(object)s_subcategoryOptionsRoot, "CheckMyStuffTaxonomyClearAll", "Clear All", new Vector2(178f, -226f), new Vector2(158f, 36f), delegate { ClearAllSelections(category); }); CreateNavigation(s_taxonomyPage, num, delegate { if (s_taxonomyPage > 0) { RebuildTaxonomyOptions(category, s_taxonomyBrowsePath, s_taxonomyPage - 1); } else if (s_taxonomyBrowsePath.Depth > ItemTaxonomy.GetInitialBrowsePath(category).Depth) { ItemTaxonomyPath parent3 = s_taxonomyBrowsePath.Parent(); List<string> children2 = ItemTaxonomy.GetChildren(category, parent3); string part = s_taxonomyBrowsePath.GetPart(s_taxonomyBrowsePath.Depth - 1); int page2 = Math.Max(0, children2.IndexOf(part)) / 8; RebuildTaxonomyOptions(category, parent3, page2); } else { SetOptionsMode(OptionsMode.None); if ((Object)(object)s_lastContainer != (Object)null) { SyncState(s_lastContainer); } } }, delegate { RebuildTaxonomyOptions(category, s_taxonomyBrowsePath, s_taxonomyPage + 1); }); } private static void CreateNavigation(int page, int count, Action previous, Action next) { //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_009b: 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_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) Transform parent = (Transform)(object)((next == null) ? s_categoryOptionsRoot : s_subcategoryOptionsRoot); List<string> list = new List<string>(); for (int i = 0; i < count; i++) { list.Add((i == page) ? ("<color=#FFD479>" + (i + 1) + "</color>") : (i + 1).ToString()); } TMP_Text obj = CreateNativeText(s_bodyFont, parent, "CheckMyStuffPageNumbers", string.Join("..", list.ToArray()), new Vector2(12f, -440f), new Vector2(326f, 24f), 12f, (TextAlignmentOptions)514, Color.white); obj.enableAutoSizing = true; obj.fontSizeMin = 8f; obj.fontSizeMax = 12f; CreateNativeButton(s_buttonTemplate, s_backgroundSource, s_bodyFont, parent, "CheckMyStuffTaxonomyPrevious", "Previous", new Vector2(12f, -470f), new Vector2(158f, 36f), previous); ((Selectable)CreateNativeButton(s_buttonTemplate, s_backgroundSource, s_bodyFont, parent, "CheckMyStuffTaxonomyNext", "Next", new Vector2(180f, -470f), new Vector2(158f, 36f), delegate { if (next != null) { next(); } })).interactable = next != null && page + 1 < count; } private static void ClearOptionButtons(Transform root) { for (int num = root.childCount - 1; num >= 0; num--) { Transform child = root.GetChild(num); if ((Object)(object)child != (Object)null) { ((Component)child).gameObject.SetActive(false); Object.Destroy((Object)(object)((Component)child).gameObject); } } } private static void ToggleOptions(OptionsMode requested) { OptionsMode optionsMode = ((s_optionsMode != requested) ? requested : OptionsMode.None); bool flag = s_optionsMode == OptionsMode.Subcategory && optionsMode != OptionsMode.Subcategory; if (optionsMode == OptionsMode.Subcategory && (Object)(object)s_lastContainer != (Object)null && ChestLabelManager.TryRead(s_lastContainer, out var state) && state != null) { s_taxonomyBrowsePath = state.Selection ?? ItemTaxonomy.GetInitialBrowsePath(state.Category); s_taxonomyPage = 0; RebuildSubcategoryOptions(state.Category); } SetOptionsMode(optionsMode); if (flag && (Object)(object)s_lastContainer != (Object)null) { SyncState(s_lastContainer); } } private static void UpdateBrowseIndicator(CheckMyStuffCategory category, ItemTaxonomyPath browsePath) { string selectionDisplayName = ItemTaxonomy.GetSelectionDisplayName(category, browsePath); if ((Object)(object)s_subcategoryButtonText != (Object)null) { s_subcategoryButtonText.text = selectionDisplayName; } } private static void SetOptionsMode(OptionsMode mode) { //IL_006c: Unknown result type (might be due to invalid IL or missing references) s_optionsMode = mode; if ((Object)(object)s_categoryOptionsRoot != (Object)null) { ((Component)s_categoryOptionsRoot).gameObject.SetActive(mode == OptionsMode.Category); } if ((Object)(object)s_subcategoryOptionsRoot != (Object)null) { ((Component)s_subcategoryOptionsRoot).gameObject.SetActive(mode == OptionsMode.Subcategory); } if ((Object)(object)s_panelRect != (Object)null) { s_panelRect.sizeDelta = new Vector2(350f, (mode == OptionsMode.None) ? 232f : 525f); } } private static void SelectCategory(CheckMyStuffCategory category) { Container val = s_lastContainer; if (!((Object)(object)val == (Object)null)) { ChestLabelState state; bool enabled = ChestLabelManager.TryRead(val, out state) && state.Enabled; if (!ChestLabelManager.TryWrite(val, category, "AllTypes", enabled)) { LogWriteFailure("Could not write chest category " + CheckMyStuffCategoryNames.ToDisplayName(category) + "."); return; } s_taxonomyBrowsePath = ItemTaxonomy.GetInitialBrowsePath(category); s_taxonomyPage = 0; RebuildSubcategoryOptions(category); SetOptionsMode(OptionsMode.None); SyncState(val); } } private static void SelectAllTypes() { Container val = s_lastContainer; if (!((Object)(object)val == (Object)null) && ChestLabelManager.TryRead(val, out var state)) { if (!ChestLabelManager.TryWrite(val, state.Category, "AllTypes", state.Enabled)) { LogWriteFailure("Could not reset the chest taxonomy selection."); return; } SetOptionsMode(OptionsMode.None); SyncState(val); } } private static void ClearAllSelections(CheckMyStuffCategory category) { Container val = s_lastContainer; if (!((Object)(object)val == (Object)null) && ChestLabelManager.TryRead(val, out var state) && state != null) { if (!ChestLabelManager.TryWriteSelections(val, state.Category, new ItemTaxonomyPath[0], state.Enabled)) { LogWriteFailure("Could not clear chest label selections."); return; } RebuildTaxonomyOptions(category, s_taxonomyBrowsePath, s_taxonomyPage); SyncState(val); } } private static bool IsTicked(ChestLabelState state, ItemTaxonomyPath path) { if (state == null || path == null) { return false; } string text = TaxonomyOrganization.Key(path); foreach (ItemTaxonomyPath selection in state.Selections) { if (TaxonomyOrganization.Key(selection) == text) { return true; } } return false; } private static void ToggleTaxonomyPath(CheckMyStuffCategory category, ItemTaxonomyPath path) { Container val = s_lastContainer; if ((Object)(object)val == (Object)null || path == null || !ChestLabelManager.TryRead(val, out var state) || state == null) { return; } List<ItemTaxonomyPath> list = new List<ItemTaxonomyPath>(state.Selections); string key = TaxonomyOrganization.Key(path); int num = list.FindIndex((ItemTaxonomyPath p) => TaxonomyOrganization.Key(p) == key); if (num >= 0) { list.RemoveAt(num); } else { if (list.Count > 0 && list[0].Depth != path.Depth) { if ((Object)(object)Player.m_localPlayer != (Object)null) { ((Character)Player.m_localPlayer).Message((MessageType)2, "Tick entries on one level only: untick the others first.", 0, (Sprite)null, false); } return; } list.Add(path); } if (!ChestLabelManager.TryWriteSelections(val, state.Category, list, state.Enabled)) { LogWriteFailure("Could not write chest label selections."); return; } if (list.Count == 0 && (Object)(object)Player.m_localPlayer != (Object)null) { ((Character)Player.m_localPlayer).Message((MessageType)2, "Nothing ticked: this chest now takes all " + CheckMyStuffCategoryNames.ToDisplayName(state.Category) + ".", 0, (Sprite)null, false); } RebuildTaxonomyOptions(category, s_taxonomyBrowsePath, s_taxonomyPage); SyncState(val); } private static void SelectTaxonomyPath(ItemTaxonomyPath selection) { Container val = s_lastContainer; if (!((Object)(object)val == (Object)null) && selection != null && ChestLabelManager.TryRead(val, out var state) && state != null) { if (!ChestLabelManager.TryWriteSelection(val, state.Category, selection, state.Enabled)) { LogWriteFailure("Could not write chest taxonomy selection: " + ItemTaxonomy.GetSelectionDisplayName(state.Category, selection)); return; } SetOptionsMode(OptionsMode.None); SyncState(val); } } private static void ToggleEnabled() { Container val = s_lastContainer; if (!((Object)(object)val == (Object)null) && ChestLabelManager.TryRead(val, out var state)) { if (!ChestLabelManager.TrySetEnabled(val, !state.Enabled)) { LogWriteFailure("Could not update chest Enabled state."); } else { SyncState(val); } } } private static void SyncState(Container container) { ChestLabelState state; bool flag = ChestLabelManager.TryRead(container, out state); string text = (flag ? CheckMyStuffCategoryNames.ToDisplayName(state.Category) : "Unassigned"); string text2 = ((!flag) ? "All Types" : ((state.Selection != null) ? ItemTaxonomy.GetSelectionsDisplayName(state.Category, state.Selections) : ((state.Subcategory != "AllTypes") ? state.Subcategory : "All Types"))); if ((Object)(object)s_categoryButtonText != (Object)null) { s_categoryButtonText.text = text; } if ((Object)(object)s_subcategoryButton != (Object)null) { ((Selectable)s_subcategoryButton).interactable = flag; } if ((Object)(object)s_subcategoryButtonText != (Object)null) { s_subcategoryButtonText.text = text2; } if ((Object)(object)s_enabledButton != (Object)null) { ((Selectable)s_enabledButton).interactable = flag; } if ((Object)(object)s_enabledButtonText != (Object)null) { s_enabledButtonText.text = "Enabled: " + ((flag && state.Enabled) ? "ON" : "OFF"); } if (flag && (!s_subcategoryOptionsCategory.HasValue || s_subcategoryOptionsCategory.Value != state.Category)) { RebuildSubcategoryOptions(state.Category); } if ((Object)(object)s_statusText != (Object)null) { s_statusText.text = (flag ? string.Empty : "Choose a category to label this chest."); } if (flag && s_optionsMode == OptionsMode.Subcategory) { UpdateBrowseIndicator(state.Category, s_taxonomyBrowsePath); } } private static Button FindNativeButtonTemplate(InventoryGui gui) { if ((Object)(object)gui == (Object)null) { return null; } Button[] array = (Button[])(object)new Button[6] { gui.m_takeAllButton, gui.m_stackAllButton, gui.m_dropButton, gui.m_craftButton, gui.m_tabCraft, gui.m_tabUpgrade }; for (int i = 0; i < array.Length; i++) { if (IsUsableButtonTemplate(array[i])) { return array[i]; } } Button[] componentsInChildren = ((Component)gui).GetComponentsInChildren<Button>(true); for (int j = 0; j < componentsInChildren.Length; j++) { if (IsUsableButtonTemplate(componentsInChildren[j])) { return componentsInChildren[j]; } } return null; } private static bool IsUsableButtonTemplate(Button button) { if ((Object)(object)button == (Object)null) { return false; } Image component = ((Component)button).GetComponent<Image>(); if ((Object)(object)component != (Object)null) { return (Object)(object)component.sprite != (Object)null; } return false; } private static TMP_Text CreateNativeText(TMP_FontAsset font, Transform parent, string name, string value, Vector2 anchoredPosition, Vector2 size, float fontSize, TextAlignmentOptions alignment, Color color) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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_0077: 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) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(TextMeshProUGUI) }) { layer = ((Component)parent).gameObject.layer }; val.transform.SetParent(parent, false); RectTransform component = val.GetComponent<RectTransform>(); component.anchorMin = new Vector2(0f, 1f); component.anchorMax = new Vector2(0f, 1f); component.pivot = new Vector2(0f, 1f); component.anchoredPosition = anchoredPosition; component.sizeDelta = size; TextMeshProUGUI component2 = val.GetComponent<TextMeshProUGUI>(); ((TMP_Text)component2).text = value; ((TMP_Text)component2).font = font; ((TMP_Text)component2).fontSize = fontSize; ((TMP_Text)component2).alignment = alignment; ((Graphic)component2).color = color; ((Graphic)component2).raycastTarget = false; ((TMP_Text)component2).overflowMode = (TextOverflowModes)1; return (TMP_Text)(object)component2; } private static Button CreateNativeButton(Button template, Image fallbackImage, TMP_FontAsset font, Transform parent, string name, string label, Vector2 anchoredPosition, Vector2 size, Action action) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006d: 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_0094: 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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Expected O, but got Unknown //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_021d: 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_0232: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_015f: 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) GameObject val = new GameObject(name, new Type[4] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Button) }) { layer = ((Component)parent).gameObject.layer }; val.transform.SetParent(parent, false); RectTransform component = val.GetComponent<RectTransform>(); component.anchorMin = new Vector2(0f, 1f); component.anchorMax = new Vector2(0f, 1f); component.pivot = new Vector2(0f, 1f); component.anchoredPosition = anchoredPosition; component.sizeDelta = size; Image component2 = val.GetComponent<Image>(); Image val2 = (((Object)(object)template != (Object)null) ? ((Component)template).GetComponent<Image>() : null); if ((Object)(object)val2 != (Object)null) { CopyImageStyle(val2, component2); ((Graphic)component2).color = ((Graphic)val2).color; } else if ((Object)(object)fallbackImage != (Object)null) { CopyImageStyle(fallbackImage, component2); ((Graphic)component2).color = new Color(0.5f, 0.35f, 0.22f, 0.95f); } Button component3 = val.GetComponent<Button>(); ((Selectable)component3).targetGraphic = (Graphic)(object)component2; if ((Object)(object)template != (Object)null) { ((Selectable)component3).transition = ((Selectable)template).transition; ((Selectable)component3).colors = ((Selectable)template).colors; ((Selectable)component3).spriteState = ((Selectable)template).spriteState; ((Selectable)component3).navigation = ((Selectable)template).navigation; } ((UnityEventBase)component3.onClick).RemoveAllListeners(); ((UnityEvent)component3.onClick).AddListener((UnityAction)delegate { action(); }); TMP_Text obj = CreateNativeText(font, (Transform)(object)component, name + "_Text", label, Vector2.zero, size, 13f, (TextAlignmentOptions)514, new Color(0.96f, 0.84f, 0.6f, 1f)); obj.enableAutoSizing = true; obj.fontSizeMin = 9f; obj.fontSizeMax = obj.fontSize; RectTransform rectTransform = obj.rectTransform; rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = Vector2.one; rectTransform.pivot = new Vector2(0.5f, 0.5f); rectTransform.anchoredPosition = Vector2.zero; rectTransform.sizeDelta = Vector2.zero; return component3; } private static GameObject CreateImage(string name, Transform parent) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown GameObject val = new GameObject(name, new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }) { layer = ((Component)parent).gameObject.layer }; val.transform.SetParent(parent, false); return val; } private static void CopyImageStyle(Image source, Image destination) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)source == (Object)null) && !((Object)(object)destination == (Object)null)) { destination.sprite = source.sprite; destination.overrideSprite = source.overrideSprite; destination.type = source.type; destination.preserveAspect = source.preserveAspect; destination.fillCenter = source.fillCenter; ((Graphic)destination).material = ((Graphic)source).material; destination.pixelsPerUnitMultiplier = source.pixelsPerUnitMultiplier; } } private static TMP_FontAsset FindFont(InventoryGui gui, string fontName) { if ((Object)(object)gui == (Object)null) { return null; } TMP_Text[] componentsInChildren = ((Component)gui).GetComponentsInChildren<TMP_Text>(true); foreach (TMP_Text val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val.font == (Object)null) && string.Equals(((Object)val.font).name, fontName, StringComparison.Ordinal)) { return val.font; } } return null; } private static TMP_FontAsset FindAnyNativeFont(InventoryGui gui) { if ((Object)(object)gui == (Object)null) { return null; } TMP_Text[] componentsInChildren = ((Component)gui).GetComponentsInChildren<TMP_Text>(true); foreach (TMP_Text val in componentsInChildren) { if ((Object)(object)val != (Object)null && (Object)(object)val.font != (Object)null) { return val.font; } } return null; } private static void SetLayerRecursively(GameObject root, int layer) { if (!((Object)(object)root == (Object)null)) { root.layer = layer; Transform transform = root.transform; for (int i = 0; i < transform.childCount; i++) { SetLayerRecursively(((Component)transform.GetChild(i)).gameObject, layer); } } } private static void LogCreateFailure(RectTransform containerRect, Image backgroundSource, TMP_FontAsset titleFont, TMP_FontAsset bodyFont, Button buttonTemplate) { if (!s_createFailureLogged && CheckMyStuffPlugin.Log != null) { CheckMyStuffPlugin.Log.LogWarning((object)("CheckMyStuff native chest UI template audit failed. container=" + ((Object)(object)containerRect != (Object)null) + " playerBkg=" + ((Object)(object)backgroundSource != (Object)null) + " titleFont=" + ((Object)(object)titleFont != (Object)null) + " bodyFont=" + ((Object)(object)bodyFont != (Object)null) + " buttonTemplate=" + ((Object)(object)buttonTemplate != (Object)null) + ". The panel will retry on later frames.")); s_createFailureLogged = true; } } private static Container GetCurrentContainer(InventoryGui gui) { if ((Object)(object)gui == (Object)null || CurrentContainerField == null) { return null; } object? value = CurrentContainerField.GetValue(gui); return (Container)((value is Container) ? value : null); } private static void HidePanel() { s_lastContainer = null; SetOptionsMode(OptionsMode.None); if ((Object)(object)s_panel != (Object)null && s_panel.activeSelf) { s_panel.SetActive(false); } } private static void LogWriteFailure(string message) { if (CheckMyStuffPlugin.Log != null) { CheckMyStuffPlugin.Log.LogWarning((object)message); } } } [HarmonyPatch(typeof(Container), "GetHoverText")] internal static class ContainerHoverPatch { private static Container s_container; private static uint s_revision; private static string s_label; private static void Postfix(Container __instance, ref string __result) { if (!((Object)(object)__instance == (Object)null) && !string.IsNullOrEmpty(__result)) { ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); uint num = (((Object)(object)component != (Object)null && component.IsValid() && component.GetZDO() != null) ? component.GetZDO().DataRevision : 0u); if (__instance != s_container || num != s_revision || num == 0) { s_container = __instance; s_revision = num; s_label = ((ChestLabelManager.TryRead(__instance, out var state) && state != null && state.Enabled) ? ItemTaxonomy.GetLabelShortName(state) : null); } __result = AppendLabel(__result, s_label); } } internal static string AppendLabel(string hoverText, string label) { if (!string.IsNullOrEmpty(label)) { return hoverText + "\n" + label; } return hoverText; } } [HarmonyPatch(typeof(ItemData), "GetTooltip", new Type[] { typeof(ItemData), typeof(int), typeof(bool), typeof(float), typeof(int), typeof(bool) })] internal static class ItemTooltipPatch { private const string WeightLine = "\n$item_weight"; private static readonly Dictionary<string, string> Lines = new Dictionary<string, string>(StringComparer.Ordinal); private static int s_revision = int.MinValue; private static void Postfix(ItemData item, bool appending, ref string __result) { if (!appending && item != null && !string.IsNullOrEmpty(__result)) { __result = InsertPath(__result, GetLine(item)); } } internal static string InsertPath(string tooltip, string path) { if (string.IsNullOrEmpty(tooltip) || string.IsNullOrEmpty(path)) { return tooltip; } string text = "\n<size=80%>" + path + "</size>"; int num = tooltip.IndexOf("\n$item_weight", StringComparison.Ordinal); if (num < 0) { return tooltip + text; } return tooltip.Insert(num, text); } private static string GetLine(ItemData item) { if (s_revision != ItemTaxonomy.Revision) { Lines.Clear(); s_revision = ItemTaxonomy.Revision; } string text = (((Object)(object)item.m_dropPrefab == (Object)null) ? null : Utils.GetPrefabName(((Object)item.m_dropPrefab).name)); if (text != null && Lines.TryGetValue(text, out var value)) { return value; } value = (ItemClassifier.TryClassifyTaxonomy(item, out var _, out var path, out var _) ? ItemTaxonomy.GetTooltipPath(path) : string.Empty); if (text != null) { Lines[text] = value; } return value; } } } namespace CheckMyStuff.Routing { [HarmonyPatch(typeof(Container), "Awake")] internal static class ContainerAwakePatch { private static void Postfix(Container __instance) { ContainerFinder.Register(__instance); } } public static class ContainerFinder { private static readonly MethodInfo LoadInventory = typeof(Container).GetMethod("Load", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly List<Container> Snapshot = new List<Container>(); private const string RequestOwnerRpc = "CheckMyStuff_RequestOwner"; private const string OwnerReplyRpc = "CheckMyStuff_OwnerReply"; private const float OwnerRequestCooldown = 3f; private static readonly HashSet<ZNetView> RpcViews = new HashSet<ZNetView>(); private static readonly Dictionary<ZDOID, float> OwnerRequests = new Dictionary<ZDOID, float>(); public static event Action OwnershipGranted; public static void Register(Container container) { if ((Object)(object)container == (Object)null) { return; } for (int num = Snapshot.Count - 1; num >= 0; num--) { if ((Object)(object)Snapshot[num] == (Object)null) { Snapshot.RemoveAt(num); } else if ((Object)(object)Snapshot[num] == (Object)(object)container) { return; } } Snapshot.Add(container); RegisterOwnershipRpcs(container); } private static void RegisterOwnershipRpcs(Container container) { ZNetView view = GetView(container); if ((Object)(object)view == (Object)null) { return; } if (RpcViews.Count > 256) { RpcViews.RemoveWhere((ZNetView v) => (Object)(object)v == (Object)null); } if (RpcViews.Add(view)) { view.Register("CheckMyStuff_RequestOwner", (Action<long>)delegate(long sender) { RPC_RequestOwner(container, view, sender); }); view.Register<bool>("CheckMyStuff_OwnerReply", (Action<long, bool>)delegate(long sender, bool granted) { RPC_OwnerReply(granted); }); } } private static void RPC_RequestOwner(Container container, ZNetView view, long sender) { if (!((Object)(object)view == (Object)null) && view.IsValid() && view.IsOwner() && view.GetZDO() != null) { bool flag = (Object)(object)container != (Object)null && !IsInUse(container); if (flag) { view.GetZDO().SetOwner(sender); } view.InvokeRPC(sender, "CheckMyStuff_OwnerReply", new object[1] { flag }); } } private static void RPC_OwnerReply(bool granted) { if (granted && ContainerFinder.OwnershipGranted != null) { ContainerFinder.OwnershipGranted(); } } private static void RequestOwnership(ZNetView view) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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) ZDOID uid = view.GetZDO().m_uid; if (!OwnerRequests.TryGetValue(uid, out var value) || !(Time.time - value < 3f)) { OwnerRequests[uid] = Time.time; view.InvokeRPC("CheckMyStuff_RequestOwner", Array.Empty<object>()); } } public static bool TryPrepareForWrite(Container container) { if ((Object)(object)container == (Object)null || !ChestLabelManager.IsSupportedChest(container) || IsInUse(container)) { return false; } if (!HasVanillaAccess(container)) { return false; } ZNetView view = GetView(container); if ((Object)(object)view == (Object)null || !view.IsValid() || view.GetZDO() == null) { return false; } if (!view.IsOwner()) { if (view.GetZDO().GetOwner() != 0L) { RequestOwnership(view); return false; } view.ClaimOwnership(); } if (!view.IsOwner() || LoadInventory == null || IsInUse(container)) { return false; } LoadInventory.Invoke(container, null); return !IsInUse(container); } public static List<Container> FindMatchingForItem(Vector3 origin, CheckMyStuffCategory category, ItemTaxonomyPath itemPath, string legacySubcategory) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) List<Container> list = new List<Container>(); float num = 2500f; for (int i = 0; i < Snapshot.Count; i++) { Container val = Snapshot[i]; if (!((Object)(object)val == (Object)null)) { Vector3 val2 = ((Component)val).transform.position - origin; if (!(((Vector3)(ref val2)).sqrMagnitude > num) && TryMatchState(val, category, itemPath, legacySubcategory, out var _)) { list.Add(val); } } } Dictionary<Container, int> depths = new Dictionary<Container, int>(); foreach (Container item in list) { depths[item] = ((TryReadState(item, out var state2) && state2 != null) ? ((state2.Selection != null && !ChestLabelManager.IsCategoryRoot(state2.Category, state2.Selection)) ? state2.Selection.Depth : ((state2.Selection == null && state2.Subcategory != "AllTypes") ? 1 : 0)) : 0); } list.Sort(delegate(Container left, Container right) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) int num2 = depths[right].CompareTo(depths[left]); if (num2 != 0) { return num2; } Vector3 val3 = ((Component)left).transform.position - origin; float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude; val3 = ((Component)right).transform.position - origin; return sqrMagnitude.CompareTo(((Vector3)(ref val3)).sqrMagnitude); }); return list; } public static bool TryPrepareForItem(Container container, CheckMyStuffCategory category, ItemTaxonomyPath itemPath, string legacySubcategory) { if (TryMatchState(container, category, itemPath, legacySubcategory, out var _)) { return TryPrepareForWrite(container); } return false; } private static bool TryMatchState(Container container, CheckMyStuffCategory category, ItemTaxonomyPath itemPath, string legacySubcategory, out ChestLabelState state) { state = null; if ((Object)(object)container == (Object)null || !ChestLabelManager.IsSupportedChest(container) || IsInUse(container) || !HasVanillaAccess(container) || !ChestLabelManager.TryRead(container, out state) || state == null || !state.Enabled || container.GetInventory() == null) { return false; } return state.Accepts(category, itemPath, legacySubcategory); } private static bool TryReadState(Container container, out ChestLabelState state) { if (!ChestLabelManager.TryRead(container, out state) || state == null) { state = new ChestLabelState(CheckMyStuffCategory.Misc, "AllTypes", enabled: false); return false; } return true; } private static bool IsInUse(Container container) { if ((Object)(object)container == (Object)null || container.IsInUse()) { return true; } ZNetView view = GetView(container); if ((Object)(object)view != (Object)null && view.IsValid() && view.GetZDO() != null) { return view.GetZDO().GetInt(ZDOVars.s_inUse, 0) != 0; } return false; } private static bool HasVanillaAccess(Container container) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Invalid comparison between Unknown and I4 //IL_0019: 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) if ((Object)(object)container == (Object)null) { return false; } if (container.m_checkGuardStone && !PrivateArea.CheckAccess(((Component)container).transform.position, 0f, false, false)) { return false; } if ((int)container.m_privacy == 2) { return true; } if ((int)container.m_privacy == 0) { Piece component = ((Component)container).GetComponent<Piece>(); if ((Object)(object)component == (Object)null || (Object)(object)Game.instance == (Object)null || Game.instance.GetPlayerProfile() == null) { return false; } return component.GetCreator() == Game.instance.GetPlayerProfile().GetPlayerID(); } return false; } private static ZNetView GetView(Container container) { if ((Object)(object)container == (Object)null) { return null; } if (Object.op_Implicit((Object)(object)container.m_rootObjectOverride)) { return ((Component)container.m_rootObjectOverride).GetComponent<ZNetView>(); } return ((Component)container).GetComponent<ZNetView>(); } } public sealed class SortingResult { public CheckMyStuffCategory? Category { get; } public int ItemsMoved { get; internal set; } public int StacksTouched { get; internal set; } public int ChestsUsed { get; internal set; } public int EligibleStacks { get; internal set; } public int RemainingStacks { get; internal set; } public SortingResult(CheckMyStuffCategory? category) { Category = category; } } public static class SortingEngine { private static Player s_lastPlayer; private static Transform s_lastBarrel; private static CheckMyStuffCategory? s_lastCategory; private static float s_lastSortTime; private static float s_retryAt; static SortingEngine() { s_lastSortTime = -999f; s_retryAt = -1f; ContainerFinder.OwnershipGranted += delegate { if (Time.time - s_lastSortTime <= 5f) { s_retryAt = Time.time + 0.5f; } }; } internal static void ProcessPendingRetry() { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) if (s_retryAt < 0f || Time.time < s_retryAt) { return; } s_retryAt = -1f; Player val = s_lastPlayer; Transform val2 = s_lastBarrel; if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val != (Object)(object)Player.m_localPlayer) { return; } Vector3 val3 = ((Component)val).transform.position - val2.position; if (!(((Vector3)(ref val3)).sqrMagnitude > 2500f) && PrivateArea.CheckAccess(val2.position, 0f, false, false)) { SortingResult sortingResult = SortBag(val, val2, s_lastCategory); if (sortingResult.ItemsMoved > 0) { ((Character)val).Message((MessageType)1, "Stored " + sortingResult.ItemsMoved + " more item(s) into " + sortingResult.ChestsUsed + " chest(s) near another player.", 0, (Sprite)null, false); } } } public static SortingResult SortCategory(Player player, Transform barrelTransform, CheckMyStuffCategory category) { return SortBag(player, barrelTransform, category); } public static SortingResult SortAll(Player player, Transform barrelTransform) { return SortBag(player, barrelTransform, null); } private static SortingResult SortBag(Player player, Transform barrelTransform, CheckMyStuffCategory? category) { //IL_00ae: Unknown result type (might be due to invalid IL or missing references) SortingResult sortingResult = new SortingResult(category); if ((Object)(object)player == (Object)null || (Object)(object)barrelTransform == (Object)null) { return sortingResult; } s_lastPlayer = player; s_lastBarrel = barrelTransform; s_lastCategory = category; s_lastSortTime = Time.time; Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory == null) { return sortingResult; } List<ItemData> list = new List<ItemData>(inventory.GetAllItems()); HashSet<Container> hashSet = new HashSet<Container>(); for (int i = 0; i < list.Count; i++) { ItemData val = list[i]; if (IsEligibleBagItem(player, inventory, val, out var actualCategory, out var itemPath, out var legacySubcategory) && (!category.HasValue || actualCategory == category.Value)) { sortingResult.EligibleStacks++; int stack = val.m_stack; List<Container> list2 = ContainerFinder.FindMatchingForItem(barrelTransform.position, actualCategory, itemPath, legacySubcategory); RouteThroughContainers(inventory, val, list2, actualCategory, itemPath, legacySubcategory, hashSet, sortingResult); if (val.m_stack < stack) { sortingResult.StacksTouched++; } if (val.m_stack > 0 && list2 != null && list2.Count > 0) { sortingResult.RemainingStacks++; } } } sortingResult.ChestsUsed = hashSet.Count; return sortingResult; } public static int CountStorable(Player player, Transform barrelTransform) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || (Object)(object)barrelTransform == (Object)null) { return 0; } Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory == null) { return 0; } int num = 0; foreach (ItemData item in new List<ItemData>(inventory.GetAllItems())) { if (IsEligibleBagItem(player, inventory, item, out var actualCategory, out var itemPath, out var legacySubcategory)) { List<Container> list = ContainerFinder.FindMatchingForItem(barrelTransform.position, actualCategory, itemPath, legacySubcategory); if (list != null && list.Count > 0) { num += item.m_stack; } } } return num; } private static void RouteThroughContainers(Inventory source, ItemData item, List<Container> containers, CheckMyStuffCategory category, ItemTaxonomyPath itemPath, string legacySubcategory, HashSet<Container> usedContainers, SortingResult result) { if (containers == null) { return; } for (int i = 0; i < containers.Count; i++) { if (item.m_stack <= 0) { break; } Container val = containers[i]; if (ContainerFinder.TryPrepareForItem(val, category, itemPath, legacySubcategory)) { int num = MoveIntoContainer(source, item, val.GetInventory()); if (num > 0) { usedContainers.Add(val); result.ItemsMoved += num; } } } } private static bool IsEligibleBagItem(Player player, Inventory source, ItemData item, out CheckMyStuffCategory actualCategory, out ItemTaxonomyPath itemPath, out string legacySubcategory) { actualCategory = CheckMyStuffCategory.Ingredients; itemPath = new ItemTaxonomyPath(null, null, null, null); legacySubcategory = "AllTypes"; if ((Object)(object)player == (Object)null || item == null || item.m_shared == null || item.m_stack <= 0) { return false; } if (source == null || source != ((Humanoid)player).GetInventory() || item.m_gridPos.y <= 0 || item.m_gridPos.y >= source.GetHeight() || item.m_gridPos.x < 0 || item.m_gridPos.x >= source.GetWidth() || source.GetItemAt(item.m_gridPos.x, item.m_gridPos.y) != item) { return false; } if (item.m_equipped || ((Humanoid)player).IsItemEquiped(item)) { return false; } if (item.m_shared.m_questItem) { return false; } if (!ItemClassifier.TryClassifyTaxonomy(item, out actualCategory, out itemPath, out legacySubcategory)) { return false; } return true; } private static int MoveIntoContainer(Inventory source, ItemData item, Inventory target) { if (source == null || item == null || target == null || source == target || item.m_stack <= 0) { return 0; } int stack = item.m_stack; FillExistingStacks(source, item, target); FillEmptySlots(source, item, target); return stack - item.m_stack; } private static void FillExistingStacks(Inventory source, ItemData item, Inventory target) { List<ItemData> list = new List<ItemData>(target.GetAllItems()); for (int i = 0; i < list.Count; i++) { if (item.m_stack <= 0) { break; } ItemData val = list[i]; if (val != null && CanStackWithoutDataLoss(val, item) && val.m_stack < val.m_shared.m_maxStackSize) { int val2 = val.m_shared.m_maxStackSize - val.m_stack; int num = Math.Min(item.m_stack, val2); int stack = item.m_stack; target.MoveItemToThis(source, item, num, val.m_gridPos.x, val.m_gridPos.y); if (item.m_stack >= stack) { break; } } } } private static void FillEmptySlots(Inventory source, ItemData item, Inventory target) { int width = target.GetWidth(); int height = target.GetHeight(); for (int i = 0; i < height; i++) { if (item.m_stack <= 0) { break; } for (int j = 0; j < width; j++) { if (item.m_stack <= 0) { break; } if (target.GetItemAt(j, i) == null) { int num = Math.Min(item.m_stack, item.m_shared.m_maxStackSize); int stack = item.m_stack; target.MoveItemToThis(source, item, num, j, i); if (item.m_stack >= stack) { return; } } } } } internal static bool CanStackWithoutDataLoss(ItemData target, ItemData item) { if (target == null || item == null || target.m_shared == null || item.m_shared == null || !target.IsSameType(item) || (Object)(object)target.m_dropPrefab != (Object)(object)item.m_dropPrefab || target.m_quality != item.m_quality || target.m_variant != item.m_variant || target.m_crafterID != item.m_crafterID || target.m_crafterName != item.m_crafterName || target.m_cheated != item.m_cheated || target.m_pickedUp != item.m_pickedUp || target.m_durability != item.m_durability || target.m_customData.Count != item.m_customData.Count) { return false; } foreach (KeyValuePair<string, string> customDatum in item.m_customData) { if (!target.m_customData.TryGetValue(customDatum.Key, out var value) || value != customDatum.Value) { return false; } } return true; } } } namespace CheckMyStuff.Classification { public enum CheckMyStuffCategory { Ingredients, BuildAndCraft, Equipment, Consumables, Greenhouse, Trophies, Valuables, Misc } public static class CheckMyStuffCategoryNames { public static CheckMyStuffCategory[] GetSelectableCategories() { CheckMyStuffCategory[] obj = new CheckMyStuffCategory[7] { CheckMyStuffCategory.Consumables, CheckMyStuffCategory.Equipment, CheckMyStuffCategory.Greenhouse, CheckMyStuffCategory.Ingredients, CheckMyStuffCategory.BuildAndCraft, CheckMyStuffCategory.Misc, CheckMyStuffCategory.Trophies }; Array.Sort(obj, (CheckMyStuffCategory left, CheckMyStuffCategory right) => StringComparer.OrdinalIgnoreCase.Compare(ToDisplayName(left), ToDisplayName(right))); return obj; } public static string ToDisplayName(CheckMyStuffCategory category) { return category switch { CheckMyStuffCategory.BuildAndCraft => "Materials", CheckMyStuffCategory.Greenhouse => "Garden", _ => category.ToString(), }; } } public static class CheckMyStuffSubcategories { public const string AllTypes = "AllTypes"; public const string Fermentables = "Fermentables"; public const string CookingIngredients = "CookingIngredients"; public const string RawFood = "RawFood"; public const string OtherIngredients = "OtherIngredients"; public const string SmeltingAndProcessing = "SmeltingAndProcessing"; public const string BuildingMaterials = "BuildingMaterials"; public const string CraftingMaterials = "CraftingMaterials"; public const string OtherMaterials = "OtherMaterials"; public const string Weapons = "Weapons"; public const string Armor = "Armor"; public const string Shields = "Shields"; public const string Ammo = "Ammo"; public const string Tools = "Tools"; public const string Accessories = "Accessories"; public const string Food = "Food"; public const string MeadsAndPotions = "MeadsAndPotions"; public const string OtherConsumables = "OtherConsumables"; public const string SeedsAndPlanting = "SeedsAndPlanting"; public const string FarmingMaterials = "FarmingMaterials"; public const string Trophies = "Trophies"; public const string TraderGoods = "TraderGoods"; public const string OtherValuables = "OtherValuables"; public const string Customization = "Customization"; public const string Miscellaneous = "Miscellaneous"; private static readonly string[] Ingredients = new string[5] { "AllTypes", "Fermentables", "CookingIngredients", "RawFood", "OtherIngredients" }; private static readonly string[] BuildAndCraft = new string[5] { "AllTypes", "SmeltingAndProcessing", "BuildingMaterials", "CraftingMaterials", "OtherMaterials" }; private static readonly string[] Equipment = new string[7] { "AllTypes", "Weapons", "Armor", "Shields", "Ammo", "Tools", "Accessories" }; private static readonly string[] Consumables = new string[4] { "AllTypes", "Food", "MeadsAndPotions", "OtherConsumables" }; private static readonly string[] Greenhouse = new string[3] { "AllTypes", "SeedsAndPlanting", "FarmingMaterials" }; private static readonly string[] TrophyOptions = new string[2] { "AllTypes", "Trophies" }; private static readonly string[] Valuables = new string[3] { "AllTypes", "TraderGoods", "OtherValuables" }; private static readonly string[] Misc = new string[3] { "AllTypes", "Customization", "Miscellaneous" }; public static string[] GetOptions(CheckMyStuffCategory category) { return category switch { CheckMyStuffCategory.Ingredients => (string[])Ingredients.Clone(), CheckMyStuffCategory.BuildAndCraft => (string[])BuildAndCraft.Clone(), CheckMyStuffCategory.Equipment => (string[])Equipment.Clone(), CheckMyStuffCategory.Consumables => (string[])Consumables.Clone(), CheckMyStuffCategory.Greenhouse => (string[])Greenhouse.Clone(), CheckMyStuffCategory.Trophies => (string[])TrophyOptions.Clone(), CheckMyStuffCategory.Valuables => (string[])Valuables.Clone(), CheckMyStuffCategory.Misc => (string[])Misc.Clone(), _ => new string[1] { "AllTypes" }, }; } public static bool IsValid(CheckMyStuffCategory category, string subcategory) { if (string.IsNullOrEmpty(subcategory)) { return false; } string[] options = GetOptions(category); for (int i = 0; i < options.Length; i++) { if (string.Equals(options[i], subcategory, StringComparison.Ordinal)) { return true; } } return false; } public static string Normalize(CheckMyStuffCategory category, string subcategory) { if (!IsValid(category, subcategory)) { return "AllTypes"; } return subcategory; } } public sealed class ChestLabelState { private static readonly ItemTaxonomyPath[] NoSelections = new ItemTaxonomyPath[0]; public CheckMyStuffCategory Category { get; } public string Subcategory { get; } public bool Enabled { get; } public ItemTaxonomyPath Selection { get; } public IList<ItemTaxonomyPath> Selections { get; } public ChestLabelState(CheckMyStuffCategory category, string subcategory, bool enabled, ItemTaxonomyPath selection = null) : this(category, subcategory, enabled, (selection == null) ? NoSelections : new ItemTaxonomyPath[1] { selection }) { } public ChestLabelState(CheckMyStuffCategory category, string subcategory, bool enabled, IList<ItemTaxonomyPath> selections) { Category = category; Subcategory = subcategory; Enabled = enabled; List<ItemTaxo