From acca9a78aff3842596e8d7ec5699f80250a722e7 Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Thu, 26 Feb 2026 18:53:51 +0000 Subject: [PATCH 1/4] Cleanup crafter slot diff --- .../inventory/CraftAbstractInventoryView.java | 71 +++---------------- .../inventory/view/CraftCrafterView.java | 50 +++++++++++++ 2 files changed, 60 insertions(+), 61 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 981a4ab3afc0..8d38d66c6408 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 @@ -52,19 +52,10 @@ public Inventory getInventory(final int rawSlot) { } Preconditions.checkArgument(rawSlot >= 0, "Negative, non outside slot %s", rawSlot); Preconditions.checkArgument(rawSlot < this.countSlots(), "Slot %s greater than inventory slot count", rawSlot); + return mapValidSlotToInventory(rawSlot); + } - // Paper start - Fix crafter slot ID conversions - if (this.getType() == InventoryType.CRAFTER) { - // Raw slot ID for crafter inventory views is 45 for result slot and 0-8 for crafting grid slots. - // Crafter inventory size is 10. Only check 0-8 and 45. - if (rawSlot < (this.getTopInventory().getSize() - 1) || rawSlot == 45) { - return this.getTopInventory(); - } else { - return this.getBottomInventory(); - } - } - // Paper end - Fix crafter slot ID conversions - + public Inventory mapValidSlotToInventory(final int rawSlot) { if (rawSlot < this.getTopInventory().getSize()) { return this.getTopInventory(); } else { @@ -74,43 +65,6 @@ public Inventory getInventory(final int rawSlot) { @Override public int convertSlot(final int rawSlot) { - // Paper start - Fix crafter slot ID conversions - // Crafter inventory size is 10, but the view uses non-contiguous raw slot IDs 0-8 (grid) and 45 (result). - // The numInTop check and slot number shift lower in this method assume contiguous slot IDs. - if (this.getType() == InventoryType.CRAFTER) { - /* - * Raw Slots: - * - * 0 1 2 - * 3 4 5 45 - * 6 7 8 - * 9 10 11 12 13 14 15 16 17 - * 18 19 20 21 22 23 24 25 26 - * 27 28 29 30 31 32 33 34 35 - * 36 37 38 39 40 41 42 43 44 - */ - - /* - * Converted Slots: - * - * 0 1 2 - * 3 4 5 9 - * 6 7 8 - * 9 10 11 12 13 14 15 16 17 - * 18 19 20 21 22 23 24 25 26 - * 27 28 29 30 31 32 33 34 35 - * 0 1 2 3 4 5 6 7 8 - */ - if (rawSlot == 45) { - return 9; // Result - } else if (rawSlot >= 36) { - return rawSlot - 36; // Quickbar - } else { - return rawSlot; // Crafting grid or player inventory - } - } - // Paper end - Fix crafter slot ID conversions - int numInTop = this.getTopInventory().getSize(); // Index from the top inventory as having slots from [0,size] if (rawSlot < numInTop) { @@ -178,18 +132,7 @@ public int convertSlot(final int rawSlot) { @Override public InventoryType.SlotType getSlotType(final int slot) { InventoryType.SlotType type = InventoryType.SlotType.CONTAINER; - // Paper start - Fix crafter slot ID conversions - if (this.getType() == InventoryType.CRAFTER) { - // Crafter inventory size is 10, but the view uses non-contiguous raw slot IDs 0-8 (grid) and 45 (result). - if (slot < 0) { - type = InventoryType.SlotType.OUTSIDE; - } else if (slot == 45) { - type = InventoryType.SlotType.RESULT; - } else if (slot > 35) { - type = InventoryType.SlotType.QUICKBAR; - } - } else if (slot >= 0 && slot < this.getTopInventory().getSize()) { - // Paper end - Fix crafter slot ID conversions + if (slot >= 0 && slot < this.getTopInventory().getSize()) { switch (this.getType()) { case BLAST_FURNACE: case FURNACE: @@ -261,6 +204,12 @@ public InventoryType.SlotType getSlotType(final int slot) { } else if (slot > 35) { type = InventoryType.SlotType.QUICKBAR; } + } else if (this.getType() == InventoryType.CRAFTER) { + if (slot == 45) { + type = InventoryType.SlotType.RESULT; + } else if (slot > 35) { + type = InventoryType.SlotType.QUICKBAR; + } } else if (slot >= (this.countSlots() - (9 + 4 + 1))) { // Quickbar, Armor, Offhand type = InventoryType.SlotType.QUICKBAR; } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/CraftCrafterView.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/CraftCrafterView.java index f8bc61ba35d6..33cf0cc65eea 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/CraftCrafterView.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/CraftCrafterView.java @@ -4,8 +4,11 @@ import net.minecraft.world.inventory.CrafterMenu; import org.bukkit.craftbukkit.inventory.CraftInventoryView; import org.bukkit.entity.HumanEntity; +import org.bukkit.event.inventory.InventoryType; import org.bukkit.inventory.CrafterInventory; +import org.bukkit.inventory.Inventory; import org.bukkit.inventory.view.CrafterView; +import org.jetbrains.annotations.Nullable; public class CraftCrafterView extends CraftInventoryView implements CrafterView { @@ -23,6 +26,53 @@ public boolean isPowered() { return this.container.isPowered(); } + @Override + public int convertSlot(final int rawSlot) { + // Crafter inventory size is 10, but the view uses non-contiguous raw slot IDs 0-8 (grid) and 45 (result). + // The numInTop check and slot number shift lower in this method assume contiguous slot IDs. + /* + * Raw Slots: + * + * 0 1 2 + * 3 4 5 45 + * 6 7 8 + * 9 10 11 12 13 14 15 16 17 + * 18 19 20 21 22 23 24 25 26 + * 27 28 29 30 31 32 33 34 35 + * 36 37 38 39 40 41 42 43 44 + */ + + /* + * Converted Slots: + * + * 0 1 2 + * 3 4 5 9 + * 6 7 8 + * 9 10 11 12 13 14 15 16 17 + * 18 19 20 21 22 23 24 25 26 + * 27 28 29 30 31 32 33 34 35 + * 0 1 2 3 4 5 6 7 8 + */ + if (rawSlot == 45) { + return 9; // Result + } else if (rawSlot >= 36) { + return rawSlot - 36; // Quickbar + } else { + return rawSlot; // Crafting grid or player inventory + } + } + + @Override + public @Nullable Inventory mapValidSlotToInventory(final int rawSlot) { + // Raw slot ID for crafter inventory views is 45 for result slot and 0-8 for crafting grid slots. + // Crafter inventory size is 10. Only check 0-8 and 45. + if (rawSlot < (this.getTopInventory().getSize() - 1) || rawSlot == 45) { + return this.getTopInventory(); + } else { + return this.getBottomInventory(); + } + } + @Override public void setSlotDisabled(final int slot, final boolean disabled) { Preconditions.checkArgument(slot >= 0 && slot < 9, "Invalid slot index %s for Crafter", slot); From fb7e364d184654d234c2a92ec1540a16bea2c7cb Mon Sep 17 00:00:00 2001 From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Date: Sat, 28 Feb 2026 16:01:11 +0100 Subject: [PATCH 2/4] swap some nullable annotations --- .../org/bukkit/inventory/EntityEquipment.java | 22 ++++++++----------- .../org/bukkit/inventory/PlayerInventory.java | 12 ++++------ .../inventory/view/CraftCrafterView.java | 4 +--- 3 files changed, 14 insertions(+), 24 deletions(-) diff --git a/paper-api/src/main/java/org/bukkit/inventory/EntityEquipment.java b/paper-api/src/main/java/org/bukkit/inventory/EntityEquipment.java index 00e63c3ecf09..1bbacc6ac421 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/EntityEquipment.java +++ b/paper-api/src/main/java/org/bukkit/inventory/EntityEquipment.java @@ -162,7 +162,7 @@ public interface EntityEquipment { * *

* This returns a copy if this equipment instance is from a non-player. - * For stacks from players, this returns a live mirror (or null). You can check if this + * For items from players, this returns a live mirror. You can check if this * will return a mirror with *

{@code
      * EntityEquipment equipment = entity.getEquipment();
@@ -175,8 +175,7 @@ public interface EntityEquipment {
      *
      * @return The helmet being worn
      */
-    @org.bukkit.UndefinedNullability("not null for entities, nullable for players") // Paper
-    ItemStack getHelmet();
+    @NotNull ItemStack getHelmet();
 
     /**
      * Sets the helmet worn by the entity
@@ -198,7 +197,7 @@ public interface EntityEquipment {
      *
      * 

* This returns a copy if this equipment instance is from a non-player. - * For stacks from players, this returns a live mirror (or null). You can check if this + * For items from players, this returns a live mirror. You can check if this * will return a mirror with *

{@code
      * EntityEquipment equipment = entity.getEquipment();
@@ -211,8 +210,7 @@ public interface EntityEquipment {
      *
      * @return The chest plate being worn
      */
-    @org.bukkit.UndefinedNullability("not null for entities, nullable for players") // Paper
-    ItemStack getChestplate();
+    @NotNull ItemStack getChestplate();
 
     /**
      * Sets the chest plate worn by the entity
@@ -234,7 +232,7 @@ public interface EntityEquipment {
      *
      * 

* This returns a copy if this equipment instance is from a non-player. - * For stacks from players, this returns a live mirror (or null). You can check if this + * For items from players, this returns a live mirror. You can check if this * will return a mirror with *

{@code
      * EntityEquipment equipment = entity.getEquipment();
@@ -247,8 +245,7 @@ public interface EntityEquipment {
      *
      * @return The leggings being worn
      */
-    @org.bukkit.UndefinedNullability("not null for entities, nullable for players") // Paper
-    ItemStack getLeggings();
+    @NotNull ItemStack getLeggings();
 
     /**
      * Sets the leggings worn by the entity
@@ -270,7 +267,7 @@ public interface EntityEquipment {
      *
      * 

* This returns a copy if this equipment instance is from a non-player. - * For stacks from players, this returns a live mirror (or null). You can check if this + * For items from players, this returns a live mirror. You can check if this * will return a mirror with *

{@code
      * EntityEquipment equipment = entity.getEquipment();
@@ -283,8 +280,7 @@ public interface EntityEquipment {
      *
      * @return The boots being worn
      */
-    @org.bukkit.UndefinedNullability("not null for entities, nullable for players") // Paper
-    ItemStack getBoots();
+    @NotNull ItemStack getBoots();
 
     /**
      * Sets the boots worn by the entity
@@ -307,7 +303,7 @@ public interface EntityEquipment {
      * 

* This returns a copy if this equipment instance is from a non-player, * or it's an empty stack (has AIR as its type). - * For non-empty stacks from players, this returns a live mirror. You can check if this + * For non-empty stacks from players, this returns a live mirror (or null). You can check if this * will return a mirror with *

{@code
      * EntityEquipment equipment = entity.getEquipment();
diff --git a/paper-api/src/main/java/org/bukkit/inventory/PlayerInventory.java b/paper-api/src/main/java/org/bukkit/inventory/PlayerInventory.java
index 0e6fa0d6a72b..8e1d2c124ef4 100644
--- a/paper-api/src/main/java/org/bukkit/inventory/PlayerInventory.java
+++ b/paper-api/src/main/java/org/bukkit/inventory/PlayerInventory.java
@@ -34,32 +34,28 @@ public interface PlayerInventory extends Inventory {
      *
      * @return The ItemStack in the helmet slot
      */
-    @Nullable
-    public ItemStack getHelmet();
+    public @NotNull ItemStack getHelmet();
 
     /**
      * Return the ItemStack from the chestplate slot
      *
      * @return The ItemStack in the chestplate slot
      */
-    @Nullable
-    public ItemStack getChestplate();
+    public @NotNull ItemStack getChestplate();
 
     /**
      * Return the ItemStack from the leg slot
      *
      * @return The ItemStack in the leg slot
      */
-    @Nullable
-    public ItemStack getLeggings();
+    public @NotNull ItemStack getLeggings();
 
     /**
      * Return the ItemStack from the boots slot
      *
      * @return The ItemStack in the boots slot
      */
-    @Nullable
-    public ItemStack getBoots();
+    public @NotNull ItemStack getBoots();
 
     /**
      * Stores the ItemStack at the given index of the inventory.
diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/CraftCrafterView.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/CraftCrafterView.java
index 33cf0cc65eea..dc0bfeb424bf 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/CraftCrafterView.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/view/CraftCrafterView.java
@@ -4,11 +4,9 @@
 import net.minecraft.world.inventory.CrafterMenu;
 import org.bukkit.craftbukkit.inventory.CraftInventoryView;
 import org.bukkit.entity.HumanEntity;
-import org.bukkit.event.inventory.InventoryType;
 import org.bukkit.inventory.CrafterInventory;
 import org.bukkit.inventory.Inventory;
 import org.bukkit.inventory.view.CrafterView;
-import org.jetbrains.annotations.Nullable;
 
 public class CraftCrafterView extends CraftInventoryView implements CrafterView {
 
@@ -63,7 +61,7 @@ public int convertSlot(final int rawSlot) {
     }
 
     @Override
-    public @Nullable Inventory mapValidSlotToInventory(final int rawSlot) {
+    public Inventory mapValidSlotToInventory(final int rawSlot) {
         // Raw slot ID for crafter inventory views is 45 for result slot and 0-8 for crafting grid slots.
         // Crafter inventory size is 10. Only check 0-8 and 45.
         if (rawSlot < (this.getTopInventory().getSize() - 1) || rawSlot == 45) {

From e62ada97e1bbbd536b7622c51ec0e79b264c9fdf Mon Sep 17 00:00:00 2001
From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
Date: Mon, 2 Mar 2026 23:28:37 +0100
Subject: [PATCH 3/4] [ci skip] format

---
 .../src/main/java/org/bukkit/inventory/EntityEquipment.java     | 2 +-
 .../craftbukkit/inventory/CraftAbstractInventoryView.java       | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/paper-api/src/main/java/org/bukkit/inventory/EntityEquipment.java b/paper-api/src/main/java/org/bukkit/inventory/EntityEquipment.java
index 1bbacc6ac421..1b320d0ff8cb 100644
--- a/paper-api/src/main/java/org/bukkit/inventory/EntityEquipment.java
+++ b/paper-api/src/main/java/org/bukkit/inventory/EntityEquipment.java
@@ -303,7 +303,7 @@ public interface EntityEquipment {
      * 

* This returns a copy if this equipment instance is from a non-player, * or it's an empty stack (has AIR as its type). - * For non-empty stacks from players, this returns a live mirror (or null). You can check if this + * For non-empty stacks from players, this returns a live mirror. You can check if this * will return a mirror with *

{@code
      * EntityEquipment equipment = entity.getEquipment();
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 8d38d66c6408..48c0a876fd54 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
@@ -52,7 +52,7 @@ public Inventory getInventory(final int rawSlot) {
         }
         Preconditions.checkArgument(rawSlot >= 0, "Negative, non outside slot %s", rawSlot);
         Preconditions.checkArgument(rawSlot < this.countSlots(), "Slot %s greater than inventory slot count", rawSlot);
-        return mapValidSlotToInventory(rawSlot);
+        return this.mapValidSlotToInventory(rawSlot);
     }
 
     public Inventory mapValidSlotToInventory(final int rawSlot) {

From ed09ce909dcda75e5f207f28e6dcd35986acb6bc Mon Sep 17 00:00:00 2001
From: Warrior <50800980+Warriorrrr@users.noreply.github.com>
Date: Tue, 3 Mar 2026 09:21:20 +0100
Subject: [PATCH 4/4] build