private void SlotMouseWheel(int slotId, int wheelDelta)
        {
            ItemStackMoveOperation op = new ItemStackMoveOperation(api.World, EnumMouseButton.Wheel, 0, EnumMergePriority.AutoMerge, 1);

            op.WheelDir     = wheelDelta > 0 ? 1 : -1;
            op.ActingPlayer = api.World.Player;
            IInventory mouseCursorInv = api.World.Player.InventoryManager.GetOwnInventory(GlobalConstants.mousecursorInvClassName);

            IInventory targetInv  = inventory;
            ItemSlot   sourceSlot = mouseCursorInv[0];

            var packet = targetInv.ActivateSlot(slotId, sourceSlot, ref op);

            if (packet != null)
            {
                if (packet is object[] packets)
                {
                    for (int i = 0; i < packets.Length; i++)
                    {
                        SendPacketHandler(packets[i]);
                    }
                }
                else
                {
                    SendPacketHandler?.Invoke(packet);
                }
            }
        }
        public virtual void SlotClick(ICoreClientAPI api, int slotId, EnumMouseButton mouseButton, bool shiftPressed, bool ctrlPressed, bool altPressed)
        {
            //Console.WriteLine("client side slot click on " + slotId);

            List <IInventory> inventories    = api.World.Player.InventoryManager.OpenedInventories;
            IInventory        mouseCursorInv = api.World.Player.InventoryManager.GetOwnInventory(GlobalConstants.mousecursorInvClassName);
            object            packet;

            EnumModifierKey modifiers =
                (shiftPressed ? EnumModifierKey.SHIFT : 0) |
                (ctrlPressed ? EnumModifierKey.CTRL : 0) |
                (altPressed ? EnumModifierKey.ALT : 0)
            ;

            ItemStackMoveOperation op = new ItemStackMoveOperation(api.World, mouseButton, modifiers, EnumMergePriority.AutoMerge);

            op.ActingPlayer = api.World.Player;

            if (shiftPressed)
            {
                ItemSlot sourceSlot = inventory[slotId];
                op.RequestedQuantity = sourceSlot.StackSize;
                packet = inventory.ActivateSlot(slotId, sourceSlot, ref op);
            }
            else
            {
                op.CurrentPriority = EnumMergePriority.DirectMerge;
                packet             = inventory.ActivateSlot(slotId, mouseCursorInv[0], ref op);
            }

            if (packet != null)
            {
                if (packet is object[] packets)
                {
                    for (int i = 0; i < packets.Length; i++)
                    {
                        SendPacketHandler(packets[i]);
                    }
                }
                else
                {
                    SendPacketHandler?.Invoke(packet);
                }
            }

            api.Input.TriggerOnMouseClickSlot(inventory[slotId]);
        }