Fix PlayerReadyArrowEvent cancellation desync (#12111)

This commit is contained in:
Tamion
2025-02-16 21:44:08 +01:00
committed by GitHub
parent 28d07dc5ab
commit 60394c5b98

View File

@@ -645,18 +645,21 @@
} }
@Override @Override
@@ -1988,17 +_,28 @@ @@ -1988,17 +_,32 @@
return ImmutableList.of(Pose.STANDING, Pose.CROUCHING, Pose.SWIMMING); return ImmutableList.of(Pose.STANDING, Pose.CROUCHING, Pose.SWIMMING);
} }
+ // Paper start - PlayerReadyArrowEvent + // Paper start - PlayerReadyArrowEvent
+ protected boolean tryReadyArrow(ItemStack bow, ItemStack itemstack) { + // We pass a result mutable boolean in to allow the caller of this method to know if the event was cancelled.
+ return !(this instanceof ServerPlayer) || + protected boolean tryReadyArrow(ItemStack bow, ItemStack itemstack, final org.apache.commons.lang3.mutable.MutableBoolean cancelled) {
+ new com.destroystokyo.paper.event.player.PlayerReadyArrowEvent( + if (!(this instanceof final ServerPlayer serverPlayer)) return true;
+ ((ServerPlayer) this).getBukkitEntity(), + final boolean notCancelled = new com.destroystokyo.paper.event.player.PlayerReadyArrowEvent(
+ serverPlayer.getBukkitEntity(),
+ org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(bow), + org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(bow),
+ org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack) + org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack)
+ ).callEvent(); + ).callEvent();
+ if (!notCancelled) cancelled.setValue(true);
+ return notCancelled;
+ } + }
+ // Paper end - PlayerReadyArrowEvent + // Paper end - PlayerReadyArrowEvent
+ +
@@ -666,16 +669,25 @@
return ItemStack.EMPTY; return ItemStack.EMPTY;
} else { } else {
- Predicate<ItemStack> supportedHeldProjectiles = ((ProjectileWeaponItem)shootable.getItem()).getSupportedHeldProjectiles(); - Predicate<ItemStack> supportedHeldProjectiles = ((ProjectileWeaponItem)shootable.getItem()).getSupportedHeldProjectiles();
+ Predicate<ItemStack> supportedHeldProjectiles = ((ProjectileWeaponItem)shootable.getItem()).getSupportedHeldProjectiles().and(item -> this.tryReadyArrow(shootable, item)); // Paper - PlayerReadyArrowEvent + final org.apache.commons.lang3.mutable.MutableBoolean anyEventCancelled = new org.apache.commons.lang3.mutable.MutableBoolean(); // Paper - PlayerReadyArrowEvent
+ Predicate<ItemStack> supportedHeldProjectiles = ((ProjectileWeaponItem)shootable.getItem()).getSupportedHeldProjectiles().and(item -> this.tryReadyArrow(shootable, item, anyEventCancelled)); // Paper - PlayerReadyArrowEvent
ItemStack heldProjectile = ProjectileWeaponItem.getHeldProjectile(this, supportedHeldProjectiles); ItemStack heldProjectile = ProjectileWeaponItem.getHeldProjectile(this, supportedHeldProjectiles);
if (!heldProjectile.isEmpty()) { if (!heldProjectile.isEmpty()) {
return heldProjectile; return heldProjectile;
} else { } else {
- supportedHeldProjectiles = ((ProjectileWeaponItem)shootable.getItem()).getAllSupportedProjectiles(); - supportedHeldProjectiles = ((ProjectileWeaponItem)shootable.getItem()).getAllSupportedProjectiles();
+ supportedHeldProjectiles = ((ProjectileWeaponItem)shootable.getItem()).getAllSupportedProjectiles().and(item -> this.tryReadyArrow(shootable, item)); // Paper - PlayerReadyArrowEvent + supportedHeldProjectiles = ((ProjectileWeaponItem)shootable.getItem()).getAllSupportedProjectiles().and(item -> this.tryReadyArrow(shootable, item, anyEventCancelled)); // Paper - PlayerReadyArrowEvent
for (int i = 0; i < this.inventory.getContainerSize(); i++) { for (int i = 0; i < this.inventory.getContainerSize(); i++) {
ItemStack item = this.inventory.getItem(i); ItemStack item = this.inventory.getItem(i);
@@ -2007,6 +_,7 @@
}
}
+ if (anyEventCancelled.booleanValue() && !this.abilities.instabuild && this instanceof final ServerPlayer player) this.resyncUsingItem(player); // Paper - resync if no item matched the Predicate
return this.abilities.instabuild ? new ItemStack(Items.ARROW) : ItemStack.EMPTY;
}
}
@@ -2089,12 +_,20 @@ @@ -2089,12 +_,20 @@
} }