diff --git a/patches/api/Allow-proper-checking-of-empty-item-stacks.patch b/patches/api/Allow-proper-checking-of-empty-item-stacks.patch
new file mode 100644
index 0000000000..e91012fd50
--- /dev/null
+++ b/patches/api/Allow-proper-checking-of-empty-item-stacks.patch
@@ -0,0 +1,36 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Aeltumn <daniel@goossens.ch>
+Date: Mon, 28 Aug 2023 13:41:09 +0200
+Subject: [PATCH] Allow proper checking of empty item stacks
+
+This adds a method to check if an item stack is empty or not. This mirrors vanilla's implementation of the same method.
+
+diff --git a/src/main/java/org/bukkit/inventory/ItemStack.java b/src/main/java/org/bukkit/inventory/ItemStack.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/org/bukkit/inventory/ItemStack.java
++++ b/src/main/java/org/bukkit/inventory/ItemStack.java
+@@ -0,0 +0,0 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat
+     public @NotNull ItemStack damage(int amount, @NotNull org.bukkit.entity.LivingEntity livingEntity) {
+         return livingEntity.damageItemStack(this, amount);
+     }
++
++    /**
++     * Returns an empty item stack, consists of an air material and a stack size of 0.
++     *
++     * Any item stack with a material of air or a stack size of 0 is seen
++     * as being empty by {@link ItemStack#isEmpty}.
++     */
++    @NotNull
++    public static ItemStack empty() {
++        return new ItemStack();
++    }
++
++    /**
++     * Returns whether this item stack is empty and contains no item. This means
++     * it is either air or the stack has a size of 0.
++     */
++    public boolean isEmpty() {
++        return type.isAir() || amount <= 0;
++    }
+     // Paper end
+ }
diff --git a/patches/api/Fix-Spigot-annotation-mistakes.patch b/patches/api/Fix-Spigot-annotation-mistakes.patch
index a936128c3e..09f063158e 100644
--- a/patches/api/Fix-Spigot-annotation-mistakes.patch
+++ b/patches/api/Fix-Spigot-annotation-mistakes.patch
@@ -592,6 +592,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          super(hopper);
          this.inventory = inventory;
          this.containerType = containerType;
+diff --git a/src/main/java/org/bukkit/event/inventory/InventoryClickEvent.java b/src/main/java/org/bukkit/event/inventory/InventoryClickEvent.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/org/bukkit/event/inventory/InventoryClickEvent.java
++++ b/src/main/java/org/bukkit/event/inventory/InventoryClickEvent.java
+@@ -0,0 +0,0 @@ public class InventoryClickEvent extends InventoryInteractEvent {
+      *
+      * @return the cursor ItemStack
+      */
+-    @Nullable
++    @NotNull // Paper - fix nullability
+     public ItemStack getCursor() {
+         return getView().getCursor();
+     }
 diff --git a/src/main/java/org/bukkit/event/player/PlayerMoveEvent.java b/src/main/java/org/bukkit/event/player/PlayerMoveEvent.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/event/player/PlayerMoveEvent.java
@@ -795,6 +808,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
      /**
       * Checks if the inventory contains any ItemStacks with the given
+diff --git a/src/main/java/org/bukkit/inventory/InventoryView.java b/src/main/java/org/bukkit/inventory/InventoryView.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/org/bukkit/inventory/InventoryView.java
++++ b/src/main/java/org/bukkit/inventory/InventoryView.java
+@@ -0,0 +0,0 @@ public abstract class InventoryView {
+     /**
+      * Get the item on the cursor of one of the viewing players.
+      *
+-     * @return The item on the player's cursor, or null if they aren't holding
+-     *     one.
++     * @return The item on the player's cursor, or an empty stack
++     * if they aren't holding one.
+      */
+-    @Nullable
++    @NotNull // Paper - fix nullability
+     public final ItemStack getCursor() {
+         return getPlayer().getItemOnCursor();
+     }
 diff --git a/src/main/java/org/bukkit/inventory/ItemFactory.java b/src/main/java/org/bukkit/inventory/ItemFactory.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/org/bukkit/inventory/ItemFactory.java
diff --git a/patches/server/Allow-proper-checking-of-empty-item-stacks.patch b/patches/server/Allow-proper-checking-of-empty-item-stacks.patch
new file mode 100644
index 0000000000..a785e97a10
--- /dev/null
+++ b/patches/server/Allow-proper-checking-of-empty-item-stacks.patch
@@ -0,0 +1,31 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Aeltumn <daniel@goossens.ch>
+Date: Mon, 28 Aug 2023 13:44:09 +0200
+Subject: [PATCH] Allow proper checking of empty item stacks
+
+
+diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
+index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
+--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
++++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
+@@ -0,0 +0,0 @@ public final class CraftItemStack extends ItemStack {
+     }
+     // Paper end - MC Utils
+ 
++    // Paper start - override isEmpty to use vanilla's impl
++    @Override
++    public boolean isEmpty() {
++        return handle == null || handle.isEmpty();
++    }
++    // Paper end
++
+     public static net.minecraft.world.item.ItemStack asNMSCopy(ItemStack original) {
+         if (original instanceof CraftItemStack) {
+             CraftItemStack stack = (CraftItemStack) original;
+             return stack.handle == null ? net.minecraft.world.item.ItemStack.EMPTY : stack.handle.copy();
+         }
+-        if (original == null || original.getType() == Material.AIR) {
++        if (original == null || original.isEmpty()) { // Paper - use isEmpty
+             return net.minecraft.world.item.ItemStack.EMPTY;
+         }
+