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 AutoStash v1.1.0
AutoStash.dll
Decompiled a week agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("dbendu")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright (c) 2026 dbendu")] [assembly: AssemblyDescription("Stashes inventory items into nearby Valheim chests according to per-chest filters.")] [assembly: AssemblyFileVersion("1.1.0.0")] [assembly: AssemblyInformationalVersion("1.1.0+0ef9b901c8c828bd9d7a7efbc329903aa2c5b519")] [assembly: AssemblyProduct("Auto Stash")] [assembly: AssemblyTitle("AutoStash")] [assembly: AssemblyVersion("1.1.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace AutoStash { internal sealed class ItemCategory { private readonly string _english; private readonly string _russian; internal string Id { get; } internal Func<SharedData, bool> Matches { get; } internal string Title => Text.T(_english, _russian); internal ItemCategory(string id, string english, string russian, Func<SharedData, bool> matches) { Id = id; _english = english; _russian = russian; Matches = matches; } } internal static class ItemCategories { internal static readonly ItemCategory[] All = new ItemCategory[10] { new ItemCategory("materials", "Materials", "Материалы", (SharedData s) => (int)s.m_itemType == 1), new ItemCategory("food", "Food", "Еда", (SharedData s) => (int)s.m_itemType == 2 && (s.m_food > 0f || s.m_foodStamina > 0f || s.m_foodEitr > 0f)), new ItemCategory("potions", "Meads", "Зелья", (SharedData s) => (int)s.m_itemType == 2), new ItemCategory("trophies", "Trophies", "Трофеи", (SharedData s) => (int)s.m_itemType == 13), new ItemCategory("fish", "Fish", "Рыба", (SharedData s) => (int)s.m_itemType == 21), new ItemCategory("weapons", "Weapons", "Оружие", delegate(SharedData s) { ItemType[] array = new ItemType[5]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); return Is(s, (ItemType[])(object)array); }), new ItemCategory("armor", "Armor", "Броня", delegate(SharedData s) { ItemType[] array = new ItemType[8]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); return Is(s, (ItemType[])(object)array); }), new ItemCategory("ammo", "Ammo", "Боеприпасы", (SharedData s) => Is(s, (ItemType)9, (ItemType)23)), new ItemCategory("tools", "Tools", "Инструменты", (SharedData s) => Is(s, (ItemType)19, (ItemType)15)), new ItemCategory("misc", "Other", "Прочее", (SharedData s) => true) }; internal static ItemCategory Of(SharedData shared) { if (shared != null) { return All.First((ItemCategory c) => c.Matches(shared)); } return null; } internal static int IndexOf(ItemCategory category) { return Array.IndexOf(All, category); } internal static bool Exists(string id) { return All.Any((ItemCategory c) => c.Id == id); } private static bool Is(SharedData shared, params ItemType[] types) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) return types.Contains(shared.m_itemType); } } internal sealed class ChestFilter { internal const int RankPicked = 0; internal const int RankCategory = 1; internal const int RankNone = -1; private const int MaxItems = 512; private const int MaxNameLength = 128; internal readonly HashSet<string> Items = new HashSet<string>(StringComparer.Ordinal); internal readonly HashSet<string> Categories = new HashSet<string>(StringComparer.Ordinal); internal bool IsEmpty { get { if (Items.Count == 0) { return Categories.Count == 0; } return false; } } internal int Count => Items.Count + Categories.Count; internal ChestFilter Copy() { ChestFilter chestFilter = new ChestFilter(); chestFilter.Items.UnionWith(Items); chestFilter.Categories.UnionWith(Categories); return chestFilter; } internal int Rank(ItemData item) { string prefab = PrefabName(item); return Rank(prefab, item.m_shared); } internal int Rank(string prefab, SharedData shared) { if (prefab != null && Items.Contains(prefab)) { return 0; } ItemCategory itemCategory = ItemCategories.Of(shared); if (itemCategory == null || !Categories.Contains(itemCategory.Id)) { return -1; } return 1; } internal static string PrefabName(ItemData item) { if (item == null || !Object.op_Implicit((Object)(object)item.m_dropPrefab)) { return null; } return ((Object)item.m_dropPrefab).name; } internal static bool ValidName(string name) { if (!string.IsNullOrEmpty(name) && name.Length <= 128 && name.IndexOf(',') < 0 && name.IndexOf('|') < 0) { return !name.Any(char.IsControl); } return false; } internal string Encode() { if (Items.Count > 512 || !Items.All(ValidName) || !Categories.All(ItemCategories.Exists)) { throw new InvalidOperationException(Text.T("The filter has too many or invalid entries.", "В фильтре слишком много или некорректные записи.")); } if (IsEmpty) { return ""; } return string.Join(",", Categories.OrderBy<string, string>((string c) => c, StringComparer.Ordinal)) + "|" + string.Join(",", Items.OrderBy<string, string>((string i) => i, StringComparer.Ordinal)); } internal static ChestFilter Decode(string raw) { ChestFilter chestFilter = new ChestFilter(); if (string.IsNullOrEmpty(raw)) { return chestFilter; } int num = raw.IndexOf('|'); string obj = ((num >= 0) ? raw.Substring(0, num) : raw); string text = ((num >= 0) ? raw.Substring(num + 1) : ""); string[] array = obj.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (string text2 in array) { if (ItemCategories.Exists(text2)) { chestFilter.Categories.Add(text2); } } array = text.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries); foreach (string text3 in array) { if (ValidName(text3) && chestFilter.Items.Count < 512) { chestFilter.Items.Add(text3); } } return chestFilter; } } internal static class FilterStore { internal const string ZdoKey = "AutoStash.Filter.v1"; private static string _lastRaw; private static ChestFilter _lastFilter; internal static bool Eligible(Container chest) { if (Object.op_Implicit((Object)(object)chest) && chest.GetInventory() != null && Object.op_Implicit((Object)(object)((Component)chest).GetComponentInParent<Piece>()) && !Object.op_Implicit((Object)(object)((Component)chest).GetComponent<TombStone>())) { return !chest.m_autoDestroyEmpty; } return false; } internal static ZNetView NetView(Container chest) { if (!Object.op_Implicit((Object)(object)chest)) { return null; } return GameAccess.NetView.Invoke(chest); } internal static string Raw(Container chest) { ZNetView val = NetView(chest); if (!Object.op_Implicit((Object)(object)val) || !val.IsValid()) { return ""; } return val.GetZDO().GetString("AutoStash.Filter.v1", ""); } internal static ChestFilter Load(Container chest) { string text = Raw(chest); if (text != _lastRaw) { _lastFilter = ChestFilter.Decode(text); _lastRaw = text; } return _lastFilter; } internal static bool CanEdit(Container chest, out string reason) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; ZNetView val = NetView(chest); if (!Eligible(chest) || !Object.op_Implicit((Object)(object)localPlayer) || ((Character)localPlayer).IsDead() || (Object)(object)GameAccess.OpenedChest() != (Object)(object)chest) { reason = Text.T("Open the chest to edit its filter.", "Откройте сундук, чтобы настроить фильтр."); return false; } if (Vector3.Distance(((Component)localPlayer).transform.position, ((Component)chest).transform.position) > 5f) { reason = Text.T("Move closer to the chest.", "Подойдите ближе к сундуку."); return false; } if (!Object.op_Implicit((Object)(object)val) || !val.IsValid() || !val.IsOwner()) { reason = Text.T("The chest is busy. Reopen it and try again.", "Сундук занят. Откройте его заново и попробуйте ещё раз."); return false; } reason = ""; return true; } internal static bool Save(Container chest, ChestFilter filter, string expected, out string message) { if (!CanEdit(chest, out message)) { return false; } if (Raw(chest) != expected) { message = Text.T("Someone else changed this filter. Reopen the chest to see it.", "Кто-то уже изменил этот фильтр. Откройте сундук заново."); return false; } try { NetView(chest).GetZDO().Set("AutoStash.Filter.v1", filter.Encode()); message = ""; return true; } catch (Exception ex) { message = ex.Message; return false; } } } internal sealed class FilterPanel { private sealed class Entry { internal string Prefab; internal SharedData Shared; internal Sprite Icon; internal string Name; internal string Search; internal ItemCategory Category; internal GameObject Cell; internal Image Background; } private const float Width = 780f; private const float Height = 620f; private const float CellSize = 56f; private const float CellGap = 6f; private const int Columns = 11; private static readonly Color CellIdle = new Color(0.12f, 0.09f, 0.06f, 0.95f); private static readonly Color CellPicked = new Color(0.86f, 0.62f, 0.18f, 1f); private static readonly Color CellCategory = new Color(0.28f, 0.5f, 0.3f, 1f); private static readonly Color CategoryOn = new Color(1f, 0.8f, 0.4f); private static readonly Color ErrorColor = new Color(1f, 0.5f, 0.4f); private readonly UiKit _kit; private readonly List<Entry> _entries = new List<Entry>(); private readonly List<KeyValuePair<ItemCategory, Button>> _categoryButtons = new List<KeyValuePair<ItemCategory, Button>>(); private GameObject _canvas; private RectTransform _panel; private ScrollRect _scroll; private Container _chest; private string _expected; private ChestFilter _draft; private TMP_InputField _search; private TMP_Text _showLabel; private TMP_Text _info; private TMP_Text _status; private bool _acceptedOnly; private Entry _hovered; internal bool IsOpen => Object.op_Implicit((Object)(object)_canvas); internal FilterPanel(UiKit kit) { _kit = kit; } internal void Open(Container chest) { if (IsOpen) { return; } if (!FilterStore.CanEdit(chest, out var reason)) { Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)2, reason, 0, (Sprite)null, false); } return; } _chest = chest; _expected = FilterStore.Raw(chest); _draft = FilterStore.Load(chest).Copy(); _acceptedOnly = false; _hovered = null; UITooltip.HideTooltip(); _kit.Capture(InventoryGui.instance); Build(); } internal void Tick() { if (IsOpen) { InventoryGui instance = InventoryGui.instance; Player localPlayer = Player.m_localPlayer; if (!Plugin.Enabled.Value || !Object.op_Implicit((Object)(object)instance) || !((Component)instance.m_container).gameObject.activeInHierarchy || (Object)(object)GameAccess.OpenedChest() != (Object)(object)_chest || !Object.op_Implicit((Object)(object)localPlayer) || ((Character)localPlayer).IsDead()) { Close(); } else if (BackPressed()) { Close(); } } } internal void Close() { if (Object.op_Implicit((Object)(object)_canvas)) { Object.Destroy((Object)(object)_canvas); InputBlock.MarkClosed(); } _canvas = null; _chest = null; _hovered = null; _entries.Clear(); _categoryButtons.Clear(); } private static bool BackPressed() { InputBlock.Polling = true; try { return ZInput.GetKeyDown((KeyCode)27, false) || ZInput.GetButtonDown("JoyButtonB"); } finally { InputBlock.Polling = false; } } private void Build() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Expected O, but got Unknown //IL_03b9: Unknown result type (might be due to invalid IL or missing references) //IL_03c3: Expected O, but got Unknown //IL_0403: Unknown result type (might be due to invalid IL or missing references) //IL_040d: Expected O, but got Unknown //IL_0484: Unknown result type (might be due to invalid IL or missing references) //IL_04c4: Unknown result type (might be due to invalid IL or missing references) //IL_04ce: Expected O, but got Unknown //IL_0505: Unknown result type (might be due to invalid IL or missing references) //IL_050f: Expected O, but got Unknown //IL_0546: Unknown result type (might be due to invalid IL or missing references) //IL_0550: Expected O, but got Unknown _canvas = new GameObject("AutoStashCanvas", new Type[4] { typeof(RectTransform), typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster) }); Canvas component = _canvas.GetComponent<Canvas>(); component.renderMode = (RenderMode)0; Canvas componentInParent = ((Component)InventoryGui.instance).GetComponentInParent<Canvas>(); component.sortingOrder = (Object.op_Implicit((Object)(object)componentInParent) ? (componentInParent.sortingOrder + 120) : 1020); CanvasScaler component2 = _canvas.GetComponent<CanvasScaler>(); component2.uiScaleMode = (ScaleMode)1; component2.referenceResolution = new Vector2(1280f, 800f); component2.matchWidthOrHeight = 1f; UiKit.Stretch(((Graphic)UiKit.AddImage("Backdrop", _canvas.transform, new Color(0f, 0f, 0f, 0.7f))).rectTransform); Image val = UiKit.AddImage("Panel", _canvas.transform, _kit.PanelColor); val.sprite = _kit.PanelSprite; val.type = _kit.PanelType; _panel = ((Graphic)val).rectTransform; RectTransform panel = _panel; RectTransform panel2 = _panel; RectTransform panel3 = _panel; Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(0.5f, 0.5f); panel3.pivot = val2; Vector2 anchorMin = (panel2.anchorMax = val2); panel.anchorMin = anchorMin; _panel.anchoredPosition = Vector2.zero; _panel.sizeDelta = new Vector2(780f, 620f); _kit.AddText((Transform)(object)_panel, Text.T("Chest filter", "Фильтр сундука"), 24f, 16f, 732f, 32f, 24f); TMP_Text obj = _kit.AddText((Transform)(object)_panel, Text.T("The chest accepts the picked items and everything in the picked categories. Press " + Plugin.StashKeyName() + " near it to stash.", "Сундук принимает выбранные предметы и всё из выбранных категорий. Нажмите " + Plugin.StashKeyName() + " рядом, чтобы разложить вещи."), 24f, 48f, 732f, 24f, 15f); obj.enableAutoSizing = true; obj.fontSizeMin = 11f; obj.fontSizeMax = 15f; _kit.AddText((Transform)(object)_panel, Text.T("Categories (include items found later):", "Категории (включая предметы, найденные позже):"), 24f, 78f, 732f, 24f, 17f); for (int i = 0; i < ItemCategories.All.Length; i++) { ItemCategory category = ItemCategories.All[i]; Button value = _kit.AddButton((Transform)(object)_panel, category.Title, 24f + (float)(i % 5) * 148f, 106f + (float)(i / 5) * 38f, 140f, 32f, (UnityAction)delegate { ToggleCategory(category); }); _categoryButtons.Add(new KeyValuePair<ItemCategory, Button>(category, value)); } _search = _kit.AddInput((Transform)(object)_panel, Text.T("Search items…", "Поиск предметов…"), 24f, 188f, 330f, 34f, 40); ((UnityEvent<string>)(object)_search.onValueChanged).AddListener((UnityAction<string>)delegate { ApplyVisibility(resetScroll: true); }); _showLabel = ((Component)_kit.AddButton((Transform)(object)_panel, "", 362f, 188f, 180f, 34f, (UnityAction)delegate { _acceptedOnly = !_acceptedOnly; Refresh(); ResetScroll(); })).GetComponentInChildren<TMP_Text>(); _kit.AddButton((Transform)(object)_panel, Text.T("Add chest contents", "Добавить содержимое"), 550f, 188f, 206f, 34f, new UnityAction(AddChestContents)); BuildGrid(); _info = _kit.AddText((Transform)(object)_panel, "", 24f, 530f, 732f, 24f, 16f); _status = _kit.AddText((Transform)(object)_panel, "", 24f, 554f, 732f, 22f, 14f); ((Graphic)_status).color = ErrorColor; _kit.AddButton((Transform)(object)_panel, Text.T("Clear all", "Очистить"), 24f, 580f, 150f, 34f, (UnityAction)delegate { _draft.Items.Clear(); _draft.Categories.Clear(); _status.text = ""; Refresh(); }); _kit.AddButton((Transform)(object)_panel, Text.T("Cancel", "Отмена"), 536f, 580f, 105f, 34f, new UnityAction(Close)); _kit.AddButton((Transform)(object)_panel, Text.T("Save", "Сохранить"), 651f, 580f, 105f, 34f, new UnityAction(Save)); Refresh(); } private void BuildGrid() { //IL_0044: 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_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Expected O, but got Unknown //IL_01ec: 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) RectTransform val = UiKit.AddRect("Items", (Transform)(object)_panel, 24f, 232f, 716f, 290f); ((Graphic)((Component)val).gameObject.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0.35f); ((Component)val).gameObject.AddComponent<RectMask2D>(); RectTransform val2 = (RectTransform)new GameObject("Content", new Type[1] { typeof(RectTransform) }).transform; ((Transform)val2).SetParent((Transform)(object)val, false); val2.anchorMin = new Vector2(0f, 1f); val2.anchorMax = Vector2.one; val2.pivot = new Vector2(0.5f, 1f); val2.anchoredPosition = Vector2.zero; val2.sizeDelta = Vector2.zero; GridLayoutGroup obj = ((Component)val2).gameObject.AddComponent<GridLayoutGroup>(); obj.cellSize = new Vector2(56f, 56f); obj.spacing = new Vector2(6f, 6f); ((LayoutGroup)obj).padding = new RectOffset(8, 8, 8, 8); obj.constraint = (Constraint)1; obj.constraintCount = 11; ((LayoutGroup)obj).childAlignment = (TextAnchor)1; ((Component)val2).gameObject.AddComponent<ContentSizeFitter>().verticalFit = (FitMode)2; _scroll = ((Component)val).gameObject.AddComponent<ScrollRect>(); _scroll.horizontal = false; _scroll.vertical = true; _scroll.movementType = (MovementType)2; _scroll.inertia = false; _scroll.scrollSensitivity = 40f; _scroll.viewport = val; _scroll.content = val2; RectTransform val3 = UiKit.AddRect("Scrollbar", (Transform)(object)_panel, 744f, 232f, 12f, 290f); ((Graphic)((Component)val3).gameObject.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0.5f); RectTransform val4 = UiKit.AddRect("Area", (Transform)(object)val3, 0f, 0f, 0f, 0f); UiKit.Stretch(val4); Image val5 = UiKit.AddImage("Handle", (Transform)(object)val4, new Color(0.85f, 0.65f, 0.35f, 0.9f)); UiKit.Stretch(((Graphic)val5).rectTransform); Scrollbar val6 = ((Component)val3).gameObject.AddComponent<Scrollbar>(); val6.handleRect = ((Graphic)val5).rectTransform; ((Selectable)val6).targetGraphic = (Graphic)(object)val5; val6.direction = (Direction)2; _scroll.verticalScrollbar = val6; _scroll.verticalScrollbarVisibility = (ScrollbarVisibility)0; foreach (Entry item in Catalog()) { AddCell((Transform)(object)val2, item); _entries.Add(item); } } private void AddCell(Transform content, Entry entry) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Expected O, but got Unknown //IL_0105: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Item", new Type[5] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image), typeof(Button), typeof(HoverRelay) }); val.transform.SetParent(content, false); Image component = val.GetComponent<Image>(); ((Graphic)component).color = CellIdle; Button component2 = val.GetComponent<Button>(); ((Selectable)component2).transition = (Transition)0; Navigation navigation = default(Navigation); ((Navigation)(ref navigation)).mode = (Mode)0; ((Selectable)component2).navigation = navigation; ((UnityEvent)component2.onClick).AddListener((UnityAction)delegate { ToggleItem(entry); }); HoverRelay component3 = val.GetComponent<HoverRelay>(); component3.Entered = delegate { SetHovered(entry); }; component3.Exited = delegate { if (_hovered == entry) { SetHovered(null); } }; if (Object.op_Implicit((Object)(object)entry.Icon)) { Image obj = UiKit.AddImage("Icon", val.transform, Color.white); UiKit.Stretch(((Graphic)obj).rectTransform, 5f); obj.sprite = entry.Icon; obj.preserveAspect = true; ((Graphic)obj).raycastTarget = false; } else { TMP_Text obj2 = _kit.AddText(val.transform, entry.Name, 0f, 0f, 0f, 0f, 10f); UiKit.Stretch(obj2.rectTransform, 3f); obj2.alignment = (TextAlignmentOptions)514; obj2.textWrappingMode = (TextWrappingModes)1; } entry.Cell = val; entry.Background = component; } private List<Entry> Catalog() { Player localPlayer = Player.m_localPlayer; HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); AddPresent(hashSet, _chest.GetInventory()); if (Object.op_Implicit((Object)(object)localPlayer)) { AddPresent(hashSet, ((Humanoid)localPlayer).GetInventory()); } Dictionary<string, Entry> dictionary = new Dictionary<string, Entry>(StringComparer.Ordinal); ObjectDB instance = ObjectDB.instance; if (Object.op_Implicit((Object)(object)instance)) { foreach (GameObject item in instance.m_items) { ItemDrop val = (Object.op_Implicit((Object)(object)item) ? item.GetComponent<ItemDrop>() : null); SharedData val2 = ((Object.op_Implicit((Object)(object)val) && val.m_itemData != null) ? val.m_itemData.m_shared : null); if (val2 != null && !string.IsNullOrEmpty(val2.m_name) && val2.m_icons != null && val2.m_icons.Length != 0 && Object.op_Implicit((Object)(object)val2.m_icons[0]) && ChestFilter.ValidName(((Object)item).name) && !dictionary.ContainsKey(((Object)item).name) && (Plugin.ShowUndiscovered.Value || _draft.Items.Contains(((Object)item).name) || hashSet.Contains(((Object)item).name) || (Object.op_Implicit((Object)(object)localPlayer) && localPlayer.IsMaterialKnown(val2.m_name)))) { string text = Text.Localize(val2.m_name); dictionary[((Object)item).name] = new Entry { Prefab = ((Object)item).name, Shared = val2, Icon = val2.m_icons[0], Name = text, Search = (text + " " + ((Object)item).name).ToLowerInvariant(), Category = ItemCategories.Of(val2) }; } } } foreach (string item2 in _draft.Items) { if (!dictionary.ContainsKey(item2)) { dictionary[item2] = new Entry { Prefab = item2, Name = item2, Search = item2.ToLowerInvariant() }; } } return dictionary.Values.OrderBy((Entry e) => (e.Category == null) ? int.MaxValue : ItemCategories.IndexOf(e.Category)).ThenBy<Entry, string>((Entry e) => e.Name, StringComparer.CurrentCultureIgnoreCase).ToList(); } private static void AddPresent(HashSet<string> present, Inventory inventory) { foreach (ItemData allItem in inventory.GetAllItems()) { string text = ChestFilter.PrefabName(allItem); if (text != null) { present.Add(text); } } } private int Rank(Entry entry) { return _draft.Rank(entry.Prefab, entry.Shared); } private void ToggleItem(Entry entry) { if (!_draft.Items.Remove(entry.Prefab)) { _draft.Items.Add(entry.Prefab); } _status.text = ""; if (_acceptedOnly) { ApplyVisibility(resetScroll: false); } else { RefreshCell(entry); } UpdateInfo(); } private void ToggleCategory(ItemCategory category) { if (!_draft.Categories.Remove(category.Id)) { _draft.Categories.Add(category.Id); } _status.text = ""; Refresh(); } private void AddChestContents() { int num = 0; foreach (ItemData allItem in _chest.GetInventory().GetAllItems()) { string text = ChestFilter.PrefabName(allItem); if (text != null && ChestFilter.ValidName(text) && _draft.Items.Add(text)) { num++; } } _status.text = ((_chest.GetInventory().NrOfItems() == 0) ? Text.T("The chest is empty.", "Сундук пуст.") : ((num == 0) ? Text.T("Everything in the chest is already picked.", "Всё содержимое сундука уже выбрано.") : "")); Refresh(); } private void SetHovered(Entry entry) { Entry hovered = _hovered; _hovered = entry; if (hovered != null) { RefreshCell(hovered); } if (entry != null) { RefreshCell(entry); } UpdateInfo(); } private void Refresh() { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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) if (!Object.op_Implicit((Object)(object)_panel)) { return; } foreach (KeyValuePair<ItemCategory, Button> categoryButton in _categoryButtons) { bool flag = _draft.Categories.Contains(categoryButton.Key.Id); ((Graphic)((Selectable)categoryButton.Value).image).color = (flag ? CategoryOn : _kit.ButtonColor); TMP_Text componentInChildren = ((Component)categoryButton.Value).GetComponentInChildren<TMP_Text>(); ((Graphic)componentInChildren).color = (flag ? Color.white : UiKit.TextColor); componentInChildren.fontStyle = (FontStyles)(flag ? 1 : 0); } _showLabel.text = (_acceptedOnly ? Text.T("Showing: accepted", "Показаны: принимаемые") : Text.T("Showing: all", "Показаны: все")); ApplyVisibility(resetScroll: false); UpdateInfo(); } private void ApplyVisibility(bool resetScroll) { string text = (Object.op_Implicit((Object)(object)_search) ? _search.text : "").Trim().ToLowerInvariant(); foreach (Entry entry in _entries) { bool flag = (text.Length == 0 || entry.Search.Contains(text)) && (!_acceptedOnly || Rank(entry) != -1); if (entry.Cell.activeSelf != flag) { entry.Cell.SetActive(flag); } if (!flag && _hovered == entry) { _hovered = null; } RefreshCell(entry); } if (resetScroll) { ResetScroll(); } UpdateInfo(); } private void ResetScroll() { if (Object.op_Implicit((Object)(object)_scroll)) { _scroll.verticalNormalizedPosition = 1f; } } private void RefreshCell(Entry entry) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0040: 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) Color val = (Color)(Rank(entry) switch { 1 => CellCategory, 0 => CellPicked, _ => CellIdle, }); ((Graphic)entry.Background).color = ((entry == _hovered) ? Color.Lerp(val, Color.white, 0.3f) : val); } private void UpdateInfo() { if (Object.op_Implicit((Object)(object)_info)) { if (_hovered != null) { int num = Rank(_hovered); string text = ((_hovered.Category != null) ? _hovered.Category.Title : ""); string text2 = num switch { 1 => Text.T("accepted via \"" + text + "\" (click to pick it too)", "принимается через «" + text + "» (нажмите, чтобы выбрать отдельно)"), 0 => Text.T("accepted, picked (click to remove)", "принимается, выбран (нажмите, чтобы убрать)"), _ => Text.T("not accepted (click to add)", "не принимается (нажмите, чтобы добавить)"), }; _info.text = _hovered.Name + ": " + text2; } else { int count = _draft.Items.Count; int count2 = _draft.Categories.Count; _info.text = (_draft.IsEmpty ? Text.T("The chest accepts nothing yet. Pick categories or click items.", "Пока сундук ничего не принимает. Выберите категории или нажмите на предметы.") : Text.T($"Picked items: {count}. Categories: {count2}.", $"Выбрано предметов: {count}. Категорий: {count2}.")); } } } private void Save() { if (IsOpen) { if (FilterStore.Save(_chest, _draft, _expected, out var message)) { Close(); } else { _status.text = message; } } } } internal sealed class LockMarker : MonoBehaviour { internal const string ObjectName = "AutoStashLock"; private const float FrameWidth = 2f; private Image[] _edges; internal static LockMarker Create(Transform element) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_0037: 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_004e: 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_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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("AutoStashLock", new Type[1] { typeof(RectTransform) }); val.transform.SetParent(element, false); RectTransform val2 = (RectTransform)val.transform; val2.anchorMin = Vector2.zero; val2.anchorMax = Vector2.one; Vector2 offsetMin = (val2.offsetMax = Vector2.zero); val2.offsetMin = offsetMin; LockMarker lockMarker = val.AddComponent<LockMarker>(); lockMarker._edges = (Image[])(object)new Image[4] { Edge((Transform)(object)val2, "Top", new Vector2(0f, 1f), Vector2.one, new Vector2(0f, -2f), Vector2.zero), Edge((Transform)(object)val2, "Bottom", Vector2.zero, new Vector2(1f, 0f), Vector2.zero, new Vector2(0f, 2f)), Edge((Transform)(object)val2, "Left", Vector2.zero, new Vector2(0f, 1f), Vector2.zero, new Vector2(2f, 0f)), Edge((Transform)(object)val2, "Right", new Vector2(1f, 0f), Vector2.one, new Vector2(-2f, 0f), Vector2.zero) }; return lockMarker; } internal void Apply(Color color) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) Image[] edges = _edges; for (int i = 0; i < edges.Length; i++) { ((Graphic)edges[i]).color = color; } } private static Image Edge(Transform parent, string name, Vector2 anchorMin, Vector2 anchorMax, Vector2 offsetMin, Vector2 offsetMax) { //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_0040: 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) //IL_004c: 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_0053: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0061: 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(Image) }); val.transform.SetParent(parent, false); RectTransform val2 = (RectTransform)val.transform; val2.anchorMin = anchorMin; val2.anchorMax = anchorMax; val2.offsetMin = offsetMin; val2.offsetMax = offsetMax; Image component = val.GetComponent<Image>(); ((Graphic)component).raycastTarget = false; return component; } } [BepInPlugin("dbendu.AutoStash", "Auto Stash", "1.1.0")] [BepInProcess("valheim.exe")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { public const string Guid = "dbendu.AutoStash"; public const string Name = "Auto Stash"; public const string Version = "1.1.0"; private static readonly KeyCode[] ExclusiveModifiers; private readonly Harmony _harmony = new Harmony("dbendu.AutoStash"); internal static ManualLogSource Log { get; private set; } internal static ConfigEntry<bool> Enabled { get; private set; } internal static ConfigEntry<KeyboardShortcut> StashKey { get; private set; } internal static ConfigEntry<float> Radius { get; private set; } internal static ConfigEntry<KeyCode> LockModifier { get; private set; } internal static ConfigEntry<bool> ProtectFromPlaceStacks { get; private set; } internal static ConfigEntry<Color> FrameColor { get; private set; } internal static ConfigEntry<bool> InventoryButton { get; private set; } internal static ConfigEntry<bool> ShowUndiscovered { get; private set; } internal static StashUi Ui { get; private set; } private void Awake() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown //IL_00fb: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable chest filters, stashing and locked slots."); StashKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "StashKey", new KeyboardShortcut((KeyCode)122, Array.Empty<KeyCode>()), "Key that puts inventory items into nearby chests whose filter accepts them. Alt/Ctrl must not be held unless they are part of the shortcut."); Radius = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Radius", 10f, new ConfigDescription("Chests farther than this many metres from the player are ignored.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(2f, 50f), Array.Empty<object>())); LockModifier = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Locked slots", "ToggleModifier", (KeyCode)308, "Hold this key and left-click an inventory slot to lock or unlock it. Items in locked slots are never stashed."); ProtectFromPlaceStacks = ((BaseUnityPlugin)this).Config.Bind<bool>("Locked slots", "ProtectFromPlaceStacks", true, "Also keep locked slots out of the game's own \"Place stacks\" action."); FrameColor = ((BaseUnityPlugin)this).Config.Bind<Color>("Locked slots", "FrameColor", new Color(1f, 0.62f, 0.2f, 1f), "Colour of the frame drawn around locked slots."); InventoryButton = ((BaseUnityPlugin)this).Config.Bind<bool>("Interface", "InventoryButton", true, "Show a Stash button next to the inventory."); ShowUndiscovered = ((BaseUnityPlugin)this).Config.Bind<bool>("Interface", "ShowUndiscoveredItems", false, "List every item in the filter editor, not only items this character has discovered."); Ui = new StashUi(); _harmony.PatchAll(typeof(Plugin).Assembly); } private void Update() { try { Ui?.Tick(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Filter window closed after an error: " + ex)); Ui?.ClosePanel(); } try { Stasher.Tick(); if (Enabled.Value && StashKeyPressed()) { Stasher.Begin(); } } catch (Exception ex2) { ((BaseUnityPlugin)this).Logger.LogError((object)("Stashing stopped after an error: " + ex2)); Stasher.Abort(); } } private void OnDestroy() { _harmony.UnpatchSelf(); Stasher.Abort(); Ui?.Dispose(); Ui = null; } private static bool StashKeyPressed() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = StashKey.Value; if ((int)((KeyboardShortcut)(ref value)).MainKey == 0 || !ZInput.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey, false)) { return false; } List<KeyCode> list = new List<KeyCode>(((KeyboardShortcut)(ref value)).Modifiers); foreach (KeyCode item in list) { if (!ZInput.GetKey(item, false)) { return false; } } KeyCode[] exclusiveModifiers = ExclusiveModifiers; foreach (KeyCode val in exclusiveModifiers) { if (!list.Contains(val) && ZInput.GetKey(val, false)) { return false; } } return CanStashNow(); } private static bool CanStashNow() { Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer) || ((Character)localPlayer).IsDead() || ((Character)localPlayer).IsTeleporting() || ((Character)localPlayer).InCutscene()) { return false; } if ((Object.op_Implicit((Object)(object)Chat.instance) && Chat.instance.HasFocus()) || Console.IsVisible() || TextInput.IsVisible() || Menu.IsVisible() || StoreGui.IsVisible() || Minimap.IsOpen() || (Object.op_Implicit((Object)(object)TextViewer.instance) && TextViewer.instance.IsVisible()) || PlayerCustomizaton.IsBarberGuiVisible() || GameCamera.InFreeFly() || (Object.op_Implicit((Object)(object)Hud.instance) && Object.op_Implicit((Object)(object)Hud.instance.m_buildUi) && Hud.instance.m_buildUi.SearchFieldFocused)) { return false; } if (!TextFieldFocused()) { if (Ui != null) { return !Ui.PanelOpen; } return true; } return false; } private static bool TextFieldFocused() { GameObject val = (Object.op_Implicit((Object)(object)EventSystem.current) ? EventSystem.current.currentSelectedGameObject : null); if (!Object.op_Implicit((Object)(object)val)) { return false; } TMP_InputField component = val.GetComponent<TMP_InputField>(); InputField component2 = val.GetComponent<InputField>(); if (!Object.op_Implicit((Object)(object)component) || !component.isFocused) { if (Object.op_Implicit((Object)(object)component2)) { return component2.isFocused; } return false; } return true; } internal unsafe static string KeyName(KeyCode key) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected I4, but got Unknown switch (key - 303) { case 4: case 5: return "Alt"; case 2: case 3: return "Ctrl"; case 0: case 1: return "Shift"; default: return ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString(); } } internal static string StashKeyName() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = StashKey.Value; List<string> list = new List<string>(); foreach (KeyCode modifier in ((KeyboardShortcut)(ref value)).Modifiers) { list.Add(KeyName(modifier)); } list.Add(KeyName(((KeyboardShortcut)(ref value)).MainKey)); return string.Join("+", list); } static Plugin() { KeyCode[] array = new KeyCode[6]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); ExclusiveModifiers = (KeyCode[])(object)array; } } internal static class GameAccess { internal static readonly FieldRef<InventoryGui, Container> CurrentContainer = AccessTools.FieldRefAccess<InventoryGui, Container>("m_currentContainer"); internal static readonly FieldRef<InventoryGui, ItemData> DragItem = AccessTools.FieldRefAccess<InventoryGui, ItemData>("m_dragItem"); internal static readonly FieldRef<InventoryGui, GameObject> DragObject = AccessTools.FieldRefAccess<InventoryGui, GameObject>("m_dragGo"); internal static readonly FieldRef<InventoryGui, ItemData> SplitItem = AccessTools.FieldRefAccess<InventoryGui, ItemData>("m_splitItem"); internal static readonly FieldRef<InventoryGrid, List<InventoryElement>> Elements = AccessTools.FieldRefAccess<InventoryGrid, List<InventoryElement>>("m_elements"); internal static readonly FieldRef<Inventory, List<ItemData>> Items = AccessTools.FieldRefAccess<Inventory, List<ItemData>>("m_inventory"); internal static readonly FieldRef<Container, ZNetView> NetView = AccessTools.FieldRefAccess<Container, ZNetView>("m_nview"); private static readonly MethodInfo InventoryChanged = AccessTools.Method(typeof(Inventory), "Changed", (Type[])null, (Type[])null); private static readonly MethodInfo ContainerLoad = AccessTools.Method(typeof(Container), "Load", (Type[])null, (Type[])null); internal static Container OpenedChest() { InventoryGui instance = InventoryGui.instance; if (!Object.op_Implicit((Object)(object)instance)) { return null; } return CurrentContainer.Invoke(instance); } internal static void Changed(Inventory inventory) { InventoryChanged.Invoke(inventory, new object[2] { false, false }); } internal static void Reload(Container chest) { ContainerLoad.Invoke(chest, Array.Empty<object>()); } } internal static class Text { internal static bool Russian { get { if (Localization.instance != null) { return Localization.instance.GetSelectedLanguage() == "Russian"; } return false; } } internal static string T(string english, string russian) { if (!Russian) { return english; } return russian; } internal static string Plural(int count, string one, string few, string many) { int num = Math.Abs(count) % 100; int num2 = num % 10; if (num > 10 && num < 20) { return many; } switch (num2) { case 1: return one; default: return many; case 2: case 3: case 4: return few; } } internal static string Localize(string token) { if (Localization.instance == null) { return token; } return Localization.instance.Localize(token); } } internal static class InputBlock { private static int _lastActiveFrame = -10; internal static bool Polling; internal static bool Active { get { if (Polling) { return false; } if (Plugin.Ui != null && Plugin.Ui.PanelOpen) { _lastActiveFrame = Time.frameCount; return true; } return Time.frameCount <= _lastActiveFrame + 1; } } internal static void MarkClosed() { _lastActiveFrame = Time.frameCount; } } [HarmonyPatch] internal static class ZInputButtonPatch { private static IEnumerable<MethodBase> TargetMethods() { string[] array = new string[3] { "GetButton", "GetButtonDown", "GetButtonUp" }; foreach (string text in array) { yield return AccessTools.Method(typeof(ZInput), text, new Type[1] { typeof(string) }, (Type[])null); } } [HarmonyPriority(0)] private static void Postfix(ref bool __result) { if (InputBlock.Active) { __result = false; } } } [HarmonyPatch] internal static class ZInputKeyPatch { private static IEnumerable<MethodBase> TargetMethods() { string[] array = new string[3] { "GetKey", "GetKeyDown", "GetKeyUp" }; foreach (string text in array) { yield return AccessTools.Method(typeof(ZInput), text, new Type[2] { typeof(KeyCode), typeof(bool) }, (Type[])null); } } [HarmonyPriority(0)] private static void Postfix(KeyCode key, ref bool __result) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Invalid comparison between Unknown and I4 if (InputBlock.Active && ((int)key < 323 || (int)key > 329)) { __result = false; } } } internal static class SlotLocks { private const string DataKey = "AutoStash.LockedSlots.v1"; private static readonly HashSet<int> Empty = new HashSet<int>(); private static Player _player; private static string _raw; private static HashSet<int> _locked = new HashSet<int>(); private static int Key(Vector2i pos) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) return pos.y * 1000 + pos.x; } private static HashSet<int> Current() { Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer)) { return Empty; } localPlayer.m_customData.TryGetValue("AutoStash.LockedSlots.v1", out var value); value = value ?? ""; if ((Object)(object)localPlayer != (Object)(object)_player || value != _raw) { _player = localPlayer; _raw = value; _locked = Parse(value); } return _locked; } private static HashSet<int> Parse(string raw) { //IL_0074: Unknown result type (might be due to invalid IL or missing references) HashSet<int> hashSet = new HashSet<int>(); string[] array = raw.Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Split(','); if (array2.Length == 2 && int.TryParse(array2[0], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result) && int.TryParse(array2[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out var result2) && result >= 0 && result < 1000 && result2 >= 0 && result2 < 1000) { hashSet.Add(Key(new Vector2i(result, result2))); } } return hashSet; } internal static bool IsLocked(Vector2i pos) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) return Current().Contains(Key(pos)); } internal static bool Lockable(Vector2i pos) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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_0045: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer)) { return false; } Inventory inventory = ((Humanoid)localPlayer).GetInventory(); if (pos.x >= 0 && pos.y >= 0 && pos.x < inventory.GetWidth() && pos.y < ExtraSlotsCompat.PlayerRows(inventory)) { return !ExtraSlotsCompat.IsSlot(pos); } return false; } internal static bool Protects(ItemData item) { //IL_0004: 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) if (item != null && IsLocked(item.m_gridPos)) { return Lockable(item.m_gridPos); } return false; } internal static void Toggle(Vector2i pos) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer)) { return; } HashSet<int> hashSet = new HashSet<int>(Current()); if (!hashSet.Remove(Key(pos))) { hashSet.Add(Key(pos)); } List<string> list = new List<string>(); foreach (int item in hashSet) { list.Add((item % 1000).ToString(CultureInfo.InvariantCulture) + "," + (item / 1000).ToString(CultureInfo.InvariantCulture)); } list.Sort(StringComparer.Ordinal); if (list.Count == 0) { localPlayer.m_customData.Remove("AutoStash.LockedSlots.v1"); } else { localPlayer.m_customData["AutoStash.LockedSlots.v1"] = string.Join(";", list); } } internal static bool ModifierHeld() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: 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_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Invalid comparison between Unknown and I4 //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Invalid comparison between Unknown and I4 //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Invalid comparison between Unknown and I4 //IL_004d: Unknown result type (might be due to invalid IL or missing references) KeyCode value = Plugin.LockModifier.Value; if ((int)value == 0) { return false; } if (ZInput.GetKey(value, false)) { return true; } KeyCode val = (KeyCode)(((int)value == 308) ? 307 : (((int)value == 306) ? 305 : (((int)value == 304) ? 303 : 0))); if ((int)val != 0) { return ZInput.GetKey(val, false); } return false; } internal static void UpdateOverlays(InventoryGrid grid) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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_00c5: Unknown result type (might be due to invalid IL or missing references) bool value = Plugin.Enabled.Value; Color value2 = Plugin.FrameColor.Value; foreach (InventoryElement item in GameAccess.Elements.Invoke(grid)) { if (!Object.op_Implicit((Object)(object)item)) { continue; } bool flag = value && IsLocked(item.Position) && Lockable(item.Position); Transform val = ((Component)item).transform.Find("AutoStashLock"); LockMarker lockMarker = (Object.op_Implicit((Object)(object)val) ? ((Component)val).GetComponent<LockMarker>() : null); if (!Object.op_Implicit((Object)(object)lockMarker)) { if (!flag) { continue; } lockMarker = LockMarker.Create(((Component)item).transform); } if (((Component)lockMarker).gameObject.activeSelf != flag) { ((Component)lockMarker).gameObject.SetActive(flag); } if (flag) { lockMarker.Apply(value2); } } } } [HarmonyPatch(typeof(InventoryGui), "OnSelectedItem")] internal static class LockClickPatch { [HarmonyPriority(800)] private static bool Prefix(InventoryGui __instance, InventoryGrid grid, Vector2i pos) { //IL_0034: 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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.Enabled.Value || (Object)(object)grid != (Object)(object)__instance.m_playerGrid || Object.op_Implicit((Object)(object)GameAccess.DragObject.Invoke(__instance)) || !SlotLocks.ModifierHeld() || !SlotLocks.Lockable(pos)) { return true; } SlotLocks.Toggle(pos); __instance.m_moveItemEffects.Create(((Component)__instance).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID)); return false; } } [HarmonyPatch(typeof(InventoryGrid), "UpdateGui")] internal static class LockOverlayPatch { private static void Postfix(InventoryGrid __instance) { InventoryGui instance = InventoryGui.instance; if (Object.op_Implicit((Object)(object)instance) && (Object)(object)__instance == (Object)(object)instance.m_playerGrid) { SlotLocks.UpdateOverlays(__instance); } } } [HarmonyPatch(typeof(Inventory), "StackAll")] internal static class PlaceStacksPatch { private static Inventory _inventory; private static readonly List<KeyValuePair<int, ItemData>> Hidden = new List<KeyValuePair<int, ItemData>>(); private static void Prefix(Inventory fromInventory) { Restore(); Player localPlayer = Player.m_localPlayer; if (!Plugin.Enabled.Value || !Plugin.ProtectFromPlaceStacks.Value || !Object.op_Implicit((Object)(object)localPlayer) || fromInventory != ((Humanoid)localPlayer).GetInventory()) { return; } List<ItemData> list = GameAccess.Items.Invoke(fromInventory); for (int num = list.Count - 1; num >= 0; num--) { ItemData val = list[num]; if (SlotLocks.Protects(val) && !((Humanoid)localPlayer).IsItemEquiped(val)) { Hidden.Add(new KeyValuePair<int, ItemData>(num, val)); list.RemoveAt(num); } } if (Hidden.Count > 0) { _inventory = fromInventory; } } private static Exception Finalizer(Exception __exception) { Restore(); return __exception; } private static void Restore() { Inventory inventory = _inventory; if (inventory == null) { Hidden.Clear(); return; } _inventory = null; List<ItemData> list = GameAccess.Items.Invoke(inventory); for (int num = Hidden.Count - 1; num >= 0; num--) { KeyValuePair<int, ItemData> keyValuePair = Hidden[num]; if (!list.Contains(keyValuePair.Value)) { list.Insert(Math.Min(keyValuePair.Key, list.Count), keyValuePair.Value); } } Hidden.Clear(); try { GameAccess.Changed(inventory); } catch (Exception ex) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)("Could not refresh the inventory after Place stacks: " + ex.Message)); } } } } internal static class ExtraSlotsCompat { internal const string Guid = "shudnal.ExtraSlots"; private static bool _initialized; private static Func<ItemData, bool> _isItemInSlot; private static Func<Vector2i, bool> _isGridPositionASlot; private static Func<int> _playerRows; private static void Init() { if (_initialized) { return; } _initialized = true; if (!Chainloader.PluginInfos.TryGetValue("shudnal.ExtraSlots", out var value) || !Object.op_Implicit((Object)(object)value.Instance)) { return; } try { Type type = ((object)value.Instance).GetType().Assembly.GetType("ExtraSlots.API"); if (type == null) { ManualLogSource log = Plugin.Log; if (log != null) { log.LogWarning((object)"ExtraSlots API not found; its slots are not recognised."); } return; } MethodInfo methodInfo = AccessTools.Method(type, "IsItemInSlot", new Type[1] { typeof(ItemData) }, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(type, "IsGridPositionASlot", new Type[1] { typeof(Vector2i) }, (Type[])null); MethodInfo methodInfo3 = AccessTools.Method(type, "GetInventoryHeightPlayer", Type.EmptyTypes, (Type[])null); _isItemInSlot = ((methodInfo != null) ? ((Func<ItemData, bool>)Delegate.CreateDelegate(typeof(Func<ItemData, bool>), methodInfo)) : null); _isGridPositionASlot = ((methodInfo2 != null) ? ((Func<Vector2i, bool>)Delegate.CreateDelegate(typeof(Func<Vector2i, bool>), methodInfo2)) : null); _playerRows = ((methodInfo3 != null) ? ((Func<int>)Delegate.CreateDelegate(typeof(Func<int>), methodInfo3)) : null); } catch (Exception ex) { ManualLogSource log2 = Plugin.Log; if (log2 != null) { log2.LogWarning((object)("ExtraSlots integration unavailable: " + ex.Message)); } } } internal static bool IsItemInSlot(ItemData item) { Init(); try { return _isItemInSlot != null && _isItemInSlot(item); } catch { return false; } } internal static bool IsSlot(Vector2i pos) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) Init(); try { return _isGridPositionASlot != null && _isGridPositionASlot(pos); } catch { return false; } } internal static int PlayerRows(Inventory inventory) { Init(); int height = inventory.GetHeight(); try { int num = ((_playerRows != null) ? _playerRows() : height); return (num > 0) ? Math.Min(num, height) : height; } catch { return height; } } } internal static class Stasher { private sealed class Target { internal Container Chest; internal float Distance; internal ChestFilter Filter; } private sealed class Session { internal readonly List<Target> Ready = new List<Target>(); internal readonly Dictionary<Container, Target> Requested = new Dictionary<Container, Target>(); internal readonly Dictionary<Container, Target> Granted = new Dictionary<Container, Target>(); internal float Deadline; internal int Unavailable; } private const float TimeoutSeconds = 3f; private static readonly HashSet<Container> Chests = new HashSet<Container>(); private static Session _session; internal static void Register(Container chest) { Chests.Add(chest); } internal static void Abort() { _session = null; } internal static void Begin() { Player localPlayer = Player.m_localPlayer; if (_session != null || !Object.op_Implicit((Object)(object)localPlayer)) { return; } long playerID = Game.instance.GetPlayerProfile().GetPlayerID(); int inUse; List<Target> targets = FindTargets(localPlayer, playerID, out inUse); if (targets.Count == 0) { ((Character)localPlayer).Message((MessageType)2, (inUse > 0) ? Text.T("The chests nearby are in use.", "Сундуки рядом заняты другими игроками.") : Text.T("No chests with a filter nearby.", "Рядом нет сундуков с фильтром."), 0, (Sprite)null, false); return; } if (!Candidates(localPlayer).Any((ItemData item) => targets.Any((Target t) => t.Filter.Rank(item) != -1))) { ((Character)localPlayer).Message((MessageType)2, Text.T("Nothing to stash.", "Нечего раскладывать."), 0, (Sprite)null, false); return; } Session session = new Session { Deadline = Time.unscaledTime + 3f, Unavailable = inUse }; foreach (Target item in targets) { ZNetView val = FilterStore.NetView(item.Chest); if (val.IsOwner()) { session.Ready.Add(item); } else if (!val.GetZDO().HasOwner()) { val.ClaimOwnership(); session.Ready.Add(item); } else { session.Requested[item.Chest] = item; } } _session = session; foreach (Container item2 in session.Requested.Keys.ToList()) { FilterStore.NetView(item2).InvokeRPC("RPC_RequestStack", new object[1] { playerID }); } Tick(); } internal static void Tick() { Session session = _session; if (session == null) { return; } foreach (KeyValuePair<Container, Target> item in session.Granted.ToList()) { ZNetView val = FilterStore.NetView(item.Key); if (!Object.op_Implicit((Object)(object)item.Key) || !Object.op_Implicit((Object)(object)val) || !val.IsValid()) { session.Granted.Remove(item.Key); } else if (val.IsOwner()) { session.Granted.Remove(item.Key); session.Ready.Add(item.Value); } } if ((session.Requested.Count <= 0 && session.Granted.Count <= 0) || !(Time.unscaledTime < session.Deadline)) { session.Unavailable += session.Requested.Count + session.Granted.Count; _session = null; Execute(session); } } internal static bool OnStackResponse(Container chest, bool granted) { Session session = _session; if (session == null || !session.Requested.TryGetValue(chest, out var value)) { return false; } session.Requested.Remove(chest); if (granted) { session.Granted[chest] = value; } else { session.Unavailable++; } return true; } private static List<Target> FindTargets(Player player, long playerId, out int inUse) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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) //IL_007c: Unknown result type (might be due to invalid IL or missing references) inUse = 0; List<Target> list = new List<Target>(); Vector3 position = ((Component)player).transform.position; float value = Plugin.Radius.Value; Chests.RemoveWhere((Container c) => !Object.op_Implicit((Object)(object)c)); foreach (Container chest in Chests) { if (!((Component)chest).gameObject.activeInHierarchy) { continue; } float num = Vector3.Distance(position, ((Component)chest).transform.position); if (num > value || !FilterStore.Eligible(chest)) { continue; } ZNetView val = FilterStore.NetView(chest); if (!Object.op_Implicit((Object)(object)val) || !val.IsValid()) { continue; } ChestFilter chestFilter = FilterStore.Load(chest); if (!chestFilter.IsEmpty && CanAccess(chest, playerId)) { if (!val.IsOwner() && val.GetZDO().GetInt(ZDOVars.s_inUse, 0) == 1) { inUse++; continue; } list.Add(new Target { Chest = chest, Distance = num, Filter = chestFilter }); } } return list; } private static bool CanAccess(Container chest, long playerId) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Invalid comparison between Unknown and I4 if (chest.m_checkGuardStone && !PrivateArea.CheckAccess(((Component)chest).transform.position, 0f, false, false)) { return false; } PrivacySetting privacy = chest.m_privacy; if ((int)privacy != 0) { if ((int)privacy == 2) { return true; } return false; } Piece component = ((Component)chest).GetComponent<Piece>(); if (Object.op_Implicit((Object)(object)component)) { return component.GetCreator() == playerId; } return false; } private static List<ItemData> Candidates(Player player) { Inventory inventory = ((Humanoid)player).GetInventory(); int num = ExtraSlotsCompat.PlayerRows(inventory); InventoryGui instance = InventoryGui.instance; ItemData val = (Object.op_Implicit((Object)(object)instance) ? GameAccess.DragItem.Invoke(instance) : null); ItemData val2 = (Object.op_Implicit((Object)(object)instance) ? GameAccess.SplitItem.Invoke(instance) : null); List<ItemData> list = new List<ItemData>(); foreach (ItemData item in inventory.GetAllItemsInGridOrder()) { if (item != null && !item.m_equipped && !((Humanoid)player).IsItemEquiped(item) && !item.m_shared.m_questItem && item != val && item != val2 && item.m_gridPos.y < num && !ExtraSlotsCompat.IsItemInSlot(item) && !SlotLocks.Protects(item)) { list.Add(item); } } return list; } private static void Execute(Session session) { //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: 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) Player localPlayer = Player.m_localPlayer; if (!Object.op_Implicit((Object)(object)localPlayer) || ((Character)localPlayer).IsDead()) { return; } Inventory inventory = ((Humanoid)localPlayer).GetInventory(); List<Target> list = new List<Target>(); foreach (Target item2 in session.Ready) { ZNetView val = FilterStore.NetView(item2.Chest); if (!Object.op_Implicit((Object)(object)item2.Chest) || !Object.op_Implicit((Object)(object)val) || !val.IsValid() || !val.IsOwner()) { session.Unavailable++; continue; } GameAccess.Reload(item2.Chest); item2.Filter = FilterStore.Load(item2.Chest); list.Add(item2); } int num = 0; int num2 = 0; HashSet<Container> hashSet = new HashSet<Container>(); foreach (ItemData item in Candidates(localPlayer)) { List<Target> list2 = (from t in list select new { Target = t, Rank = t.Filter.Rank(item) } into t where t.Rank != -1 orderby t.Rank, (!t.Target.Chest.GetInventory().ContainsItemByName(item.m_shared.m_name)) ? 1 : 0, t.Target.Distance select t.Target).ToList(); if (list2.Count == 0) { continue; } foreach (Target item3 in list2) { int num3 = Move(inventory, item3.Chest.GetInventory(), item); if (num3 > 0) { num += num3; hashSet.Add(item3.Chest); } if (!inventory.ContainsItem(item)) { break; } } if (inventory.ContainsItem(item)) { num2 += item.m_stack; } } if (num > 0) { GameAccess.Changed(inventory); if (Object.op_Implicit((Object)(object)InventoryGui.instance)) { InventoryGui.instance.m_moveItemEffects.Create(((Component)localPlayer).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID)); } } ((Character)localPlayer).Message((MessageType)2, Report(num, hashSet.Count, num2, session.Unavailable), 0, (Sprite)null, false); } private static int Move(Inventory from, Inventory to, ItemData item) { if (!HasRoom(to, item)) { return 0; } int stack = item.m_stack; if (to.AddItem(item)) { from.RemoveItem(item); return stack; } return stack - item.m_stack; } private static bool HasRoom(Inventory inventory, ItemData item) { if (inventory.HaveEmptySlot()) { return true; } if (item.m_shared.m_maxStackSize <= 1) { return false; } foreach (ItemData allItem in inventory.GetAllItems()) { if (allItem.m_shared.m_name == item.m_shared.m_name && allItem.m_quality == item.m_quality && allItem.m_worldLevel == item.m_worldLevel && allItem.m_stack < allItem.m_shared.m_maxStackSize) { return true; } } return false; } private static string Report(int moved, int chests, int left, int unavailable) { List<string> list = new List<string>(); if (moved > 0) { list.Add(Text.T($"Stashed {moved} item(s) in {chests} chest(s).", string.Format("Разложено {0} {1} по {2} {3}.", moved, Text.Plural(moved, "предмет", "предмета", "предметов"), chests, Text.Plural(chests, "сундуку", "сундукам", "сундукам")))); } if (left > 0) { list.Add(Text.T($"No room left for {left} item(s).", $"Не хватило места ещё для {left} шт.")); } if (unavailable > 0) { list.Add(Text.T("Some chests are in use by other players.", "Часть сундуков занята другими игроками.")); } if (list.Count == 0) { list.Add(Text.T("Nothing to stash.", "Нечего раскладывать.")); } return string.Join("\n", list); } } [HarmonyPatch(typeof(Container), "Awake")] internal static class ContainerRegisterPatch { private static void Postfix(Container __instance) { if (__instance.GetInventory() != null) { Stasher.Register(__instance); } } } [HarmonyPatch(typeof(Container), "RPC_StackResponse")] internal static class StackResponsePatch { [HarmonyPriority(800)] private static bool Prefix(Container __instance, bool granted) { return !Stasher.OnStackResponse(__instance, granted); } } internal sealed class StashUi : IDisposable { [CompilerGenerated] private static class <>O { public static UnityAction <0>__Begin; } private readonly UiKit _kit = new UiKit(); private readonly FilterPanel _panel; private Button _filterButton; private TMP_Text _filterLabel; private Button _stashButton; private TMP_Text _stashLabel; private string _stashTextKey; internal bool PanelOpen => _panel.IsOpen; internal StashUi() { _panel = new FilterPanel(_kit); } internal void Tick() { InventoryGui instance = InventoryGui.instance; if (Object.op_Implicit((Object)(object)instance) && (!Object.op_Implicit((Object)(object)_filterButton) || !Object.op_Implicit((Object)(object)_stashButton))) { _kit.Capture(instance); if (!Object.op_Implicit((Object)(object)_filterButton) && Object.op_Implicit((Object)(object)instance.m_container)) { CreateFilterButton(instance); } if (!Object.op_Implicit((Object)(object)_stashButton) && Object.op_Implicit((Object)(object)instance.m_player)) { CreateStashButton(instance); } } bool value = Plugin.Enabled.Value; if (Object.op_Implicit((Object)(object)_filterButton)) { Container chest = GameAccess.OpenedChest(); bool flag = value && FilterStore.Eligible(chest); if (((Component)_filterButton).gameObject.activeSelf != flag) { ((Component)_filterButton).gameObject.SetActive(flag); } if (flag) { int count = FilterStore.Load(chest).Count; string text = Text.T("Filter", "Фильтр") + ((count > 0) ? (" (" + count + ")") : ""); if (_filterLabel.text != text) { _filterLabel.text = text; } } } if (Object.op_Implicit((Object)(object)_stashButton)) { bool flag2 = value && Plugin.InventoryButton.Value; if (((Component)_stashButton).gameObject.activeSelf != flag2) { ((Component)_stashButton).gameObject.SetActive(flag2); } if (flag2) { UpdateStashTexts(); } } _panel.Tick(); } internal void ClosePanel() { _panel.Close(); } public void Dispose() { _panel.Close(); if (Object.op_Implicit((Object)(object)_filterButton)) { Object.Destroy((Object)(object)((Component)_filterButton).gameObject); } if (Object.op_Implicit((Object)(object)_stashButton)) { Object.Destroy((Object)(object)((Component)_stashButton).gameObject); } } private void CreateFilterButton(InventoryGui gui) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) _filterButton = _kit.AddButton((Transform)(object)gui.m_container, "", 0f, 0f, 140f, 36f, (UnityAction)delegate { _panel.Open(GameAccess.OpenedChest()); }); ((Object)_filterButton).name = "AutoStashFilterButton"; RectTransform val = (RectTransform)((Component)_filterButton).transform; Vector2 val2 = default(Vector2); ((Vector2)(ref val2))..ctor(1f, 0f); val.anchorMax = val2; val.anchorMin = val2; val.pivot = Vector2.one; val.anchoredPosition = new Vector2(-8f, -6f); _filterLabel = ((Component)_filterButton).GetComponentInChildren<TMP_Text>(); } private void CreateStashButton(InventoryGui gui) { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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_0036: 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: Expected O, but got Unknown UiKit kit = _kit; RectTransform player = gui.m_player; object obj = <>O.<0>__Begin; if (obj == null) { UnityAction val = Stasher.Begin; <>O.<0>__Begin = val; obj = (object)val; } _stashButton = kit.AddButton((Transform)(object)player, "", 0f, 0f, 100f, 36f, (UnityAction)obj); ((Object)_stashButton).name = "AutoStashButton"; RectTransform val2 = (RectTransform)((Component)_stashButton).transform; Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(1f, 0.5f); val2.anchorMax = val3; val2.anchorMin = val3; val2.pivot = new Vector2(0f, 0.5f); val2.anchoredPosition = new Vector2(-8f, -6f); _stashLabel = ((Component)_stashButton).GetComponentInChildren<TMP_Text>(); _stashTextKey = null; } private void UpdateStashTexts() { //IL_000b: Unknown result type (might be due to invalid IL or missing references) string text = Plugin.StashKeyName(); string text2 = Plugin.KeyName(Plugin.LockModifier.Value); float value = Plugin.Radius.Value; string text3 = Text.Russian + "|" + text + "|" + text2 + "|" + value + "|" + Object.op_Implicit((Object)(object)_kit.TooltipPrefab); if (!(text3 == _stashTextKey)) { _stashTextKey = text3; _stashLabel.text = Text.T("Stash", "Разложить") + " (" + text + ")"; _kit.AddTooltip(((Component)_stashButton).gameObject, Text.T("Stash to chests", "Разложить по сундукам"), Text.T($"Moves items into chests within {value:0} m whose filter accepts them. Key: {text}.\n{text2}+click a slot to lock it: locked slots are never stashed.", $"Переносит вещи в сундуки в радиусе {value:0} м, если их фильтр принимает эти вещи. Клавиша: {text}.\n{text2}+клик по слоту блокирует его: вещи из заблокированных слотов не раскладываются.")); } } } internal sealed class UiKit { internal static readonly Color TextColor = new Color(1f, 0.85f, 0.57f); internal TMP_FontAsset Font; internal Sprite ButtonSprite; internal Type ButtonType = (Type)1; internal Color ButtonColor = new Color(0.29f, 0.2f, 0.13f); internal Sprite PanelSprite; internal Type PanelType = (Type)1; internal Color PanelColor = new Color(0.16f, 0.11f, 0.08f, 0.97f); internal GameObject TooltipPrefab; internal void Capture(InventoryGui gui) { //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)gui)) { return; } if (Object.op_Implicit((Object)(object)gui.m_containerName) && Object.op_Implicit((Object)(object)gui.m_containerName.font)) { Font = gui.m_containerName.font; } Image val = (Object.op_Implicit((Object)(object)gui.m_takeAllButton) ? ((Selectable)gui.m_takeAllButton).image : null); if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.sprite)) { ButtonSprite = val.sprite; ButtonType = val.type; ButtonColor = ((Graphic)val).color; } Image val2 = (Object.op_Implicit((Object)(object)gui.m_container) ? ((Component)gui.m_container).GetComponent<Image>() : null); if (Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)val2.sprite)) { PanelSprite = val2.sprite; PanelType = val2.type; PanelColor = ((Graphic)val2).color; } if (!Object.op_Implicit((Object)(object)TooltipPrefab) && Object.op_Implicit((Object)(object)gui.m_playerGrid) && Object.op_Implicit((Object)(object)gui.m_playerGrid.m_elementPrefab)) { InventoryElement component = gui.m_playerGrid.m_elementPrefab.GetComponent<InventoryElement>(); if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.m_tooltip) && Object.op_Implicit((Object)(object)component.m_tooltip.m_tooltipPrefab)) { TooltipPrefab = component.m_tooltip.m_tooltipPrefab; } } if (Object.op_Implicit((Object)(object)TooltipPrefab)) { return; } UITooltip[] componentsInChildren = ((Component)gui).GetComponentsInChildren<UITooltip>(true); foreach (UITooltip val3 in componentsInChildren) { if (Object.op_Implicit((Object)(object)val3.m_tooltipPrefab)) { TooltipPrefab = val3.m_tooltipPrefab; break; } } } internal static RectTransform AddRect(string name, Transform parent, float x, float y, float width, float height) { //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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_004c: 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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }); val.transform.SetParent(parent, false); RectTransform val2 = (RectTransform)val.transform; Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(0f, 1f); val2.pivot = val3; Vector2 anchorMin = (val2.anchorMax = val3); val2.anchorMin = anchorMin; val2.anchoredPosition = new Vector2(x, 0f - y); val2.sizeDelta = new Vector2(width, height); return val2; } internal static Image AddImage(string name, Transform parent, Color color) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) Image obj = ((Component)AddRect(name, parent, 0f, 0f, 0f, 0f)).gameObject.AddComponent<Image>(); ((Graphic)obj).color = color; return obj; } internal static void Stretch(RectTransform rect, float inset = 0f) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) rect.anchorMin = Vector2.zero; rect.anchorMax = Vector2.one; rect.pivot = new Vector2(0.5f, 0.5f); rect.offsetMin = new Vector2(inset, inset); rect.offsetMax = new Vector2(0f - inset, 0f - inset); } internal TMP_Text AddText(Transform parent, string value, float x, float y, float width, float height, float size) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) TextMeshProUGUI val = ((Component)AddRect("Text", parent, x, y, width, height)).gameObject.AddComponent<TextMeshProUGUI>(); if (Object.op_Implicit((Object)(object)Font)) { ((TMP_Text)val).font = Font; } ((TMP_Text)val).text = value; ((TMP_Text)val).fontSize = size; ((Graphic)val).color = TextColor; ((TMP_Text)val).richText = false; ((Graphic)val).raycastTarget = false; ((TMP_Text)val).alignment = (TextAlignmentOptions)4097; ((TMP_Text)val).overflowMode = (TextOverflowModes)1; return (TMP_Text)(object)val; } internal Button AddButton(Transform parent, string label, float x, float y, float width, float height, UnityAction action) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) RectTransform val = AddRect("Button", parent, x, y, width, height); Image val2 = ((Component)val).gameObject.AddComponent<Image>(); val2.sprite = ButtonSprite; val2.type = ButtonType; ((Graphic)val2).color = ButtonColor; Button obj = ((Component)val).gameObject.AddComponent<Button>(); ((Selectable)obj).targetGraphic = (Graphic)(object)val2; ((UnityEvent)obj.onClick).AddListener(action); TMP_Text obj2 = AddText((Transform)(object)val, label, 6f, 0f, width - 12f, height, 18f); obj2.alignment = (TextAlignmentOptions)514; obj2.enableAutoSizing = true; obj2.fontSizeMin = 11f; obj2.fontSizeMax = 18f; return obj; } internal TMP_InputField AddInput(Transform parent, string placeholder, float x, float y, float width, float height, int limit) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) RectTransform val = AddRect("Input", parent, x, y, width, height); Image val2 = ((Component)val).gameObject.AddComponent<Image>(); ((Graphic)val2).color = new Color(0.08f, 0.06f, 0.04f); TMP_InputField obj = ((Component)val).gameObject.AddComponent<TMP_InputField>(); ((Selectable)obj).targetGraphic = (Graphic)(object)val2; obj.characterLimit = limit; obj.lineType = (LineType)0; RectTransform val3 = AddRect("Viewport", (Transform)(object)val, 8f, 0f, width - 16f, height); ((Component)val3).gameObject.AddComponent<RectMask2D>(); TMP_Text val4 = AddText((Transform)(object)val3, "", 0f, 0f, width - 16f, height, 18f); val4.overflowMode = (TextOverflowModes)0; TMP_Text val5 = AddText((Transform)(object)val3, placeholder, 0f, 0f, width - 16f, height, 18f); ((Graphic)val5).color = Color.gray; obj.textViewport = val3; obj.textComponent = val4; obj.placeholder = (Graphic)(object)val5; return obj; } internal void AddTooltip(GameObject target, string topic, string text) { if (Object.op_Implicit((Object)(object)TooltipPrefab)) { UITooltip val = target.GetComponent<UITooltip>(); if (!Object.op_Implicit((Object)(object)val)) { val = target.AddComponent<UITooltip>(); } val.m_tooltipPrefab = TooltipPrefab; val.m_topic = topic; val.m_text = text; } } } internal sealed class HoverRelay : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler { internal Action Entered; internal Action Exited; public void OnPointerEnter(PointerEventData eventData) { Entered?.Invoke(); } public void OnPointerExit(PointerEventData eventData) { Exited?.Invoke(); } } }