Decompiled source of PlayerInventoryStacks v1.0.2

plugins\PlayerInventoryStacks\PlayerInventoryStacks.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using SpaceCraft;
using TMPro;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("PlayerInventoryStacks")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2+45e5172ad6e1b8825bacc8ef96eea6630edaa594")]
[assembly: AssemblyProduct("PlayerInventoryStacks")]
[assembly: AssemblyTitle("PlayerInventoryStacks")]
[assembly: AssemblyVersion("1.0.2.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 PlayerInventoryStacks
{
	internal static class Backpacks
	{
		private static readonly HashSet<int> Ids = new HashSet<int>();

		[ThreadStatic]
		private static Dictionary<StackKey, int> usageCounts;

		internal static void Clear()
		{
			Ids.Clear();
			usageCounts?.Clear();
		}

		internal static void Register(int id)
		{
			if (id > 0)
			{
				Ids.Add(id);
			}
		}

		internal static bool IsPlayer(Inventory inventory)
		{
			if (inventory != null)
			{
				return Ids.Contains(inventory.GetId());
			}
			return false;
		}

		internal static StackKey Key(WorldObject item)
		{
			return new StackKey(item);
		}

		internal static List<StackLayout.Stack<WorldObject>> Layout(Inventory inventory)
		{
			return StackLayout.Create(inventory.GetInsideWorldObjects(), Key);
		}

		internal static bool IsFull(Inventory inventory)
		{
			int candidateCount;
			return CountUsage(inventory, default(StackKey), findCandidate: false, out candidateCount) >= inventory.GetSize();
		}

		internal static bool FullFor(Inventory inventory, WorldObject item)
		{
			if (!IsPlayer(inventory))
			{
				return inventory.IsFull();
			}
			if (item == null)
			{
				return IsFull(inventory);
			}
			if (inventory.ContainWorldObject(item))
			{
				return false;
			}
			StackKey candidate = new StackKey(item);
			int candidateCount;
			int num = CountUsage(inventory, candidate, findCandidate: true, out candidateCount);
			if (num <= inventory.GetSize())
			{
				if (candidateCount % 64 == 0)
				{
					return num >= inventory.GetSize();
				}
				return false;
			}
			return true;
		}

		internal static bool FullForGroup(Inventory inventory, Group group)
		{
			if (!IsPlayer(inventory))
			{
				return inventory.IsFull();
			}
			StackKey candidate = new StackKey(group);
			int candidateCount;
			int num = CountUsage(inventory, candidate, findCandidate: true, out candidateCount);
			if (num <= inventory.GetSize())
			{
				if (candidateCount % 64 == 0)
				{
					return num >= inventory.GetSize();
				}
				return false;
			}
			return true;
		}

		private static int CountUsage(Inventory inventory, StackKey candidate, bool findCandidate, out int candidateCount)
		{
			Dictionary<StackKey, int> dictionary = usageCounts ?? (usageCounts = new Dictionary<StackKey, int>(64));
			dictionary.Clear();
			int num = 0;
			candidateCount = 0;
			try
			{
				foreach (WorldObject insideWorldObject in inventory.GetInsideWorldObjects())
				{
					StackKey key = new StackKey(insideWorldObject);
					dictionary.TryGetValue(key, out var value);
					if (value % 64 == 0)
					{
						num++;
					}
					value = (dictionary[key] = value + 1);
					if (findCandidate && key.Equals(candidate))
					{
						candidateCount = value;
					}
				}
				return num;
			}
			finally
			{
				dictionary.Clear();
			}
		}

		internal static bool FitsCraft(Inventory inventory, List<Group> ingredients, Group output, bool freeCraft)
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			List<WorldObject> list = inventory.GetInsideWorldObjects().ToList();
			if (!freeCraft)
			{
				foreach (Group group in ingredients)
				{
					int num = list.FindLastIndex((WorldObject item) => item.GetGroup() == group);
					if (num >= 0)
					{
						list.RemoveAt(num);
					}
				}
			}
			return StackLayout.CanAdd(list, new WorldObject(0, output), inventory.GetSize(), Key);
		}
	}
	internal readonly struct StackKey : IEquatable<StackKey>
	{
		private static readonly FieldRef<WorldObject, float> LockTime = AccessTools.FieldRefAccess<WorldObject, float>("_lockInInventoryTime");

		private readonly bool unique;

		private readonly int uniqueId;

		private readonly string groupId;

		private readonly string text;

		private readonly int setting;

		private readonly GeneticTraitType geneticType;

		private readonly int geneticValue;

		private readonly Color color;

		private readonly float energy;

		private readonly float growth;

		private readonly float hunger;

		private readonly float petTime;

		private readonly Vector2Int count;

		private readonly int planetLinkedHash;

		private readonly List<Group> linkedGroups;

		private readonly List<int> panels;

		private readonly int hashCode;

		internal StackKey(WorldObject item)
		{
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: 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_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			hashCode = 0;
			if (item == null)
			{
				throw new ArgumentNullException("item");
			}
			int num;
			if (item.GetLinkedInventoryId() == 0)
			{
				List<int> secondaryInventoriesId = item.GetSecondaryInventoriesId();
				if ((secondaryInventoriesId == null || secondaryInventoriesId.Count <= 0) && item.GetLinkedWorldObject() == 0)
				{
					num = ((LockTime.Invoke(item) != 0f) ? 1 : 0);
					goto IL_0056;
				}
			}
			num = 1;
			goto IL_0056;
			IL_0056:
			unique = (byte)num != 0;
			uniqueId = (unique ? item.GetId() : 0);
			Group obj = item.GetGroup();
			groupId = ((obj != null) ? obj.GetId() : null) ?? string.Empty;
			text = item.GetText() ?? string.Empty;
			setting = item.GetSetting();
			geneticType = item.GetGeneticTraitType();
			geneticValue = item.GetGeneticTraitValue();
			color = item.GetColor();
			energy = item.GetEnergy();
			growth = item.GetGrowth();
			hunger = item.GetHunger();
			petTime = item.GetPetTime();
			count = item.GetCount();
			planetLinkedHash = item.GetPlanetLinkedHash();
			linkedGroups = item.GetLinkedGroups();
			panels = item.GetPanelsId();
			hashCode = ComputeHash();
		}

		internal StackKey(Group group)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: 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)
			hashCode = 0;
			unique = false;
			uniqueId = 0;
			groupId = ((group != null) ? group.GetId() : null) ?? string.Empty;
			text = string.Empty;
			setting = 0;
			geneticType = (GeneticTraitType)0;
			geneticValue = 0;
			color = default(Color);
			energy = 1f;
			growth = 0f;
			hunger = 0f;
			petTime = 0f;
			count = default(Vector2Int);
			planetLinkedHash = 0;
			linkedGroups = null;
			panels = null;
			hashCode = ComputeHash();
		}

		public bool Equals(StackKey other)
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: 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_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			if (unique || other.unique)
			{
				if (unique && other.unique)
				{
					return uniqueId == other.uniqueId;
				}
				return false;
			}
			if (StringComparer.Ordinal.Equals(groupId, other.groupId) && StringComparer.Ordinal.Equals(text, other.text) && setting == other.setting && geneticType == other.geneticType && geneticValue == other.geneticValue && color.r.Equals(other.color.r) && color.g.Equals(other.color.g) && color.b.Equals(other.color.b) && color.a.Equals(other.color.a) && energy.Equals(other.energy) && growth.Equals(other.growth) && hunger.Equals(other.hunger) && petTime.Equals(other.petTime) && ((Vector2Int)(ref count)).Equals(other.count) && planetLinkedHash == other.planetLinkedHash && GroupsEqual(linkedGroups, other.linkedGroups))
			{
				return ListsEqual(panels, other.panels);
			}
			return false;
		}

		public override bool Equals(object obj)
		{
			if (obj is StackKey other)
			{
				return Equals(other);
			}
			return false;
		}

		public override int GetHashCode()
		{
			return hashCode;
		}

		private int ComputeHash()
		{
			//IL_004f: 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_0056: Expected I4, but got Unknown
			if (unique)
			{
				return uniqueId;
			}
			int num = 17;
			num = num * 31 + StringComparer.Ordinal.GetHashCode(groupId);
			num = num * 31 + StringComparer.Ordinal.GetHashCode(text);
			num = num * 31 + setting;
			num = num * 31 + geneticType;
			num = num * 31 + geneticValue;
			num = num * 31 + color.r.GetHashCode();
			num = num * 31 + color.g.GetHashCode();
			num = num * 31 + color.b.GetHashCode();
			num = num * 31 + color.a.GetHashCode();
			num = num * 31 + energy.GetHashCode();
			num = num * 31 + growth.GetHashCode();
			num = num * 31 + hunger.GetHashCode();
			num = num * 31 + petTime.GetHashCode();
			num = num * 31 + ((object)Unsafe.As<Vector2Int, Vector2Int>(ref count)/*cast due to .constrained prefix*/).GetHashCode();
			num = num * 31 + planetLinkedHash;
			if (linkedGroups != null)
			{
				foreach (Group linkedGroup in linkedGroups)
				{
					num = num * 31 + StringComparer.Ordinal.GetHashCode(((linkedGroup != null) ? linkedGroup.GetId() : null) ?? string.Empty);
				}
			}
			if (panels != null)
			{
				foreach (int panel in panels)
				{
					num = num * 31 + panel;
				}
			}
			return num;
		}

		private static bool GroupsEqual(List<Group> left, List<Group> right)
		{
			int num = left?.Count ?? 0;
			if (num != (right?.Count ?? 0))
			{
				return false;
			}
			for (int i = 0; i < num; i++)
			{
				StringComparer ordinal = StringComparer.Ordinal;
				Group obj = left[i];
				string x = ((obj != null) ? obj.GetId() : null);
				Group obj2 = right[i];
				if (!ordinal.Equals(x, (obj2 != null) ? obj2.GetId() : null))
				{
					return false;
				}
			}
			return true;
		}

		private static bool ListsEqual(List<int> left, List<int> right)
		{
			int num = left?.Count ?? 0;
			if (num != (right?.Count ?? 0))
			{
				return false;
			}
			for (int i = 0; i < num; i++)
			{
				if (left[i] != right[i])
				{
					return false;
				}
			}
			return true;
		}
	}
	[BepInPlugin("local.planetcrafter.playerinventorystacks", "Player Inventory Stacks", "1.0.2")]
	[BepInProcess("Planet Crafter.exe")]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string Id = "local.planetcrafter.playerinventorystacks";

		private Harmony harmony;

		private void Awake()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			harmony = new Harmony("local.planetcrafter.playerinventorystacks");
			try
			{
				harmony.PatchAll(typeof(Plugin).Assembly);
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Player Inventory Stacks 1.0.2 loaded: 64 items per backpack stack; containers unchanged.");
			}
			catch (Exception ex)
			{
				harmony.UnpatchSelf();
				((BaseUnityPlugin)this).Logger.LogError((object)("Player Inventory Stacks could not patch this game version; all its patches were removed. " + ex));
			}
		}

		private void OnDestroy()
		{
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}
	}
	[HarmonyPatch(typeof(InventoriesHandler), "OnNetworkSpawn")]
	internal static class ResetWorld
	{
		private static void Prefix()
		{
			Backpacks.Clear();
		}
	}
	[HarmonyPatch(typeof(PlayerBackpack), "SetInventory")]
	internal static class RegisterBackpack
	{
		private static void Prefix(Inventory _playerInventory)
		{
			if (_playerInventory != null)
			{
				Backpacks.Register(_playerInventory.GetId());
			}
		}
	}
	[HarmonyPatch(typeof(PlayerMainController), "InitPlayerClientRpc")]
	internal static class RegisterClientBackpack
	{
		private static void Prefix(int inventoryId)
		{
			Backpacks.Register(inventoryId);
		}
	}
	[HarmonyPatch(typeof(SavedDataHandler), "LoadSavedData")]
	internal static class RegisterSavedBackpacks
	{
		private static void Postfix(SavedDataHandler __instance)
		{
			List<JsonablePlayerState> lastLoadedPlayerData = __instance.GetLastLoadedPlayerData();
			if (lastLoadedPlayerData == null)
			{
				return;
			}
			foreach (JsonablePlayerState item in lastLoadedPlayerData)
			{
				Backpacks.Register(item.inventoryId);
			}
		}
	}
	[HarmonyPatch(typeof(Inventory), "IsFull")]
	internal static class InventoryFull
	{
		private static bool Prefix(Inventory __instance, ref bool __result)
		{
			if (!Backpacks.IsPlayer(__instance))
			{
				return true;
			}
			__result = Backpacks.IsFull(__instance);
			return false;
		}
	}
	[HarmonyPatch(typeof(Inventory), "AddItemInInventory")]
	internal static class AddItemCapacity
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			return PatchTools.ReplaceFull(instructions, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Ldarg_1, (object)null)
			}, "FullFor");
		}
	}
	[HarmonyPatch(typeof(Inventory), "DropObjectsIfNotEnoughSpace")]
	internal static class BackpackShrink
	{
		private static bool Prefix(Inventory __instance, Vector3 dropPosition, bool removeOnly, ref List<WorldObject> __result)
		{
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			if (!Backpacks.IsPlayer(__instance))
			{
				return true;
			}
			List<WorldObject> list = Backpacks.Layout(__instance).Skip(Math.Max(0, __instance.GetSize())).SelectMany((StackLayout.Stack<WorldObject> s) => s.Items)
				.ToList();
			foreach (WorldObject item in list)
			{
				if (!removeOnly)
				{
					WorldObjectsHandler.Instance.DropOnFloor(item, dropPosition, 0f, true, false, 0);
				}
				__instance.RemoveItem(item);
			}
			__result = list;
			return false;
		}
	}
	[HarmonyPatch(typeof(InventoryDisplayer), "SetInventoryBlocks")]
	internal static class DisplayStacks
	{
		private static void Prefix(Inventory ____inventory, ref ReadOnlyCollection<WorldObject> inventoryWorldObjects, out List<StackLayout.Stack<WorldObject>> __state)
		{
			__state = null;
			if (!Backpacks.IsPlayer(____inventory))
			{
				return;
			}
			__state = Backpacks.Layout(____inventory);
			List<WorldObject> list = new List<WorldObject>(__state.Count);
			foreach (StackLayout.Stack<WorldObject> item in __state)
			{
				list.Add(item.Items[0]);
			}
			inventoryWorldObjects = list.AsReadOnly();
		}

		private static void Postfix(Inventory ____inventory, GridLayoutGroup ____grid, List<StackLayout.Stack<WorldObject>> __state)
		{
			//IL_0074: 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_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: 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_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: 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_013f: Unknown result type (might be due to invalid IL or missing references)
			if (__state == null)
			{
				return;
			}
			InventoryBlock[] componentsInChildren = ((Component)____grid).GetComponentsInChildren<InventoryBlock>();
			int num = Math.Max(0, componentsInChildren.Length - ____inventory.GetSize());
			int num2 = Math.Min(componentsInChildren.Length - num, __state.Count);
			for (int i = 0; i < num2; i++)
			{
				int count = __state[i].Items.Count;
				if (count > 1)
				{
					GameObject val = new GameObject("PlayerStackCount", new Type[2]
					{
						typeof(RectTransform),
						typeof(TextMeshProUGUI)
					});
					val.transform.SetParent(((Component)componentsInChildren[num + i]).transform, false);
					RectTransform val2 = (RectTransform)val.transform;
					val2.anchorMin = Vector2.zero;
					val2.anchorMax = Vector2.one;
					val2.offsetMin = new Vector2(3f, 3f);
					val2.offsetMax = new Vector2(-5f, -3f);
					TextMeshProUGUI component = val.GetComponent<TextMeshProUGUI>();
					((TMP_Text)component).font = TMP_Settings.defaultFontAsset;
					((TMP_Text)component).text = count.ToString();
					((TMP_Text)component).fontSize = 22f;
					((TMP_Text)component).fontStyle = (FontStyles)1;
					((Graphic)component).color = Color.white;
					((TMP_Text)component).alignment = (TextAlignmentOptions)1028;
					((Graphic)component).raycastTarget = false;
					((TMP_Text)component).textWrappingMode = (TextWrappingModes)0;
					((TMP_Text)component).outlineWidth = 0.22f;
					((TMP_Text)component).outlineColor = new Color32((byte)0, (byte)0, (byte)0, byte.MaxValue);
				}
			}
		}
	}
	internal static class PatchTools
	{
		internal static readonly MethodInfo IsFull = AccessTools.Method(typeof(Inventory), "IsFull", (Type[])null, (Type[])null);

		internal static IEnumerable<CodeInstruction> ReplaceFull(IEnumerable<CodeInstruction> source, IEnumerable<CodeInstruction> loadCandidate, string helper, int expected = 1)
		{
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>();
			int num = 0;
			foreach (CodeInstruction item in source)
			{
				if (CodeInstructionExtensions.Calls(item, IsFull))
				{
					List<CodeInstruction> list2 = loadCandidate.Select((Func<CodeInstruction, CodeInstruction>)((CodeInstruction c) => new CodeInstruction(c))).ToList();
					list2[0].labels.AddRange(item.labels);
					list2[0].blocks.AddRange(item.blocks);
					list.AddRange(list2);
					list.Add(new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(Backpacks), helper, (Type[])null, (Type[])null)));
					num++;
				}
				else
				{
					list.Add(item);
				}
			}
			if (num != expected)
			{
				throw new InvalidOperationException($"Expected {expected} capacity checks, found {num}.");
			}
			return list;
		}

		internal static WorldObject ActionItem(Component component)
		{
			WorldObjectAssociated componentInParent = component.GetComponentInParent<WorldObjectAssociated>();
			if (componentInParent == null)
			{
				return null;
			}
			return componentInParent.GetWorldObject();
		}

		internal static IEnumerable<CodeInstruction> ActionCapacity(IEnumerable<CodeInstruction> source, FieldInfo owner = null)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Expected O, but got Unknown
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>
			{
				new CodeInstruction(OpCodes.Ldarg_0, (object)null)
			};
			if (owner != null)
			{
				list.Add(new CodeInstruction(OpCodes.Ldfld, (object)owner));
			}
			list.Add(new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(PatchTools), "ActionItem", (Type[])null, (Type[])null)));
			return ReplaceFull(source, list, "FullFor");
		}
	}
	[HarmonyPatch(typeof(ActionMinable), "OnAction")]
	internal static class StartMiningCapacity
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			return PatchTools.ActionCapacity(instructions);
		}
	}
	[HarmonyPatch]
	internal static class FinishMiningCapacity
	{
		private static MethodBase TargetMethod()
		{
			return AccessTools.EnumeratorMoveNext((MethodBase)AccessTools.Method(typeof(ActionMinable), "FinishMining", (Type[])null, (Type[])null));
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, MethodBase original)
		{
			return PatchTools.ActionCapacity(instructions, AccessTools.Field(original.DeclaringType, "<>4__this"));
		}
	}
	[HarmonyPatch(typeof(ActionGrabable), "OnAction")]
	internal static class GrabCapacity
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			return PatchTools.ActionCapacity(instructions);
		}
	}
	[HarmonyPatch(typeof(CraftManager), "TryToCraftInInventory")]
	internal static class CraftCapacity
	{
		private static bool Prefix(PlayerMainController playerController, GroupItem groupItem, ref bool __result)
		{
			Inventory inventory = playerController.GetPlayerBackpack().GetInventory();
			if (!Backpacks.IsPlayer(inventory))
			{
				return true;
			}
			bool freeCraft = Managers.GetManager<GameSettingsHandler>().GetCurrentGameSettings().GetFreeCraft();
			if (Backpacks.FitsCraft(inventory, ((Group)groupItem).GetRecipe().GetIngredientsGroupInRecipe(), (Group)(object)groupItem, freeCraft))
			{
				return true;
			}
			Managers.GetManager<BaseHudHandler>().DisplayCursorText("UI_InventoryFull", 2f, "", "", false);
			__result = false;
			return false;
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			return PatchTools.ReplaceFull(instructions, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Ldarg_2, (object)null)
			}, "FullForGroup", 2);
		}
	}
	[HarmonyPatch(typeof(WorldObjectsHandler), "RetrieveResourcesFromDeconstructionServerRpc")]
	internal static class DeconstructionCapacity
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected O, but got Unknown
			List<CodeInstruction> list = instructions.ToList();
			int num = list.FindIndex((CodeInstruction c) => CodeInstructionExtensions.Calls(c, PatchTools.IsFull));
			int num2 = ((num < 0) ? (-1) : list.FindLastIndex(num, (CodeInstruction c) => CodeInstructionExtensions.Calls(c, AccessTools.Method(typeof(WorldObject), "GetGroup", (Type[])null, (Type[])null))));
			if (num2 <= 0 || !CodeInstructionExtensions.IsLdloc(list[num2 - 1], (LocalBuilder)null))
			{
				throw new InvalidOperationException("Could not identify deconstruction resource local.");
			}
			return PatchTools.ReplaceFull(list, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[1]
			{
				new CodeInstruction(list[num2 - 1].opcode, list[num2 - 1].operand)
			}, "FullFor");
		}
	}
	[HarmonyPatch(typeof(ActionPanelDeconstruct), "Deconstruct")]
	internal static class PanelCapacity
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, MethodBase original)
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Expected O, but got Unknown
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Expected O, but got Unknown
			var list = (from local in original.GetMethodBody().LocalVariables
				select new
				{
					local = local,
					field = local.LocalType.GetField("group", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
				} into pair
				where pair.field?.FieldType == typeof(Group)
				select pair).ToList();
			if (list.Count != 1)
			{
				throw new InvalidOperationException("Could not identify panel ingredient local.");
			}
			var anon = list[0];
			return PatchTools.ReplaceFull(instructions, (IEnumerable<CodeInstruction>)(object)new CodeInstruction[2]
			{
				new CodeInstruction(OpCodes.Ldloc, (object)anon.local.LocalIndex),
				new CodeInstruction(OpCodes.Ldfld, (object)anon.field)
			}, "FullForGroup");
		}
	}
	[HarmonyPatch(typeof(InventoriesHandler), "AnInventoryHasBeenClicked")]
	internal static class QuickTransferKey
	{
		internal static bool IsPressed(PlayerInputDispatcher input, Inventory source)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			if (input.IsPressingAccessibilityKey())
			{
				return true;
			}
			if (Keyboard.current == null || !Keyboard.current.shiftKey.isPressed)
			{
				return false;
			}
			WindowsHandler manager = Managers.GetManager<WindowsHandler>();
			UiWindow windowViaUiId = manager.GetWindowViaUiId(manager.GetOpenedUi());
			UiWindowContainer val = (UiWindowContainer)(object)((windowViaUiId is UiWindowContainer) ? windowViaUiId : null);
			if ((Object)(object)val != (Object)null)
			{
				if (!Backpacks.IsPlayer(source))
				{
					return Backpacks.IsPlayer(val.GetOtherInventory(source));
				}
				return true;
			}
			return false;
		}

		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Expected O, but got Unknown
			List<CodeInstruction> list = new List<CodeInstruction>();
			int num = 0;
			MethodInfo methodInfo = AccessTools.Method(typeof(PlayerInputDispatcher), "IsPressingAccessibilityKey", (Type[])null, (Type[])null);
			foreach (CodeInstruction instruction in instructions)
			{
				if (CodeInstructionExtensions.Calls(instruction, methodInfo))
				{
					CodeInstruction val = new CodeInstruction(OpCodes.Ldarg_1, (object)null);
					val.labels.AddRange(instruction.labels);
					val.blocks.AddRange(instruction.blocks);
					list.Add(val);
					list.Add(new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(QuickTransferKey), "IsPressed", (Type[])null, (Type[])null)));
					num++;
				}
				else
				{
					list.Add(instruction);
				}
			}
			if (num != 1)
			{
				throw new InvalidOperationException("Could not identify inventory quick-transfer key check.");
			}
			return list;
		}
	}
	internal static class StackLayout
	{
		internal sealed class Stack<T>
		{
			internal readonly List<T> Items = new List<T>();
		}

		internal const int Limit = 64;

		internal static List<Stack<T>> Create<T, TKey>(IEnumerable<T> items, Func<T, TKey> key, IEqualityComparer<TKey> comparer = null)
		{
			List<Stack<T>> list = new List<Stack<T>>();
			Dictionary<TKey, Stack<T>> dictionary = new Dictionary<TKey, Stack<T>>(comparer ?? EqualityComparer<TKey>.Default);
			foreach (T item in items)
			{
				TKey key2 = key(item);
				if (!dictionary.TryGetValue(key2, out var value) || value.Items.Count == 64)
				{
					value = (dictionary[key2] = new Stack<T>());
					list.Add(value);
				}
				value.Items.Add(item);
			}
			return list;
		}

		internal static bool CanAdd<T, TKey>(IEnumerable<T> items, T candidate, int slots, Func<T, TKey> key, IEqualityComparer<TKey> comparer = null)
		{
			Dictionary<TKey, int> dictionary = new Dictionary<TKey, int>(comparer ?? EqualityComparer<TKey>.Default);
			int num = 0;
			foreach (T item in items)
			{
				TKey key2 = key(item);
				dictionary.TryGetValue(key2, out var value);
				if (value % 64 == 0)
				{
					num++;
				}
				dictionary[key2] = value + 1;
			}
			TKey key3 = key(candidate);
			if (num > slots)
			{
				return false;
			}
			if (!dictionary.TryGetValue(key3, out var value2) || value2 % 64 == 0)
			{
				return num < slots;
			}
			return true;
		}
	}
}