From 45d901a0bcc6991af5cfc0de0f3b84d709cac563 Mon Sep 17 00:00:00 2001 From: Felix Cravic Date: Fri, 22 May 2020 23:19:04 +0200 Subject: [PATCH] Lot of inventory improvements/fixes --- .../minestom/server/inventory/Inventory.java | 126 +++++++++++++----- .../inventory/InventoryClickHandler.java | 21 +-- .../server/inventory/InventoryModifier.java | 2 + .../server/inventory/PlayerInventory.java | 67 +++++----- .../click/InventoryClickProcessor.java | 18 ++- .../inventory/click/InventoryClickResult.java | 10 ++ .../server/listener/WindowListener.java | 48 ++++--- .../utils/inventory/PlayerInventoryUtils.java | 28 ++++ 8 files changed, 227 insertions(+), 93 deletions(-) diff --git a/src/main/java/net/minestom/server/inventory/Inventory.java b/src/main/java/net/minestom/server/inventory/Inventory.java index 688e07172..a89e4f2a3 100644 --- a/src/main/java/net/minestom/server/inventory/Inventory.java +++ b/src/main/java/net/minestom/server/inventory/Inventory.java @@ -11,6 +11,7 @@ import net.minestom.server.item.ItemStack; import net.minestom.server.network.packet.server.play.SetSlotPacket; import net.minestom.server.network.packet.server.play.WindowItemsPacket; import net.minestom.server.network.packet.server.play.WindowPropertyPacket; +import net.minestom.server.utils.inventory.PlayerInventoryUtils; import java.util.Arrays; import java.util.Collections; @@ -76,7 +77,7 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View @Override public void setItemStack(int slot, ItemStack itemStack) { - if (slot < 0 || slot > inventoryType.getAdditionalSlot()) + if (slot < 0 || slot > getSize()) throw new IllegalArgumentException(inventoryType.toString() + " does not have slot " + slot); safeItemInsert(slot, itemStack); @@ -97,6 +98,11 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View return Arrays.copyOf(itemStacks, itemStacks.length); } + @Override + public int getSize() { + return size; + } + @Override public List getInventoryConditions() { return inventoryConditions; @@ -107,11 +113,28 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View this.inventoryConditions.add(inventoryCondition); } + /** + * Refresh the inventory for all viewers + */ public void update() { WindowItemsPacket windowItemsPacket = getWindowItemsPacket(); sendPacketToViewers(windowItemsPacket); } + /** + * Refresh the inventory for a specific viewer + * the player needs to be a viewer, otherwise nothing is sent + * + * @param player the player to update the inventory + */ + public void update(Player player) { + if (!getViewers().contains(player)) + return; + + WindowItemsPacket windowItemsPacket = getWindowItemsPacket(); + player.getPlayerConnection().sendPacket(windowItemsPacket); + } + @Override public Set getViewers() { return Collections.unmodifiableSet(viewers); @@ -168,11 +191,11 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View } private boolean isClickInWindow(int slot) { - return slot < inventoryType.getAdditionalSlot(); + return slot < getSize(); } @Override - public void leftClick(Player player, int slot) { + public boolean leftClick(Player player, int slot) { PlayerInventory playerInventory = player.getInventory(); ItemStack cursor = getCursorItem(player); boolean isInWindow = isClickInWindow(slot); @@ -181,8 +204,9 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View InventoryClickResult clickResult = clickProcessor.leftClick(this, player, slot, clicked, cursor); - if (clickResult.doRefresh()) - player.getPlayerConnection().sendPacket(getWindowItemsPacket()); + if (clickResult.doRefresh()) { + updateFromClick(clickResult, player); + } if (isInWindow) { setItemStack(slot, clickResult.getClicked()); @@ -194,10 +218,12 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View if (!clickResult.isCancel()) callClickEvent(player, this, slot, ClickType.LEFT_CLICK, clicked, cursor); + + return !clickResult.isCancel(); } @Override - public void rightClick(Player player, int slot) { + public boolean rightClick(Player player, int slot) { PlayerInventory playerInventory = player.getInventory(); ItemStack cursor = getCursorItem(player); boolean isInWindow = isClickInWindow(slot); @@ -205,8 +231,9 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View InventoryClickResult clickResult = clickProcessor.rightClick(this, player, slot, clicked, cursor); - if (clickResult.doRefresh()) - player.getPlayerConnection().sendPacket(getWindowItemsPacket()); + if (clickResult.doRefresh()) { + updateFromClick(clickResult, player); + } if (isInWindow) { setItemStack(slot, clickResult.getClicked()); @@ -218,10 +245,12 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View if (!clickResult.isCancel()) callClickEvent(player, this, slot, ClickType.RIGHT_CLICK, clicked, cursor); + + return !clickResult.isCancel(); } @Override - public void shiftClick(Player player, int slot) { + public boolean shiftClick(Player player, int slot) { PlayerInventory playerInventory = player.getInventory(); boolean isInWindow = isClickInWindow(slot); ItemStack clicked = isInWindow ? getItemStack(slot) : playerInventory.getItemStack(slot, offset); @@ -234,7 +263,7 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View clickResult = clickProcessor.shiftClick(this, player, slot, clicked, cursor, // Player inventory loop new InventoryClickLoopHandler(0, PlayerInventory.INVENTORY_SIZE, 1, - i -> playerInventory.convertToPacketSlot(i), + i -> PlayerInventoryUtils.convertToPacketSlot(i), index -> isClickInWindow(index) ? getItemStack(index) : playerInventory.getItemStack(index, offset), (index, itemStack) -> { if (isClickInWindow(index)) { @@ -259,18 +288,21 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View } if (clickResult == null) - return; + return false; - if (clickResult.doRefresh()) - update(); + if (clickResult.doRefresh()) { + updateFromClick(clickResult, player); + } setCursorPlayerItem(player, clickResult.getCursor()); playerInventory.update(); update(); + + return !clickResult.isCancel(); } @Override - public void changeHeld(Player player, int slot, int key) { + public boolean changeHeld(Player player, int slot, int key) { PlayerInventory playerInventory = player.getInventory(); boolean isInWindow = isClickInWindow(slot); ItemStack clicked = isInWindow ? getItemStack(slot) : playerInventory.getItemStack(slot, offset); @@ -278,8 +310,9 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View InventoryClickResult clickResult = clickProcessor.changeHeld(this, player, slot, key, clicked, heldItem); - if (clickResult.doRefresh()) - player.getPlayerConnection().sendPacket(getWindowItemsPacket()); + if (clickResult.doRefresh()) { + updateFromClick(clickResult, player); + } if (isInWindow) { setItemStack(slot, clickResult.getClicked()); @@ -290,15 +323,18 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View if (!clickResult.isCancel()) callClickEvent(player, this, slot, ClickType.CHANGE_HELD, clicked, getCursorItem(player)); + + return !clickResult.isCancel(); } @Override - public void middleClick(Player player, int slot) { - + public boolean middleClick(Player player, int slot) { + // TODO + return false; } @Override - public void drop(Player player, int mode, int slot, int button) { + public boolean drop(Player player, int mode, int slot, int button) { PlayerInventory playerInventory = player.getInventory(); boolean isInWindow = isClickInWindow(slot); ItemStack clicked = slot == -999 ? @@ -308,8 +344,9 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View InventoryClickResult clickResult = clickProcessor.drop(this, player, mode, slot, button, clicked, cursor); - if (clickResult.doRefresh()) - player.getPlayerConnection().sendPacket(getWindowItemsPacket()); + if (clickResult.doRefresh()) { + updateFromClick(clickResult, player); + } ItemStack resultClicked = clickResult.getClicked(); if (isInWindow) { @@ -322,10 +359,11 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View setCursorPlayerItem(player, clickResult.getCursor()); } + return !clickResult.isCancel(); } @Override - public void dragging(Player player, int slot, int button) { + public boolean dragging(Player player, int slot, int button) { PlayerInventory playerInventory = player.getInventory(); boolean isInWindow = isClickInWindow(slot); ItemStack clicked = null; @@ -347,18 +385,21 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View } }); - if (clickResult == null) - return; - - if (isInWindow) { - setCursorPlayerItem(player, clickResult.getCursor()); - } else { - setCursorPlayerItem(player, clickResult.getCursor()); + if (clickResult == null) { + return false; } + + if (clickResult.doRefresh()) { + updateFromClick(clickResult, player); + } + + setCursorPlayerItem(player, clickResult.getCursor()); + + return !clickResult.isCancel(); } @Override - public void doubleClick(Player player, int slot) { + public boolean doubleClick(Player player, int slot) { PlayerInventory playerInventory = player.getInventory(); ItemStack cursor = getCursorItem(player); @@ -371,24 +412,39 @@ public class Inventory implements InventoryModifier, InventoryClickHandler, View (index, itemStack) -> setItemStack(index, itemStack)), // Looping through player inventory new InventoryClickLoopHandler(0, PlayerInventory.INVENTORY_SIZE - 9, 1, - i -> playerInventory.convertToPacketSlot(i), + i -> PlayerInventoryUtils.convertToPacketSlot(i), index -> playerInventory.getItemStack(index, offset), (index, itemStack) -> playerInventory.setItemStack(index, offset, itemStack)), // Player hotbar new InventoryClickLoopHandler(0, 9, 1, - i -> playerInventory.convertToPacketSlot(i), + i -> PlayerInventoryUtils.convertToPacketSlot(i), index -> playerInventory.getItemStack(index, offset), (index, itemStack) -> { playerInventory.setItemStack(index, offset, itemStack); })); if (clickResult == null) - return; + return false; if (clickResult.doRefresh()) - update(); + updateFromClick(clickResult, player); setCursorPlayerItem(player, clickResult.getCursor()); - playerInventory.update(); + + return !clickResult.isCancel(); + } + + /** + * Used to update the inventory for a specific player in order to fix his cancelled actions + * + * @param clickResult the action result + * @param player the player who did the action + */ + private void updateFromClick(InventoryClickResult clickResult, Player player) { + if (clickResult.isPlayerInventory()) { + player.getInventory().update(); + } else { + update(player); + } } } diff --git a/src/main/java/net/minestom/server/inventory/InventoryClickHandler.java b/src/main/java/net/minestom/server/inventory/InventoryClickHandler.java index 598ec5eb0..3f776f55a 100644 --- a/src/main/java/net/minestom/server/inventory/InventoryClickHandler.java +++ b/src/main/java/net/minestom/server/inventory/InventoryClickHandler.java @@ -5,23 +5,28 @@ import net.minestom.server.event.inventory.InventoryClickEvent; import net.minestom.server.inventory.click.ClickType; import net.minestom.server.item.ItemStack; +/** + * Represent an inventory which can receive click input + *

+ * all methods returning boolean returns true if the action is successful, false otherwise + */ public interface InventoryClickHandler { - void leftClick(Player player, int slot); + boolean leftClick(Player player, int slot); - void rightClick(Player player, int slot); + boolean rightClick(Player player, int slot); - void shiftClick(Player player, int slot); // shift + left/right click have the same behavior + boolean shiftClick(Player player, int slot); // shift + left/right click have the same behavior - void changeHeld(Player player, int slot, int key); + boolean changeHeld(Player player, int slot, int key); - void middleClick(Player player, int slot); + boolean middleClick(Player player, int slot); - void drop(Player player, int mode, int slot, int button); + boolean drop(Player player, int mode, int slot, int button); - void dragging(Player player, int slot, int button); + boolean dragging(Player player, int slot, int button); - void doubleClick(Player player, int slot); + boolean doubleClick(Player player, int slot); default void callClickEvent(Player player, Inventory inventory, int slot, ClickType clickType, ItemStack clicked, ItemStack cursor) { diff --git a/src/main/java/net/minestom/server/inventory/InventoryModifier.java b/src/main/java/net/minestom/server/inventory/InventoryModifier.java index 0fd9031d6..07bf5640f 100644 --- a/src/main/java/net/minestom/server/inventory/InventoryModifier.java +++ b/src/main/java/net/minestom/server/inventory/InventoryModifier.java @@ -15,6 +15,8 @@ public interface InventoryModifier { ItemStack[] getItemStacks(); + int getSize(); + List getInventoryConditions(); void addInventoryCondition(InventoryCondition inventoryCondition); diff --git a/src/main/java/net/minestom/server/inventory/PlayerInventory.java b/src/main/java/net/minestom/server/inventory/PlayerInventory.java index 8172487eb..60467b83f 100644 --- a/src/main/java/net/minestom/server/inventory/PlayerInventory.java +++ b/src/main/java/net/minestom/server/inventory/PlayerInventory.java @@ -13,6 +13,7 @@ import net.minestom.server.network.packet.server.play.EntityEquipmentPacket; import net.minestom.server.network.packet.server.play.SetSlotPacket; import net.minestom.server.network.packet.server.play.WindowItemsPacket; import net.minestom.server.network.player.PlayerConnection; +import net.minestom.server.utils.MathUtils; import java.util.Arrays; import java.util.List; @@ -101,6 +102,11 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler return false; } + @Override + public int getSize() { + return INVENTORY_SIZE; + } + @Override public ItemStack getItemInMainHand() { return getItemStack(player.getHeldSlot()); @@ -235,24 +241,9 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler return this.items[slot]; } - protected int convertToPacketSlot(int slot) { - if (slot > -1 && slot < 9) { // Held bar 0-9 - slot = slot + 36; - } else if (slot > 8 && slot < 36) { // Inventory 9-35 - slot = slot; - } else if (slot >= CRAFT_RESULT && slot <= CRAFT_SLOT_4) { // Crafting 36-40 - slot = slot - 36; - } else if (slot >= HELMET_SLOT && slot <= BOOTS_SLOT) { // Armor 41-44 - slot = slot - 36; - } else if (slot == OFFHAND_SLOT) { // Off hand - slot = 45; - } - return slot; - } - private void sendSlotRefresh(short slot, ItemStack itemStack) { SetSlotPacket setSlotPacket = new SetSlotPacket(); - setSlotPacket.windowId = (byte) (slot > 35 && slot < INVENTORY_SIZE ? 0 : -2); + setSlotPacket.windowId = (byte) (MathUtils.isBetween(slot, 35, INVENTORY_SIZE) ? 0 : -2); setSlotPacket.slot = slot; setSlotPacket.itemStack = itemStack; player.getPlayerConnection().sendPacket(setSlotPacket); @@ -274,7 +265,7 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler } @Override - public void leftClick(Player player, int slot) { + public boolean leftClick(Player player, int slot) { ItemStack cursor = getCursorItem(); ItemStack clicked = getItemStack(convertSlot(slot, OFFSET)); @@ -288,10 +279,12 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler if (!clickResult.isCancel()) callClickEvent(player, null, slot, ClickType.LEFT_CLICK, clicked, cursor); + + return !clickResult.isCancel(); } @Override - public void rightClick(Player player, int slot) { + public boolean rightClick(Player player, int slot) { ItemStack cursor = getCursorItem(); ItemStack clicked = getItemStack(slot, OFFSET); @@ -305,15 +298,18 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler if (!clickResult.isCancel()) callClickEvent(player, null, slot, ClickType.RIGHT_CLICK, clicked, cursor); + + return !clickResult.isCancel(); } @Override - public void middleClick(Player player, int slot) { - + public boolean middleClick(Player player, int slot) { + // TODO + return false; } @Override - public void drop(Player player, int mode, int slot, int button) { + public boolean drop(Player player, int mode, int slot, int button) { ItemStack cursor = getCursorItem(); ItemStack clicked = slot == -999 ? null : getItemStack(slot, OFFSET); @@ -327,10 +323,12 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler if (resultClicked != null) setItemStack(slot, OFFSET, resultClicked); setCursorItem(clickResult.getCursor()); + + return !clickResult.isCancel(); } @Override - public void shiftClick(Player player, int slot) { + public boolean shiftClick(Player player, int slot) { ItemStack cursor = getCursorItem(); ItemStack clicked = getItemStack(slot, OFFSET); @@ -348,18 +346,20 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler (index, itemStack) -> setItemStack(index, OFFSET, itemStack))); if (clickResult == null) - return; + return false; if (clickResult.doRefresh()) update(); setCursorItem(clickResult.getCursor()); + + return !clickResult.isCancel(); } @Override - public void changeHeld(Player player, int slot, int key) { + public boolean changeHeld(Player player, int slot, int key) { if (!getCursorItem().isAir()) - return; + return false; ItemStack heldItem = getItemStack(key); ItemStack clicked = getItemStack(slot, OFFSET); @@ -374,10 +374,12 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler if (!clickResult.isCancel()) callClickEvent(player, null, slot, ClickType.CHANGE_HELD, clicked, getCursorItem()); + + return !clickResult.isCancel(); } @Override - public void dragging(Player player, int slot, int button) { + public boolean dragging(Player player, int slot, int button) { ItemStack cursor = getCursorItem(); ItemStack clicked = null; if (slot != -999) @@ -388,17 +390,20 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler clicked, cursor, s -> getItemStack(s, OFFSET), (s, item) -> setItemStack(s, OFFSET, item)); - if (clickResult == null) - return; + if (clickResult == null) { + return false; + } if (clickResult.doRefresh()) update(); setCursorItem(clickResult.getCursor()); + + return !clickResult.isCancel(); } @Override - public void doubleClick(Player player, int slot) { + public boolean doubleClick(Player player, int slot) { ItemStack cursor = getCursorItem(); InventoryClickResult clickResult = clickProcessor.doubleClick(null, player, slot, cursor, @@ -408,11 +413,13 @@ public class PlayerInventory implements InventoryModifier, InventoryClickHandler (index, itemStack) -> setItemStack(index, itemStack))); if (clickResult == null) - return; + return false; if (clickResult.doRefresh()) update(); setCursorItem(clickResult.getCursor()); + + return !clickResult.isCancel(); } } 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 9fffb39fd..bfa64a713 100644 --- a/src/main/java/net/minestom/server/inventory/click/InventoryClickProcessor.java +++ b/src/main/java/net/minestom/server/inventory/click/InventoryClickProcessor.java @@ -127,7 +127,10 @@ public class InventoryClickProcessor { return clickResult; } - clickResult = startCondition(clickResult, inventory, player, key, ClickType.CHANGE_HELD, clicked, cursor); + // Converted again during the inventory condition calling to internal slot + int keySlot = PlayerInventoryUtils.convertToPacketSlot(key); + clickResult = startCondition(clickResult, null, player, keySlot, ClickType.CHANGE_HELD, clicked, cursor); + if (clickResult.isCancel()) { return clickResult; } @@ -478,13 +481,18 @@ public class InventoryClickProcessor { return clickResult; } - private InventoryClickResult startCondition(InventoryClickResult clickResult, Inventory inventory, Player player, int slot, ClickType clickType, ItemStack clicked, ItemStack cursor) { + private InventoryClickResult startCondition(InventoryClickResult clickResult, Inventory inventory, + Player player, int slot, ClickType clickType, + ItemStack clicked, ItemStack cursor) { boolean isPlayerInventory = inventory == null; - int inventorySlot = isPlayerInventory ? 0 : inventory.getInventoryType().getAdditionalSlot(); + int inventorySlot = isPlayerInventory ? 0 : inventory.getSize(); isPlayerInventory = isPlayerInventory ? isPlayerInventory : slot >= inventorySlot; - if (isPlayerInventory && inventory != null) + clickResult.setPlayerInventory(isPlayerInventory); + + if (isPlayerInventory && inventory != null) { slot = slot - inventorySlot + PlayerInventoryUtils.OFFSET; + } List inventoryConditions = isPlayerInventory ? player.getInventory().getInventoryConditions() : inventory.getInventoryConditions(); @@ -507,8 +515,8 @@ public class InventoryClickProcessor { cursor = result.getCursorItem(); clicked = result.getClickedItem(); - clickResult.setClicked(clicked); clickResult.setCursor(cursor); + clickResult.setClicked(clicked); clickResult.setCancel(result.isCancel()); if (result.isCancel()) { diff --git a/src/main/java/net/minestom/server/inventory/click/InventoryClickResult.java b/src/main/java/net/minestom/server/inventory/click/InventoryClickResult.java index 9ba746904..9b29192ba 100644 --- a/src/main/java/net/minestom/server/inventory/click/InventoryClickResult.java +++ b/src/main/java/net/minestom/server/inventory/click/InventoryClickResult.java @@ -7,6 +7,8 @@ public class InventoryClickResult { private ItemStack clicked; private ItemStack cursor; + private boolean playerInventory; + private boolean cancel; private boolean refresh; @@ -31,6 +33,14 @@ public class InventoryClickResult { this.cursor = cursor; } + public boolean isPlayerInventory() { + return playerInventory; + } + + protected void setPlayerInventory(boolean playerInventory) { + this.playerInventory = playerInventory; + } + public boolean isCancel() { return cancel; } diff --git a/src/main/java/net/minestom/server/listener/WindowListener.java b/src/main/java/net/minestom/server/listener/WindowListener.java index 38d410d1e..27382ef45 100644 --- a/src/main/java/net/minestom/server/listener/WindowListener.java +++ b/src/main/java/net/minestom/server/listener/WindowListener.java @@ -27,10 +27,7 @@ public class WindowListener { // System.out.println("Window id: " + windowId + " | slot: " + slot + " | button: " + button + " | mode: " + mode); - WindowConfirmationPacket windowConfirmationPacket = new WindowConfirmationPacket(); - windowConfirmationPacket.windowId = windowId; - windowConfirmationPacket.actionNumber = actionNumber; - windowConfirmationPacket.accepted = true; // Change depending on output + boolean successful = false; switch (mode) { case 0: @@ -38,53 +35,74 @@ public class WindowListener { case 0: if (slot != -999) { // Left click - clickHandler.leftClick(player, slot); + successful = clickHandler.leftClick(player, slot); } else { // DROP - clickHandler.drop(player, mode, slot, button); + successful = clickHandler.drop(player, mode, slot, button); } break; case 1: if (slot != -999) { // Right click - clickHandler.rightClick(player, slot); + successful = clickHandler.rightClick(player, slot); } else { // DROP - clickHandler.drop(player, mode, slot, button); + successful = clickHandler.drop(player, mode, slot, button); } break; } break; case 1: - clickHandler.shiftClick(player, slot); // Shift + left/right have identical behavior + successful = clickHandler.shiftClick(player, slot); // Shift + left/right have identical behavior break; case 2: - clickHandler.changeHeld(player, slot, button); + successful = clickHandler.changeHeld(player, slot, button); break; case 3: // Middle click (only creative players in non-player inventories) break; case 4: // Dropping functions - clickHandler.drop(player, mode, slot, button); + successful = clickHandler.drop(player, mode, slot, button); break; case 5: // Dragging - clickHandler.dragging(player, slot, button); + successful = clickHandler.dragging(player, slot, button); break; case 6: - clickHandler.doubleClick(player, slot); + successful = clickHandler.doubleClick(player, slot); break; } - ItemStack cursorItem = clickHandler instanceof Inventory ? ((Inventory) clickHandler).getCursorItem(player) : ((PlayerInventory) clickHandler).getCursorItem(); + refreshCursorItem(player, player.getOpenInventory()); + + WindowConfirmationPacket windowConfirmationPacket = new WindowConfirmationPacket(); + windowConfirmationPacket.windowId = windowId; + windowConfirmationPacket.actionNumber = actionNumber; + windowConfirmationPacket.accepted = successful; + + player.getPlayerConnection().sendPacket(windowConfirmationPacket); + } + + private static void refreshCursorItem(Player player, Inventory inventory) { + PlayerInventory playerInventory = player.getInventory(); + + ItemStack cursorItem; + if (inventory != null) { + cursorItem = inventory.getCursorItem(player); + } else { + cursorItem = playerInventory.getCursorItem(); + } + + // Setting the window id properly seems to broke +64 stack support + //byte windowId = inventory == null ? 0 : inventory.getWindowId(); + SetSlotPacket setSlotPacket = new SetSlotPacket(); setSlotPacket.windowId = -1; setSlotPacket.slot = -1; setSlotPacket.itemStack = cursorItem; player.getPlayerConnection().sendPacket(setSlotPacket); - player.getPlayerConnection().sendPacket(windowConfirmationPacket); } public static void closeWindowListener(ClientCloseWindow packet, Player player) { diff --git a/src/main/java/net/minestom/server/utils/inventory/PlayerInventoryUtils.java b/src/main/java/net/minestom/server/utils/inventory/PlayerInventoryUtils.java index 9fb9a9fd8..1d2ef0564 100644 --- a/src/main/java/net/minestom/server/utils/inventory/PlayerInventoryUtils.java +++ b/src/main/java/net/minestom/server/utils/inventory/PlayerInventoryUtils.java @@ -16,6 +16,13 @@ public class PlayerInventoryUtils { public static final int BOOTS_SLOT = 44; public static final int OFFHAND_SLOT = 45; + /** + * Convert a packet slot to an internal one + * + * @param slot the packet slot + * @param offset the slot count separating the up part of the inventory to the bottom part (armor/craft in PlayerInventory, inventory slots in others) + * @return a packet which can be use internally with Minestom + */ public static int convertSlot(int slot, int offset) { switch (slot) { case 0: @@ -48,4 +55,25 @@ public class PlayerInventoryUtils { //System.out.println("CONVERT: " + slot); return slot; } + + /** + * Used to convert internal slot to one used in packets + * + * @param slot the internal slot + * @return a slot id which can be used for packets + */ + public static int convertToPacketSlot(int slot) { + if (slot > -1 && slot < 9) { // Held bar 0-9 + slot = slot + 36; + } else if (slot > 8 && slot < 36) { // Inventory 9-35 + slot = slot; + } else if (slot >= CRAFT_RESULT && slot <= CRAFT_SLOT_4) { // Crafting 36-40 + slot = slot - 36; + } else if (slot >= HELMET_SLOT && slot <= BOOTS_SLOT) { // Armor 41-44 + slot = slot - 36; + } else if (slot == OFFHAND_SLOT) { // Off hand + slot = 45; + } + return slot; + } }