From a75910fe3fd348a58b40250f510f66bfa038f9c6 Mon Sep 17 00:00:00 2001 From: TheMode Date: Sun, 29 Aug 2021 00:07:58 +0200 Subject: [PATCH] Fix drag clicks --- .../minestom/server/inventory/Inventory.java | 13 +--- .../server/inventory/PlayerInventory.java | 4 +- .../click/InventoryClickProcessor.java | 67 +++++++++++-------- 3 files changed, 40 insertions(+), 44 deletions(-) diff --git a/src/main/java/net/minestom/server/inventory/Inventory.java b/src/main/java/net/minestom/server/inventory/Inventory.java index edc155626..c8a253939 100644 --- a/src/main/java/net/minestom/server/inventory/Inventory.java +++ b/src/main/java/net/minestom/server/inventory/Inventory.java @@ -401,18 +401,7 @@ public class Inventory extends AbstractInventory implements Viewable { final InventoryClickResult clickResult = clickProcessor.dragging(player, slot != -999 ? (isInWindow ? this : playerInventory) : null, clickSlot, button, - clicked, cursor, - - s -> isClickInWindow(s) ? getItemStack(s) : - playerInventory.getItemStack(PlayerInventoryUtils.convertSlot(s, offset)), - - (s, item) -> { - if (isClickInWindow(s)) { - setItemStack(s, item); - } else { - playerInventory.setItemStack(PlayerInventoryUtils.convertSlot(s, offset), item); - } - }); + clicked, cursor); if (clickResult == null || clickResult.isCancel()) { updateAll(player); return false; diff --git a/src/main/java/net/minestom/server/inventory/PlayerInventory.java b/src/main/java/net/minestom/server/inventory/PlayerInventory.java index af3fbe2d2..def1fdca1 100644 --- a/src/main/java/net/minestom/server/inventory/PlayerInventory.java +++ b/src/main/java/net/minestom/server/inventory/PlayerInventory.java @@ -317,9 +317,7 @@ public class PlayerInventory extends AbstractInventory implements EquipmentHandl final ItemStack cursor = getCursorItem(); final ItemStack clicked = slot != -999 ? getItemStackFromPacketSlot(slot) : ItemStack.AIR; final InventoryClickResult clickResult = clickProcessor.dragging(player, this, - slot, button, - clicked, cursor, this::getItemStackFromPacketSlot, - this::setItemStackFromPacketSlot); + convertPlayerInventorySlot(slot, OFFSET), button, clicked, cursor); if (clickResult == null || clickResult.isCancel()) { update(); return false; diff --git a/src/main/java/net/minestom/server/inventory/click/InventoryClickProcessor.java b/src/main/java/net/minestom/server/inventory/click/InventoryClickProcessor.java index acc8ffa10..b88ba53b7 100644 --- a/src/main/java/net/minestom/server/inventory/click/InventoryClickProcessor.java +++ b/src/main/java/net/minestom/server/inventory/click/InventoryClickProcessor.java @@ -1,8 +1,5 @@ package net.minestom.server.inventory.click; -import it.unimi.dsi.fastutil.ints.Int2ObjectFunction; -import it.unimi.dsi.fastutil.ints.IntOpenHashSet; -import it.unimi.dsi.fastutil.ints.IntSet; import net.minestom.server.entity.EquipmentSlot; import net.minestom.server.entity.Player; import net.minestom.server.event.EventDispatcher; @@ -18,18 +15,18 @@ import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; -import java.util.function.BiConsumer; import java.util.function.BiFunction; @ApiStatus.Internal public final class InventoryClickProcessor { // Dragging maps - private final Map leftDraggingMap = new ConcurrentHashMap<>(); - private final Map rightDraggingMap = new ConcurrentHashMap<>(); + private final Map> leftDraggingMap = new ConcurrentHashMap<>(); + private final Map> rightDraggingMap = new ConcurrentHashMap<>(); public @NotNull InventoryClickResult leftClick(@NotNull Player player, @NotNull AbstractInventory inventory, int slot, @@ -162,23 +159,21 @@ public final class InventoryClickProcessor { public @Nullable InventoryClickResult dragging(@NotNull Player player, @Nullable AbstractInventory inventory, int slot, int button, - @NotNull ItemStack clicked, @NotNull ItemStack cursor, - @NotNull Int2ObjectFunction itemGetter, - @NotNull BiConsumer itemSetter) { + @NotNull ItemStack clicked, @NotNull ItemStack cursor) { InventoryClickResult clickResult = null; final StackingRule stackingRule = cursor.getStackingRule(); if (slot != -999) { // Add slot if (button == 1) { // Add left - IntSet left = leftDraggingMap.get(player); + List left = leftDraggingMap.get(player); if (left == null) return null; - left.add(slot); + left.add(new DragData(slot, inventory)); } else if (button == 5) { // Add right - IntSet right = rightDraggingMap.get(player); + List right = rightDraggingMap.get(player); if (right == null) return null; - right.add(slot); + right.add(new DragData(slot, inventory)); } else if (button == 9) { // Add middle // TODO @@ -188,18 +183,18 @@ public final class InventoryClickProcessor { if (button == 0) { // Start left clickResult = startCondition(player, inventory, slot, ClickType.START_LEFT_DRAGGING, clicked, cursor); - if (!clickResult.isCancel()) this.leftDraggingMap.put(player, new IntOpenHashSet()); + if (!clickResult.isCancel()) this.leftDraggingMap.put(player, new ArrayList<>()); } else if (button == 2) { // End left - final IntSet slots = leftDraggingMap.remove(player); + final List slots = leftDraggingMap.remove(player); if (slots == null) return null; final int slotCount = slots.size(); final int cursorAmount = stackingRule.getAmount(cursor); if (slotCount > cursorAmount) return null; - for (int s : slots) { + for (DragData s : slots) { // Apply each drag element - final ItemStack slotItem = itemGetter.apply(s); - clickResult = startCondition(player, inventory, s, ClickType.LEFT_DRAGGING, slotItem, cursor); + final ItemStack slotItem = s.inventory.getItemStack(s.slot); + clickResult = startCondition(player, s.inventory, s.slot, ClickType.LEFT_DRAGGING, slotItem, cursor); if (clickResult.isCancel()) { return clickResult; } @@ -210,8 +205,10 @@ public final class InventoryClickProcessor { final int slotSize = (int) ((float) cursorAmount / (float) slotCount); // Place all waiting drag action int finalCursorAmount = cursorAmount; - for (int s : slots) { - ItemStack slotItem = itemGetter.apply(s); + for (DragData dragData : slots) { + final var inv = dragData.inventory; + final int s = dragData.slot; + ItemStack slotItem = inv.getItemStack(s); final StackingRule slotItemRule = slotItem.getStackingRule(); final int amount = slotItemRule.getAmount(slotItem); if (stackingRule.canBeStacked(cursor, slotItem)) { @@ -231,7 +228,7 @@ public final class InventoryClickProcessor { slotItem = stackingRule.apply(cursor, slotSize); finalCursorAmount -= slotSize; } - itemSetter.accept(s, slotItem); + inv.setItemStack(s, slotItem); callClickEvent(player, inventory, s, ClickType.LEFT_DRAGGING, slotItem, cursor); } // Update the cursor @@ -239,18 +236,18 @@ public final class InventoryClickProcessor { } else if (button == 4) { // Start right clickResult = startCondition(player, inventory, slot, ClickType.START_RIGHT_DRAGGING, clicked, cursor); - if (!clickResult.isCancel()) this.rightDraggingMap.put(player, new IntOpenHashSet()); + if (!clickResult.isCancel()) this.rightDraggingMap.put(player, new ArrayList<>()); } else if (button == 6) { // End right - final IntSet slots = rightDraggingMap.remove(player); + final List slots = rightDraggingMap.remove(player); if (slots == null) return null; final int size = slots.size(); int cursorAmount = stackingRule.getAmount(cursor); if (size > cursorAmount) return null; // Verify if each slot can be modified (or cancel the whole drag) - for (int s : slots) { - ItemStack slotItem = itemGetter.apply(s); - clickResult = startCondition(player, inventory, s, ClickType.RIGHT_DRAGGING, slotItem, cursor); + for (DragData s : slots) { + final ItemStack slotItem = s.inventory.getItemStack(s.slot); + clickResult = startCondition(player, s.inventory, s.slot, ClickType.RIGHT_DRAGGING, slotItem, cursor); if (clickResult.isCancel()) { return clickResult; } @@ -259,8 +256,10 @@ public final class InventoryClickProcessor { if (clickResult.isCancel()) return clickResult; // Place all waiting drag action int finalCursorAmount = cursorAmount; - for (int s : slots) { - ItemStack slotItem = itemGetter.apply(s); + for (DragData dragData : slots) { + final var inv = dragData.inventory; + final int s = dragData.slot; + ItemStack slotItem = inv.getItemStack(s); StackingRule slotItemRule = slotItem.getStackingRule(); if (stackingRule.canBeStacked(cursor, slotItem)) { // Compatible item in the slot, increment by 1 @@ -274,7 +273,7 @@ public final class InventoryClickProcessor { slotItem = stackingRule.apply(cursor, 1); finalCursorAmount -= 1; } - itemSetter.accept(s, slotItem); + inv.setItemStack(s, slotItem); callClickEvent(player, inventory, s, ClickType.RIGHT_DRAGGING, slotItem, cursor); } // Update the cursor @@ -462,4 +461,14 @@ public final class InventoryClickProcessor { this.leftDraggingMap.remove(player); this.rightDraggingMap.remove(player); } + + private static final class DragData { + private final int slot; + private final AbstractInventory inventory; + + public DragData(int slot, AbstractInventory inventory) { + this.slot = slot; + this.inventory = inventory; + } + } }