From 14b0751f02e82c59c3508ced3130f27a17df3b97 Mon Sep 17 00:00:00 2001 From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> Date: Fri, 12 Apr 2024 17:16:22 -0400 Subject: [PATCH] Deprecate ItemStack#setType & add ItemStack#withType (#10290) --- patches/api/Deprecate-ItemStack-setType.patch | 54 +++++++++++++++++++ ...for-InventoryBlockStartEvent-subclas.patch | 4 +- .../api/Fix-Spigot-annotation-mistakes.patch | 24 +++++++++ patches/api/Item-Mutation-Fixes.patch | 50 +++++++++++++++++ patches/api/PlayerElytraBoostEvent.patch | 16 +++++- .../server/Deprecate-ItemStack-setType.patch | 30 +++++++++++ patches/server/Item-Mutation-Fixes.patch | 49 +++++++++++++++++ patches/server/MC-Utils.patch | 4 ++ patches/server/PlayerElytraBoostEvent.patch | 2 +- 9 files changed, 229 insertions(+), 4 deletions(-) create mode 100644 patches/api/Deprecate-ItemStack-setType.patch create mode 100644 patches/api/Item-Mutation-Fixes.patch create mode 100644 patches/server/Deprecate-ItemStack-setType.patch create mode 100644 patches/server/Item-Mutation-Fixes.patch diff --git a/patches/api/Deprecate-ItemStack-setType.patch b/patches/api/Deprecate-ItemStack-setType.patch new file mode 100644 index 0000000000..f6f1cd5b9f --- /dev/null +++ b/patches/api/Deprecate-ItemStack-setType.patch @@ -0,0 +1,54 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> +Date: Thu, 29 Feb 2024 17:54:26 -0500 +Subject: [PATCH] Deprecate ItemStack#setType + + +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 + * {@link Material#isItem()} returns false. + * + * @param type New type to set the items in this stack to ++ * @deprecated Setting the material type of ItemStacks is no longer supported. ++ *

++ * This method is deprecated due to potential illegal behavior that may occur ++ * during the context of which this ItemStack is being used, allowing for certain item validation to be bypassed. ++ * It is recommended to instead create a new ItemStack object with the desired ++ * Material type, and if possible, set it in the appropriate context. ++ * ++ * Using this method in ItemStacks passed in events will result in undefined behavior. ++ * @see ItemStack#withType(Material) + */ + @Utility ++ @Deprecated // Paper + public void setType(@NotNull Material type) { + Preconditions.checkArgument(type != null, "Material cannot be null"); + this.type = type; +@@ -0,0 +0,0 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat + this.data = null; + } + } ++ // Paper start ++ /** ++ * Creates a new ItemStack with the specified Material type, where the item count and item meta is preserved. ++ * ++ * @param type The Material type of the new ItemStack. ++ * @return A new ItemStack instance with the specified Material type. ++ */ ++ @NotNull ++ @org.jetbrains.annotations.Contract(value = "_ -> new", pure = true) ++ public ItemStack withType(@NotNull Material type) { ++ ItemStack itemStack = new ItemStack(type, this.amount); ++ if (this.hasItemMeta()) { ++ itemStack.setItemMeta(this.getItemMeta()); ++ } ++ ++ return itemStack; ++ } ++ // Paper end + + /** + * Gets the amount of items in this stack diff --git a/patches/api/Fix-HandlerList-for-InventoryBlockStartEvent-subclas.patch b/patches/api/Fix-HandlerList-for-InventoryBlockStartEvent-subclas.patch index e18527824d..7e9bd53440 100644 --- a/patches/api/Fix-HandlerList-for-InventoryBlockStartEvent-subclas.patch +++ b/patches/api/Fix-HandlerList-for-InventoryBlockStartEvent-subclas.patch @@ -9,7 +9,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/org/bukkit/event/block/BrewingStartEvent.java +++ b/src/main/java/org/bukkit/event/block/BrewingStartEvent.java @@ -0,0 +0,0 @@ import org.jetbrains.annotations.NotNull; - */ + @org.jetbrains.annotations.ApiStatus.Experimental // Paper public class BrewingStartEvent extends InventoryBlockStartEvent { - private static final HandlerList handlers = new HandlerList(); @@ -38,7 +38,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 --- a/src/main/java/org/bukkit/event/block/CampfireStartEvent.java +++ b/src/main/java/org/bukkit/event/block/CampfireStartEvent.java @@ -0,0 +0,0 @@ import org.jetbrains.annotations.NotNull; - */ + @org.jetbrains.annotations.ApiStatus.Experimental // Paper public class CampfireStartEvent extends InventoryBlockStartEvent { - private static final HandlerList handlers = new HandlerList(); diff --git a/patches/api/Fix-Spigot-annotation-mistakes.patch b/patches/api/Fix-Spigot-annotation-mistakes.patch index 3aef8679bc..dd625d8162 100644 --- a/patches/api/Fix-Spigot-annotation-mistakes.patch +++ b/patches/api/Fix-Spigot-annotation-mistakes.patch @@ -982,6 +982,30 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 public static final MemoryKey SNIFFER_EXPLORED_POSITIONS = new MemoryKey<>(NamespacedKey.minecraft("sniffer_explored_positions"), Location.class); /** +diff --git a/src/main/java/org/bukkit/event/block/BrewingStartEvent.java b/src/main/java/org/bukkit/event/block/BrewingStartEvent.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/org/bukkit/event/block/BrewingStartEvent.java ++++ b/src/main/java/org/bukkit/event/block/BrewingStartEvent.java +@@ -0,0 +0,0 @@ import org.jetbrains.annotations.NotNull; + /** + * Called when a brewing stand starts to brew. + */ ++@org.jetbrains.annotations.ApiStatus.Experimental // Paper + public class BrewingStartEvent extends InventoryBlockStartEvent { + + private static final HandlerList handlers = new HandlerList(); +diff --git a/src/main/java/org/bukkit/event/block/CampfireStartEvent.java b/src/main/java/org/bukkit/event/block/CampfireStartEvent.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/org/bukkit/event/block/CampfireStartEvent.java ++++ b/src/main/java/org/bukkit/event/block/CampfireStartEvent.java +@@ -0,0 +0,0 @@ import org.jetbrains.annotations.NotNull; + /** + * Called when a Campfire starts to cook. + */ ++@org.jetbrains.annotations.ApiStatus.Experimental // Paper + public class CampfireStartEvent extends InventoryBlockStartEvent { + + private static final HandlerList handlers = new HandlerList(); diff --git a/src/main/java/org/bukkit/event/enchantment/PrepareItemEnchantEvent.java b/src/main/java/org/bukkit/event/enchantment/PrepareItemEnchantEvent.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/org/bukkit/event/enchantment/PrepareItemEnchantEvent.java diff --git a/patches/api/Item-Mutation-Fixes.patch b/patches/api/Item-Mutation-Fixes.patch new file mode 100644 index 0000000000..8122eecdec --- /dev/null +++ b/patches/api/Item-Mutation-Fixes.patch @@ -0,0 +1,50 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> +Date: Wed, 20 Mar 2024 20:42:31 -0400 +Subject: [PATCH] Item Mutation Fixes + + +diff --git a/src/main/java/org/bukkit/event/block/InventoryBlockStartEvent.java b/src/main/java/org/bukkit/event/block/InventoryBlockStartEvent.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/org/bukkit/event/block/InventoryBlockStartEvent.java ++++ b/src/main/java/org/bukkit/event/block/InventoryBlockStartEvent.java +@@ -0,0 +0,0 @@ import org.jetbrains.annotations.NotNull; + public class InventoryBlockStartEvent extends BlockEvent { + + private static final HandlerList handlers = new HandlerList(); +- private final ItemStack source; ++ protected ItemStack source; // Paper + + public InventoryBlockStartEvent(@NotNull final Block block, @NotNull ItemStack source) { + super(block); +diff --git a/src/main/java/org/bukkit/event/enchantment/EnchantItemEvent.java b/src/main/java/org/bukkit/event/enchantment/EnchantItemEvent.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/org/bukkit/event/enchantment/EnchantItemEvent.java ++++ b/src/main/java/org/bukkit/event/enchantment/EnchantItemEvent.java +@@ -0,0 +0,0 @@ import org.jetbrains.annotations.NotNull; + public class EnchantItemEvent extends InventoryEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private final Block table; +- private final ItemStack item; ++ private ItemStack item; // Paper + private int level; + private boolean cancelled; + private final Map enchants; +@@ -0,0 +0,0 @@ public class EnchantItemEvent extends InventoryEvent implements Cancellable { + return item; + } + ++ // Paper start ++ /** ++ * Sets the item to be enchanted ++ * ++ * @param item item ++ */ ++ public void setItem(@NotNull final ItemStack item) { ++ this.item = item; ++ } ++ // Paper end ++ + /** + * Gets the cost (minimum level) which is displayed as a number on the right + * hand side of the enchantment offer. diff --git a/patches/api/PlayerElytraBoostEvent.patch b/patches/api/PlayerElytraBoostEvent.patch index b947bdf0a4..ae001dfca5 100644 --- a/patches/api/PlayerElytraBoostEvent.patch +++ b/patches/api/PlayerElytraBoostEvent.patch @@ -17,6 +17,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 +import org.bukkit.event.Cancellable; +import org.bukkit.event.HandlerList; +import org.bukkit.event.player.PlayerEvent; ++import org.bukkit.inventory.EquipmentSlot; +import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; @@ -31,14 +32,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + @NotNull private final ItemStack itemStack; + @NotNull private final Firework firework; + private boolean consume = true; ++ @NotNull ++ private final EquipmentSlot hand; + + private boolean cancelled; + + @ApiStatus.Internal -+ public PlayerElytraBoostEvent(@NotNull Player player, @NotNull ItemStack itemStack, @NotNull Firework firework) { ++ public PlayerElytraBoostEvent(@NotNull Player player, @NotNull ItemStack itemStack, @NotNull Firework firework, @NotNull EquipmentSlot hand) { + super(player); + this.itemStack = itemStack; + this.firework = firework; ++ this.hand = hand; + } + + /** @@ -79,6 +83,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + this.consume = consume; + } + ++ /** ++ * Gets the hand holding the firework used for boosting this player. ++ * ++ * @return interaction hand ++ */ ++ @NotNull ++ public EquipmentSlot getHand() { ++ return this.hand; ++ } ++ + @Override + public boolean isCancelled() { + return this.cancelled; diff --git a/patches/server/Deprecate-ItemStack-setType.patch b/patches/server/Deprecate-ItemStack-setType.patch new file mode 100644 index 0000000000..6e35974967 --- /dev/null +++ b/patches/server/Deprecate-ItemStack-setType.patch @@ -0,0 +1,30 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> +Date: Tue, 26 Mar 2024 21:42:23 -0400 +Subject: [PATCH] Deprecate ItemStack#setType + + +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 { + static boolean hasItemMeta(net.minecraft.world.item.ItemStack item) { + return !(item == null || item.getTag() == null || item.getTag().isEmpty()); + } ++ // Paper start - with type ++ @Override ++ public ItemStack withType(final Material type) { ++ if (type == Material.AIR) return CraftItemStack.asCraftMirror(null); ++ ++ final net.minecraft.world.item.ItemStack copy = new net.minecraft.world.item.ItemStack( ++ CraftItemType.bukkitToMinecraft(type), this.getAmount() ++ ); ++ if (this.handle != null && this.handle.getTag() != null) copy.setTag(this.handle.getTag().copy()); ++ ++ final CraftItemStack mirrored = CraftItemStack.asCraftMirror(copy); ++ mirrored.setItemMeta(mirrored.getItemMeta()); ++ return mirrored; ++ } ++ // Paper end + } diff --git a/patches/server/Item-Mutation-Fixes.patch b/patches/server/Item-Mutation-Fixes.patch new file mode 100644 index 0000000000..6d36480ae4 --- /dev/null +++ b/patches/server/Item-Mutation-Fixes.patch @@ -0,0 +1,49 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> +Date: Wed, 20 Mar 2024 20:41:35 -0400 +Subject: [PATCH] Item Mutation Fixes + + +diff --git a/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java b/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java +index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 +--- a/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java ++++ b/src/main/java/net/minecraft/world/inventory/EnchantmentMenu.java +@@ -0,0 +0,0 @@ public class EnchantmentMenu extends AbstractContainerMenu { + return false; + } else if (this.costs[id] > 0 && !itemstack.isEmpty() && (player.experienceLevel >= j && player.experienceLevel >= this.costs[id] || player.getAbilities().instabuild)) { + this.access.execute((world, blockposition) -> { +- ItemStack itemstack2 = itemstack; ++ ItemStack itemstack2 = itemstack; // Paper - diff on change + List list = this.getEnchantmentList(itemstack, id, this.costs[id]); + + // CraftBukkit start +@@ -0,0 +0,0 @@ public class EnchantmentMenu extends AbstractContainerMenu { + return; + } + // CraftBukkit end +- boolean flag = itemstack.is(Items.BOOK); ++ // Paper start ++ itemstack2 = org.bukkit.craftbukkit.inventory.CraftItemStack.getOrCloneOnMutation(item, event.getItem()); ++ if (itemstack2 != itemstack) { ++ this.enchantSlots.setItem(0, itemstack2); ++ } ++ boolean flag = itemstack2.is(Items.BOOK); ++ // Paper end + + if (flag) { ++ CompoundTag nbttagcompound = itemstack2.getTag(); // Paper - move up + itemstack2 = new ItemStack(Items.ENCHANTED_BOOK); +- CompoundTag nbttagcompound = itemstack.getTag(); ++ // Paper - move up + + if (nbttagcompound != null) { + itemstack2.setTag(nbttagcompound.copy()); +@@ -0,0 +0,0 @@ public class EnchantmentMenu extends AbstractContainerMenu { + EnchantmentInstance weightedrandomenchant = new EnchantmentInstance(nms, entry.getValue()); + EnchantedBookItem.addEnchantment(itemstack2, weightedrandomenchant); + } else { +- item.addUnsafeEnchantment(entry.getKey(), entry.getValue()); ++ CraftItemStack.asCraftMirror(itemstack2).addUnsafeEnchantment(entry.getKey(), entry.getValue()); // Paper + } + } catch (IllegalArgumentException e) { + /* Just swallow invalid enchantments */ diff --git a/patches/server/MC-Utils.patch b/patches/server/MC-Utils.patch index 6a69de83f5..e089158042 100644 --- a/patches/server/MC-Utils.patch +++ b/patches/server/MC-Utils.patch @@ -7907,6 +7907,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return asNMSCopy(bukkit); + } + } ++ ++ public static net.minecraft.world.item.ItemStack getOrCloneOnMutation(ItemStack old, ItemStack newInstance) { ++ return old == newInstance ? unwrap(old) : asNMSCopy(newInstance); ++ } + // Paper end - MC Utils + public static net.minecraft.world.item.ItemStack asNMSCopy(ItemStack original) { diff --git a/patches/server/PlayerElytraBoostEvent.patch b/patches/server/PlayerElytraBoostEvent.patch index e7396f4455..e9dd2a4715 100644 --- a/patches/server/PlayerElytraBoostEvent.patch +++ b/patches/server/PlayerElytraBoostEvent.patch @@ -15,7 +15,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 - world.addFreshEntity(fireworkRocketEntity); - if (!user.getAbilities().instabuild) { + // Paper start - PlayerElytraBoostEvent -+ com.destroystokyo.paper.event.player.PlayerElytraBoostEvent event = new com.destroystokyo.paper.event.player.PlayerElytraBoostEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Firework) fireworkRocketEntity.getBukkitEntity()); ++ com.destroystokyo.paper.event.player.PlayerElytraBoostEvent event = new com.destroystokyo.paper.event.player.PlayerElytraBoostEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Firework) fireworkRocketEntity.getBukkitEntity(), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand)); + if (event.callEvent() && world.addFreshEntity(fireworkRocketEntity)) { + user.awardStat(Stats.ITEM_USED.get(this)); + if (event.shouldConsume() && !user.getAbilities().instabuild) {