Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of SwmarlyValheimQOL v1.0.8
SwmarlyValheimQOL.dll
Decompiled 15 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; 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 Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [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: IgnoresAccessChecksTo("assembly_guiutils")] [assembly: IgnoresAccessChecksTo("assembly_utils")] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: AssemblyCompany("SwmarlyValheimQOL")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.8.0")] [assembly: AssemblyInformationalVersion("1.0.8+295b56949d0ef86aa187bfab75c0057865cbc0d9")] [assembly: AssemblyProduct("SwmarlyValheimQOL")] [assembly: AssemblyTitle("SwmarlyValheimQOL")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.8.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 SwmarlyValheimQOL { public class ContainerExtend : MonoBehaviour { private static readonly ConditionalWeakTable<Inventory, ContainerInventoryOwner> Containers = new ConditionalWeakTable<Inventory, ContainerInventoryOwner>(); private Container container; private Inventory inventory; private float nextRegistrationAttempt; private void Awake() { if (((Component)this).TryGetComponent<Container>(ref container)) { TryRegister(); nextRegistrationAttempt = Time.unscaledTime + 0.25f; } } private void Update() { if (Object.op_Implicit((Object)(object)container) && (inventory == null || !Containers.TryGetValue(inventory, out var value) || value == null || !((Object)(object)value.Container == (Object)(object)container)) && !(Time.unscaledTime < nextRegistrationAttempt)) { nextRegistrationAttempt = Time.unscaledTime + 0.25f; TryRegister(); } } private bool TryRegister() { if (!Object.op_Implicit((Object)(object)container)) { return false; } Inventory val = container.GetInventory(); if (val == null) { return false; } if (inventory != null && inventory != val) { Containers.Remove(inventory); } inventory = val; if (Containers.TryGetValue(val, out var value)) { if (value != null && (Object)(object)value.Container == (Object)(object)container) { return true; } Containers.Remove(val); } Containers.Add(val, new ContainerInventoryOwner(container)); return true; } private void OnDestroy() { if (inventory != null) { Containers.Remove(inventory); inventory = null; } } internal static bool EnsureRegistered(Container container) { if (!Object.op_Implicit((Object)(object)container)) { return false; } ContainerExtend component = ((Component)container).GetComponent<ContainerExtend>(); if ((Object)(object)component != (Object)null) { return component.TryRegister(); } return false; } public static bool GetContainer(Inventory inventory, out ContainerInventoryOwner container) { if (inventory == null) { container = null; return false; } return Containers.TryGetValue(inventory, out container); } } public static class ContainerHandler { public static RequestChestAdd AddItemToChest(this Container container, ItemData item, Inventory sourceInventory, Vector2i to, ZDOID sender, int dragAmount = -1) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0038: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)container) || !Object.op_Implicit((Object)(object)container.m_nview) || !container.m_nview.HasOwner()) { return new RequestChestAdd(Vector2i.zero, 0, null, null, null); } dragAmount = PossibleDragAmount(container.GetInventory(), item, to, dragAmount); ItemData itemAt = container.GetInventory().GetItemAt(to.x, to.y); bool flag = itemAt != null && dragAmount != item.m_stack && !InventoryHelper.CanStack(itemAt, item); if (dragAmount <= 0 || flag || !sourceInventory.ContainsItem(item)) { return new RequestChestAdd(Vector2i.zero, 0, null, null, null); } RequestChestAdd requestChestAdd = new RequestChestAdd(to, dragAmount, item, sourceInventory, container.GetInventory()); InventoryBlock.Get(sourceInventory).BlockSlot(item.m_gridPos); InventoryPreview.AddPackage(requestChestAdd); sourceInventory.RemoveItem(item, dragAmount); if (container.m_nview.IsOwner()) { RequestChestAddResponse response = container.GetInventory().RequestItemAdd(requestChestAdd); InventoryHandler.RPC_RequestItemAddResponse(sourceInventory, response); return null; } GamePatches.InvokeRPC(container.m_nview, "MUC_RequestItemAdd", requestChestAdd); return requestChestAdd; } internal static int PossibleDragAmount(Inventory inventoryTo, ItemData dragItem, Vector2i to, int dragAmount) { //IL_001c: 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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) dragAmount = ((dragAmount >= 0) ? Mathf.Min(dragAmount, dragItem.m_stack) : dragItem.m_stack); if (to.x >= 0 && to.y >= 0) { ItemData itemAt = inventoryTo.GetItemAt(to.x, to.y); if (itemAt != null && dragAmount < dragItem.m_stack) { if (InventoryHelper.CanStack(itemAt, dragItem)) { return Mathf.Min(dragAmount, itemAt.m_shared.m_maxStackSize - itemAt.m_stack); } return 0; } } else if (!inventoryTo.HaveEmptySlot()) { int num = inventoryTo.FindFreeStackSpace(dragItem.m_shared.m_name, (float)dragItem.m_worldLevel); return Mathf.Min(dragAmount, num); } return dragAmount; } public static RequestChestRemove RemoveItemFromChest(this Container container, ItemData item, Inventory destinationInventory, Vector2i to, ZDOID sender, int dragAmount = -1, ItemData switchItem = null) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0052: 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) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)container) || !Object.op_Implicit((Object)(object)container.m_nview) || !container.m_nview.HasOwner()) { return new RequestChestRemove(Vector2i.zero, Vector2i.zero, 0, null, container.GetInventory(), destinationInventory); } dragAmount = PossibleDragAmount(destinationInventory, item, to, dragAmount); if (dragAmount <= 0 || InventoryBlock.Get(destinationInventory).IsSlotBlocked(to)) { return new RequestChestRemove(Vector2i.zero, Vector2i.zero, 0, null, container.GetInventory(), destinationInventory); } RequestChestRemove requestChestRemove = new RequestChestRemove(item.m_gridPos, to, dragAmount, switchItem, container.GetInventory(), destinationInventory); if (switchItem != null && !InventoryHelper.CanStack(item, switchItem)) { if (dragAmount != item.m_stack) { return new RequestChestRemove(Vector2i.zero, Vector2i.zero, 0, null, container.GetInventory(), destinationInventory); } destinationInventory.RemoveItem(switchItem); } InventoryBlock.Get(destinationInventory).BlockSlot(requestChestRemove.toPos); InventoryPreview.AddPackage(requestChestRemove); if (container.m_nview.IsOwner()) { RequestChestRemoveResponse response = container.GetInventory().RequestItemRemove(requestChestRemove); InventoryHandler.RPC_RequestItemRemoveResponse(destinationInventory, response); return null; } GamePatches.InvokeRPC(container.m_nview, "MUC_RequestItemRemove", requestChestRemove); return requestChestRemove; } public static void MoveItemInChest(this Container container, ItemData item, Vector2i toPos, int dragAmount) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) RequestMove package = new RequestMove(item, toPos, dragAmount, container.GetInventory()); InventoryPreview.AddPackage(package); GamePatches.InvokeRPC(container.m_nview, "MUC_RequestItemMove", package); } } public static class ContainerRPCHandler { public static void RPC_RequestItemAdd(long sender, ZDOID containerId, ZPackage package) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) HandleRPC(containerId, sender, "MUC_RequestItemAddResponse", RequestItemAdd, new RequestChestAdd(package)); } public static void RPC_RequestItemRemove(long sender, ZDOID containerId, ZPackage package) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) HandleRPC(containerId, sender, "MUC_RequestItemRemoveResponse", RequestItemRemove, new RequestChestRemove(package)); } public static void RPC_RequestItemConsume(long sender, ZDOID containerId, ZPackage package) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) HandleRPC(containerId, sender, "MUC_RequestItemConsumeResponse", RequestItemConsume, new RequestConsume(package)); } public static void RPC_RequestItemMove(long sender, ZDOID containerId, ZPackage package) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) HandleRPC(containerId, sender, "MUC_RequestItemMoveResponse", RequestItemMove, new RequestMove(package)); } public static void RPC_RequestDrop(long sender, ZDOID containerId, ZPackage package) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) HandleRPC(containerId, sender, "MUC_RequestItemDropResponse", RequestDrop, new RequestDrop(package)); } private static void HandleRPC<TResponse, TInput>(ZDOID containerId, long target, string rpcInvoke, Func<Inventory, TInput, TResponse> message, TInput input) where TResponse : IResponse, new() where TInput : IPackage { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) ZDO zDO = ZDOMan.instance.GetZDO(containerId); ZNetView val = ((zDO != null) ? ZNetScene.instance.FindInstance(zDO) : null); TResponse val2; if (!Object.op_Implicit((Object)(object)val) || !val.IsOwner()) { val2 = FallbackResponse<TResponse>(input as IRequest); } else { Container componentInChildren = ((Component)val).GetComponentInChildren<Container>(); if (Object.op_Implicit((Object)(object)componentInChildren)) { val2 = message(componentInChildren.GetInventory(), input); } else { Log.LogWarning(input.GetType().Name + ": not handling RPC, Container component not found on " + ((Object)val).name); val2 = FallbackResponse<TResponse>(input as IRequest); } } ZRoutedRpc.instance.InvokeRoutedRPC(target, rpcInvoke, new object[2] { containerId, val2.WriteToPackage() }); } private static TResponse FallbackResponse<TResponse>(IRequest request) where TResponse : IResponse, new() { //IL_0058: 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) TResponse val = new TResponse { SourceID = (request?.RequestID ?? 0) }; if (request is RequestChestAdd requestChestAdd && val is RequestChestAddResponse requestChestAddResponse) { requestChestAddResponse.switchItem = requestChestAdd.dragItem; requestChestAddResponse.inventoryPos = requestChestAdd.dragItem?.m_gridPos ?? Vector2i.zero; } else if (request is RequestChestRemove requestChestRemove && val is RequestChestRemoveResponse requestChestRemoveResponse) { requestChestRemoveResponse.responseItem = requestChestRemove.switchItem; } return val; } public static RequestChestAddResponse RequestItemAdd(this Inventory inventory, RequestChestAdd request) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (request.dragItem == null) { return new RequestChestAddResponse(request.RequestID, success: false, Vector2i.zero, 0, request.dragItem); } if (request.toPos.x < 0 || request.toPos.y < 0) { return AddToAnySlot(inventory, request); } return AddToSlot(inventory, request); } private static RequestChestAddResponse AddToSlot(Inventory inventory, RequestChestAdd request) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0091: 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_007f: Unknown result type (might be due to invalid IL or missing references) if (!CanStack(inventory, request, out var stackSpace, out var removedItem)) { return new RequestChestAddResponse(request.RequestID, success: false, request.dragItem.m_gridPos, 0, request.dragItem); } bool flag = inventory.AddItemToInventory(request.dragItem, stackSpace, request.toPos); if (!flag) { stackSpace = 0; } if (!flag || stackSpace != request.dragItem.m_stack) { removedItem = request.dragItem; removedItem.m_stack = request.dragItem.m_stack - stackSpace; } if (removedItem != null) { removedItem.m_gridPos = request.dragItem.m_gridPos; } return new RequestChestAddResponse(request.RequestID, flag, request.dragItem.m_gridPos, stackSpace, removedItem); } private static bool CanStack(Inventory inventory, RequestChestAdd request, out int stackSpace, out ItemData removedItem) { ItemData itemAt = inventory.GetItemAt(request.toPos.x, request.toPos.y); removedItem = null; if (itemAt == null) { stackSpace = request.dragItem.m_stack; return true; } if (InventoryHelper.CanStack(itemAt, request.dragItem)) { stackSpace = Mathf.Min(itemAt.m_shared.m_maxStackSize - itemAt.m_stack, request.dragItem.m_stack); return true; } if (request.allowSwitch) { inventory.RemoveItem(itemAt, itemAt.m_stack); removedItem = itemAt; stackSpace = request.dragItem.m_stack; return true; } stackSpace = 0; return false; } private static RequestChestAddResponse AddToAnySlot(Inventory inventory, RequestChestAdd request) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Expected O, but got Unknown //IL_00c0: 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) Inventory val = new Inventory("tmp", (Sprite)null, 1, 1); val.AddItem(request.dragItem.Clone(), request.dragItem.m_stack, 0, 0, false); inventory.MoveItemToThis(val, val.GetItemAt(0, 0)); ItemData itemAt = val.GetItemAt(0, 0); if (itemAt == null) { return new RequestChestAddResponse(request.RequestID, success: true, request.dragItem.m_gridPos, request.dragItem.m_stack, null); } ItemData val2 = request.dragItem.Clone(); int num = request.dragItem.m_stack - itemAt.m_stack; val2.m_stack -= num; bool success = itemAt.m_stack != request.dragItem.m_stack; return new RequestChestAddResponse(request.RequestID, success, request.dragItem.m_gridPos, num, val2); } public static RequestChestRemoveResponse RequestItemRemove(this Inventory inventory, RequestChestRemove request) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) Vector2i fromPos = request.fromPos; int dragAmount = request.dragAmount; ItemData switchItem = request.switchItem; ItemData itemAt = inventory.GetItemAt(request.fromPos.x, request.fromPos.y); if (itemAt == null) { Log.LogDebug("from is null"); return new RequestChestRemoveResponse(request.RequestID, success: false, 0, hasSwitched: false, null); } int num = 0; bool flag = false; bool flag2 = false; if (switchItem == null) { num = Mathf.Min(itemAt.m_stack, dragAmount); flag = inventory.RemoveItem(itemAt, num); } else if (InventoryHelper.CanStack(itemAt, switchItem)) { num = Mathf.Min(switchItem.m_shared.m_maxStackSize - switchItem.m_stack, dragAmount); flag = inventory.RemoveItem(itemAt, num); } else { if (dragAmount < itemAt.m_stack) { return new RequestChestRemoveResponse(request.RequestID, success: false, 0, hasSwitched: false, request.switchItem); } flag = inventory.RemoveItem(itemAt, dragAmount); num = Mathf.Min(itemAt.m_stack, dragAmount); flag2 = inventory.AddItemToInventory(switchItem, switchItem.m_stack, fromPos); if (!flag2) { Log.LogWarning("Could not switch item in Remove Request"); InventoryHandler.DropItem(switchItem, switchItem.m_stack); } } ItemData val = itemAt.Clone(); val.m_stack = num; return new RequestChestRemoveResponse(request.RequestID, flag, num, flag2, val); } public static RequestConsumeResponse RequestItemConsume(this Inventory inventory, RequestConsume request) { ItemData itemAt = inventory.GetItemAt(request.itemPosX, request.itemPosY); if (itemAt == null || itemAt.m_stack <= 0) { return new RequestConsumeResponse(null, success: false, 0); } inventory.RemoveOneItem(itemAt); ItemData obj = itemAt.Clone(); obj.m_stack = 1; return new RequestConsumeResponse(obj, success: true, 1); } public static RequestMoveResponse RequestItemMove(this Inventory inventory, RequestMove request) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0008: 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_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: 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) Vector2i fromPos = request.fromPos; Vector2i toPos = request.toPos; int dragAmount = request.dragAmount; ItemData itemAt = inventory.GetItemAt(fromPos.x, fromPos.y); if (itemAt == null) { return new RequestMoveResponse(request.RequestID, success: false, 0); } if (StringExtensionMethods.GetStableHashCode(itemAt.PrefabName()) != request.itemHash) { return new RequestMoveResponse(request.RequestID, success: false, 0); } int movedAmount; bool success = InventoryHelper.MoveItem(inventory, itemAt, dragAmount, toPos, out movedAmount); return new RequestMoveResponse(request.RequestID, success, movedAmount); } public static RequestDropResponse RequestDrop(this Inventory inventory, RequestDrop request) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) ItemData itemAt = inventory.GetItemAt(request.targetContainerSlot.x, request.targetContainerSlot.y); if (itemAt == null) { return new RequestDropResponse(null, request.sender, success: false, 0); } int num = Mathf.Min(itemAt.m_stack, request.amount); inventory.RemoveItem(itemAt, num); if (num == 0) { return new RequestDropResponse(null, request.sender, success: false, 0); } ItemData obj = itemAt.Clone(); obj.m_stack = num; return new RequestDropResponse(obj, request.sender, success: true, num); } } public interface IPackage { ZPackage WriteToPackage(); } public interface IRequest : IPackage { int RequestID { get; set; } Inventory SourceInventory { get; } Inventory TargetInventory { get; } } public interface IResponse : IPackage { int SourceID { get; set; } bool Success { get; set; } int Amount { get; set; } } public class RequestChestAdd : IRequest, IPackage { public readonly Vector2i toPos; public readonly ItemData dragItem; public readonly bool allowSwitch; public int RequestID { get; set; } public Inventory SourceInventory { get; } public Inventory TargetInventory { get; } public RequestChestAdd(Vector2i toPos, int dragAmount, ItemData dragItem, Inventory sourceInventory, Inventory targetInventory) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) this.toPos = toPos; if (dragItem != null) { this.dragItem = dragItem.Clone(); this.dragItem.m_stack = Mathf.Min(dragAmount, this.dragItem.m_stack); allowSwitch = dragAmount == dragItem.m_stack; } SourceInventory = sourceInventory; TargetInventory = targetInventory; } public RequestChestAdd(ZPackage package) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) RequestID = package.ReadInt(); toPos = package.ReadVector2i(); dragItem = InventoryHelper.LoadItemFromPackage(package); allowSwitch = package.ReadBool(); } public ZPackage WriteToPackage() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_0014: Unknown result type (might be due to invalid IL or missing references) ZPackage val = new ZPackage(); val.Write(RequestID); val.Write(toPos); InventoryHelper.WriteItemToPackage(dragItem, val); val.Write(allowSwitch); return val; } } public class RequestChestAddResponse : IPackage, IResponse { public Vector2i inventoryPos; public ItemData switchItem; public int SourceID { get; set; } public bool Success { get; set; } public int Amount { get; set; } public RequestChestAddResponse(int sourceID, bool success, Vector2i inventoryPos, int amount, ItemData switchItem) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) SourceID = sourceID; Success = success; Amount = amount; this.inventoryPos = inventoryPos; this.switchItem = switchItem.ClampStackSize(); } public RequestChestAddResponse(ZPackage package) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) SourceID = package.ReadInt(); inventoryPos = package.ReadVector2i(); Success = package.ReadBool(); Amount = package.ReadInt(); switchItem = InventoryHelper.LoadItemFromPackage(package); } public RequestChestAddResponse() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) SourceID = 0; Success = false; inventoryPos = new Vector2i(-1, -1); Amount = 0; switchItem = null; } public ZPackage WriteToPackage() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_0014: Unknown result type (might be due to invalid IL or missing references) ZPackage val = new ZPackage(); val.Write(SourceID); val.Write(inventoryPos); val.Write(Success); val.Write(Amount); InventoryHelper.WriteItemToPackage(switchItem, val); return val; } } public class RequestChestRemove : IRequest, IPackage { public readonly Vector2i fromPos; public readonly Vector2i toPos; public readonly int dragAmount; public readonly ItemData switchItem; public readonly ItemData item; public int RequestID { get; set; } public Inventory SourceInventory { get; } public Inventory TargetInventory { get; } public RequestChestRemove(Vector2i fromPos, Vector2i toPos, int dragAmount, ItemData switchItem, Inventory sourceInventory, Inventory targetInventory) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: 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_004f: Unknown result type (might be due to invalid IL or missing references) this.fromPos = fromPos; this.toPos = toPos; this.dragAmount = dragAmount; this.switchItem = ((switchItem != null) ? switchItem.Clone() : null); SourceInventory = sourceInventory; TargetInventory = targetInventory; object obj; if (sourceInventory == null) { obj = null; } else { ItemData itemAt = sourceInventory.GetItemAt(fromPos.x, fromPos.y); obj = ((itemAt != null) ? itemAt.Clone() : null); } item = (ItemData)obj; } public RequestChestRemove(ZPackage package) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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) RequestID = package.ReadInt(); fromPos = package.ReadVector2i(); toPos = package.ReadVector2i(); dragAmount = package.ReadInt(); switchItem = InventoryHelper.LoadItemFromPackage(package); } public ZPackage WriteToPackage() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) ZPackage val = new ZPackage(); val.Write(RequestID); val.Write(fromPos); val.Write(toPos); val.Write(dragAmount); InventoryHelper.WriteItemToPackage(switchItem, val); return val; } } public class RequestChestRemoveResponse : IPackage, IResponse { public ItemData responseItem; public bool hasSwitched; public int SourceID { get; set; } public bool Success { get; set; } public int Amount { get; set; } public RequestChestRemoveResponse(int sourceID, bool success, int amount, bool hasSwitched, ItemData responseItem) { SourceID = sourceID; Success = success; Amount = amount; this.hasSwitched = hasSwitched; this.responseItem = responseItem.ClampStackSize(); } public RequestChestRemoveResponse(ZPackage package) { SourceID = package.ReadInt(); Success = package.ReadBool(); Amount = package.ReadInt(); hasSwitched = package.ReadBool(); responseItem = InventoryHelper.LoadItemFromPackage(package); } public RequestChestRemoveResponse() { Success = false; Amount = 0; hasSwitched = false; responseItem = null; } public ZPackage WriteToPackage() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(SourceID); val.Write(Success); val.Write(Amount); val.Write(hasSwitched); InventoryHelper.WriteItemToPackage(responseItem, val); return val; } } public class RequestConsume : IPackage { public readonly int itemPosX; public readonly int itemPosY; public RequestConsume(ItemData item) { itemPosX = item.m_gridPos.x; itemPosY = item.m_gridPos.y; } public RequestConsume(ZPackage package) { itemPosX = package.ReadInt(); itemPosY = package.ReadInt(); } public ZPackage WriteToPackage() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_001e: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(itemPosX); val.Write(itemPosY); return val; } } public class RequestConsumeResponse : IPackage, IResponse { public readonly ItemData item; public int SourceID { get; set; } public bool Success { get; set; } public int Amount { get; set; } public RequestConsumeResponse(ZPackage package) { item = InventoryHelper.LoadItemFromPackage(package); Success = package.ReadBool(); Amount = package.ReadInt(); } public RequestConsumeResponse(ItemData item, bool success, int amount) { this.item = item.ClampStackSize(); Success = success; Amount = amount; } public RequestConsumeResponse() { item = null; } public ZPackage WriteToPackage() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown ZPackage val = new ZPackage(); InventoryHelper.WriteItemToPackage(item, val); val.Write(Success); val.Write(Amount); return val; } } public class RequestDrop : IPackage { public readonly Vector2i targetContainerSlot; public readonly int amount; public readonly ZDOID sender; public RequestDrop(Vector2i targetContainerSlot, int amount, ZDOID sender) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) this.targetContainerSlot = targetContainerSlot; this.amount = amount; this.sender = sender; } public RequestDrop(ZPackage package) { //IL_0008: 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_0020: 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) targetContainerSlot = package.ReadVector2i(); amount = package.ReadInt(); sender = package.ReadZDOID(); } public ZPackage WriteToPackage() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(targetContainerSlot); val.Write(amount); val.Write(sender); return val; } } public class RequestDropResponse : IPackage, IResponse { public readonly ItemData responseItem; public readonly ZDOID sender; public int SourceID { get; set; } public bool Success { get; set; } public int Amount { get; set; } public RequestDropResponse(ItemData responseItem, ZDOID sender, bool success, int amount) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) this.responseItem = responseItem.ClampStackSize(); this.sender = sender; Success = success; Amount = amount; } public RequestDropResponse(ZPackage package) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) responseItem = InventoryHelper.LoadItemFromPackage(package); sender = package.ReadZDOID(); Success = package.ReadBool(); Amount = package.ReadInt(); } public RequestDropResponse() { responseItem = null; } public ZPackage WriteToPackage() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_0014: Unknown result type (might be due to invalid IL or missing references) ZPackage val = new ZPackage(); InventoryHelper.WriteItemToPackage(responseItem, val); val.Write(sender); val.Write(Success); val.Write(Amount); return val; } } public class RequestMove : IRequest, IPackage { public readonly Vector2i fromPos; public readonly Vector2i toPos; public readonly int itemHash; public readonly int dragAmount; public readonly ItemData item; public int RequestID { get; set; } public Inventory SourceInventory { get; } public Inventory TargetInventory { get; } public RequestMove(ItemData itemToMove, Vector2i toPos, int dragAmount, Inventory inventory) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) if (itemToMove == null) { Log.LogWarning("Item is null"); fromPos = new Vector2i(-1, -1); this.toPos = new Vector2i(-1, -1); itemHash = 0; this.dragAmount = 0; } else { SourceInventory = inventory; TargetInventory = inventory; fromPos = itemToMove.m_gridPos; this.toPos = toPos; itemHash = StringExtensionMethods.GetStableHashCode(itemToMove.PrefabName()); item = itemToMove.Clone(); this.dragAmount = dragAmount; } } public RequestMove(ZPackage package) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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) RequestID = package.ReadInt(); fromPos = package.ReadVector2i(); toPos = package.ReadVector2i(); itemHash = package.ReadInt(); dragAmount = package.ReadInt(); } public ZPackage WriteToPackage() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(RequestID); val.Write(fromPos); val.Write(toPos); val.Write(itemHash); val.Write(dragAmount); return val; } } public class RequestMoveResponse : IPackage, IResponse { public int SourceID { get; set; } public bool Success { get; set; } public int Amount { get; set; } public RequestMoveResponse(int sourceID, bool success, int amount) { SourceID = sourceID; Success = success; Amount = amount; } public RequestMoveResponse() { SourceID = 0; Success = false; Amount = 0; } public RequestMoveResponse(ZPackage package) { SourceID = package.ReadInt(); Success = package.ReadBool(); Amount = package.ReadInt(); } public ZPackage WriteToPackage() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_001d: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown ZPackage val = new ZPackage(); val.Write(SourceID); val.Write(Success); val.Write(Amount); return val; } } public class SlotPreview { private Inventory originalInventory; private Inventory inventory; private bool hasChanges; public SlotPreview(Inventory inventory) { originalInventory = inventory; this.inventory = InventoryHelper.CopyInventory(inventory); } public void Add(Vector2i pos, ItemData item, int amount) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (item != null && amount != 0) { ItemData val = item.Clone(); val.m_stack = amount; if (pos.x >= 0 && pos.y >= 0) { inventory.AddItem(val, amount, pos.x, pos.y, false); } else { inventory.AddItem(val); } hasChanges = true; } } public void Add(Vector2i pos, ItemData item) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) Add(pos, item, item?.m_stack ?? 0); } public void Remove(Vector2i pos, ItemData item) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) Remove(pos, item, item?.m_stack ?? 0); } public void Remove(Vector2i pos, ItemData item, int amount) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) if (item != null && amount != 0 && inventory.GetItemAt(pos.x, pos.y) != null) { inventory.RemoveItem(inventory.GetItemAt(pos.x, pos.y), amount); hasChanges = true; } } public bool GetSlot(Vector2i pos, out ItemData item) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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) ItemData itemAt = originalInventory.GetItemAt(pos.x, pos.y); item = inventory.GetItemAt(pos.x, pos.y); if (itemAt == null && item == null) { return false; } if (itemAt == null || item == null) { return true; } if (!(itemAt.m_shared.m_name != item.m_shared.m_name)) { return itemAt.m_stack != item.m_stack; } return true; } public bool HasChanges() { return hasChanges; } } public static class ConditionalWeakTableExtension { public static void TryAdd<TKey, TValue>(this ConditionalWeakTable<TKey, TValue> table, TKey key, ConditionalWeakTable<TKey, TValue>.CreateValueCallback createCallback) where TKey : class where TValue : class { table.GetValue(key, createCallback); } } public static class InventoryHelper { public delegate void MoveAction(Inventory from, Inventory to); private static MethodBase memberwiseCloneMethod = AccessTools.Method(typeof(object), "MemberwiseClone", (Type[])null, (Type[])null); public static ItemData LoadItemFromPackage(ZPackage pkg) { //IL_0020: 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_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) if (!pkg.ReadBool()) { return null; } string text = pkg.ReadString(); int num = pkg.ReadInt(); float durability = pkg.ReadSingle(); Vector2i val = pkg.ReadVector2i(); int num2 = pkg.ReadInt(); int num3 = pkg.ReadInt(); long num4 = pkg.ReadLong(); string text2 = pkg.ReadString(); int worldLevel = pkg.ReadInt(); bool flag = pkg.ReadBool(); Dictionary<string, string> dictionary = new Dictionary<string, string>(); int num5 = pkg.ReadInt(); for (int i = 0; i < num5; i++) { string key = pkg.ReadString(); string value = pkg.ReadString(); dictionary[key] = value; } Inventory val2 = new Inventory("tmp", (Sprite)null, val.x + 1, val.y + 1); ItemData val3 = val2.AddItem(text, num, num2, num3, num4, text2, val, flag, false, true); if (val3 != null) { val3.m_durability = durability; val3.m_worldLevel = worldLevel; val3.m_customData = dictionary; } ItemData itemAt = val2.GetItemAt(val.x, val.y); val2.RemoveItem(itemAt); return itemAt; } public static void WriteItemToPackage(ItemData itemData, ZPackage pkg) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) pkg.Write(itemData != null); if (itemData == null) { return; } pkg.Write(itemData.PrefabName()); pkg.Write(itemData.m_stack); pkg.Write(itemData.m_durability); pkg.Write(itemData.m_gridPos); pkg.Write(itemData.m_quality); pkg.Write(itemData.m_variant); pkg.Write(itemData.m_crafterID); pkg.Write(itemData.m_crafterName); pkg.Write(itemData.m_worldLevel); pkg.Write(itemData.m_pickedUp); pkg.Write(itemData.m_customData.Count); foreach (KeyValuePair<string, string> customDatum in itemData.m_customData) { pkg.Write(customDatum.Key); pkg.Write(customDatum.Value); } } public static ItemData ClampStackSize(this ItemData item) { if (item == null) { return null; } object obj; if (!((Object)(object)ObjectDB.instance == (Object)null)) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(item.PrefabName()); obj = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null); } else { obj = null; } ItemDrop val = (ItemDrop)obj; if ((Object)(object)val != (Object)null) { item.m_shared.m_maxStackSize = val.m_itemData.m_shared.m_maxStackSize; } return item; } public static string PrefabName(this ItemData item) { if ((Object)(object)item.m_dropPrefab != (Object)null) { return ((Object)item.m_dropPrefab).name; } Log.LogWarning("Item missing prefab " + item.m_shared.m_name); return item.m_shared.m_name; } public static bool MoveItem(Inventory inventory, ItemData item, int amount, Vector2i toPos, out int movedAmount) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) movedAmount = 0; if (item == null) { return false; } ItemData itemAt = inventory.GetItemAt(toPos.x, toPos.y); if (itemAt == item) { return true; } if (itemAt == null) { movedAmount = amount; return inventory.MoveItemToThis(inventory, item, amount, toPos.x, toPos.y); } if (CanStack(itemAt, item)) { movedAmount = Mathf.Min(amount, itemAt.m_shared.m_maxStackSize - itemAt.m_stack); return inventory.MoveItemToThis(inventory, item, movedAmount, toPos.x, toPos.y); } if (item.m_stack != amount) { return false; } inventory.RemoveItem(item); inventory.MoveItemToThis(inventory, itemAt, itemAt.m_stack, item.m_gridPos.x, item.m_gridPos.y); inventory.MoveItemToThis(inventory, item, amount, toPos.x, toPos.y); movedAmount = amount; return true; } public static bool CanStack(ItemData itemA, ItemData itemB) { if (itemA.m_shared.m_name == itemB.m_shared.m_name && (itemA.m_shared.m_maxQuality <= 1 || itemB.m_quality == itemA.m_quality)) { return itemA.m_shared.m_maxStackSize != 1; } return false; } public static Vector2i FindEmptySlot(Inventory inventory, List<Vector2i> blockedSlots) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < inventory.m_height; i++) { for (int j = 0; j < inventory.m_width; j++) { if (inventory.GetItemAt(j, i) == null && !blockedSlots.Contains(new Vector2i(j, i))) { return new Vector2i(j, i); } } } return new Vector2i(-1, -1); } public static List<ItemData> GetAllMoveableItems(Inventory from, Inventory to, MoveAction moveAction) { Inventory val = CopyInventory(from); Inventory to2 = CopyInventory(to); moveAction(val, to2); return CountMoved(from, val); } public static List<ItemData> GetAllMoveableItems(Inventory from, Inventory to) { return GetAllMoveableItems(from, to, MoveAll); } public static void MoveAll(Inventory from, Inventory to) { to.MoveAll(from); } private static List<ItemData> CountMoved(Inventory from, Inventory fromCopy) { List<ItemData> list = new List<ItemData>(); foreach (ItemData item in from.m_inventory) { ItemData itemAt = fromCopy.GetItemAt(item.m_gridPos.x, item.m_gridPos.y); if (itemAt == null) { list.Add(item); } else if (item.m_stack > itemAt.m_stack) { ItemData val = item.Clone(); val.m_stack = item.m_stack - itemAt.m_stack; list.Add(val); } } return list; } public static Inventory CopyInventory(Inventory target) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown return new Inventory(target.m_name, target.m_bkg, target.m_width, target.m_height) { m_inventory = new List<ItemData>(from x in target.GetAllItems() select x.Clone()) }; } public static bool AddItemToInventory(this Inventory target, ItemData item, int amount, Vector2i pos) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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) if (amount == 0) { return false; } ItemData itemAt = target.GetItemAt(pos.x, pos.y); if (itemAt != null) { if (!CanStack(itemAt, item)) { return false; } if (itemAt.m_stack + amount > itemAt.m_shared.m_maxStackSize) { return false; } } ItemData val = item.CloneDeeper(); val.m_stack = amount; return target.AddItem(val, amount, pos.x, pos.y, false); } public static ItemData CloneDeeper(this ItemData itemDrop) { ItemData obj = itemDrop.Clone(); ref SharedData shared = ref obj.m_shared; object? obj2 = memberwiseCloneMethod.Invoke(itemDrop.m_shared, null); shared = (SharedData)((obj2 is SharedData) ? obj2 : null); return obj; } public static void PrintItem(string title, ItemData itemData) { } } public static class Log { private static ManualLogSource logSource; internal static void Init(ManualLogSource manualLogSource) { logSource = manualLogSource; } public static void LogCodeInstruction(object data) { } public static void LogDebug(string data) { } public static void LogError(string data) { if (logSource != null) { logSource.LogError((object)data); } else { Debug.LogError((object)data); } } public static void LogFatal(string data) { if (logSource != null) { logSource.LogFatal((object)data); } else { Debug.LogError((object)data); } } public static void LogInfo(string data) { if (logSource != null) { logSource.LogInfo((object)data); } else { Debug.Log((object)data); } } public static void LogWarning(string data) { if (logSource != null) { logSource.LogWarning((object)data); } else { Debug.LogWarning((object)data); } } } public static class ReflectionHelper { private const BindingFlags allFlags = (BindingFlags)(-1); public static bool IsType(this object target, string name) { return target.GetType().Name == name; } public static bool HasField(this object target, string name) { return target.GetType().GetField(name, (BindingFlags)(-1)) != null; } public static T GetField<T>(this object target, string name) { return (T)(target.GetType().GetField(name, (BindingFlags)(-1))?.GetValue(target)); } public static T InvokeMethod<T>(this object target, string name, params object[] parameter) { parameter = ((parameter.Length == 0) ? null : parameter); return (T)(target.GetType().GetMethod(name, (BindingFlags)(-1))?.Invoke(target, parameter)); } public static T InvokeStaticMethod<T>(string type, string name, params object[] parameter) { parameter = ((parameter.Length == 0) ? null : parameter); return (T)(Type.GetType(type)?.GetMethod(name, (BindingFlags)(-1))?.Invoke(null, parameter)); } } public class HumanoidExtend : MonoBehaviour { private static readonly ConditionalWeakTable<Inventory, HumanoidInventoryOwner> Humanoids = new ConditionalWeakTable<Inventory, HumanoidInventoryOwner>(); private Inventory inventory; private void Awake() { UpdateInventory(); } private void Start() { UpdateInventory(); } private void UpdateInventory() { Humanoid humanoid = default(Humanoid); if (!((Component)this).TryGetComponent<Humanoid>(ref humanoid)) { return; } inventory = humanoid.GetInventory(); if (inventory == null) { return; } foreach (Inventory inventory in inventory.GetInventories()) { Humanoids.TryAdd(inventory, (Inventory i) => new HumanoidInventoryOwner(humanoid, i)); } } private void OnDestroy() { if (inventory == null) { return; } foreach (Inventory inventory in inventory.GetInventories()) { Humanoids.Remove(inventory); } } public static bool GetHumanoid(Inventory inventory, out HumanoidInventoryOwner humanoid) { return Humanoids.TryGetValue(inventory, out humanoid); } } public class InventoryBlock { private static readonly Dictionary<Inventory, InventoryBlock> Inventories = new Dictionary<Inventory, InventoryBlock>(); public bool BlockAllSlots { get; set; } public bool BlockConsume { get; set; } public Dictionary<Vector2i, int> BlockedSlots { get; } = new Dictionary<Vector2i, int>(); public static InventoryBlock Get(Inventory inventory) { if (Inventories.TryGetValue(inventory, out var value)) { return value; } InventoryBlock inventoryBlock = new InventoryBlock(); Inventories.Add(inventory, inventoryBlock); return inventoryBlock; } public void BlockSlot(Vector2i slot) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000f: 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_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) if (CanBlockSlot(slot)) { if (BlockedSlots.ContainsKey(slot)) { BlockedSlots[slot]++; } else { BlockedSlots[slot] = 1; } } } public void ReleaseSlot(Vector2i slot) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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_0046: Unknown result type (might be due to invalid IL or missing references) if (CanBlockSlot(slot) && BlockedSlots.ContainsKey(slot)) { BlockedSlots[slot]--; if (BlockedSlots[slot] <= 0) { BlockedSlots.Remove(slot); } } } public void ReleaseBlockedSlots() { BlockedSlots.Clear(); BlockAllSlots = false; BlockConsume = false; } public bool IsSlotBlocked(Vector2i slot) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) if (!BlockConsume && !BlockAllSlots) { return BlockedSlots.ContainsKey(slot); } return true; } public bool IsAnySlotBlocked() { if (!BlockConsume && !BlockAllSlots) { return BlockedSlots.Count > 0; } return true; } private static bool CanBlockSlot(Vector2i slot) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (slot.x >= 0) { return slot.y >= 0; } return false; } } public static class InventoryHandler { public static void RPC_RequestItemAddResponse(long sender, ZDOID containerId, ZPackage package) { HandleRPC(new RequestChestAddResponse(package), (RequestChestAddResponse p) => GetSourceInventory(p.SourceID), RPC_RequestItemAddResponse); } public static void RPC_RequestItemRemoveResponse(long sender, ZDOID containerId, ZPackage package) { HandleRPC(new RequestChestRemoveResponse(package), (RequestChestRemoveResponse p) => GetTargetInventory(p.SourceID), RPC_RequestItemRemoveResponse); } public static void RPC_RequestDropResponse(long sender, ZDOID containerId, ZPackage package) { HandleRPC(new RequestDropResponse(package), RPC_RequestDropResponse); } public static void RPC_RequestItemConsumeResponse(long sender, ZDOID containerId, ZPackage package) { HandleRPC(new RequestConsumeResponse(package), RPC_RequestItemConsumeResponse); } public static void RPC_RequestItemMoveResponse(long sender, ZDOID containerId, ZPackage package) { HandleRPC(new RequestMoveResponse(package), RPC_RequestItemMoveResponse); } private static void HandleRPC<T>(T package, Func<T, Inventory> inventory, Container container, Action<Inventory, Container, T> handle) where T : IPackage { CallRPC(handle.Method.Name, package, delegate { handle(inventory(package), container, package); }); } private static void HandleRPC<T>(T package, Func<T, Inventory> inventory, Action<Inventory, T> handle) where T : IPackage { CallRPC(handle.Method.Name, package, delegate { handle(inventory(package), package); }); } private static void HandleRPC<T>(T package, Action<T> handle) where T : IPackage { CallRPC(handle.Method.Name, package, delegate { handle(package); }); } private static void CallRPC(string timerName, IPackage package, Action action) { action?.Invoke(); } public static void RPC_RequestItemRemoveResponse(Inventory inventory, RequestChestRemoveResponse response) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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_00d5: Expected O, but got Unknown //IL_003a: 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_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) Vector2i toPos = PackageHandler.GetPackage<RequestChestRemove>(response.SourceID).toPos; InventoryBlock.Get(inventory).ReleaseSlot(toPos); InventoryPreview.RemovePackage(response); if (response.Success && toPos.x >= 0 && toPos.y >= 0) { if (!inventory.AddItemToInventory(response.responseItem, response.Amount, toPos)) { int num = response.Amount; ItemData itemAt = inventory.GetItemAt(toPos.x, toPos.y); if (itemAt != null && InventoryHelper.CanStack(response.responseItem, itemAt)) { int maxStackSize = itemAt.m_shared.m_maxStackSize; int stack = itemAt.m_stack; int num2 = maxStackSize - stack; itemAt.m_stack += num2; num -= num2; } DropItem(response.responseItem, num); } } else if (response.responseItem != null) { Inventory val = new Inventory("tmp", (Sprite)null, 1, 1); val.AddItem(response.responseItem); inventory.MoveItemToThis(val, response.responseItem); ItemData itemAt2 = val.GetItemAt(0, 0); if (itemAt2 != null) { DropItem(itemAt2, itemAt2.m_stack); } } UpdateGUIAfterPlayerMove(GetTargetInventory(response.SourceID)); } private static void RPC_RequestDropResponse(RequestDropResponse response) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) DropItem(response.responseItem, response.responseItem?.m_stack ?? 0); UpdateGUIAfterPlayerMove(response.sender); } private static void UpdateGUIAfterPlayerMove(ZDOID sender) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)InventoryGui.instance) && Object.op_Implicit((Object)(object)Player.m_localPlayer) && sender == ((Character)Player.m_localPlayer).GetZDOID()) { InventoryGui.instance.UpdateCraftingPanel(false); } } private static void UpdateGUIAfterPlayerMove(Inventory inventory) { if (Object.op_Implicit((Object)(object)InventoryGui.instance) && Object.op_Implicit((Object)(object)Player.m_localPlayer) && ((Humanoid)Player.m_localPlayer).GetInventory().GetInventories().Contains(inventory)) { InventoryGui.instance.UpdateCraftingPanel(false); } } public static void DropItem(ItemData item, int amount) { if (amount > 0 && item != null) { DropItem(Player.m_localPlayer, item, amount); } } private static void DropItem(Player player, ItemData item, int amount) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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_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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) Transform transform = ((Component)player).transform; ItemDrop obj = ItemDrop.DropItem(item, amount, transform.position + transform.forward + transform.up, transform.rotation); obj.OnPlayerDrop(); ((Component)obj).GetComponent<Rigidbody>().velocity = (transform.forward + Vector3.up) * 5f; ((Character)player).m_zanim.SetTrigger("interact"); ((Humanoid)player).m_dropEffects.Create(transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID)); ItemData itemData = obj.m_itemData; ((Character)player).Message((MessageType)1, "$msg_dropped " + itemData.m_shared.m_name, itemData.m_stack, itemData.GetIcon(), false); } public static void RPC_RequestItemAddResponse(Inventory inventory, RequestChestAddResponse response) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) Vector2i inventoryPos = response.inventoryPos; ItemData switchItem = response.switchItem; InventoryBlock.Get(inventory).ReleaseSlot(inventoryPos); InventoryPreview.RemovePackage(response); if (switchItem != null && !inventory.AddItemToInventory(switchItem, switchItem.m_stack, inventoryPos)) { DropItem(switchItem, switchItem.m_stack); } UpdateGUIAfterPlayerMove(GetSourceInventory(response.SourceID)); } public static void RPC_RequestItemConsumeResponse(RequestConsumeResponse response) { Player localPlayer = Player.m_localPlayer; InventoryBlock.Get(((Humanoid)localPlayer).GetInventory()).BlockConsume = false; if (response.item != null && ((Humanoid)localPlayer).CanConsumeItem(response.item, false)) { if (Object.op_Implicit((Object)(object)response.item.m_shared.m_consumeStatusEffect)) { ((Character)localPlayer).m_seman.AddStatusEffect(response.item.m_shared.m_consumeStatusEffect, true, 0, 0f, (short)(-1)); } if ((double)response.item.m_shared.m_food > 0.0) { localPlayer.EatFood(response.item); } } } public static void RPC_RequestItemMoveResponse(RequestMoveResponse response) { InventoryPreview.RemovePackage(response); } internal static Inventory GetSourceInventory(int id) { return PackageHandler.GetPackage<IRequest>(id)?.SourceInventory; } internal static Inventory GetTargetInventory(int id) { return PackageHandler.GetPackage<IRequest>(id)?.TargetInventory; } } internal static class MultiUserChestInventoryIgnore { internal static bool IgnoreInventory(this InventoryOwner owner) { if (owner == null || !Object.op_Implicit((Object)(object)owner.ZNetView) || owner.ZNetView.GetZDO() == null) { return false; } return owner.ZNetView.GetZDO().GetBool("MUC_Ignore", false); } internal static bool IgnoreInventory(this Container container) { return InventoryOwner.GetOwner((container != null) ? container.GetInventory() : null).IgnoreInventory(); } internal static IEnumerable<Inventory> GetInventories(this Inventory inventory) { if (inventory != null) { yield return inventory; } } } public abstract class InventoryOwner { public abstract ZNetView ZNetView { get; } public abstract Inventory Inventory { get; } public virtual bool IsValid() { if (Object.op_Implicit((Object)(object)ZNetView) && ZNetView.HasOwner()) { return Inventory != null; } return false; } public static InventoryOwner GetOwner(Inventory inventory) { if (inventory == null) { return null; } if (HumanoidExtend.GetHumanoid(inventory, out var humanoid)) { return humanoid; } if (ContainerExtend.GetContainer(inventory, out var container)) { return container; } return null; } public static InventoryOwner GetOwner(ItemData item) { if (item == null) { return null; } if (InventoryPatch.InventoryOfItem.TryGetValue(item, out var value)) { return GetOwner(value); } return null; } public string GetDescription() { if (!IsValid()) { return "-"; } return $"{Inventory.GetName()} ({GetType().Name}), is owner: {ZNetView.IsOwner()}"; } } public class ContainerInventoryOwner : InventoryOwner { public Container Container { get; } public bool IsItemDrawer { get; } public override ZNetView ZNetView => Container.m_nview; public override Inventory Inventory => Container.GetInventory(); public ContainerInventoryOwner(Container container) { Container = container; IsItemDrawer = false; } } public class HumanoidInventoryOwner : InventoryOwner { private readonly Inventory inventory; public Humanoid Humanoid { get; } public override ZNetView ZNetView => ((Character)Humanoid).m_nview; public override Inventory Inventory => inventory; public HumanoidInventoryOwner(Humanoid humanoid, Inventory inventory) { Humanoid = humanoid; this.inventory = inventory; } } public static class InventoryPreview { public static readonly ConditionalWeakTable<Inventory, List<IRequest>> PackageChanges = new ConditionalWeakTable<Inventory, List<IRequest>>(); public static readonly ConditionalWeakTable<Inventory, List<IRequest>> ToRemovePackages = new ConditionalWeakTable<Inventory, List<IRequest>>(); private static WaitForSeconds removeQueuedPackagesDelay = new WaitForSeconds(0.2f); public static void AddPackage(IRequest package) { package.RequestID = PackageHandler.AddPackage(package); AppendPackage(package.SourceInventory, package); AppendPackage(package.TargetInventory, package); } private static void AppendPackage(Inventory inventory, IRequest package) { if (PackageChanges.TryGetValue(inventory, out var value)) { if (!value.Contains(package)) { value.Add(package); } Log.LogDebug($"InventoryPreview: Appended package {package.RequestID} to inventory {inventory.m_name}, total packages: {value.Count}"); return; } PackageChanges.Add(inventory, new List<IRequest> { package }); Inventory obj = inventory; obj.m_onChanged = (Action)Delegate.Combine(obj.m_onChanged, (Action)delegate { RemoveQueuedPackages(inventory); }); Log.LogDebug($"InventoryPreview: Added package {package.RequestID} to inventory {inventory.m_name}, total packages: 1 (new)"); } public static void RemovePackage(IResponse package) { RemovePackage(InventoryHandler.GetSourceInventory(package.SourceID), package); RemovePackage(InventoryHandler.GetTargetInventory(package.SourceID), package); PackageHandler.RemovePackage(package.SourceID); } private static void RemovePackage(Inventory inventory, IResponse package) { if (inventory == null) { return; } InventoryOwner owner = InventoryOwner.GetOwner(inventory); IRequest request = null; if (PackageChanges.TryGetValue(inventory, out var value)) { request = value.Find((IRequest p) => p.RequestID == package.SourceID); } if (request != null) { if (ToRemovePackages.TryGetValue(inventory, out var value2)) { value2.Add(request); } else { ToRemovePackages.Add(inventory, new List<IRequest> { request }); } if (owner != null && owner.IsValid() && owner.ZNetView.IsOwner()) { RemoveQueuedPackages(inventory); } else if (!package.Success) { ((MonoBehaviour)ThreadingHelper.Instance).StartCoroutine(RemoveQueuedPackagesDelayed(inventory)); } } } private static void RemoveQueuedPackages(Inventory inventory) { if (!ToRemovePackages.TryGetValue(inventory, out var value) || value.Count <= 0) { return; } foreach (IRequest item in new List<IRequest>(value)) { if (PackageChanges.TryGetValue(inventory, out var value2)) { value2.Remove(item); } value.Remove(item); Log.LogDebug($"InventoryPreview: Removed package {item.RequestID} from inventory {inventory.m_name}, total packages: {value.Count}"); } } private static IEnumerator RemoveQueuedPackagesDelayed(Inventory inventory) { yield return removeQueuedPackagesDelay; RemoveQueuedPackages(inventory); } public static bool GetChanges(Inventory inventory, out SlotPreview preview) { //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: 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) //IL_0128: 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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0232: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) if (inventory == null) { preview = null; return false; } if (PackageChanges.TryGetValue(inventory, out var value)) { preview = new SlotPreview(inventory); foreach (IRequest item3 in value) { if (item3 is RequestChestAdd requestChestAdd) { if (requestChestAdd.dragItem != null) { ItemData item = null; if (requestChestAdd.allowSwitch) { item = item3.TargetInventory.GetItemAt(requestChestAdd.toPos.x, requestChestAdd.toPos.y); } if (inventory == item3.SourceInventory) { preview.Add(requestChestAdd.dragItem.m_gridPos, item); } if (inventory == item3.TargetInventory) { preview.Remove(requestChestAdd.toPos, item); preview.Add(requestChestAdd.toPos, requestChestAdd.dragItem); } } } else if (item3 is RequestChestRemove { fromPos: var fromPos, toPos: var toPos } requestChestRemove) { if (inventory == item3.SourceInventory) { preview.Remove(fromPos, requestChestRemove.item, requestChestRemove.dragAmount); preview.Add(fromPos, requestChestRemove.switchItem); } if (inventory == item3.TargetInventory) { preview.Add(toPos, requestChestRemove.item, requestChestRemove.dragAmount); } } else { if (!(item3 is RequestMove requestMove) || (preview.GetSlot(requestMove.fromPos, out var item2) && requestMove.itemHash != ((item2 != null) ? new int?(StringExtensionMethods.GetStableHashCode(item2.PrefabName())) : ((int?)null)))) { continue; } ItemData itemAt = requestMove.TargetInventory.GetItemAt(requestMove.toPos.x, requestMove.toPos.y); if (itemAt != null && !InventoryHelper.CanStack(requestMove.item, itemAt)) { if (requestMove.dragAmount == requestMove.item.m_stack) { preview.Remove(requestMove.fromPos, requestMove.item, requestMove.dragAmount); preview.Remove(requestMove.toPos, itemAt, itemAt.m_stack); preview.Add(requestMove.fromPos, itemAt, itemAt.m_stack); preview.Add(requestMove.toPos, requestMove.item, requestMove.dragAmount); } } else { int amount = Mathf.Max(0, requestMove.dragAmount); if (itemAt != null) { amount = Mathf.Min(itemAt.m_shared.m_maxStackSize - itemAt.m_stack, requestMove.dragAmount); } preview.Remove(requestMove.fromPos, requestMove.item, amount); preview.Add(requestMove.toPos, requestMove.item, amount); } } } return preview.HasChanges(); } preview = null; return false; } } public static class PackageHandler { private static readonly Dictionary<int, IPackage> Packages = new Dictionary<int, IPackage>(); private static readonly Random Random = new Random(); private static int total; public static int AddPackage(IPackage package) { int randomId = GetRandomId(); Packages.Add(randomId, package); return randomId; } public static void RemovePackage(int id) { Packages.Remove(id); } private static int GetRandomId() { return Random.Next(int.MinValue, int.MaxValue); } public static bool GetPackage<T>(int id, out T package) where T : IPackage { if (Packages.TryGetValue(id, out var value)) { package = (T)value; return true; } package = default(T); return false; } public static T GetPackage<T>(int id) where T : IPackage { if (Packages.TryGetValue(id, out var value)) { return (T)value; } return default(T); } } [HarmonyPatch(typeof(Container), "IsOwner")] internal static class MultiUserChestGuiOwnerPatch { private static bool Prefix(Container __instance, ref bool __result) { if (!Plugin.IsFeatureEnabled(Plugin.MultiUserChests) || (Object)(object)__instance == (Object)null || __instance.IgnoreInventory()) { return true; } InventoryGui instance = InventoryGui.instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance.m_currentContainer != (Object)(object)__instance) { return true; } StackTrace stackTrace = new StackTrace(); for (int i = 2; i < stackTrace.FrameCount && i < 10; i++) { if (stackTrace.GetFrame(i)?.GetMethod()?.Name == "UpdateContainer") { __result = true; return false; } } return true; } } [HarmonyPatch] public static class ContainerPatch { public const string ItemMoveRPC = "MUC_RequestItemMove"; public const string ItemMoveResponseRPC = "MUC_RequestItemMoveResponse"; public const string ItemAddRPC = "MUC_RequestItemAdd"; public const string ItemAddResponseRPC = "MUC_RequestItemAddResponse"; public const string ItemRemoveRPC = "MUC_RequestItemRemove"; public const string ItemRemoveResponseRPC = "MUC_RequestItemRemoveResponse"; public const string ItemConsumeRPC = "MUC_RequestItemConsume"; public const string ItemConsumeResponseRPC = "MUC_RequestItemConsumeResponse"; public const string ItemDropRPC = "MUC_RequestItemDrop"; public const string ItemDropResponseRPC = "MUC_RequestItemDropResponse"; [HarmonyPatch(typeof(Container), "Awake")] [HarmonyPostfix] public static void ContainerAwakePatch(Container __instance) { if (!Plugin.IsFeatureEnabled(Plugin.MultiUserChests) || (Object)(object)__instance == (Object)null) { return; } if (!Object.op_Implicit((Object)(object)((Component)__instance).GetComponent<ContainerExtend>())) { ((Component)__instance).gameObject.AddComponent<ContainerExtend>(); } if (!__instance.IgnoreInventory()) { if (!Object.op_Implicit((Object)(object)__instance.m_nview)) { __instance.m_nview = (Object.op_Implicit((Object)(object)__instance.m_rootObjectOverride) ? ((Component)__instance.m_rootObjectOverride).GetComponent<ZNetView>() : ((Component)__instance).GetComponent<ZNetView>()); } ContainerExtend.EnsureRegistered(__instance); } } [HarmonyPatch(typeof(Container), "IsInUse")] [HarmonyPrefix] public static bool ContainerIsInUsePatch(Container __instance, ref bool __result) { if (!Plugin.IsFeatureEnabled(Plugin.MultiUserChests) || (Object)(object)__instance == (Object)null || __instance.IgnoreInventory()) { return true; } __result = false; return false; } } [HarmonyPatch] public static class GamePatches { [HarmonyPatch(typeof(Game), "Start")] [HarmonyPostfix] public static void GameStartPatch() { if (Plugin.IsFeatureEnabled(Plugin.MultiUserChests)) { RegisterRPCs(); } } public static void RegisterRPCs() { ZRoutedRpc.instance.Register<ZDOID, ZPackage>("MUC_RequestItemMove", (Action<long, ZDOID, ZPackage>)ContainerRPCHandler.RPC_RequestItemMove); ZRoutedRpc.instance.Register<ZDOID, ZPackage>("MUC_RequestItemAdd", (Action<long, ZDOID, ZPackage>)ContainerRPCHandler.RPC_RequestItemAdd); ZRoutedRpc.instance.Register<ZDOID, ZPackage>("MUC_RequestItemRemove", (Action<long, ZDOID, ZPackage>)ContainerRPCHandler.RPC_RequestItemRemove); ZRoutedRpc.instance.Register<ZDOID, ZPackage>("MUC_RequestItemConsume", (Action<long, ZDOID, ZPackage>)ContainerRPCHandler.RPC_RequestItemConsume); ZRoutedRpc.instance.Register<ZDOID, ZPackage>("MUC_RequestItemDrop", (Action<long, ZDOID, ZPackage>)ContainerRPCHandler.RPC_RequestDrop); ZRoutedRpc.instance.Register<ZDOID, ZPackage>("MUC_RequestItemMoveResponse", (Action<long, ZDOID, ZPackage>)InventoryHandler.RPC_RequestItemMoveResponse); ZRoutedRpc.instance.Register<ZDOID, ZPackage>("MUC_RequestItemAddResponse", (Action<long, ZDOID, ZPackage>)InventoryHandler.RPC_RequestItemAddResponse); ZRoutedRpc.instance.Register<ZDOID, ZPackage>("MUC_RequestItemRemoveResponse", (Action<long, ZDOID, ZPackage>)InventoryHandler.RPC_RequestItemRemoveResponse); ZRoutedRpc.instance.Register<ZDOID, ZPackage>("MUC_RequestItemConsumeResponse", (Action<long, ZDOID, ZPackage>)InventoryHandler.RPC_RequestItemConsumeResponse); ZRoutedRpc.instance.Register<ZDOID, ZPackage>("MUC_RequestItemDropResponse", (Action<long, ZDOID, ZPackage>)InventoryHandler.RPC_RequestDropResponse); } public static void InvokeRPC(ZNetView netView, string rpc, IPackage package) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) ZRoutedRpc.instance.InvokeRoutedRPC(netView.m_zdo.GetOwner(), rpc, new object[2] { netView.m_zdo.m_uid, package.WriteToPackage() }); } } [HarmonyPatch] public static class HumanoidPatch { [HarmonyPatch(typeof(Humanoid), "Awake")] [HarmonyPostfix] public static void HumanoidAwakePatch(Humanoid __instance) { if (Plugin.IsFeatureEnabled(Plugin.MultiUserChests)) { ((Component)__instance).gameObject.AddComponent<HumanoidExtend>(); } } } [HarmonyPatch] public static class InventoryGuiPatch { [HarmonyPatch(typeof(InventoryGui), "Update")] [HarmonyPostfix] public static void InventoryGuiUpdatePatch(InventoryGui __instance) { if (Plugin.IsFeatureEnabled(Plugin.MultiUserChests) && Object.op_Implicit((Object)(object)__instance.m_currentContainer) && Object.op_Implicit((Object)(object)__instance.m_currentContainer.m_nview) && __instance.m_currentContainer.m_nview.IsValid()) { __instance.m_currentContainer.CheckForChanges(); } } [HarmonyPatch(typeof(InventoryGui), "OnRightClickItem")] [HarmonyPrefix] public static bool InventoryGuiOnRightClickItemPatch(InventoryGui __instance, InventoryGrid grid, ItemData item) { if (!Plugin.IsFeatureEnabled(Plugin.MultiUserChests)) { return true; } Player localPlayer = Player.m_localPlayer; if (item == null || !Object.op_Implicit((Object)(object)localPlayer)) { return true; } if (grid.GetInventory() == ((Humanoid)localPlayer).GetInventory()) { return true; } if (!Object.op_Implicit((Object)(object)__instance.m_currentContainer) || __instance.m_currentContainer.IsOwner()) { return true; } if (InventoryBlock.Get(((Humanoid)localPlayer).GetInventory()).BlockConsume) { return false; } if (((Humanoid)localPlayer).CanConsumeItem(item, false)) { InventoryBlock.Get(((Humanoid)localPlayer).GetInventory()).BlockConsume = true; RequestConsume package = new RequestConsume(item); GamePatches.InvokeRPC(__instance.m_currentContainer.m_nview, "MUC_RequestItemConsume", package); } return false; } [HarmonyPatch(typeof(InventoryGui), "UpdateContainer")] [HarmonyTranspiler] public static IEnumerable<CodeInstruction> ChangeOwnerCheck(IEnumerable<CodeInstruction> instructions) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Expected O, but got Unknown if (!Plugin.IsFeatureEnabled(Plugin.MultiUserChests)) { return instructions; } try { CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null); val.MatchForward(true, (CodeMatch[])(object)new CodeMatch[3] { new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null), new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Ldfld && i.operand is FieldInfo fieldInfo && fieldInfo.Name == "m_currentContainer"), (string)null), new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => (i.opcode == OpCodes.Call || i.opcode == OpCodes.Callvirt) && i.operand is MethodInfo methodInfo && methodInfo.Name == "IsOwner"), (string)null) }); if (!val.IsValid) { Plugin.LogWarning("Multi-user chest: UpdateContainer owner check was not found; using the guarded Container.IsOwner fallback."); return instructions; } val.RemoveInstructions(1); val.Insert((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(InventoryGuiPatch), "CanOpenContainer", (Type[])null, (Type[])null)) }); return val.InstructionEnumeration(); } catch (Exception ex) { Plugin.LogWarning("Multi-user chest: UpdateContainer transpiler skipped safely: " + ex.Message); return instructions; } } public static bool CanOpenContainer(Container container) { if (!Plugin.IsFeatureEnabled(Plugin.MultiUserChests)) { return container.IsOwner(); } if (container.IgnoreInventory()) { return container.IsOwner(); } return true; } [HarmonyPatch(typeof(InventoryGui), "OnDropOutside")] [HarmonyPrefix] public static void InventoryGuiOnDropOutsidePatch(InventoryGui __instance, ref bool __runOriginal) { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.IsFeatureEnabled(Plugin.MultiUserChests) || !__runOriginal || !Object.op_Implicit((Object)(object)__instance.m_dragGo)) { return; } if (((Humanoid)Player.m_localPlayer).GetInventory().GetInventories().Contains(__instance.m_dragInventory)) { Log.LogDebug("Drop item from own inventory"); return; } bool flag = Object.op_Implicit((Object)(object)__instance.m_currentContainer) && __instance.m_currentContainer.IsOwner(); if (!(!Object.op_Implicit((Object)(object)__instance.m_currentContainer) || flag)) { RequestDrop package = new RequestDrop(__instance.m_dragItem.m_gridPos, __instance.m_dragAmount, ((Character)Player.m_localPlayer).GetZDOID()); GamePatches.InvokeRPC(__instance.m_currentContainer.m_nview, "MUC_RequestItemDrop", package); __instance.SetupDragItem((ItemData)null, (Inventory)null, 1); __runOriginal = false; } } [HarmonyPatch(typeof(Inventory), "Load", new Type[] { typeof(ZPackage) })] [HarmonyPostfix] public static void InventorySelectSameItemAfterLoad(Inventory __instance) { SelectSameItemAfterLoad(__instance); } [HarmonyPatch(typeof(Inventory), "Load", new Type[] { typeof(ZPackage), typeof(bool) })] [HarmonyPostfix] public static void InventorySelectSameItemAfterLoadWithOptions(Inventory __instance) { SelectSameItemAfterLoad(__instance); } private static void SelectSameItemAfterLoad(Inventory __instance) { if (Plugin.IsFeatureEnabled(Plugin.MultiUserChests) && Object.op_Implicit((Object)(object)InventoryGui.instance) && InventoryGui.instance.m_dragItem != null && Object.op_Implicit((Object)(object)InventoryGui.instance.m_currentContainer) && InventoryGui.instance.m_currentContainer.GetInventory() == __instance && InventoryGui.instance.m_dragInventory != null && InventoryGui.instance.m_dragInventory == __instance) { ItemData dragItem = InventoryGui.instance.m_dragItem; ItemData itemAt = __instance.GetItemAt(dragItem.m_gridPos.x, dragItem.m_gridPos.y); if (itemAt == null) { InventoryGui.instance.SetupDragItem((ItemData)null, (Inventory)null, 1); return; } int dragAmount = Mathf.Min(itemAt.m_stack, InventoryGui.instance.m_dragAmount); InventoryGui.instance.m_dragAmount = dragAmount; InventoryGui.instance.m_dragItem = itemAt; } } [HarmonyPatch(typeof(InventoryGrid), "UpdateInventory")] [HarmonyPostfix] public static void InventoryGridUpdateInventoryPatch(InventoryGrid __instance) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.IsFeatureEnabled(Plugin.MultiUserChests) || !InventoryPreview.GetChanges(__instance.m_inventory, out var preview)) { return; } foreach (InventoryElement element in __instance.m_elements) { if (preview.GetSlot(element.Position, out var item)) { if (item == null) { ShowNoItem(element); } else { ShowItem(__instance, element, item); } } } } private static void ShowItem(InventoryGrid inventoryGrid, InventoryElement element, ItemData item) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Invalid comparison between Unknown and I4 //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Unknown result type (might be due to invalid IL or missing references) if (item?.m_shared == null) { return; } int stack = item.m_stack; int maxStackSize = item.m_shared.m_maxStackSize; ((Behaviour)element.m_icon).enabled = stack > 0; element.m_icon.sprite = item.GetIcon(); ((Graphic)element.m_icon).color = Color.white; ((Behaviour)element.m_amount).enabled = stack > 0 && maxStackSize > 1; element.m_amount.text = $"{stack}/{maxStackSize}"; bool flag = item.m_shared.m_useDurability && item.m_durability < item.GetMaxDurability(); ((Component)element.m_durability).gameObject.SetActive(flag); if (flag) { if ((double)item.m_durability <= 0.0) { element.m_durability.SetValue(1f); element.m_durability.SetColor((Color)(((double)Mathf.Sin(Time.time * 10f) > 0.0) ? Color.red : new Color(0f, 0f, 0f, 0f))); } else { element.m_durability.SetValue(item.GetDurabilityPercentage()); element.m_durability.ResetColor(); } } ((Behaviour)element.m_equiped).enabled = false; ((Behaviour)element.m_queued).enabled = false; ((Behaviour)element.m_noteleport).enabled = !item.m_shared.m_teleportable && !ZoneSystem.instance.GetGlobalKey((GlobalKeys)35); if ((int)item.m_shared.m_itemType == 2 && ((double)item.m_shared.m_food > 0.0 || (double)item.m_shared.m_foodStamina > 0.0 || (double)item.m_shared.m_foodEitr > 0.0)) { ((Behaviour)element.m_food).enabled = true; if ((double)item.m_shared.m_food < (double)item.m_shared.m_foodEitr / 2.0 && (double)item.m_shared.m_foodStamina < (double)item.m_shared.m_foodEitr / 2.0) { ((Graphic)element.m_food).color = inventoryGrid.m_foodEitrColor; } else if ((double)item.m_shared.m_foodStamina < (double)item.m_shared.m_food / 2.0) { ((Graphic)element.m_food).color = inventoryGrid.m_foodHealthColor; } else if ((double)item.m_shared.m_food < (double)item.m_shared.m_foodStamina / 2.0) { ((Graphic)element.m_food).color = inventoryGrid.m_foodStaminaColor; } else { ((Graphic)element.m_food).color = Color.white; } } else { ((Behaviour)element.m_food).enabled = false; } ((Behaviour)element.m_quality).enabled = item.m_shared.m_maxQuality > 1; if (item.m_shared.m_maxQuality > 1) { element.m_quality.text = item.m_quality.ToString(); } } private static void ShowNoItem(InventoryElement element) { ((Component)element.m_durability).gameObject.SetActive(false); ((Behaviour)element.m_icon).enabled = false; ((Behaviour)element.m_amount).enabled = false; ((Behaviour)element.m_quality).enabled = false; ((Behaviour)element.m_equiped).enabled = false; ((Behaviour)element.m_queued).enabled = false; ((Behaviour)element.m_noteleport).enabled = false; ((Behaviour)element.m_food).enabled = false; element.m_tooltip.m_text = ""; element.m_tooltip.m_topic = ""; } } [HarmonyPatch] public static class InventoryPatch { public static readonly ConditionalWeakTable<ItemData, Inventory> InventoryOfItem = new ConditionalWeakTable<ItemData, Inventory>(); private static readonly WeakReference<ItemData> LastRemovedItem = new WeakReference<ItemData>(null); private static bool allowItemSwap = true; [HarmonyPatch(typeof(Inventory), "AddItem", new Type[] { typeof(ItemData), typeof(int), typeof(int), typeof(int), typeof(bool) })] [HarmonyPrefix] [HarmonyPriority(100)] public static void AddItem1Prefix(Inventory __instance, ref bool __runOriginal, ItemData item, int amount, int x, int y, bool skipValidPositionCheck, ref bool __result) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (Plugin.IsFeatureEnabled(Plugin.MultiUserChests) && __runOriginal && InterceptAddItem(__instance, item, amount, new Vector2i(x, y), out var successfulAdded)) { __result = successfulAdded; __runOriginal = false; } } [HarmonyPatch(typeof(Inventory), "AddItem", new Type[] { typeof(ItemData) })] [HarmonyPrefix] [HarmonyPriority(100)] public static void AddItem2Prefix(Inventory __instance, ref bool __runOriginal, ItemData item, ref bool __result) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) if (Plugin.IsFeatureEnabled(Plugin.MultiUserChests) && __runOriginal && InterceptAddItem(__instance, item, item.m_stack, new Vector2i(-1, -1), out var successfulAdded)) { __result = successfulAdded; __runOriginal = false; } } [HarmonyPatch(typeof(Inventory), "RemoveItem", new Type[] { typeof(ItemData) })] [HarmonyPrefix] [HarmonyPriority(100)] public static void RemoveItemPrefix(Inventory __instance, ref bool __runOriginal, ref bool __result) { if (Plugin.IsFeatureEnabled(Plugin.MultiUserChests) && __runOriginal) { InventoryOwner owner = InventoryOwner.GetOwner(__instance); if (owner != null && !owner.IgnoreInventory() && owner != null && owner.IsValid() && !owner.ZNetView.IsOwner()) { __result = false; __runOriginal = false; } } } [HarmonyPatch(typeof(Inventory), "RemoveItem", new Type[] { typeof(ItemData) })] [HarmonyPostfix] public static void RemoveItemPostfix(Inventory __instance, ItemData item, ref bool __result) { if (Plugin.IsFeatureEnabled(Plugin.MultiUserChests)) { if (__result) { LastRemovedItem.SetTarget(item); } else { LastRemovedItem.SetTarget(null); } } } [HarmonyPatch(typeof(Inventory), "MoveAll")] [HarmonyPrefix] [HarmonyPriority(800)] public static void MoveAllPrefix() { if (Plugin.IsFeatureEnabled(Plugin.MultiUserChests)) { allowItemSwap = false; } } [HarmonyPatch(typeof(Inventory), "MoveAll")] [HarmonyPostfix] [HarmonyPriority(0)] public static void MoveAllPostfix() { if (Plugin.IsFeatureEnabled(Plugin.MultiUserChests)) { allowItemSwap = true; } } [HarmonyPatch(typeof(Inventory), "Changed")] [HarmonyPostfix] public static void AddItemPostfix(Inventory __instance) { if (!Plugin.IsFeatureEnabled(Plugin.MultiUserChests)) { return; } foreach (Inventory inventory in __instance.GetInventories()) { AssignItemsOfInventory(inventory); } if (LastRemovedItem.TryGetTarget(out var target) && InventoryOwner.GetOwner(target)?.Inventory == __instance) { LastRemovedItem.SetTarget(null); } } [HarmonyPatch(typeof(Inventory), "AddItem", new Type[] { typeof(ItemData), typeof(int), typeof(int), typeof(int), typeof(bool) })] [HarmonyTranspiler] public static IEnumerable<CodeInstruction> RemoveLogging(IEnumerable<CodeInstruction> instructions) { return instructions; } private static void AssignItemsOfInventory(Inventory inventory) { foreach (ItemData allItem in inventory.GetAllItems()) { InventoryOfItem.Remove(allItem); InventoryOfItem.Add(allItem, inventory); } } internal static bool InterceptAddItem(Inventory inventory, ItemData item, int amount, Vector2i pos, out bool successfulAdded) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) InventoryOwner owner = InventoryOwner.GetOwner(item); InventoryOwner owner2 = InventoryOwner.GetOwner(inventory); if (owner == null || !owner.IsValid() || owner2 == null || !owner2.IsValid()) { successfulAdded = false; return false; } if (owner2.IgnoreInventory() || owner.IgnoreInventory()) { successfulAdded = false; return false; } if (owner.ZNetView.IsOwner() && !owner2.ZNetView.IsOwner() && owner2 is ContainerInventoryOwner containerInventoryOwner) { RequestChestAdd requestChestAdd = containerInventoryOwner.Container.AddItemToChest(item, owner.Inventory, pos, owner.ZNetView.GetZDO().m_uid, amount); successfulAdded = requestChestAdd != null && requestChestAdd.dragItem?.m_stack == amount; return true; } if (!owner.ZNetView.IsOwner() && owner2.ZNetView.IsOwner() && owner is ContainerInventoryOwner containerInventoryOwner2) { ItemData val = owner2.Inventory.GetItemAt(pos.x, pos.y); if (val == null && LastRemovedItem.TryGetTarget(out var target) && InventoryOwner.GetOwner(target) == owner2 && target.m_gridPos == pos) { val = target; } if (!allowItemSwap && val != null) { successfulAdded = false; return true; } if (val != null && InventoryHelper.CanStack(item, val)) { val = null; } RequestChestRemove requestChestRemove = containerInventoryOwner2.Container.RemoveItemFromChest(item, owner2.Inventory, pos, owner2.ZNetView.GetZDO().m_uid, amount, val); successfulAdded = requestChestRemove != null && requestChestRemove.dragAmount == amount; return true; } if (!owner.ZNetView.IsOwner() && !owner2.ZNetView.IsOwner() && owner is ContainerInventoryOwner containerInventoryOwner3 && owner2 is ContainerInventoryOwner containerInventoryOwner4 && (Object)(object)containerInventoryOwner3.Container == (Object)(object)containerInventoryOwner4.Container) { containerInventoryOwner3.Container.MoveItemInChest(item, pos, amount); successfulAdded = true; return true; } successfulAdded = false; return false; } } [HarmonyPatch] public static class PickupPatch { [HarmonyPatch(typeof(Humanoid), "Pickup")] [HarmonyPrefix] public static bool HaveEmptySlotPrefix(Humanoid __instance, ref bool __result) { if (!Plugin.IsFeatureEnabled(Plugin.MultiUserChests)) { return true; } if (InventoryBlock.Get(__instance.GetInventory()).IsAnySlotBlocked()) { __result = false; return false; } return true; } } [HarmonyPatch] internal static class NoStaminaToolUseScopePatch { private static readonly HashSet<string> ToolActionNames = new HashSet<string>(StringComparer.Ordinal) { "UseItem", "UseItemSwitch", "Attack", "UpdatePlacement", "PlacePiece", "RemovePiece", "Repair", "RaiseTerrain", "LowerTerrain", "LevelTerrain", "Flatten", "Cultivate", "Plant", "PaveRoad", "SmoothTerrain" }; [ThreadStatic] private stati