Decompiled source of AltSplitOne v1.0.0

AltSplitOne.dll

Decompiled 2 weeks ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
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("AltSplitOne")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Alt + left click to take, gather and place items one at a time, without the split dialog.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+45f1db0b0085dc39ab45145208d0b526eb021323")]
[assembly: AssemblyProduct("AltSplitOne")]
[assembly: AssemblyTitle("AltSplitOne")]
[assembly: AssemblyVersion("1.0.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 AltSplitOne
{
	internal static class InventoryGuiAccess
	{
		internal static FieldRef<InventoryGui, GameObject> DragGo;

		internal static FieldRef<InventoryGui, ItemData> DragItem;

		internal static FieldRef<InventoryGui, Inventory> DragInventory;

		internal static FieldRef<InventoryGui, int> DragAmount;

		internal static Action<InventoryGui, ItemData, Inventory, int> SetupDragItem;

		internal static Action<InventoryGui, bool> SetIsSplitDropping;

		internal static Action<InventoryGui, bool> UpdateCraftingPanel;

		internal static bool TryBind(out string error)
		{
			string text = null;
			try
			{
				text = "m_dragGo";
				DragGo = AccessTools.FieldRefAccess<InventoryGui, GameObject>(text);
				text = "m_dragItem";
				DragItem = AccessTools.FieldRefAccess<InventoryGui, ItemData>(text);
				text = "m_dragInventory";
				DragInventory = AccessTools.FieldRefAccess<InventoryGui, Inventory>(text);
				text = "m_dragAmount";
				DragAmount = AccessTools.FieldRefAccess<InventoryGui, int>(text);
				text = "SetupDragItem";
				SetupDragItem = OpenDelegate<Action<InventoryGui, ItemData, Inventory, int>>(AccessTools.Method(typeof(InventoryGui), text, (Type[])null, (Type[])null), text);
				text = "IsSplitDropping";
				SetIsSplitDropping = OpenDelegate<Action<InventoryGui, bool>>(AccessTools.PropertySetter(typeof(InventoryGui), text), text);
				text = "UpdateCraftingPanel";
				UpdateCraftingPanel = OpenDelegate<Action<InventoryGui, bool>>(AccessTools.Method(typeof(InventoryGui), text, (Type[])null, (Type[])null), text);
				error = null;
				return true;
			}
			catch (Exception ex)
			{
				error = "InventoryGui." + text + ": " + ex.Message;
				return false;
			}
		}

		private static TDelegate OpenDelegate<TDelegate>(MethodInfo method, string name) where TDelegate : Delegate
		{
			if (method == null)
			{
				throw new MissingMemberException("not found on InventoryGui: " + name);
			}
			return AccessTools.MethodDelegate<TDelegate>(method, (object)null, true);
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "OnSelectedItem")]
	internal static class OnSelectedItemPatch
	{
		private static bool Prefix(InventoryGui __instance, InventoryGrid grid, ItemData item, Vector2i pos)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				return Handle(__instance, grid, item, pos);
			}
			catch (Exception ex)
			{
				AltSplitOnePlugin.Log.LogError((object)("Prefix threw, passing the click to vanilla: " + ex));
				return true;
			}
		}

		private static bool Handle(InventoryGui gui, InventoryGrid grid, ItemData item, Vector2i pos)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			if (!AltSplitOnePlugin.ModifierHeld())
			{
				return true;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsTeleporting())
			{
				return true;
			}
			if ((Object)(object)InventoryGuiAccess.DragGo.Invoke(gui) == (Object)null)
			{
				return !TryTakeOne(gui, grid, item);
			}
			if (TryTakeOneMore(gui, grid, pos, localPlayer))
			{
				return false;
			}
			if (!CanPlaceOne(gui, grid, pos))
			{
				return true;
			}
			PlaceOne(gui, grid, pos, localPlayer);
			return false;
		}

		private static bool TryTakeOne(InventoryGui gui, InventoryGrid grid, ItemData item)
		{
			if (item == null || !item.CanRemoveFromStack())
			{
				return false;
			}
			InventoryGuiAccess.SetupDragItem(gui, item, grid.GetInventory(), 1);
			InventoryGuiAccess.SetIsSplitDropping(gui, arg2: true);
			return true;
		}

		private static bool TryTakeOneMore(InventoryGui gui, InventoryGrid grid, Vector2i pos, Player player)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			ItemData val = InventoryGuiAccess.DragItem.Invoke(gui);
			Inventory val2 = InventoryGuiAccess.DragInventory.Invoke(gui);
			if (val == null || val2 == null || !val2.ContainsItem(val))
			{
				return false;
			}
			if (grid.GetInventory() != val2)
			{
				return false;
			}
			ItemData itemAt = val2.GetItemAt(pos.x, pos.y);
			if (itemAt == null)
			{
				return false;
			}
			if (itemAt == val)
			{
				return TakeOneFromSameCell(gui, val);
			}
			if (!itemAt.IsSameType(val))
			{
				return false;
			}
			return TakeOneViaRebind(gui, grid, pos, player, val, val2, itemAt);
		}

		private static bool TakeOneFromSameCell(InventoryGui gui, ItemData drag)
		{
			//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_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			if (InventoryGuiAccess.DragAmount.Invoke(gui) >= drag.m_stack)
			{
				return true;
			}
			InventoryGuiAccess.DragAmount.Invoke(gui)++;
			gui.m_moveItemEffects.Create(((Component)gui).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
			return true;
		}

		private static bool TakeOneViaRebind(InventoryGui gui, InventoryGrid grid, Vector2i pos, Player player, ItemData drag, Inventory from, ItemData target)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			int num = InventoryGuiAccess.DragAmount.Invoke(gui);
			if (target.m_shared.m_maxStackSize - target.m_stack < num)
			{
				return true;
			}
			bool num2 = ((Humanoid)player).IsItemEquiped(drag);
			if (num2)
			{
				((Humanoid)player).RemoveEquipAction(drag);
				((Humanoid)player).UnequipItem(drag, false);
			}
			if (grid.DropItem(from, drag, num, pos))
			{
				InventoryGuiAccess.SetupDragItem(gui, target, from, num + 1);
				InventoryGuiAccess.SetIsSplitDropping(gui, arg2: true);
			}
			else
			{
				AltSplitOnePlugin.Log.LogWarning((object)"DropItem refused during rebind, the carried items were left untouched.");
			}
			if (num2 && ((Humanoid)player).GetInventory().ContainsItem(drag))
			{
				((Humanoid)player).EquipItem(drag, false);
			}
			return true;
		}

		private static bool CanPlaceOne(InventoryGui gui, InventoryGrid grid, Vector2i pos)
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			ItemData val = InventoryGuiAccess.DragItem.Invoke(gui);
			Inventory val2 = InventoryGuiAccess.DragInventory.Invoke(gui);
			if (val == null || val2 == null || !val2.ContainsItem(val))
			{
				return false;
			}
			if (InventoryGuiAccess.DragAmount.Invoke(gui) <= 1)
			{
				return false;
			}
			Inventory inventory = grid.GetInventory();
			if (val.m_shared.m_questItem && val2 != inventory)
			{
				return false;
			}
			ItemData itemAt = inventory.GetItemAt(pos.x, pos.y);
			if (itemAt == null)
			{
				return true;
			}
			if (itemAt == val || !itemAt.IsSameType(val))
			{
				return false;
			}
			return itemAt.m_stack < itemAt.m_shared.m_maxStackSize;
		}

		private static void PlaceOne(InventoryGui gui, InventoryGrid grid, Vector2i pos, Player player)
		{
			//IL_0037: 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_0060: 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_0074: Unknown result type (might be due to invalid IL or missing references)
			ItemData val = InventoryGuiAccess.DragItem.Invoke(gui);
			Inventory val2 = InventoryGuiAccess.DragInventory.Invoke(gui);
			bool num = ((Humanoid)player).IsItemEquiped(val);
			if (num)
			{
				((Humanoid)player).RemoveEquipAction(val);
				((Humanoid)player).UnequipItem(val, false);
			}
			if (grid.DropItem(val2, val, 1, pos))
			{
				InventoryGuiAccess.DragAmount.Invoke(gui)--;
				gui.m_moveItemEffects.Create(((Component)gui).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
			}
			else
			{
				AltSplitOnePlugin.Log.LogWarning((object)"DropItem refused despite the check passing, the item stayed on the cursor.");
			}
			if (num && ((Humanoid)player).GetInventory().ContainsItem(val))
			{
				((Humanoid)player).EquipItem(val, false);
			}
			if (val.m_stack < InventoryGuiAccess.DragAmount.Invoke(gui))
			{
				InventoryGuiAccess.DragAmount.Invoke(gui) = val.m_stack;
			}
			if (InventoryGuiAccess.DragAmount.Invoke(gui) <= 0 || val.m_stack <= 0 || !val2.ContainsItem(val))
			{
				InventoryGuiAccess.SetIsSplitDropping(gui, arg2: false);
				InventoryGuiAccess.SetupDragItem(gui, null, null, 1);
			}
			InventoryGuiAccess.UpdateCraftingPanel(gui, arg2: false);
		}
	}
	[BepInPlugin("org.vibeodrone.altsplitone", "AltSplitOne", "1.0.0")]
	public class AltSplitOnePlugin : BaseUnityPlugin
	{
		public const string PluginGuid = "org.vibeodrone.altsplitone";

		public const string PluginName = "AltSplitOne";

		public const string PluginVersion = "1.0.0";

		public const string BoostyUrl = "https://boosty.to/vibeodrone";

		internal static ManualLogSource Log;

		internal static ConfigEntry<KeyCode> ModifierPrimary;

		internal static ConfigEntry<KeyCode> ModifierSecondary;

		private Harmony _harmony;

		private void Awake()
		{
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			((BaseUnityPlugin)this).Config.Bind<string>("Support", "Boosty", "https://boosty.to/vibeodrone", "Follow Vibe O'Drone on Boosty.");
			ModifierPrimary = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Keys", "ModifierPrimary", (KeyCode)308, "Primary modifier key.");
			ModifierSecondary = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Keys", "ModifierSecondary", (KeyCode)307, "Secondary modifier key. KeyCode.None to disable.");
			if (!InventoryGuiAccess.TryBind(out var error))
			{
				Log.LogError((object)("Failed to bind to private members of InventoryGui, mod disabled. " + error));
				return;
			}
			_harmony = new Harmony("org.vibeodrone.altsplitone");
			_harmony.PatchAll(typeof(OnSelectedItemPatch));
			Log.LogInfo((object)"AltSplitOne 1.0.0 loaded.");
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		internal static bool ModifierHeld()
		{
			//IL_0005: 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_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if ((int)ModifierPrimary.Value != 0 && ZInput.GetKey(ModifierPrimary.Value, false))
			{
				return true;
			}
			if ((int)ModifierSecondary.Value != 0)
			{
				return ZInput.GetKey(ModifierSecondary.Value, false);
			}
			return false;
		}
	}
}