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 QuickStackPlus v1.2.0
QuickStackPlus.dll
Decompiled 5 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ConditionalConfigSync; using HarmonyLib; using Microsoft.CodeAnalysis; using QuickStackPlus.UI; 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: AssemblyTitle("QuickStackPlus")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Goneryx")] [assembly: AssemblyProduct("QuickStackPlus")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("dfffd921-4f13-41b7-9dd6-fed57ea5fb5c")] [assembly: AssemblyFileVersion("1.1.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [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 QuickStackPlus { [BepInPlugin("Goneryx.QuickStackPlus", "QuickStackPlus", "1.2.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { private const string PluginGuid = "Goneryx.QuickStackPlus"; private const string PluginName = "QuickStackPlus"; private const string PluginVersion = "1.2.0"; private ConfigEntry<bool> _modEnabled; private ConfigEntry<float> _searchRadius; private ConfigEntry<KeyboardShortcut> _quickStackShortcut; private ConfigEntry<KeyboardShortcut> _sortShortcut; private ConfigEntry<KeyboardShortcut> _trashShortcut; private ConfigEntry<KeyboardShortcut> _containerSortShortcut; private ConfigEntry<bool> _enableStorageFilters; private ConfigEntry<bool> _showSmartStorageButton; private ConfigEntry<KeyboardShortcut> _toggleSmartStorageButtonShortcut; private ConfigEntry<bool> _enableQuickStackBlacklist; private ConfigEntry<KeyboardShortcut> _blacklistShortcut; private Harmony _harmonyInstance; internal static readonly ConfigSync configSync = new ConfigSync("Goneryx.QuickStackPlus") { DisplayName = "QuickStackPlus", CurrentVersion = "1.2.0", MinimumRequiredVersion = "1.2.0", ModRequired = true }; internal static Plugin Instance { get; private set; } internal static ManualLogSource Log { get; private set; } internal static bool ModEnabled { get { if (Instance?._modEnabled != null) { return Instance._modEnabled.Value; } return true; } } internal static float SearchRadius { get { if (Instance?._searchRadius == null) { return 25f; } return Mathf.Clamp(Instance._searchRadius.Value, 5f, 80f); } } internal static KeyboardShortcut QuickStackShortcut { get { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) if (Instance?._quickStackShortcut == null) { return new KeyboardShortcut((KeyCode)112, Array.Empty<KeyCode>()); } return Instance._quickStackShortcut.Value; } } internal static KeyboardShortcut SortShortcut { get { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) if (Instance?._sortShortcut == null) { return new KeyboardShortcut((KeyCode)111, Array.Empty<KeyCode>()); } return Instance._sortShortcut.Value; } } internal static KeyboardShortcut TrashShortcut { get { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) if (Instance?._trashShortcut == null) { return new KeyboardShortcut((KeyCode)127, Array.Empty<KeyCode>()); } return Instance._trashShortcut.Value; } } internal static KeyboardShortcut ContainerSortShortcut { get { //IL_0029: 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) if (Instance?._containerSortShortcut == null) { return new KeyboardShortcut((KeyCode)0, Array.Empty<KeyCode>()); } return Instance._containerSortShortcut.Value; } } internal static bool EnableStorageFilters { get { if (Instance?._enableStorageFilters != null) { return Instance._enableStorageFilters.Value; } return true; } } internal static bool ShowSmartStorageButton { get { if (Instance?._showSmartStorageButton != null) { return Instance._showSmartStorageButton.Value; } return true; } } internal static KeyboardShortcut ToggleSmartStorageButtonShortcut { get { //IL_0029: 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) if (Instance?._toggleSmartStorageButtonShortcut == null) { return new KeyboardShortcut((KeyCode)0, Array.Empty<KeyCode>()); } return Instance._toggleSmartStorageButtonShortcut.Value; } } internal static bool EnableQuickStackBlacklist { get { if (Instance?._enableQuickStackBlacklist != null) { return Instance._enableQuickStackBlacklist.Value; } return true; } } internal static KeyboardShortcut BlacklistShortcut { get { //IL_0036: 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) if (Instance?._blacklistShortcut == null) { return new KeyboardShortcut((KeyCode)324, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }); } return Instance._blacklistShortcut.Value; } } private void Awake() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown //IL_0093: 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_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Expected O, but got Unknown //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Expected O, but got Unknown //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Expected O, but got Unknown //IL_01d5: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Expected O, but got Unknown //IL_0208: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Expected O, but got Unknown //IL_03ab: Unknown result type (might be due to invalid IL or missing references) //IL_03b5: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; _modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, new ConfigDescription("Master switch for QuickStackPlus. This setting is controlled by the server. When disabled, all QuickStackPlus features and in-game buttons are disabled for every connected player.", (AcceptableValueBase)null, Array.Empty<object>())); _searchRadius = ((BaseUnityPlugin)this).Config.Bind<float>("General", "SearchRadius", 25f, new ConfigDescription("The radius in which to search for nearby containers when quick stacking.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 80f), Array.Empty<object>())); _quickStackShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "QuickStackShortcut", new KeyboardShortcut((KeyCode)112, Array.Empty<KeyCode>()), "Keyboard shortcut used to quick stack nearby containers."); _sortShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "SortShortcut", new KeyboardShortcut((KeyCode)111, Array.Empty<KeyCode>()), "Keyboard shortcut used to sort the player inventory and open container."); _trashShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "TrashShortcut", new KeyboardShortcut((KeyCode)127, Array.Empty<KeyCode>()), "Keyboard shortcut used to delete items marked as junk."); _containerSortShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "ContainerSortShortcut", new KeyboardShortcut((KeyCode)0, Array.Empty<KeyCode>()), "Optional keyboard shortcut used to sort the currently open container. Leave empty to disable."); _enableStorageFilters = ((BaseUnityPlugin)this).Config.Bind<bool>("Smart Storage", "EnableStorageFilters", true, new ConfigDescription("Enables the Smart Storage filter button on opened containers. When enabled, filtered containers are preferred by Quick Stack and can accept selected items even while empty. This setting is local to each player.", (AcceptableValueBase)null, Array.Empty<object>())); _showSmartStorageButton = ((BaseUnityPlugin)this).Config.Bind<bool>("Smart Storage", "ShowSmartStorageButton", true, new ConfigDescription("Shows the Smart Storage button next to opened containers. Turning this off only hides the button; existing Smart Storage filters continue to work during Quick Stack. This setting is local to each player.", (AcceptableValueBase)null, Array.Empty<object>())); _toggleSmartStorageButtonShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Smart Storage", "ToggleSmartStorageButtonShortcut", new KeyboardShortcut((KeyCode)0, Array.Empty<KeyCode>()), new ConfigDescription("Optional player-controlled shortcut that toggles ShowSmartStorageButton on or off. Leave empty to disable the shortcut.", (AcceptableValueBase)null, Array.Empty<object>())); _enableQuickStackBlacklist = ((BaseUnityPlugin)this).Config.Bind<bool>("Quick Stack Blacklist", "EnableBlacklist", true, new ConfigDescription("Enables the player-local Quick Stack blacklist. When disabled, blacklist markings are hidden and blacklisted item types are no longer protected from Quick Stack.", (AcceptableValueBase)null, Array.Empty<object>())); _blacklistShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Quick Stack Blacklist", "BlacklistShortcut", new KeyboardShortcut((KeyCode)324, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), new ConfigDescription("Player-controlled shortcut used while clicking an item in your inventory to add or remove that item type from the Quick Stack blacklist. Default: Left Alt + Right Click.", (AcceptableValueBase)null, Array.Empty<object>())); ((ConditionalConfigSync)configSync).AddConfigEntry<bool>(_modEnabled, (ConfigSyncMode)0); ((ConditionalConfigSync)configSync).AddConfigEntry<float>(_searchRadius, (ConfigSyncMode)0); ((ConditionalConfigSync)configSync).AddConfigEntry<KeyboardShortcut>(_quickStackShortcut, (ConfigSyncMode)2); ((ConditionalConfigSync)configSync).AddConfigEntry<KeyboardShortcut>(_sortShortcut, (ConfigSyncMode)2); ((ConditionalConfigSync)configSync).AddConfigEntry<KeyboardShortcut>(_trashShortcut, (ConfigSyncMode)2); ((ConditionalConfigSync)configSync).AddConfigEntry<KeyboardShortcut>(_containerSortShortcut, (ConfigSyncMode)2); ((ConditionalConfigSync)configSync).AddConfigEntry<bool>(_enableStorageFilters, (ConfigSyncMode)2); ((ConditionalConfigSync)configSync).AddConfigEntry<bool>(_showSmartStorageButton, (ConfigSyncMode)2); ((ConditionalConfigSync)configSync).AddConfigEntry<KeyboardShortcut>(_toggleSmartStorageButtonShortcut, (ConfigSyncMode)2); ((ConditionalConfigSync)configSync).AddConfigEntry<bool>(_enableQuickStackBlacklist, (ConfigSyncMode)2); ((ConditionalConfigSync)configSync).AddConfigEntry<KeyboardShortcut>(_blacklistShortcut, (ConfigSyncMode)2); _modEnabled.SettingChanged += delegate { InventoryUiController.RefreshModVisibility(); }; _enableStorageFilters.SettingChanged += delegate { InventoryUiController.RefreshStorageFilterVisibility(); }; _showSmartStorageButton.SettingChanged += delegate { InventoryUiController.RefreshStorageFilterVisibility(); }; _enableQuickStackBlacklist.SettingChanged += delegate { InventoryUiController.RefreshPlayerInventoryBorders(); }; TrashService.Initialize(); BlacklistService.Initialize(); Assembly executingAssembly = Assembly.GetExecutingAssembly(); _harmonyInstance = new Harmony("Goneryx.QuickStackPlus"); _harmonyInstance.PatchAll(executingAssembly); Log.LogInfo((object)"QuickStackPlus v1.2.0 loaded."); } private void Update() { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0066: 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_0089: Unknown result type (might be due to invalid IL or missing references) if (!ModEnabled || IsTypingInInputField()) { return; } Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { KeyboardShortcut toggleSmartStorageButtonShortcut = ToggleSmartStorageButtonShortcut; if ((int)((KeyboardShortcut)(ref toggleSmartStorageButtonShortcut)).MainKey != 0 && IsShortcutDown(ToggleSmartStorageButtonShortcut)) { _showSmartStorageButton.Value = !_showSmartStorageButton.Value; } if (IsShortcutDown(QuickStackShortcut)) { QuickStackService.QuickStack(localPlayer); } if (IsShortcutDown(SortShortcut)) { InventoryUiController.SortFromShortcut(); } if (IsShortcutDown(TrashShortcut)) { TrashService.DeleteMarkedItems(localPlayer); } if (IsShortcutDown(ContainerSortShortcut)) { InventoryUiController.SortOpenContainer(); } } } internal static bool IsShortcutDown(KeyboardShortcut shortcut) { //IL_0002: 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_0042: Unknown result type (might be due to invalid IL or missing references) if ((int)((KeyboardShortcut)(ref shortcut)).MainKey == 0) { return false; } foreach (KeyCode modifier in ((KeyboardShortcut)(ref shortcut)).Modifiers) { if (!ZInput.GetKey(modifier, true)) { return false; } } return ZInput.GetKeyDown(((KeyboardShortcut)(ref shortcut)).MainKey, true); } internal static bool IsShortcutPressed(KeyboardShortcut shortcut) { //IL_0002: 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_002c: Unknown result type (might be due to invalid IL or missing references) if ((int)((KeyboardShortcut)(ref shortcut)).MainKey == 0) { return false; } if (!ZInput.GetKey(((KeyboardShortcut)(ref shortcut)).MainKey, true)) { return false; } foreach (KeyCode modifier in ((KeyboardShortcut)(ref shortcut)).Modifiers) { if (!ZInput.GetKey(modifier, true)) { return false; } } return true; } private void OnDestroy() { Harmony harmonyInstance = _harmonyInstance; if (harmonyInstance != null) { harmonyInstance.UnpatchSelf(); } ManualLogSource log = Log; if (log != null) { log.LogInfo((object)"QuickStackPlus v1.2.0 unloaded."); } Instance = null; } private static bool IsTypingInInputField() { if ((Object)(object)EventSystem.current == (Object)null || (Object)(object)EventSystem.current.currentSelectedGameObject == (Object)null) { return false; } GameObject currentSelectedGameObject = EventSystem.current.currentSelectedGameObject; if (!((Object)(object)currentSelectedGameObject.GetComponent<InputField>() != (Object)null)) { return (Object)(object)currentSelectedGameObject.GetComponent<TMP_InputField>() != (Object)null; } return true; } } internal static class BlacklistService { private const string BlacklistFileName = "QuickStackPlus.blacklist.txt"; private static readonly HashSet<string> BlacklistedItemIds = new HashSet<string>(StringComparer.Ordinal); private static string BlacklistFilePath => Path.Combine(Paths.ConfigPath, "QuickStackPlus.blacklist.txt"); internal static void Initialize() { Load(); } internal static bool IsBlacklisted(ItemData item) { string itemId = StorageFilterService.GetItemId(item); if (!string.IsNullOrEmpty(itemId)) { return BlacklistedItemIds.Contains(itemId); } return false; } internal static void Toggle(ItemData item) { string itemId = StorageFilterService.GetItemId(item); if (!string.IsNullOrEmpty(itemId)) { if (!BlacklistedItemIds.Add(itemId)) { BlacklistedItemIds.Remove(itemId); } Save(); } } private static void Load() { BlacklistedItemIds.Clear(); if (!File.Exists(BlacklistFilePath)) { return; } string[] array = File.ReadAllLines(BlacklistFilePath); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (!string.IsNullOrEmpty(text)) { BlacklistedItemIds.Add(text); } } } private static void Save() { Directory.CreateDirectory(Paths.ConfigPath); List<string> list = new List<string>(BlacklistedItemIds); list.Sort(StringComparer.Ordinal); File.WriteAllLines(BlacklistFilePath, list); } } internal static class ContainerService { internal static List<Container> GetNearbyContainers(Player player) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) List<Container> list = new List<Container>(); if (!Plugin.ModEnabled || (Object)(object)player == (Object)null) { return list; } Collider[] array = Physics.OverlapSphere(((Component)player).transform.position, Plugin.SearchRadius); HashSet<Container> hashSet = new HashSet<Container>(); Collider[] array2 = array; for (int i = 0; i < array2.Length; i++) { Container componentInParent = ((Component)array2[i]).GetComponentInParent<Container>(); if (!((Object)(object)componentInParent == (Object)null) && hashSet.Add(componentInParent)) { list.Add(componentInParent); } } return list; } } internal static class InventorySortService { private static readonly MethodInfo ChangedMethod = AccessTools.Method(typeof(Inventory), "Changed", new Type[2] { typeof(bool), typeof(bool) }, (Type[])null); private static readonly object[] ChangedArguments = new object[2] { false, false }; internal static void SortPlayerInventory() { if (!Plugin.ModEnabled) { return; } Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { Inventory inventory = ((Humanoid)localPlayer).GetInventory(); if (inventory != null) { int vanillaInventoryHeight = GetVanillaInventoryHeight(localPlayer); Sort(inventory, vanillaInventoryHeight, preserveHotbar: true); } } } internal static void SortContainer(Container container) { if (Plugin.ModEnabled && !((Object)(object)container == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null)) { Inventory inventory = container.GetInventory(); if (inventory != null) { Sort(inventory, inventory.GetHeight(), preserveHotbar: false); } } } private static void Sort(Inventory inventory, int validHeight, bool preserveHotbar) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) List<ItemData> allItems = inventory.GetAllItems(); if (allItems == null || allItems.Count <= 1) { return; } int width = inventory.GetWidth(); if (width <= 0 || validHeight <= 0) { return; } List<ItemData> list = new List<ItemData>(allItems.Count); HashSet<(int, int)> hashSet = new HashSet<(int, int)>(); foreach (ItemData item in allItems) { if (item != null && IsValidSlot(item.m_gridPos, width, validHeight)) { if (item.m_equipped) { hashSet.Add((item.m_gridPos.x, item.m_gridPos.y)); } else if (preserveHotbar && item.m_gridPos.y == 0) { hashSet.Add((item.m_gridPos.x, item.m_gridPos.y)); } else { list.Add(item); } } } list.Sort(CompareItems); int num = 0; for (int i = (preserveHotbar ? 1 : 0); i < validHeight; i++) { if (num >= list.Count) { break; } for (int j = 0; j < width; j++) { if (num >= list.Count) { break; } if (!hashSet.Contains((j, i))) { list[num].m_gridPos = new Vector2i(j, i); num++; } } } ChangedMethod?.Invoke(inventory, ChangedArguments); } private static int GetVanillaInventoryHeight(Player player) { string s = default(string); if (player.TryGetUniqueKeyValue("invrows", ref s) && int.TryParse(s, out var result)) { return Mathf.Clamp(result, 0, 9); } return 4; } private static bool IsValidSlot(Vector2i position, int width, int height) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (position.x >= 0 && position.x < width && position.y >= 0) { return position.y < height; } return false; } private static int CompareItems(ItemData a, ItemData b) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) ref ItemType itemType = ref a.m_shared.m_itemType; object target = b.m_shared.m_itemType; int num = ((Enum)Unsafe.As<ItemType, ItemType>(ref itemType)/*cast due to .constrained prefix*/).CompareTo(target); if (num != 0) { return num; } num = string.Compare(a.m_shared.m_name, b.m_shared.m_name, StringComparison.Ordinal); if (num != 0) { return num; } num = b.m_quality.CompareTo(a.m_quality); if (num != 0) { return num; } return b.m_stack.CompareTo(a.m_stack); } } internal static class QuickStackService { internal static void QuickStack(Player player) { if (!Plugin.ModEnabled || (Object)(object)player == (Object)null) { return; } Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory == null) { return; } int vanillaInventoryHeight = GetVanillaInventoryHeight(player); List<Container> nearbyContainers = ContainerService.GetNearbyContainers(player); int num = 0; Dictionary<string, int> dictionary = new Dictionary<string, int>(); if (Plugin.EnableStorageFilters) { foreach (Container item in nearbyContainers) { if (!((Object)(object)item == (Object)null) && StorageFilterService.HasAnyFilter(item)) { Inventory inventory2 = item.GetInventory(); if (inventory2 != null) { num += QuickStackIntoContainer(player, inventory, item, inventory2, vanillaInventoryHeight, dictionary, filteredPass: true); } } } } foreach (Container item2 in nearbyContainers) { if (!((Object)(object)item2 == (Object)null)) { Inventory inventory3 = item2.GetInventory(); if (inventory3 != null) { num += QuickStackIntoContainer(player, inventory, item2, inventory3, vanillaInventoryHeight, dictionary, filteredPass: false); } } } if (num <= 0) { return; } StringBuilder stringBuilder = new StringBuilder("<size=75%>Quick Stack:\n"); bool flag = true; foreach (KeyValuePair<string, int> item3 in dictionary) { if (!flag) { stringBuilder.Append("\n"); } stringBuilder.Append(item3.Key); stringBuilder.Append(" x"); stringBuilder.Append(item3.Value); flag = false; } stringBuilder.Append("</size>"); ((Character)player).Message((MessageType)2, stringBuilder.ToString(), 0, (Sprite)null, false); } private static int QuickStackIntoContainer(Player player, Inventory playerInventory, Container container, Inventory containerInventory, int vanillaHeight, Dictionary<string, int> movedItems, bool filteredPass) { int num = 0; foreach (ItemData item in new List<ItemData>(playerInventory.GetAllItems())) { if (!CanMoveItem(player, item, vanillaHeight)) { continue; } if (filteredPass) { if (!StorageFilterService.AcceptsItem(container, item)) { continue; } } else if (!ContainerHasMatchingItem(containerInventory, item)) { continue; } if (!containerInventory.CanAddItem(item, -1)) { continue; } int stack = item.m_stack; string key = ((item.m_shared != null) ? item.m_shared.m_name : StorageFilterService.GetItemId(item)); if (containerInventory.AddItem(item)) { playerInventory.RemoveItem(item); num++; if (!movedItems.ContainsKey(key)) { movedItems[key] = 0; } movedItems[key] += stack; } } return num; } private static bool CanMoveItem(Player player, ItemData item, int vanillaHeight) { if (item == null) { return false; } if (item.m_gridPos.y < 0 || item.m_gridPos.y >= vanillaHeight) { return false; } if (item.m_gridPos.y == 0) { return false; } if (((Humanoid)player).IsItemEquiped(item)) { return false; } if (Plugin.EnableQuickStackBlacklist && BlacklistService.IsBlacklisted(item)) { return false; } return true; } private static bool ContainerHasMatchingItem(Inventory containerInventory, ItemData sourceItem) { List<ItemData> allItems = containerInventory.GetAllItems(); string itemId = StorageFilterService.GetItemId(sourceItem); foreach (ItemData item in allItems) { if (item != null) { string itemId2 = StorageFilterService.GetItemId(item); if (!string.IsNullOrEmpty(itemId) && itemId == itemId2) { return true; } if (item.m_shared != null && sourceItem.m_shared != null && item.m_shared.m_name == sourceItem.m_shared.m_name) { return true; } } } return false; } private static int GetVanillaInventoryHeight(Player player) { string s = default(string); if (player.TryGetUniqueKeyValue("invrows", ref s) && int.TryParse(s, out var result)) { return Mathf.Clamp(result, 0, 9); } return 4; } } internal static class StorageFilterService { internal sealed class StorageItemInfo { internal string Id; internal string DisplayName; } private const string ZdoKey = "Goneryx.QuickStackPlus.StorageFilter"; private const char Separator = '\u001f'; internal static HashSet<string> GetSelectedItems(Container container) { HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); string rawFilter = GetRawFilter(container); if (string.IsNullOrEmpty(rawFilter)) { return hashSet; } string[] array = rawFilter.Split(new char[1] { '\u001f' }, StringSplitOptions.RemoveEmptyEntries); foreach (string text in array) { if (!string.IsNullOrWhiteSpace(text)) { hashSet.Add(text.Trim()); } } return hashSet; } internal static bool AcceptsItem(Container container, ItemData item) { if (!Plugin.ModEnabled || (Object)(object)container == (Object)null || item == null) { return false; } string itemId = GetItemId(item); if (string.IsNullOrEmpty(itemId)) { return false; } return GetSelectedItems(container).Contains(itemId); } internal static bool HasAnyFilter(Container container) { if (Plugin.ModEnabled && (Object)(object)container != (Object)null) { return !string.IsNullOrEmpty(GetRawFilter(container)); } return false; } internal static void SetItemSelected(Container container, string itemId, bool selected) { if (Plugin.ModEnabled && !((Object)(object)container == (Object)null) && !string.IsNullOrEmpty(itemId)) { HashSet<string> selectedItems = GetSelectedItems(container); if (selected) { selectedItems.Add(itemId); } else { selectedItems.Remove(itemId); } SaveSelectedItems(container, selectedItems); } } internal static void Clear(Container container) { if (Plugin.ModEnabled) { SaveSelectedItems(container, new HashSet<string>(StringComparer.Ordinal)); } } internal static List<StorageItemInfo> GetEligibleItems() { List<StorageItemInfo> list = new List<StorageItemInfo>(); HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); if ((Object)(object)ObjectDB.instance == (Object)null || ObjectDB.instance.m_items == null) { return list; } foreach (GameObject item in ObjectDB.instance.m_items) { if ((Object)(object)item == (Object)null) { continue; } ItemDrop component = item.GetComponent<ItemDrop>(); if (!((Object)(object)component == (Object)null) && component.m_itemData != null && component.m_itemData.m_shared != null && IsEligibleStorageItem(component.m_itemData)) { string name = ((Object)item).name; if (!string.IsNullOrEmpty(name) && hashSet.Add(name) && TryGetDisplayName(component.m_itemData, out var displayName)) { list.Add(new StorageItemInfo { Id = name, DisplayName = displayName }); } } } return list.OrderBy<StorageItemInfo, string>((StorageItemInfo item) => item.DisplayName, StringComparer.CurrentCultureIgnoreCase).ToList(); } internal static string GetItemId(ItemData item) { if (item == null) { return null; } if ((Object)(object)item.m_dropPrefab != (Object)null && !string.IsNullOrEmpty(((Object)item.m_dropPrefab).name)) { return ((Object)item.m_dropPrefab).name; } if (item.m_shared == null) { return null; } return item.m_shared.m_name; } private static bool IsEligibleStorageItem(ItemData item) { if (item == null || item.m_shared == null) { return false; } if (item.m_shared.m_maxStackSize <= 1) { return false; } if (item.m_shared.m_icons == null || item.m_shared.m_icons.Length == 0 || (Object)(object)item.m_shared.m_icons[0] == (Object)null) { return false; } string text = ((object)Unsafe.As<ItemType, ItemType>(ref item.m_shared.m_itemType)/*cast due to .constrained prefix*/).ToString(); string[] array = new string[13] { "Weapon", "Bow", "Shield", "Helmet", "Chest", "Legs", "Hands", "Shoulder", "Utility", "Tool", "Torch", "Customization", "Attach" }; foreach (string value in array) { if (text.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0) { return false; } } return true; } private static bool TryGetDisplayName(ItemData item, out string displayName) { displayName = null; if (item == null || item.m_shared == null) { return false; } string name = item.m_shared.m_name; if (string.IsNullOrWhiteSpace(name)) { return false; } string text = name; if (Localization.instance != null) { text = Localization.instance.Localize(name); } if (string.IsNullOrWhiteSpace(text)) { return false; } string value = (name.StartsWith("$", StringComparison.Ordinal) ? name.Substring(1) : name); string text2 = text.Trim(); if ((name.StartsWith("$", StringComparison.Ordinal) && (text2.Equals(name, StringComparison.OrdinalIgnoreCase) || text2.Equals(value, StringComparison.OrdinalIgnoreCase))) || text2.StartsWith("$item_", StringComparison.OrdinalIgnoreCase) || text2.StartsWith("item_", StringComparison.OrdinalIgnoreCase)) { return false; } displayName = text2; return true; } private static string GetRawFilter(Container container) { ZDO zdo = GetZdo(container); if (zdo == null) { return string.Empty; } return zdo.GetString("Goneryx.QuickStackPlus.StorageFilter", string.Empty); } private static void SaveSelectedItems(Container container, HashSet<string> selectedItems) { ZNetView nView = GetNView(container); if ((Object)(object)nView == (Object)null || !nView.IsValid()) { return; } if (!nView.IsOwner()) { nView.ClaimOwnership(); } ZDO zDO = nView.GetZDO(); if (zDO != null) { string text = ((selectedItems != null && selectedItems.Count > 0) ? string.Join('\u001f'.ToString(), selectedItems.OrderBy<string, string>((string value) => value, StringComparer.Ordinal)) : string.Empty); zDO.Set("Goneryx.QuickStackPlus.StorageFilter", text); } } private static ZDO GetZdo(Container container) { ZNetView nView = GetNView(container); if (!((Object)(object)nView != (Object)null) || !nView.IsValid()) { return null; } return nView.GetZDO(); } private static ZNetView GetNView(Container container) { if (!((Object)(object)container != (Object)null)) { return null; } return ((Component)container).GetComponent<ZNetView>(); } } internal static class TrashService { private const string JunkFileName = "QuickStackPlus.junk.txt"; private static readonly HashSet<string> JunkItemNames = new HashSet<string>(StringComparer.Ordinal); private static readonly FieldInfo DragItemField = AccessTools.Field(typeof(InventoryGui), "m_dragItem"); private static readonly FieldInfo DragInventoryField = AccessTools.Field(typeof(InventoryGui), "m_dragInventory"); private static readonly FieldInfo DragAmountField = AccessTools.Field(typeof(InventoryGui), "m_dragAmount"); private static readonly MethodInfo SetupDragItemMethod = AccessTools.Method(typeof(InventoryGui), "SetupDragItem", (Type[])null, (Type[])null); private static string JunkFilePath => Path.Combine(Paths.ConfigPath, "QuickStackPlus.junk.txt"); internal static void Initialize() { LoadJunkItems(); } internal static bool IsMarked(ItemData item) { if (item == null || item.m_shared == null) { return false; } return JunkItemNames.Contains(item.m_shared.m_name); } internal static void ToggleMarked(Player player, ItemData item) { if ((Object)(object)player == (Object)null || item == null || item.m_shared == null || !IsVanillaInventoryItem(player, item)) { return; } if (!CanDeleteItem(item)) { ShowProtectedItemMessage(player); return; } string name = item.m_shared.m_name; if (!JunkItemNames.Add(name)) { JunkItemNames.Remove(name); } SaveJunkItems(); } internal static void DeleteDraggedItem(InventoryGui inventoryGui, Player player) { if ((Object)(object)inventoryGui == (Object)null || (Object)(object)player == (Object)null) { return; } object? obj = DragItemField?.GetValue(inventoryGui); ItemData val = (ItemData)((obj is ItemData) ? obj : null); object? obj2 = DragInventoryField?.GetValue(inventoryGui); Inventory val2 = (Inventory)((obj2 is Inventory) ? obj2 : null); if (val == null || val2 == null) { return; } Inventory inventory = ((Humanoid)player).GetInventory(); if (val2 != inventory || !IsVanillaInventoryItem(player, val)) { return; } if (!CanDeleteItem(val)) { ShowProtectedItemMessage(player); return; } int num = Mathf.Min((!(DragAmountField != null)) ? 1 : ((int)DragAmountField.GetValue(inventoryGui)), val.m_stack); if (val2.RemoveItem(val, num)) { SetupDragItemMethod?.Invoke(inventoryGui, new object[3] { null, null, 1 }); } } internal static void DeleteMarkedItems(Player player) { if ((Object)(object)player == (Object)null) { return; } Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory == null) { return; } List<ItemData> list = new List<ItemData>(inventory.GetAllItems()); bool flag = false; foreach (ItemData item in list) { if (item != null && item.m_shared != null && JunkItemNames.Contains(item.m_shared.m_name) && IsVanillaInventoryItem(player, item) && !CanDeleteItem(item)) { flag = true; } } if (flag) { ShowProtectedItemMessage(player); } } internal static bool IsVanillaInventoryItem(Player player, ItemData item) { if ((Object)(object)player == (Object)null || item == null) { return false; } int vanillaInventoryHeight = GetVanillaInventoryHeight(player); if (item.m_gridPos.y >= 0) { return item.m_gridPos.y < vanillaInventoryHeight; } return false; } private static bool CanDeleteItem(ItemData item) { if (item == null) { return false; } if (item.m_equipped) { return false; } if (item.m_gridPos.y == 0) { return false; } return true; } private static int GetVanillaInventoryHeight(Player player) { string s = default(string); if (player.TryGetUniqueKeyValue("invrows", ref s) && int.TryParse(s, out var result)) { return Mathf.Clamp(result, 0, 9); } return 4; } private static void LoadJunkItems() { JunkItemNames.Clear(); if (!File.Exists(JunkFilePath)) { return; } string[] array = File.ReadAllLines(JunkFilePath); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (!string.IsNullOrEmpty(text)) { JunkItemNames.Add(text); } } } private static void SaveJunkItems() { Directory.CreateDirectory(Paths.ConfigPath); List<string> list = new List<string>(JunkItemNames); list.Sort(StringComparer.Ordinal); File.WriteAllLines(JunkFilePath, list); } private static void ShowProtectedItemMessage(Player player) { ((Character)player).Message((MessageType)2, "Can't delete equipped or hotbar items.", 0, (Sprite)null, false); } } internal static class InventoryUiController { [CompilerGenerated] private static class <>O { public static UnityAction <0>__OnSortClicked; public static UnityAction <1>__OnQuickStackClicked; public static UnityAction <2>__OnTrashClicked; public static UnityAction <3>__OnContainerSortClicked; } private const string SortButtonName = "QuickStackPlusSortButton"; private const string QuickStackButtonName = "QuickStackPlusQuickStackButton"; private const string TrashButtonName = "QuickStackPlusTrashButton"; private const string ContainerSortButtonName = "QuickStackPlusContainerSortButton"; private const float ButtonSize = 36f; private const float ButtonSpacing = 4f; private const float TrashIconSize = 30f; private const float TrashIconXOffset = 0f; private const float TrashIconYOffset = 0f; private static readonly FieldInfo CurrentContainerField = AccessTools.Field(typeof(InventoryGui), "m_currentContainer"); private static readonly FieldInfo DragItemField = AccessTools.Field(typeof(InventoryGui), "m_dragItem"); private static readonly FieldInfo ContainerUiField = AccessTools.Field(typeof(InventoryGui), "m_container"); private static readonly FieldInfo ContainerGridField = AccessTools.Field(typeof(InventoryGui), "m_containerGrid"); private static InventoryGui _inventoryGui; private static Sprite _trashSprite; internal static void Initialize(InventoryGui inventoryGui) { if (!((Object)(object)inventoryGui == (Object)null)) { _inventoryGui = inventoryGui; StorageFilterUi.Initialize(inventoryGui); CreateButtons(); } } private static void CreateButtons() { //IL_0042: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Expected O, but got Unknown if (!((Object)(object)_inventoryGui == (Object)null) && !((Object)(object)_inventoryGui.m_player == (Object)null) && !((Object)(object)_inventoryGui.m_takeAllButton == (Object)null)) { Button takeAllButton = _inventoryGui.m_takeAllButton; string shortcutLabel = GetShortcutLabel(Plugin.SortShortcut, "O"); object obj = <>O.<0>__OnSortClicked; if (obj == null) { UnityAction val = OnSortClicked; <>O.<0>__OnSortClicked = val; obj = (object)val; } CreateActionButton(takeAllButton, "QuickStackPlusSortButton", shortcutLabel, 0, (UnityAction)obj); string shortcutLabel2 = GetShortcutLabel(Plugin.QuickStackShortcut, "P"); object obj2 = <>O.<1>__OnQuickStackClicked; if (obj2 == null) { UnityAction val2 = OnQuickStackClicked; <>O.<1>__OnQuickStackClicked = val2; obj2 = (object)val2; } CreateActionButton(takeAllButton, "QuickStackPlusQuickStackButton", shortcutLabel2, 1, (UnityAction)obj2); object obj3 = <>O.<2>__OnTrashClicked; if (obj3 == null) { UnityAction val3 = OnTrashClicked; <>O.<2>__OnTrashClicked = val3; obj3 = (object)val3; } CreateTrashButton((UnityAction)obj3); CreateContainerSortButton(); StorageFilterUi.RefreshVisibility(); } } private static Button CreateActionButton(Button template, string buttonName, string text, int index, UnityAction onClick) { Transform val = ((Component)_inventoryGui.m_player).transform.Find(buttonName); if ((Object)(object)val != (Object)null) { return ((Component)val).GetComponent<Button>(); } GameObject val2 = Object.Instantiate<GameObject>(((Component)template).gameObject, ((Component)_inventoryGui.m_player).transform); ((Object)val2).name = buttonName; Button component = val2.GetComponent<Button>(); if ((Object)(object)component == (Object)null) { Object.Destroy((Object)(object)val2); return null; } ((UnityEventBase)component.onClick).RemoveAllListeners(); ((UnityEvent)component.onClick).AddListener(onClick); SetButtonText(val2, text); StyleActionButton(val2); PositionActionButton(val2, index); val2.SetActive(true); return component; } internal static void CreateContainerSortButton() { //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Expected O, but got Unknown //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_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0127: 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) if ((Object)(object)_inventoryGui == (Object)null || (Object)(object)_inventoryGui.m_takeAllButton == (Object)null) { return; } Transform containerUiTransform = GetContainerUiTransform(); if ((Object)(object)containerUiTransform == (Object)null || (Object)(object)FindChildRecursive(containerUiTransform, "QuickStackPlusContainerSortButton") != (Object)null) { return; } GameObject val = Object.Instantiate<GameObject>(((Component)_inventoryGui.m_takeAllButton).gameObject, containerUiTransform); ((Object)val).name = "QuickStackPlusContainerSortButton"; Button component = val.GetComponent<Button>(); if ((Object)(object)component == (Object)null) { Object.Destroy((Object)(object)val); return; } ((UnityEventBase)component.onClick).RemoveAllListeners(); ButtonClickedEvent onClick = component.onClick; object obj = <>O.<3>__OnContainerSortClicked; if (obj == null) { UnityAction val2 = OnContainerSortClicked; <>O.<3>__OnContainerSortClicked = val2; obj = (object)val2; } ((UnityEvent)onClick).AddListener((UnityAction)obj); SetButtonText(val, "Sort"); StyleActionButton(val); RectTransform component2 = val.GetComponent<RectTransform>(); RectTransform component3 = ((Component)containerUiTransform).GetComponent<RectTransform>(); if ((Object)(object)component2 != (Object)null && (Object)(object)component3 != (Object)null) { component2.anchorMin = new Vector2(0f, 0f); component2.anchorMax = new Vector2(0f, 0f); component2.pivot = new Vector2(0f, 0f); Rect rect = component3.rect; component2.anchoredPosition = new Vector2(((Rect)(ref rect)).width + 8f, 0f); } val.SetActive(true); } internal static Transform GetContainerUiTransformForExtensions() { return GetContainerUiTransform(); } private static Transform GetContainerUiTransform() { Transform transformFromObject = GetTransformFromObject(ContainerUiField?.GetValue(_inventoryGui)); if ((Object)(object)transformFromObject != (Object)null) { return transformFromObject; } return GetTransformFromObject(ContainerGridField?.GetValue(_inventoryGui)); } private static Transform GetTransformFromObject(object value) { Transform val = (Transform)((value is Transform) ? value : null); if (val != null) { return val; } Component val2 = (Component)((value is Component) ? value : null); if (val2 != null) { return val2.transform; } GameObject val3 = (GameObject)((value is GameObject) ? value : null); if (val3 != null) { return val3.transform; } return null; } private static Button CreateTrashButton(UnityAction onClick) { Transform val = FindChildRecursive(((Component)_inventoryGui).transform, "QuickStackPlusTrashButton"); if ((Object)(object)val != (Object)null) { return ((Component)val).GetComponent<Button>(); } RectTransform val2 = FindStatusTab("armor"); RectTransform val3 = FindStatusTab("weight"); if ((Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null) { return null; } GameObject val4 = Object.Instantiate<GameObject>(((Component)val3).gameObject, ((Transform)val3).parent); ((Object)val4).name = "QuickStackPlusTrashButton"; RectTransform component = val4.GetComponent<RectTransform>(); Transform val5 = val4.transform.Find("weight_icon"); Transform val6 = val4.transform.Find("weight_text"); if ((Object)(object)val6 != (Object)null) { ((Component)val6).gameObject.SetActive(false); } if ((Object)(object)val5 != (Object)null) { ((Component)val5).gameObject.SetActive(false); } CreateTrashIcon(val4.transform); Button val7 = val4.GetComponent<Button>(); if ((Object)(object)val7 == (Object)null) { val7 = val4.AddComponent<Button>(); } Image component2 = val4.GetComponent<Image>(); if ((Object)(object)component2 != (Object)null) { ((Selectable)val7).targetGraphic = (Graphic)(object)component2; } ((UnityEventBase)val7.onClick).RemoveAllListeners(); ((UnityEvent)val7.onClick).AddListener(onClick); PositionTrashButton(component, val2, val3); int siblingIndex = Mathf.Min(((Transform)val2).GetSiblingIndex(), ((Transform)val3).GetSiblingIndex()); ((Transform)component).SetSiblingIndex(siblingIndex); val4.SetActive(true); return val7; } private static void CreateTrashIcon(Transform parent) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("TrashIcon", new Type[2] { typeof(RectTransform), typeof(Image) }); RectTransform component = val.GetComponent<RectTransform>(); ((Transform)component).SetParent(parent, false); component.anchorMin = new Vector2(0.5f, 0.5f); component.anchorMax = new Vector2(0.5f, 0.5f); component.pivot = new Vector2(0.5f, 0.5f); component.sizeDelta = new Vector2(30f, 30f); component.anchoredPosition = new Vector2(0f, 0f); Image component2 = val.GetComponent<Image>(); component2.sprite = LoadTrashSprite(); component2.preserveAspect = true; ((Graphic)component2).raycastTarget = false; if ((Object)(object)component2.sprite == (Object)null) { ((Behaviour)component2).enabled = false; } } private static Sprite LoadTrashSprite() { //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown //IL_00ba: 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) if ((Object)(object)_trashSprite != (Object)null) { return _trashSprite; } try { using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("QuickStackPlus.Assets.trash_icon.rgba"); if (stream == null) { return null; } byte[] array = new byte[stream.Length]; int i; int num; for (i = 0; i < array.Length; i += num) { num = stream.Read(array, i, array.Length - i); if (num <= 0) { break; } } if (i != array.Length) { return null; } Texture2D val = new Texture2D(82, 82, (TextureFormat)4, false); val.LoadRawTextureData(array); val.Apply(false, false); ((Object)val).name = "QuickStackPlusTrashIconTexture"; ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)1; _trashSprite = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); ((Object)_trashSprite).name = "QuickStackPlusTrashIcon"; return _trashSprite; } catch (Exception) { return null; } } private static void PositionTrashButton(RectTransform trashRect, RectTransform armorRect, RectTransform weightRect) { //IL_001e: 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_0036: 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_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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)trashRect == (Object)null) && !((Object)(object)armorRect == (Object)null) && !((Object)(object)weightRect == (Object)null)) { trashRect.anchorMin = weightRect.anchorMin; trashRect.anchorMax = weightRect.anchorMax; trashRect.pivot = weightRect.pivot; trashRect.sizeDelta = weightRect.sizeDelta; Vector3 position = (((Transform)armorRect).position + ((Transform)weightRect).position) * 0.5f; ((Transform)trashRect).position = position; } } private static RectTransform FindStatusTab(string namePart) { RectTransform[] componentsInChildren = ((Component)_inventoryGui).GetComponentsInChildren<RectTransform>(true); foreach (RectTransform val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && ((Object)val).name.IndexOf(namePart, StringComparison.OrdinalIgnoreCase) >= 0) { return val; } } return null; } private static Transform FindChildRecursive(Transform parent, string childName) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown if ((Object)(object)parent == (Object)null) { return null; } foreach (Transform item in parent) { Transform val = item; if (((Object)val).name == childName) { return val; } Transform val2 = FindChildRecursive(val, childName); if ((Object)(object)val2 != (Object)null) { return val2; } } return null; } private static void SetButtonText(GameObject buttonObject, string text) { TMP_Text componentInChildren = buttonObject.GetComponentInChildren<TMP_Text>(true); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren.text = text; componentInChildren.alignment = (TextAlignmentOptions)514; return; } Text componentInChildren2 = buttonObject.GetComponentInChildren<Text>(true); if ((Object)(object)componentInChildren2 != (Object)null) { componentInChildren2.text = text; componentInChildren2.alignment = (TextAnchor)4; } } private static void StyleActionButton(GameObject buttonObject) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) RectTransform component = buttonObject.GetComponent<RectTransform>(); if (!((Object)(object)component == (Object)null)) { component.sizeDelta = new Vector2(36f, 36f); Image component2 = buttonObject.GetComponent<Image>(); if ((Object)(object)component2 != (Object)null) { component2.type = (Type)1; } } } private static void PositionActionButton(GameObject buttonObject, int index) { //IL_0035: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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_008e: Unknown result type (might be due to invalid IL or missing references) RectTransform component = buttonObject.GetComponent<RectTransform>(); RectTransform component2 = ((Component)_inventoryGui.m_player).GetComponent<RectTransform>(); if (!((Object)(object)component == (Object)null) && !((Object)(object)component2 == (Object)null)) { component.anchorMin = new Vector2(0f, 0f); component.anchorMax = new Vector2(0f, 0f); component.pivot = new Vector2(0f, 0f); Rect rect = component2.rect; float num = ((Rect)(ref rect)).width + 8f + (float)index * 40f; component.anchoredPosition = new Vector2(num, -0.71999997f); } } internal static void RefreshModVisibility() { if (!((Object)(object)_inventoryGui == (Object)null)) { if (Plugin.ModEnabled) { CreateButtons(); } bool modEnabled = Plugin.ModEnabled; Transform val = (((Object)(object)_inventoryGui.m_player != (Object)null) ? ((Component)_inventoryGui.m_player).transform.Find("QuickStackPlusSortButton") : null); Transform val2 = (((Object)(object)_inventoryGui.m_player != (Object)null) ? ((Component)_inventoryGui.m_player).transform.Find("QuickStackPlusQuickStackButton") : null); Transform val3 = FindChildRecursive(((Component)_inventoryGui).transform, "QuickStackPlusTrashButton"); Transform val4 = FindChildRecursive(((Component)_inventoryGui).transform, "QuickStackPlusContainerSortButton"); if ((Object)(object)val != (Object)null) { ((Component)val).gameObject.SetActive(modEnabled); } if ((Object)(object)val2 != (Object)null) { ((Component)val2).gameObject.SetActive(modEnabled); } if ((Object)(object)val3 != (Object)null) { ((Component)val3).gameObject.SetActive(modEnabled); } if ((Object)(object)val4 != (Object)null) { ((Component)val4).gameObject.SetActive(modEnabled); } StorageFilterUi.RefreshVisibility(); } } internal static void RefreshPlayerInventoryBorders() { InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance != (Object)null && (Object)(object)instance.m_playerGrid != (Object)null) { TrashBorderRenderer.Refresh(instance.m_playerGrid); } } internal static void RefreshStorageFilterVisibility() { StorageFilterUi.RefreshVisibility(); } internal static void SortFromShortcut() { if (Plugin.ModEnabled) { OnSortClicked(); } } private static string GetShortcutLabel(KeyboardShortcut shortcut, string fallback) { //IL_0002: 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_0012: Unknown result type (might be due to invalid IL or missing references) if ((int)((KeyboardShortcut)(ref shortcut)).MainKey == 0) { return fallback; } string text = ((object)((KeyboardShortcut)(ref shortcut)).MainKey/*cast due to .constrained prefix*/).ToString(); if (text == "Delete") { return "Del"; } return text; } internal static void SortOpenContainer() { if (Plugin.ModEnabled) { OnContainerSortClicked(); } } private static void OnContainerSortClicked() { if (Plugin.ModEnabled && !((Object)(object)_inventoryGui == (Object)null)) { object? obj = CurrentContainerField?.GetValue(_inventoryGui); Container val = (Container)((obj is Container) ? obj : null); if ((Object)(object)val != (Object)null) { InventorySortService.SortContainer(val); } } } private static void OnSortClicked() { if (!Plugin.ModEnabled) { return; } InventorySortService.SortPlayerInventory(); if (!((Object)(object)_inventoryGui == (Object)null)) { object? obj = CurrentContainerField?.GetValue(_inventoryGui); Container val = (Container)((obj is Container) ? obj : null); if ((Object)(object)val != (Object)null) { InventorySortService.SortContainer(val); } } } private static void OnQuickStackClicked() { if (Plugin.ModEnabled) { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { QuickStackService.QuickStack(localPlayer); } } } private static void OnTrashClicked() { if (!Plugin.ModEnabled) { return; } Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && !((Object)(object)_inventoryGui == (Object)null)) { if (DragItemField?.GetValue(_inventoryGui) is ItemData) { TrashService.DeleteDraggedItem(_inventoryGui, localPlayer); } else { TrashService.DeleteMarkedItems(localPlayer); } } } } internal static class StorageFilterUi { [CompilerGenerated] private static class <>O { public static UnityAction <0>__TogglePanel; public static UnityAction <1>__ClosePanel; public static UnityAction <2>__SelectVisible; public static UnityAction <3>__ClearAll; public static UnityAction <4>__ToggleInventoryOnly; } private const string FilterButtonName = "QuickStackPlusStorageFilterButton"; private const string FilterPanelName = "QuickStackPlusStorageFilterPanel"; private const float ButtonSize = 36f; private const float PanelWidth = 340f; private const float PanelHeight = 500f; private const float RowHeight = 30f; private const float ScrollSensitivity = 140f; private const int RowsPerFrame = 24; private static InventoryGui _inventoryGui; private static Container _currentContainer; private static GameObject _filterButton; private static GameObject _panel; private static RectTransform _content; private static InputField _searchInput; private static ScrollRect _scrollRect; private static Font _font; private static List<StorageFilterService.StorageItemInfo> _allItems; private static HashSet<string> _selectedItems; private static readonly List<RowView> _rowPool = new List<RowView>(); private static Coroutine _rebuildCoroutine; private static int _rebuildGeneration; private static bool _inventoryOnly; private static Button _inventoryOnlyButton; private static Text _inventoryOnlyButtonLabel; internal static void Initialize(InventoryGui inventoryGui) { _inventoryGui = inventoryGui; EnsureFont(); } internal static void OnContainerOpened(Container container) { _currentContainer = container; CreateOrRefreshButton(); ClosePanel(); } internal static void RefreshVisibility() { if ((Object)(object)_filterButton != (Object)null) { _filterButton.SetActive(Plugin.ModEnabled && Plugin.EnableStorageFilters && Plugin.ShowSmartStorageButton && (Object)(object)_currentContainer != (Object)null); } if (!Plugin.ModEnabled || !Plugin.EnableStorageFilters || !Plugin.ShowSmartStorageButton) { ClosePanel(); } } private static void CreateOrRefreshButton() { //IL_00bb: 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_00c6: Expected O, but got Unknown //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_inventoryGui == (Object)null || (Object)(object)_inventoryGui.m_takeAllButton == (Object)null) { return; } Transform containerUiTransformForExtensions = InventoryUiController.GetContainerUiTransformForExtensions(); if ((Object)(object)containerUiTransformForExtensions == (Object)null) { return; } Transform val = FindChildRecursive(containerUiTransformForExtensions, "QuickStackPlusStorageFilterButton"); if ((Object)(object)val != (Object)null) { _filterButton = ((Component)val).gameObject; RefreshVisibility(); return; } GameObject val2 = Object.Instantiate<GameObject>(((Component)_inventoryGui.m_takeAllButton).gameObject, containerUiTransformForExtensions); ((Object)val2).name = "QuickStackPlusStorageFilterButton"; _filterButton = val2; Button component = val2.GetComponent<Button>(); if ((Object)(object)component == (Object)null) { Object.Destroy((Object)(object)val2); _filterButton = null; return; } ((UnityEventBase)component.onClick).RemoveAllListeners(); ButtonClickedEvent onClick = component.onClick; object obj = <>O.<0>__TogglePanel; if (obj == null) { UnityAction val3 = TogglePanel; <>O.<0>__TogglePanel = val3; obj = (object)val3; } ((UnityEvent)onClick).AddListener((UnityAction)obj); HideTemplateText(val2); DrawFilterGlyph(val2.transform); RectTransform component2 = val2.GetComponent<RectTransform>(); RectTransform component3 = ((Component)containerUiTransformForExtensions).GetComponent<RectTransform>(); if ((Object)(object)component2 != (Object)null && (Object)(object)component3 != (Object)null) { component2.sizeDelta = new Vector2(36f, 36f); component2.anchorMin = new Vector2(0f, 0f); component2.anchorMax = new Vector2(0f, 0f); component2.pivot = new Vector2(0f, 0f); Rect rect = component3.rect; component2.anchoredPosition = new Vector2(((Rect)(ref rect)).width + 8f + 36f + 4f, 0f); } RefreshVisibility(); } private static void TogglePanel() { if (!Plugin.ModEnabled || !Plugin.EnableStorageFilters || !Plugin.ShowSmartStorageButton || (Object)(object)_currentContainer == (Object)null) { return; } if ((Object)(object)_panel != (Object)null) { bool flag = !_panel.activeSelf; _panel.SetActive(flag); if (flag) { ReloadPanel(resetScroll: true); } } else { CreatePanel(); ReloadPanel(resetScroll: true); } } private static void CreatePanel() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0086: 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_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: 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_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_0163: 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_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01e7: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Expected O, but got Unknown //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_0290: Expected O, but got Unknown //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_0316: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: 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_02e3: Expected O, but got Unknown //IL_032b: Unknown result type (might be due to invalid IL or missing references) //IL_0330: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Expected O, but got Unknown //IL_0396: Unknown result type (might be due to invalid IL or missing references) //IL_039c: Expected O, but got Unknown //IL_03c2: Unknown result type (might be due to invalid IL or missing references) //IL_03d8: Unknown result type (might be due to invalid IL or missing references) //IL_03ee: 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_041a: Unknown result type (might be due to invalid IL or missing references) //IL_043e: Unknown result type (might be due to invalid IL or missing references) //IL_046c: Unknown result type (might be due to invalid IL or missing references) //IL_0497: Unknown result type (might be due to invalid IL or missing references) //IL_04b0: Unknown result type (might be due to invalid IL or missing references) //IL_04c9: Unknown result type (might be due to invalid IL or missing references) //IL_04d8: Unknown result type (might be due to invalid IL or missing references) //IL_04f1: Unknown result type (might be due to invalid IL or missing references) Transform containerUiTransformForExtensions = InventoryUiController.GetContainerUiTransformForExtensions(); if (!((Object)(object)containerUiTransformForExtensions == (Object)null)) { _panel = new GameObject("QuickStackPlusStorageFilterPanel", new Type[2] { typeof(RectTransform), typeof(Image) }); RectTransform component = _panel.GetComponent<RectTransform>(); ((Transform)component).SetParent(containerUiTransformForExtensions, false); component.anchorMin = new Vector2(0f, 0f); component.anchorMax = new Vector2(0f, 0f); component.pivot = new Vector2(0f, 0f); component.sizeDelta = new Vector2(340f, 500f); RectTransform component2 = ((Component)containerUiTransformForExtensions).GetComponent<RectTransform>(); float num; if (!((Object)(object)component2 != (Object)null)) { num = 500f; } else { Rect rect = component2.rect; num = ((Rect)(ref rect)).width; } float num2 = num; component.anchoredPosition = new Vector2(num2 + 88f, 0f); ((Graphic)_panel.GetComponent<Image>()).color = new Color(0.08f, 0.08f, 0.08f, 0.96f); CreateText(_panel.transform, "Title", "Smart Storage", 18, new Vector2(12f, -10f), new Vector2(210f, 28f), (TextAnchor)3); Transform transform = _panel.transform; Vector2 position = new Vector2(298f, -8f); Vector2 size = new Vector2(32f, 28f); object obj = <>O.<1>__ClosePanel; if (obj == null) { UnityAction val = ClosePanel; <>O.<1>__ClosePanel = val; obj = (object)val; } CreateButton(transform, "Close", "X", position, size, (UnityAction)obj); CreateText(_panel.transform, "Help", "Checked items are sent here first by Quick Stack, even when this chest is empty.", 11, new Vector2(12f, -40f), new Vector2(316f, 42f), (TextAnchor)0); _searchInput = CreateInputField(_panel.transform, new Vector2(12f, -84f), new Vector2(316f, 32f)); ((UnityEvent<string>)(object)_searchInput.onValueChanged).AddListener((UnityAction<string>)delegate { RebuildRows(); }); ((Component)_searchInput).gameObject.AddComponent<SearchInputMovementBlocker>(); Transform transform2 = _panel.transform; Vector2 position2 = new Vector2(12f, -122f); Vector2 size2 = new Vector2(96f, 28f); object obj2 = <>O.<2>__SelectVisible; if (obj2 == null) { UnityAction val2 = SelectVisible; <>O.<2>__SelectVisible = val2; obj2 = (object)val2; } CreateButton(transform2, "SelectVisible", "Select shown", position2, size2, (UnityAction)obj2); Transform transform3 = _panel.transform; Vector2 position3 = new Vector2(114f, -122f); Vector2 size3 = new Vector2(76f, 28f); object obj3 = <>O.<3>__ClearAll; if (obj3 == null) { UnityAction val3 = ClearAll; <>O.<3>__ClearAll = val3; obj3 = (object)val3; } CreateButton(transform3, "Clear", "Clear all", position3, size3, (UnityAction)obj3); Transform transform4 = _panel.transform; Vector2 position4 = new Vector2(196f, -122f); Vector2 size4 = new Vector2(132f, 28f); object obj4 = <>O.<4>__ToggleInventoryOnly; if (obj4 == null) { UnityAction val4 = ToggleInventoryOnly; <>O.<4>__ToggleInventoryOnly = val4; obj4 = (object)val4; } _inventoryOnlyButton = CreateButton(transform4, "InventoryOnly", "Inventory", position4, size4, (UnityAction)obj4); _inventoryOnlyButtonLabel = (((Object)(object)_inventoryOnlyButton != (Object)null) ? ((Component)_inventoryOnlyButton).GetComponentInChildren<Text>() : null); UpdateInventoryOnlyButtonLabel(); GameObject val5 = new GameObject("Viewport", new Type[3] { typeof(RectTransform), typeof(Image), typeof(Mask) }); RectTransform component3 = val5.GetComponent<RectTransform>(); ((Transform)component3).SetParent(_panel.transform, false); component3.anchorMin = new Vector2(0f, 1f); component3.anchorMax = new Vector2(0f, 1f); component3.pivot = new Vector2(0f, 1f); component3.anchoredPosition = new Vector2(12f, -158f); component3.sizeDelta = new Vector2(316f, 330f); ((Graphic)val5.GetComponent<Image>()).color = new Color(0.03f, 0.03f, 0.03f, 0.75f); val5.GetComponent<Mask>().showMaskGraphic = true; _content = new GameObject("Content", new Type[1] { typeof(RectTransform) }).GetComponent<RectTransform>(); ((Transform)_content).SetParent((Transform)(object)component3, false); _content.anchorMin = new Vector2(0f, 1f); _content.anchorMax = new Vector2(1f, 1f); _content.pivot = new Vector2(0f, 1f); _content.anchoredPosition = Vector2.zero; _content.sizeDelta = new Vector2(0f, 0f); _scrollRect = val5.AddComponent<ScrollRect>(); _scrollRect.viewport = component3; _scrollRect.content = _content; _scrollRect.horizontal = false; _scrollRect.vertical = true; _scrollRect.movementType = (MovementType)2; _scrollRect.scrollSensitivity = 140f; } } private static void ReloadPanel(bool resetScroll) { if (!((Object)(object)_currentContainer == (Object)null) && !((Object)(object)_panel == (Object)null)) { if (_allItems == null) { _allItems = StorageFilterService.GetEligibleItems(); } _selectedItems = StorageFilterService.GetSelectedItems(_currentContainer); RebuildRows(resetScroll); } } private static void RebuildRows(bool resetScroll = false) { //IL_014b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_content == (Object)null) { return; } if (_allItems == null) { _allItems = StorageFilterService.GetEligibleItems(); } if (_selectedItems == null) { _selectedItems = (((Object)(object)_currentContainer != (Object)null) ? StorageFilterService.GetSelectedItems(_currentContainer) : new HashSet<string>(StringComparer.Ordinal)); } string value = (((Object)(object)_searchInput != (Object)null) ? (_searchInput.text ?? string.Empty).Trim() : string.Empty); List<StorageFilterService.StorageItemInfo> list = new List<StorageFilterService.StorageItemInfo>(); HashSet<string> hashSet = (_inventoryOnly ? GetPlayerInventoryItemIds() : null); foreach (StorageFilterService.StorageItemInfo allItem in _allItems) { if ((hashSet == null || hashSet.Contains(allItem.Id)) && (string.IsNullOrEmpty(value) || allItem.DisplayName.IndexOf(value, StringComparison.CurrentCultureIgnoreCase) >= 0 || allItem.Id.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0)) { list.Add(allItem); } } list.Sort(delegate(StorageFilterService.StorageItemInfo a, StorageFilterService.StorageItemInfo b) { bool flag = _selectedItems.Contains(a.Id); bool flag2 = _selectedItems.Contains(b.Id); return (flag != flag2) ? ((!flag) ? 1 : (-1)) : StringComparer.CurrentCultureIgnoreCase.Compare(a.DisplayName, b.DisplayName); }); _content.sizeDelta = new Vector2(0f, Mathf.Max(1f, (float)list.Count * 30f)); if (resetScroll) { ScrollToTop(); } _rebuildGeneration++; int rebuildGeneration = _rebuildGeneration; if (_rebuildCoroutine != null && (Object)(object)Plugin.Instance != (Object)null) { ((MonoBehaviour)Plugin.Instance).StopCoroutine(_rebuildCoroutine); _rebuildCoroutine = null; } for (int num = 0; num < _rowPool.Count; num++) { if (_rowPool[num] != null && (Object)(object)_rowPool[num].GameObject != (Object)null) { _rowPool[num].GameObject.SetActive(false); } } if ((Object)(object)Plugin.Instance != (Object)null) { _rebuildCoroutine = ((MonoBehaviour)Plugin.Instance).StartCoroutine(RebuildRowsRoutine(list, rebuildGeneration)); return; } for (int num2 = 0; num2 < list.Count; num2++) { UpdatePooledRow(num2, list[num2]); } } private static IEnumerator RebuildRowsRoutine(List<StorageFilterService.StorageItemInfo> visibleItems, int generation) { int i = 0; while (i < visibleItems.Count) { if (generation != _rebuildGeneration) { yield break; } UpdatePooledRow(i, visibleItems[i]); if (i > 0 && i % 24 == 0) { yield return null; } int num = i + 1; i = num; } _rebuildCoroutine = null; } private static void UpdatePooledRow(int rowIndex, StorageFilterService.StorageItemInfo info) { //IL_0053: 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_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Expected O, but got Unknown RowView rowView = EnsureRow(rowIndex); ((Object)rowView.GameObject).name = "Item_" + info.Id; rowView.GameObject.SetActive(true); rowView.Rect.anchoredPosition = new Vector2(0f, (float)(-rowIndex) * 30f); ((Graphic)rowView.Image).color = ((rowIndex % 2 == 0) ? new Color(0.13f, 0.13f, 0.13f, 0.92f) : new Color(0.1f, 0.1f, 0.1f, 0.92f)); UpdateRowLabel(rowView.Label, info); ((UnityEventBase)rowView.Button.onClick).RemoveAllListeners(); ((UnityEvent)rowView.Button.onClick).AddListener((UnityAction)delegate { bool flag = !_selectedItems.Contains(info.Id); if (flag) { _selectedItems.Add(info.Id); } else { _selectedItems.Remove(info.Id); } StorageFilterService.SetItemSelected(_currentContainer, info.Id, flag); RebuildRows(); }); } private static RowView EnsureRow(int rowIndex) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_009a: 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_00dd: Unknown result type (might be due to invalid IL or missing references) while (_rowPool.Count <= rowIndex) { GameObject val = new GameObject("Item", new Type[3] { typeof(RectTransform), typeof(Image), typeof(Button) }); RectTransform component = val.GetComponent<RectTransform>(); ((Transform)component).SetParent((Transform)(object)_content, false); component.anchorMin = new Vector2(0f, 1f); component.anchorMax = new Vector2(1f, 1f); component.pivot = new Vector2(0f, 1f); component.sizeDelta = new Vector2(0f, 28f); Image component2 = val.GetComponent<Image>(); Button component3 = val.GetComponent<Button>(); Text label = CreateText(val.transform, "Label", string.Empty, 13, new Vector2(8f, -1f), new Vector2(286f, 26f), (TextAnchor)3); _rowPool.Add(new RowView { GameObject = val, Rect = component, Image = component2, Button = component3, Label = label }); } return _rowPool[rowIndex]; } private static void ScrollToTop() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_content != (Object)null) { _content.anchoredPosition = Vector2.zero; } if ((Object)(object)_scrollRect != (Object)null) { _scrollRect.StopMovement(); _scrollRect.verticalNormalizedPosition = 1f; } } private static void UpdateRowLabel(Text label, StorageFilterService.StorageItemInfo info) { if (!((Object)(object)label == (Object)null)) { bool flag = _selectedItems != null && _selectedItems.Contains(info.Id); label.text = (flag ? "[X] " : "[ ] ") + info.DisplayName; } } private static void SelectVisible() { if ((Object)(object)_currentContainer == (Object)null || _allItems == null) { return; } string value = (((Object)(object)_searchInput != (Object)null) ? (_searchInput.text ?? string.Empty).Trim() : string.Empty); HashSet<string> hashSet = (_inventoryOnly ? GetPlayerInventoryItemIds() : null); foreach (StorageFilterService.StorageItemInfo allItem in _allItems) { if ((hashSet == null || hashSet.Contains(allItem.Id)) && (string.IsNullOrEmpty(value) || allItem.DisplayName.IndexOf(value, StringComparison.CurrentCultureIgnoreCase) >= 0 || allItem.Id.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0)) { _selectedItems.Add(allItem.Id); StorageFilterService.SetItemSelected(_currentContainer, allItem.Id, selected: true); } } RebuildRows(); } private static void ToggleInventoryOnly() { _inventoryOnly = !_inventoryOnly; UpdateInventoryOnlyButtonLabel(); RebuildRows(resetScroll: true); } private static void UpdateInventoryOnlyButtonLabel() { if ((Object)(object)_inventoryOnlyButtonLabel != (Object)null) { _inventoryOnlyButtonLabel.text = (_inventoryOnly ? "Inventory: ON" : "Inventory"); } } private static HashSet<string> GetPlayerInventoryItemIds() { HashSet<string> hashSet = new HashSet<string>(StringComparer.Ordinal); Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || ((Humanoid)localPlayer).GetInventory() == null) { return hashSet; } foreach (ItemData allItem in ((Humanoid)localPlayer).GetInventory().GetAllItems()) { if (allItem != null) { string itemId = StorageFilterService.GetItemId(allItem); if (!string.IsNullOrEmpty(itemId)) { hashSet.Add(itemId); } } } return hashSet; } private static void ClearAll() { if (!((Object)(object)_currentContainer == (Object)null)) { StorageFilterService.Clear(_currentContainer); _selectedItems = new HashSet<string>(StringComparer.Ordinal); RebuildRows(); } } private static void ClosePanel() { if ((Object)(object)_panel != (Object)null) { _panel.SetActive(false); } } private static InputField CreateInputField(Transform parent, Vector2 position, Vector2 size) { //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_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: 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) //IL_00e4: 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_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0129: 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_0156: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Search", new Type[3] { typeof(RectTransform), typeof(Image), typeof(InputField) }); RectTransform component = val.GetComponent<RectTransform>(); ((Transform)component).SetParent(parent, false); component.anchorMin = new Vector2(0f, 1f); component.anchorMax = new Vector2(0f, 1f); component.pivot = new Vector2(0f, 1f); component.anchoredPosition = position; component.sizeDelta = size; Image component2 = val.GetComponent<Image>(); ((Graphic)component2).color = new Color(0.16f, 0.16f, 0.16f, 1f); Text textComponent = CreateText(val.transform, "Text", string.Empty, 13, new Vector2(8f, -2f), new Vector2(size.x - 16f, size.y - 4f), (TextAnchor)3); Text val2 = CreateText(val.transform, "Placeholder", "Search items...", 13, new Vector2(8f, -2f), new Vector2(size.x - 16f, size.y - 4f), (TextAnchor)3); ((Graphic)val2).color = new Color(0.7f, 0.7f, 0.7f, 0.75f); InputField component3 = val.GetComponent<InputField>(); ((Selectable)component3).targetGraphic = (Graphic)(object)component2; component3.textComponent = textComponent; component3.placeholder = (Graphic)(object)val2; component3.lineType = (LineType)0; return component3; } private static Button CreateButton(Transform parent, string name, string labelText, Vector2 position, Vector2 size, UnityAction onClick) { //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_004c: 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) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008e: 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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[3] { typeof(RectTransform), typeof(Image), typeof(Button) }); RectTransform component = val.GetComponent<RectTransform>(); ((Transform)component).SetParent(parent, false); component.anchorMin = new Vector2(0f, 1f); component.anchorMax = new Vector2(0f, 1f); component.pivot = new Vector2(0f, 1f); component.anchoredPosition = position; component.sizeDelta = size; Image component2 = val.GetComponent<Image>(); ((Graphic)component2).color = new Color(0.22f, 0.22f, 0.22f, 1f); Button component3 = val.GetComponent<Button>(); ((Selectable)component3).targetGraphic = (Graphic)(object)component2; ((UnityEvent)component3.onClick).AddListener(onClick); CreateText(val.transform, "Label", labelText, 12, Vector2.zero, size, (TextAnchor)4); return component3; } private static Text CreateText(Transform parent, string name, string value, int fontSize, Vector2 position, Vector2 size, TextAnchor alignment) { //IL_0026: 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_0044: 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) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) EnsureFont(); GameObject val = new GameObject(name, new Type[2] { typeof(RectTransform), typeof(Text) }); RectTransform component = val.GetComponent<RectTransform>(); ((Transform)component).SetParent(parent, false); component.anchorMin = new Vector2(0f, 1f); component.anchorMax = new Vector2(0f, 1f); component.pivot = new Vector2(0f, 1f); component.anchoredPosition = position; component.sizeDelta = size; Text component2 = val.GetComponent<Text>(); component2.font = _font; component2.fontSize = fontSize; component2.alignment = alignment; ((Graphic)component2).color = Color.white; component2.text = value; component2.horizontalOverflow = (HorizontalWrapMode)0; component2.verticalOverflow = (VerticalWrapMode)0; ((Graphic)component2).raycastTarget = false; return component2; } private static void DrawFilterGlyph(Transform parent) { CreateGlyphBar(parent, 20f, 7f); CreateGlyphBar(parent, 14f, 0f); CreateGlyphBar(parent, 8f, -7f); } private static void CreateGlyphBar(Transform parent, float width, float y) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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_006d: 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_008e: 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) GameObject val = new GameObject("FilterBar", new Type[2] { typeof(RectTransform), typeof(Image) }); RectTransform component = val.GetComponent<RectTransform>(); ((Transform)component).SetParent(parent, false); component.anchorMin = new Vector2(0.5f, 0.5f); component.anchorMax = new Vector2(0.5f, 0.5f); component.pivot = new Vector2(0.5f, 0.5f); component.anchoredPosition = new Vector2(0f, y); component.sizeDelta = new Vector2(width, 3f); Image component2 = val.GetComponent<Image>(); ((Graphic)component2).color = Color.white; ((Graphic)component2).raycastTarget = false; } private static void HideTemplateText(GameObject buttonObject) { TMP_Text[] componentsInChildren = buttonObject.GetComponentsInChildren<TMP_Text>(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].text = string.Empty; } Text[] componentsInChildren2 = buttonObject.GetComponentsInChildren<Text>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { componentsInChildren2[i].text = string.Empty; } } private static void EnsureFont() { if ((Object)(object)_font != (Object)null) { return; } try { _font = Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf"); } catch (Exception) { try { _font = Resources.GetBuiltinResource<Font>("Arial.ttf"); } catch (Exception) { _font = null; } } } private static Transform FindChildRecursive(Transform parent, string childName) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown if ((Object)(object)parent == (Object)null) { return null; } foreach (Transform item in parent) { Transform val = item; if (((Object)val).name == childName) { return val; } Transform val2 = FindChildRecursive(val, childName); if ((Object)(object)val2 != (Object)null) { return val2; } } return null; } } internal sealed class RowView { internal GameObject GameObject; internal RectTransform Rect; internal Image Image; internal Button Button; internal Text Label; } internal sealed class SearchInputMovementBlocker : MonoBehaviour { private InputField _input; private static FieldInfo _inputBlockedField; private static bool _fieldResolved; private bool _wasBlocking; private bool _previousValue; private void Awake() { _input = ((Component)this).GetComponent<InputField>(); ResolveField(); } private void Update() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || _inputBlockedField == null || (Object)(object)_input == (Object)null) { return; } bool flag = _input.isFocused && ((Component)this).gameObject.activeInHierarchy; if (flag && !_wasBlocking) { try { object value = _inputBlockedField.GetValue(localPlayer); _previousValue = value is bool && (bool)value; _inputBlockedField.SetValue(localPlayer, true); _wasBlocking = true; return; } catch (Exception) { _wasBlocking = false; return; } } if (!flag && _wasBlocking) { Restore(localPlayer); } else if (flag) { try { _inputBlockedField.SetValue(localPlayer, true); } catch (Exception) { } } } private void OnDisable() { Restore(Player.m_localPlayer); } private void OnDestroy() { Restore(Player.m_localPlayer); } private void Restore(Player player) { if (!_wasBlocking || (Object)(object)player == (Object)null || _inputBlockedField == null) { _wasBlocking = false; return; } try { _inputBlockedField.SetValue(player, _previousValue); } catch (Exception) { } _wasBlocking = false; } private static void ResolveField() { if (!_fieldResolved) { _fieldResolved = true; Type type = typeof(Player); while (type != null && _inputBlockedField == null) { _inputBlockedField = type.GetField("m_inputBlocked", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); type = type.BaseType; } } } } } namespace QuickStackPlus.UI { internal static class TrashBorderRenderer { private const string TrashBorderName = "QuickStackPlusTrashBorder"; private const string BlacklistBorderName = "QuickStackPlusBlacklistBorder"; private const float BorderThickness = 2f; private static readonly FieldInfo ElementsField = AccessTools.Field(typeof(InventoryGrid), "m_elements"); internal static void Refresh(InventoryGrid grid) { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)grid == (Object)null || grid.GetInventory() == null) { return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || grid.GetInventory() != ((Humanoid)localPlayer).GetInventory() || !(ElementsField?.GetValue(grid) is List<InventoryElement> list)) { return; } int width = grid.GetInventory().GetWidth(); foreach (InventoryElement item in list) { if (!((Object)(object)item == (Object)null)) { SetBorderVisible(item, "QuickStackPlusTrashBorder", visible: false, Color.red, 0f); SetBorderVisible(item, "QuickStackPlusBlacklistBorder", visible: false, new Color(1f, 0.65f, 0f, 1f), 3f); } } if (!Plugin.ModEnabled) { return; } foreach (ItemData allItem in grid.GetInventory().GetAllItems()) { if (allItem == null) { continue; } int num = allItem.m_gridPos.y * width + allItem.m_gridPos.x; if (num < 0 || num >= list.Count) { continue; } InventoryElement val = list[num]; if (!((Object)(object)val == (Object)null)) { if (TrashService.IsMarked(allItem)) { SetBorderVisible(val, "QuickStackPlusTrashBorder", visible: true, Color.red, 0f); } if (Plugin.EnableQuickStackBlacklist && BlacklistService.IsBlacklisted(allItem)) { SetBorderVisible(val, "QuickStackPlusBlacklistBorder", visible: true, new Color(1f, 0.65f, 0f, 1f), 3f); } } } } private static void SetBorderVisible(InventoryElement element, string borderName, bool visible, Color color, float inset) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) Transform val = ((Component)element).transform.Find(borderName); GameObject val2 = (((Object)(object)val != (Object)null) ? ((Component)val).gameObject : null); if ((Object)(object)val2 == (Object)null && visible) { val2 = CreateBorder(((Component)element).transform, borderName, color, inset); } if ((Object)(object)val2 != (Object)null) { val2.SetActive(visible); } } private static GameObject CreateBorder(Transform parent, string borderName, Color color, float inset) { //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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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_0050: 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_006f: 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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: 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_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: 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_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: 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_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be