Decompiled source of NathansQol QuickStack v0.2.2

NathansQol.QuickStack.dll

Decompiled 6 days ago
using 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)
		{
		}
	}
}