From 5b66fcfab509055fbb6b0bba87c29189cbd632e8 Mon Sep 17 00:00:00 2001 From: Gunjan Jaswal Date: Mon, 13 Jul 2026 07:36:21 +0530 Subject: [PATCH] Fix wrong slot data when clicking your own inventory during invsee Opening another player's inventory renders their inventory as a generic 9x4 chest (36 slots), but a player inventory reports a size of 41 since it also counts the armour and off-hand slots. The view's slot math used that reported size, so clicks in the bottom (viewer's own) inventory were mapped five slots off, making InventoryClickEvent report an unrelated slot and item. Route the top-slot count through an overridable helper and, for a player inventory shown in a container, use the number of slots actually laid out so the raw-to-inventory slot mapping lines up again. --- .../inventory/CraftAbstractInventoryView.java | 15 +++++++++++---- .../craftbukkit/inventory/CraftContainer.java | 12 ++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftAbstractInventoryView.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftAbstractInventoryView.java index 48c0a876fd54..876eda8d82b6 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftAbstractInventoryView.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftAbstractInventoryView.java @@ -56,16 +56,23 @@ public Inventory getInventory(final int rawSlot) { } public Inventory mapValidSlotToInventory(final int rawSlot) { - if (rawSlot < this.getTopInventory().getSize()) { + if (rawSlot < this.getTopSlots()) { return this.getTopInventory(); } else { return this.getBottomInventory(); } } + // The number of raw slots the top inventory occupies in the open menu. This is + // usually just its size, but a view can override it when the menu renders fewer + // slots than the inventory reports (e.g. a player inventory shown as a chest). + public int getTopSlots() { + return this.getTopInventory().getSize(); + } + @Override public int convertSlot(final int rawSlot) { - int numInTop = this.getTopInventory().getSize(); + int numInTop = this.getTopSlots(); // Index from the top inventory as having slots from [0,size] if (rawSlot < numInTop) { return rawSlot; @@ -132,7 +139,7 @@ public int convertSlot(final int rawSlot) { @Override public InventoryType.SlotType getSlotType(final int slot) { InventoryType.SlotType type = InventoryType.SlotType.CONTAINER; - if (slot >= 0 && slot < this.getTopInventory().getSize()) { + if (slot >= 0 && slot < this.getTopSlots()) { switch (this.getType()) { case BLAST_FURNACE: case FURNACE: @@ -229,7 +236,7 @@ public void close() { @Override public int countSlots() { - return this.getTopInventory().getSize() + this.getBottomInventory().getSize(); + return this.getTopSlots() + this.getBottomInventory().getSize(); } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java index 2f41a92465b9..fe6f9da3dfe5 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java @@ -72,6 +72,18 @@ public InventoryType getType() { return inventory.getType(); } + @Override + public int getTopSlots() { + // A player inventory shown inside a container is laid out as a generic + // chest (whole rows of 9), so the armour and off-hand slots that + // getSize() counts are not rendered. Use the number of slots actually + // laid out so the raw-slot mapping matches the open menu. + if (inventory.getType() == InventoryType.PLAYER) { + return (inventory.getSize() / 9) * 9; + } + return inventory.getSize(); + } + // Paper start @Override public net.kyori.adventure.text.Component title() {