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 NathansQol QuickStack v0.2.2
NathansQol.QuickStack.dll
Decompiled 6 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Jotunn.Utils; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("assembly_guiutils")] [assembly: IgnoresAccessChecksTo("assembly_utils")] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("NathansQol.QuickStack")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.2.2.0")] [assembly: AssemblyInformationalVersion("0.2.2+d4126be973f0be660e31d2112d3f9998b67c1334")] [assembly: AssemblyProduct("NathansQol.QuickStack")] [assembly: AssemblyTitle("NathansQol.QuickStack")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.2.2.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace NathansQol.QuickStack { internal static class ChestFinder { internal static List<Container> InRange(Vector3 center, float radius) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) List<Piece> list = new List<Piece>(); Piece.GetAllPiecesInRadius(center, radius, list); List<Container> list2 = new List<Container>(); foreach (Piece item in list) { Container component = ((Component)item).GetComponent<Container>(); if ((Object)(object)component != (Object)null) { list2.Add(component); } } return list2; } } internal static class ItemLock { private const string Key = "nathan.quickstack.locked"; internal static bool IsLocked(ItemData item) { return item?.m_customData.ContainsKey("nathan.quickstack.locked") ?? false; } internal static void Toggle(ItemData item) { if (!item.m_customData.Remove("nathan.quickstack.locked")) { item.m_customData["nathan.quickstack.locked"] = "1"; } } internal static void Unlock(ItemData item) { item.m_customData.Remove("nathan.quickstack.locked"); } } internal sealed class KeyBindingsBridge { private const string LibraryGuid = "nathan.qol.keybindings"; private const int MinimumApiVersion = 1; private readonly object _binding; private readonly Func<bool> _ownDown; private readonly Func<bool> _ownPressed; private readonly Func<bool> _ownUp; private readonly MethodInfo _isDown; private readonly MethodInfo _isPressed; private readonly MethodInfo _isUp; public bool Registered => _binding != null; private KeyBindingsBridge(object binding, Func<bool> down, Func<bool> pressed, Func<bool> up) { _binding = binding; _ownDown = down; _ownPressed = pressed; _ownUp = up; if (binding != null) { Type type = binding.GetType(); _isDown = type.GetMethod("IsDown", Type.EmptyTypes); _isPressed = type.GetMethod("IsPressed", Type.EmptyTypes); _isUp = type.GetMethod("IsUp", Type.EmptyTypes); } } public bool IsDown() { if (_binding == null || !(_isDown != null)) { return _ownDown(); } return (bool)_isDown.Invoke(_binding, null); } public bool IsPressed() { if (_binding == null || !(_isPressed != null)) { return _ownPressed(); } return (bool)_isPressed.Invoke(_binding, null); } public bool IsUp() { if (_binding == null || !(_isUp != null)) { return _ownUp(); } return (bool)_isUp.Invoke(_binding, null); } public static KeyBindingsBridge Register(BaseUnityPlugin plugin, ConfigEntry<KeyboardShortcut> shortcut, string label, string defaultGamepad = "None") { return new KeyBindingsBridge(TryRegister(plugin, shortcut, label, defaultGamepad), delegate { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = shortcut.Value; return ((KeyboardShortcut)(ref value)).IsDown(); }, delegate { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = shortcut.Value; return ((KeyboardShortcut)(ref value)).IsPressed(); }, delegate { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = shortcut.Value; return ((KeyboardShortcut)(ref value)).IsUp(); }); } public static KeyBindingsBridge Register(BaseUnityPlugin plugin, ConfigEntry<KeyCode> key, string label, string defaultGamepad = "None") { return new KeyBindingsBridge(TryRegister(plugin, key, label, defaultGamepad), () => (int)key.Value != 0 && Input.GetKeyDown(key.Value), () => (int)key.Value != 0 && Input.GetKey(key.Value), () => (int)key.Value != 0 && Input.GetKeyUp(key.Value)); } private static object TryRegister(BaseUnityPlugin plugin, object entry, string label, string defaultGamepad) { try { if (!Chainloader.PluginInfos.TryGetValue("nathan.qol.keybindings", out var value) || (Object)(object)value.Instance == (Object)null) { return null; } Assembly assembly = ((object)value.Instance).GetType().Assembly; Type type = assembly.GetType("NathansQol.KeyBindings.KeyBindings"); Type type2 = assembly.GetType("NathansQol.KeyBindings.GamepadButton"); if (type == null || type2 == null) { return null; } FieldInfo field = type.GetField("ApiVersion", BindingFlags.Static | BindingFlags.Public); if (field == null || (int)field.GetRawConstantValue() < 1) { return null; } int num = (int)field.GetRawConstantValue(); string text = defaultGamepad ?? "None"; if (num >= 2) { MethodInfo method = type.GetMethod("Register", new Type[4] { typeof(PluginInfo), entry.GetType(), typeof(string), typeof(string) }); if (method != null) { return method.Invoke(null, new object[4] { plugin.Info, entry, label, text }); } } object obj; try { obj = Enum.Parse(type2, text.Split(new char[1] { '+' })[0].Trim(), ignoreCase: true); } catch (ArgumentException) { obj = Enum.Parse(type2, "None"); } return type.GetMethod("Register", new Type[4] { typeof(PluginInfo), entry.GetType(), typeof(string), type2 })?.Invoke(null, new object[4] { plugin.Info, entry, label, obj }); } catch (Exception ex2) { ManualLogSource val = Logger.CreateLogSource(plugin.Info.Metadata.Name); val.LogWarning((object)("Could not register '" + label + "' with the Key Bindings mod: " + ex2.Message)); Logger.Sources.Remove((ILogSource)(object)val); return null; } } } internal static class LockIcon { private static Sprite _sprite; internal static Sprite Sprite => _sprite ?? (_sprite = Load()); private static Sprite Load() { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) byte[] array; using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("lock.png")) { using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); array = memoryStream.ToArray(); } Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); typeof(ImageConversion).GetMethod("LoadImage", new Type[3] { typeof(Texture2D), typeof(byte[]), typeof(bool) }).Invoke(null, new object[3] { val, array, false }); return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); } } [HarmonyPatch(typeof(InventoryGrid), "UpdateGui")] internal static class LockOverlayPatch { private const string OverlayName = "QuickStackLock"; private static void Postfix(InventoryGrid __instance) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; Inventory inventory = __instance.GetInventory(); if (!QuickStackPlugin.Enabled.Value || (Object)(object)localPlayer == (Object)null || inventory == null) { return; } bool flag = inventory == ((Humanoid)localPlayer).GetInventory(); foreach (InventoryElement element in __instance.m_elements) { ItemData itemAt = inventory.GetItemAt(element.Position.x, element.Position.y); bool flag2 = flag && ItemLock.IsLocked(itemAt); Transform val = ((Component)element).transform.Find("QuickStackLock"); if ((Object)(object)val == (Object)null) { if (!flag2) { continue; } val = CreateOverlay(element); } ((Component)val).gameObject.SetActive(flag2); } } private static Transform CreateOverlay(InventoryElement element) { //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_003c: 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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("QuickStackLock", new Type[2] { typeof(RectTransform), typeof(Image) }); val.transform.SetParent(((Component)element).transform, false); RectTransform val2 = (RectTransform)val.transform; Vector2 val3 = default(Vector2); ((Vector2)(ref val3))..ctor(1f, 1f); val2.pivot = val3; Vector2 anchorMin = (val2.anchorMax = val3); val2.anchorMin = anchorMin; val2.anchoredPosition = new Vector2(-4f, -4f); val2.sizeDelta = new Vector2(22f, 22f); Image component = val.GetComponent<Image>(); component.sprite = LockIcon.Sprite; ((Graphic)component).raycastTarget = false; return val.transform; } } [HarmonyPatch(typeof(Player), "Update")] internal static class QuickStackHotkeyPatch { private static void Postfix(Player __instance) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) if (!QuickStackPlugin.Enabled.Value || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || !((Character)__instance).TakeInput() || !QuickStackPlugin.StackBinding.IsDown()) { return; } List<Container> list = ChestFinder.InRange(((Component)__instance).transform.position, QuickStackPlugin.Radius.Value); QuickStackPlugin.Log.LogDebug((object)$"Quick stack: {list.Count} chest(s) in range"); if (list.Count == 0) { ((Character)__instance).Message((MessageType)2, "No chests nearby", 0, (Sprite)null, false); return; } foreach (Container item in list) { if (item.GetInventory() != null) { item.StackAll(); } } } } [HarmonyPatch(typeof(InventoryGui), "OnSelectedItem")] internal static class LockToggleClickPatch { private static bool Prefix(InventoryGui __instance, InventoryGrid grid, ItemData item) { if (!QuickStackPlugin.Enabled.Value) { return true; } if (item == null) { return true; } if ((Object)(object)grid != (Object)(object)__instance.m_playerGrid) { return true; } if ((Object)(object)__instance.m_dragGo != (Object)null) { return true; } if (!QuickStackPlugin.LockBinding.IsPressed() && !QuickStackPlugin.LockBinding.IsUp()) { return true; } ItemLock.Toggle(item); string text = (ItemLock.IsLocked(item) ? "locked" : "unlocked"); string text2 = Localization.instance.Localize(item.m_shared.m_name); ((Character)Player.m_localPlayer).Message((MessageType)1, text2 + " " + text, 0, (Sprite)null, false); return false; } } [HarmonyPatch(typeof(Inventory), "StackAll")] internal static class StackAllScopePatch { internal static bool Active; private static void Prefix() { Active = true; } private static void Finalizer() { Active = false; } } [HarmonyPatch(typeof(Humanoid), "IsItemEquiped")] internal static class LockedLooksEquippedPatch { private static void Postfix(ItemData item, ref bool __result) { if (StackAllScopePatch.Active && ItemLock.IsLocked(item)) { __result = true; } } } [HarmonyPatch(typeof(Inventory), "Changed")] internal static class ClearLocksOutsidePlayerPatch { private static void Postfix(Inventory __instance) { Player localPlayer = Player.m_localPlayer; if (!QuickStackPlugin.Enabled.Value || (Object)(object)localPlayer == (Object)null || __instance == ((Humanoid)localPlayer).GetInventory()) { return; } foreach (ItemData allItem in __instance.GetAllItems()) { ItemLock.Unlock(allItem); } } } [BepInPlugin("nathan.qol.quickstack", "Nathans Quick Stack", "0.2.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class QuickStackPlugin : BaseUnityPlugin { public const string PluginGuid = "nathan.qol.quickstack"; public const string PluginName = "Nathans Quick Stack"; public const string PluginVersion = "0.2.2"; internal static ManualLogSource Log; internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<KeyboardShortcut> StackKey; internal static KeyBindingsBridge StackBinding; internal static ConfigEntry<float> Radius; internal static ConfigEntry<KeyboardShortcut> LockShortcut; internal static KeyBindingsBridge LockBinding; private void Awake() { //IL_004b: 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_0097: Expected O, but got Unknown //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Turns the mod on or off (quick stack, item locks and the padlock icons). Takes effect immediately."); StackKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "StackKey", new KeyboardShortcut((KeyCode)103, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }), "Quick stack your inventory into the chests nearby."); Radius = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Radius", 10f, new ConfigDescription("How far away (in meters) chests are used.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 50f), Array.Empty<object>())); LockShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "LockShortcut", new KeyboardShortcut((KeyCode)323, (KeyCode[])(object)new KeyCode[1] { (KeyCode)308 }), "Click an item in your inventory with this shortcut to lock or unlock it (default: Alt + left mouse button)."); StackBinding = KeyBindingsBridge.Register((BaseUnityPlugin)(object)this, StackKey, "Quick stack into nearby chests"); LockBinding = KeyBindingsBridge.Register((BaseUnityPlugin)(object)this, LockShortcut, "Lock or unlock an item (click it)"); new Harmony("nathan.qol.quickstack").PatchAll(); Log.LogInfo((object)"Nathans Quick Stack 0.2.2 loaded"); } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }