13
0
geforkt von Mirrors/Paper

Bulk bugfixes for itemstack damage API (#11063)

A general set of bugfixes for itemstack damage related logic.

1. Prevent NPE when calling deprecated ItemStack#getMaxItemUseDuration()
2. Do not apply enchantments when damaging items via API
3. Do not error when passing a null equipment slot to hurtAndBreak
4. Correctly call PlayerItemBreakEvent
Dieser Commit ist enthalten in:
Bjarne Koll 2024-07-12 20:47:08 +02:00
Ursprung 32d0bfcdea
Commit 1b20e12355
3 geänderte Dateien mit 43 neuen und 3 gelöschten Zeilen

Datei anzeigen

@ -0,0 +1,34 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Bjarne Koll <git@lynxplay.dev>
Date: Fri, 12 Jul 2024 19:09:44 +0200
Subject: [PATCH] Correctly call PlayerItemBreakEvent
The minecraft 1.21 update changed the invocation order in
ItemStack#hurtAndBreak, now first shrinking the itemstack to a count of
zero and then invoking the break callback.
This leads to spigots logic no longer firing at all. This patch now
correctly executes on count of zero and temporarily bumps the count to
one before passing it to event handlers to maintain compatibility with
the event contracts.
This fix was chosen over invoking the callback prior to shrinking the
stack to not disrupt potential new vanilla changes that might depend on
this behaviour.
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
@@ -0,0 +0,0 @@ public final class ItemStack implements DataComponentHolder {
this.hurtAndBreak(amount, worldserver, entity, (item) -> { // Paper - Add EntityDamageItemEvent
// CraftBukkit start - Check for item breaking
- if (this.count == 1 && entity instanceof net.minecraft.world.entity.player.Player) {
+ if (this.count == 0 && entity instanceof net.minecraft.world.entity.player.Player) { // Paper - correctly call item break event - run if count reached 0
+ this.setCount(1); // Paper - correctly call item break event - grow to count 1
org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemBreakEvent((net.minecraft.world.entity.player.Player) entity, this);
+ this.setCount(0); // Paper - correctly call item break event - reset to count 0
}
// CraftBukkit end
if (slot != null) entity.onEquippedItemBroken(item, slot); // Paper - itemstack damage API - do not process entity related callbacks when damaging from API

Datei anzeigen

@ -28,7 +28,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ if (player == null || !player.hasInfiniteMaterials() || force) { // Paper
if (amount > 0) {
int originalDamage = amount; // Paper - Expand PlayerItemDamageEvent
amount = EnchantmentHelper.processDurabilityChange(world, this, amount);
- amount = EnchantmentHelper.processDurabilityChange(world, this, amount);
+ if (!force) amount = EnchantmentHelper.processDurabilityChange(world, this, amount); // Paper - itemstack damage API - do not consider enchantments when damaging from API
// CraftBukkit start
if (player instanceof ServerPlayer serverPlayer) { // Paper - Add EntityDamageItemEvent
PlayerItemDamageEvent event = new PlayerItemDamageEvent(serverPlayer.getBukkitEntity(), CraftItemStack.asCraftMirror(this), amount, originalDamage); // Paper - Add EntityDamageItemEvent & Expand PlayerItemDamageEvent
@@ -0,0 +0,0 @@ public final class ItemStack implements DataComponentHolder {
}
@ -42,10 +46,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
if (world instanceof ServerLevel worldserver) {
@@ -0,0 +0,0 @@ public final class ItemStack implements DataComponentHolder {
org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemBreakEvent((net.minecraft.world.entity.player.Player) entity, this);
}
// CraftBukkit end
entity.onEquippedItemBroken(item, slot);
- entity.onEquippedItemBroken(item, slot);
- });
+ if (slot != null) entity.onEquippedItemBroken(item, slot); // Paper - itemstack damage API - do not process entity related callbacks when damaging from API
+ }, force); // Paper
}

Datei anzeigen

@ -42,7 +42,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
+ if (entity == null && handle.is(Items.CROSSBOW)) {
+ throw new UnsupportedOperationException("This item requires an entity to determine the max use duration");
+ }
+ return handle.getUseDuration(((CraftLivingEntity) entity).getHandle());
+ return handle.getUseDuration(entity != null ? ((CraftLivingEntity) entity).getHandle() : null);
+ }
+ // Paper end
+