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;
}
}
}