diff --git a/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch b/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch index d182a76be888..ee3004c4f3b5 100644 --- a/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch @@ -1089,6 +1089,21 @@ if (this.hasClientLoaded()) { BlockPos pos = packet.getPos(); this.player.resetLastActionTime(); +@@ -1282,6 +_,14 @@ + PiercingWeapon piercingWeapon = itemInHand.get(DataComponents.PIERCING_WEAPON); + if (piercingWeapon != null) { + piercingWeapon.attack(this.player, EquipmentSlot.MAINHAND); ++ ++ // Paper start - Call interact event ++ Location origin = CraftLocation.toBukkit(this.player.getEyePosition(), this.player.level(), this.player.getYRot(), this.player.getXRot()); ++ org.bukkit.util.RayTraceResult result = doInteractionRayTrace(origin); ++ ++ if (result != null && result.getHitBlock() != null) { ++ CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_BLOCK, ((org.bukkit.craftbukkit.block.CraftBlock) result.getHitBlock()).getPosition(), org.bukkit.craftbukkit.block.CraftBlock.blockFaceToNotch(result.getHitBlockFace()), itemInHand, InteractionHand.MAIN_HAND); ++ } // Paper end - Call interact event + } + + return; @@ -1289,32 +_,95 @@ case SWAP_ITEM_WITH_OFFHAND: if (!this.player.isSpectator()) { @@ -1692,7 +1707,7 @@ } } } -@@ -1694,7 +_,34 @@ +@@ -1694,14 +_,60 @@ @Override public void handleAnimate(final ServerboundSwingPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); @@ -1700,13 +1715,7 @@ this.player.resetLastActionTime(); + // CraftBukkit start - Raytrace to look for 'rogue armswings' + Location origin = CraftLocation.toBukkit(this.player.getEyePosition(), this.player.level(), this.player.getYRot(), this.player.getXRot()); -+ double maxRange = Math.max(this.player.blockInteractionRange(), this.player.entityInteractionRange()); // todo flawed -+ // SPIGOT-5607: Only call interact event if no block or entity is being clicked. Use bukkit ray trace method, because it handles blocks and entities at the same time -+ // SPIGOT-7429: Make sure to call PlayerInteractEvent for spectators and non-pickable entities -+ org.bukkit.util.RayTraceResult result = this.player.level().getWorld().rayTrace(origin, origin.getDirection(), maxRange, org.bukkit.FluidCollisionMode.NEVER, false, 0.0, entity -> { // Paper - Call interact event; change raySize from 0.1 to 0.0 -+ Entity handle = ((CraftEntity) entity).getHandle(); -+ return entity != this.player.getBukkitEntity() && this.player.getBukkitEntity().canSee(entity) && !handle.isSpectator() && handle.isPickable() && !handle.isPassengerOfSameVehicle(this.player); -+ }); ++ org.bukkit.util.RayTraceResult result = doInteractionRayTrace(origin); + if (result == null) { + CraftEventFactory.callPlayerInteractEvent(this.player, Action.LEFT_CLICK_AIR, this.player.getInventory().getSelectedItem(), InteractionHand.MAIN_HAND); + } else { // Paper start - Call interact event @@ -1727,7 +1736,17 @@ this.player.swing(packet.getHand()); } -@@ -1702,6 +_,21 @@ ++ private org.bukkit.util.@org.jspecify.annotations.Nullable RayTraceResult doInteractionRayTrace(org.bukkit.Location origin) { ++ double maxRange = Math.max(this.player.blockInteractionRange(), this.player.entityInteractionRange()); // todo flawed ++ // SPIGOT-5607: Only call interact event if no block or entity is being clicked. Use bukkit ray trace method, because it handles blocks and entities at the same time ++ // SPIGOT-7429: Make sure to call PlayerInteractEvent for spectators and non-pickable entities ++ return this.player.level().getWorld().rayTrace(origin, origin.getDirection(), maxRange, org.bukkit.FluidCollisionMode.NEVER, false, 0.0, entity -> { // Paper - Call interact event; change raySize from 0.1 to 0.0 ++ net.minecraft.world.entity.Entity handle = ((org.bukkit.craftbukkit.entity.CraftEntity) entity).getHandle(); ++ return entity != this.player.getBukkitEntity() && this.player.getBukkitEntity().canSee(entity) && !handle.isSpectator() && handle.isPickable() && !handle.isPassengerOfSameVehicle(this.player); ++ }); ++ } ++ + @Override public void handlePlayerCommand(final ServerboundPlayerCommandPacket packet) { PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); if (this.hasClientLoaded()) {