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:
Ursprung
32d0bfcdea
Commit
1b20e12355
34
patches/server/Correctly-call-PlayerItemBreakEvent.patch
Normale Datei
34
patches/server/Correctly-call-PlayerItemBreakEvent.patch
Normale Datei
@ -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
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
+
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren