Decompiled source of DropToCapacity v0.1.1

plugins/DropToCapacity.dll

Decompiled 3 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using DropToCapacity.Core;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("DropToCapacity")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("DropToCapacity")]
[assembly: AssemblyTitle("DropToCapacity")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace DropToCapacity
{
	[BepInPlugin("com.jonasd.valheim.droptocapacity", "Drop to Capacity", "0.1.1")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.jonasd.valheim.droptocapacity";

		public const string PluginName = "Drop to Capacity";

		public const string PluginVersion = "0.1.1";

		private const KeyCode DefaultMainKey = (KeyCode)308;

		private const string DefaultInventoryKey = "Tab";

		private const string DefaultUseKey = "E";

		public static ConfigEntry<KeyboardShortcut> ModifierKey;

		private Harmony harmony;

		private void Awake()
		{
			//IL_001a: 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: Expected O, but got Unknown
			ModifierKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "ModifierKey", new KeyboardShortcut((KeyCode)308, Array.Empty<KeyCode>()), "Hold this while left-clicking an inventory item to drop just enough of that stack to bring your carried weight down to capacity, instead of the default move/pickup behavior. Rejected if it conflicts with Escape, Shift, Ctrl, a mouse button, or whatever the vanilla Inventory/Use actions are currently bound to.");
			ValidateModifierKey();
			ModifierKey.SettingChanged += delegate
			{
				ValidateModifierKey();
			};
			harmony = new Harmony("com.jonasd.valheim.droptocapacity");
			harmony.PatchAll();
		}

		private unsafe void ValidateModifierKey()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: 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_0090: Unknown result type (might be due to invalid IL or missing references)
			KeyboardShortcut value = ModifierKey.Value;
			KeyCode mainKey = ((KeyboardShortcut)(ref value)).MainKey;
			IEnumerable<string> enumerable = new string[2]
			{
				GetVanillaBoundKeyName("Inventory") ?? "Tab",
				GetVanillaBoundKeyName("Use") ?? "E"
			};
			if (!MainKeyValidator.IsAllowed(((object)(*(KeyCode*)(&mainKey))/*cast due to .constrained prefix*/).ToString(), enumerable))
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)$"ModifierKey '{mainKey}' conflicts with Escape, Shift, Ctrl, a mouse button, or the vanilla Inventory/Use hotkey - falling back to {(object)(KeyCode)308}.");
				ModifierKey.Value = new KeyboardShortcut((KeyCode)308, Array.Empty<KeyCode>());
			}
		}

		private static string GetVanillaBoundKeyName(string buttonName)
		{
			try
			{
				ZInput instance = ZInput.instance;
				object obj;
				if (instance == null)
				{
					obj = null;
				}
				else
				{
					ButtonDef buttonDef = instance.GetButtonDef(buttonName);
					obj = ((buttonDef != null) ? buttonDef.GetActionPath(true) : null);
				}
				string text = (string)obj;
				if (string.IsNullOrEmpty(text))
				{
					return null;
				}
				int num = text.LastIndexOf('/');
				return (num >= 0) ? text.Substring(num + 1) : text;
			}
			catch (Exception arg)
			{
				Debug.LogWarning((object)$"[DropToCapacity] Failed to read vanilla '{buttonName}' binding: {arg}");
				return null;
			}
		}

		private void OnDestroy()
		{
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}
	}
}
namespace DropToCapacity.Patches
{
	[HarmonyPatch(typeof(InventoryGui), "OnSelectedItem", new Type[]
	{
		typeof(InventoryGrid),
		typeof(ItemData),
		typeof(Vector2i),
		typeof(Modifier)
	})]
	public static class InventoryGuiOnSelectedItemPatch
	{
		private static bool Prefix(InventoryGui __instance, InventoryGrid grid, ItemData item)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if (item == null || (Object)(object)grid != (Object)(object)__instance.m_playerGrid)
			{
				return true;
			}
			if (!IsModifierHeld(Plugin.ModifierKey.Value))
			{
				return true;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				return false;
			}
			Inventory inventory = ((Humanoid)localPlayer).GetInventory();
			int num = DropCalculator.ComputeDropAmount(inventory.GetTotalWeight(), localPlayer.GetMaxCarryWeight(), item.m_shared.m_weight, item.m_stack);
			if (num > 0)
			{
				((Humanoid)localPlayer).DropItem(inventory, item, num);
			}
			return false;
		}

		private unsafe static bool IsModifierHeld(KeyboardShortcut shortcut)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			KeyCode result;
			return ShortcutMatcher.IsHeld(((object)((KeyboardShortcut)(ref shortcut)).MainKey/*cast due to .constrained prefix*/).ToString(), ((KeyboardShortcut)(ref shortcut)).Modifiers.Select((KeyCode key) => ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString()), (Func<string, bool>)((string keyName) => Enum.TryParse<KeyCode>(keyName, out result) && UnityInput.Current.GetKey(result)));
		}
	}
}

plugins/DropToCapacity.Core.dll

Decompiled 3 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("DropToCapacity.Core")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("DropToCapacity.Core")]
[assembly: AssemblyTitle("DropToCapacity.Core")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace DropToCapacity.Core;

public static class DropCalculator
{
	private const float WeightEpsilon = 0.0001f;

	public static int ComputeDropAmount(float currentWeight, float maxWeight, float itemUnitWeight, int stackSize)
	{
		if (stackSize <= 0 || itemUnitWeight <= 0f)
		{
			return 0;
		}
		float num = currentWeight - maxWeight;
		if (num <= 0.0001f)
		{
			return 0;
		}
		return Math.Min((int)Math.Ceiling(num / itemUnitWeight), stackSize);
	}
}
public static class MainKeyValidator
{
	private static readonly HashSet<string> AlwaysDenylisted = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
	{
		"None", "Escape", "LeftShift", "RightShift", "LeftControl", "RightControl", "Mouse0", "Mouse1", "Mouse2", "Mouse3",
		"Mouse4", "Mouse5", "Mouse6"
	};

	public static bool IsAllowed(string mainKeyName, IEnumerable<string> vanillaBoundKeyNames)
	{
		if (string.IsNullOrEmpty(mainKeyName) || AlwaysDenylisted.Contains(mainKeyName))
		{
			return false;
		}
		if (vanillaBoundKeyNames != null)
		{
			foreach (string vanillaBoundKeyName in vanillaBoundKeyNames)
			{
				if (string.Equals(mainKeyName, vanillaBoundKeyName, StringComparison.OrdinalIgnoreCase))
				{
					return false;
				}
			}
		}
		return true;
	}
}
public static class ShortcutMatcher
{
	public static bool IsHeld(string mainKeyName, IEnumerable<string> modifierKeyNames, Func<string, bool> isKeyHeld)
	{
		if (string.IsNullOrEmpty(mainKeyName) || string.Equals(mainKeyName, "None", StringComparison.OrdinalIgnoreCase))
		{
			return false;
		}
		if (!isKeyHeld(mainKeyName))
		{
			return false;
		}
		if (modifierKeyNames != null)
		{
			foreach (string modifierKeyName in modifierKeyNames)
			{
				if (!isKeyHeld(modifierKeyName))
				{
					return false;
				}
			}
		}
		return true;
	}
}