From 31913c0b0a2fd1de1206eb83e9058467a1383c55 Mon Sep 17 00:00:00 2001 From: Jake Potrebic Date: Sat, 14 Dec 2024 12:50:20 -0800 Subject: [PATCH] net.minecraft.world.item --- build-data/paper.at | 1 - .../minecraft/world/item/BlockItem.java.patch | 13 + .../world/item/DebugStickItem.java.patch | 7 + .../item/ExperienceBottleItem.java.patch | 48 +- .../world/item/FireChargeItem.java.patch | 31 + .../world/item/FireworkRocketItem.java.patch | 50 +- .../world/item/FishingRodItem.java.patch | 54 ++ .../world/item/FlintAndSteelItem.java.patch | 28 + .../world/item/HangingEntityItem.java.patch | 22 + .../world/item/HoneycombItem.java.patch | 10 +- .../world/item/ItemCooldowns.java.patch | 16 + .../minecraft/world/item/ItemStack.java.patch | 404 +++++++++++ .../minecraft/world/item/ItemUtils.java.patch | 12 +- .../minecraft/world/item/LeadItem.java.patch | 70 ++ .../world/item/LingeringPotionItem.java.patch | 16 +- .../minecraft/world/item/MapItem.java.patch | 22 + .../world/item/MinecartItem.java.patch | 17 + .../world/item/NameTagItem.java.patch | 12 +- .../world/item/PotionItem.java.patch | 15 + .../item/ProjectileWeaponItem.java.patch | 55 ++ .../world/item/ServerItemCooldowns.java.patch | 11 +- .../world/item/ShovelItem.java.patch | 33 + .../minecraft/world/item/SignItem.java.patch | 22 + .../world/item/SnowballItem.java.patch | 54 ++ .../world/item/SpawnEggItem.java.patch | 19 + .../world/item/SplashPotionItem.java.patch | 16 +- .../item/StandingAndWallBlockItem.java.patch | 24 + .../world/item/ThrowablePotionItem.java.patch | 35 + .../world/item/TridentItem.java.patch | 51 ++ .../world/item/WindChargeItem.java.patch | 44 ++ .../world/item/WrittenBookItem.java.patch | 11 + .../world/item/ArmorStandItem.java.patch | 15 - .../minecraft/world/item/AxeItem.java.patch | 14 - .../minecraft/world/item/BlockItem.java.patch | 109 --- .../minecraft/world/item/BoatItem.java.patch | 33 - .../world/item/BoneMealItem.java.patch | 41 -- .../world/item/BucketItem.java.patch | 168 ----- .../world/item/CrossbowItem.java.patch | 48 -- .../world/item/DebugStickItem.java.patch | 25 - .../minecraft/world/item/DyeItem.java.patch | 29 - .../minecraft/world/item/EggItem.java.patch | 40 -- .../world/item/EndCrystalItem.java.patch | 31 - .../world/item/EnderEyeItem.java.patch | 56 -- .../world/item/EnderpearlItem.java.patch | 39 -- .../world/item/FireChargeItem.java.patch | 31 - .../world/item/FishingRodItem.java.patch | 50 -- .../world/item/FlintAndSteelItem.java.patch | 28 - .../world/item/HangingEntityItem.java.patch | 67 -- .../world/item/ItemCooldowns.java.patch | 16 - .../minecraft/world/item/ItemStack.java.patch | 630 ------------------ .../minecraft/world/item/LeadItem.java.patch | 92 --- .../minecraft/world/item/MapItem.java.patch | 22 - .../world/item/MinecartItem.java.patch | 17 - .../world/item/PotionItem.java.patch | 15 - .../item/ProjectileWeaponItem.java.patch | 52 -- .../world/item/ShovelItem.java.patch | 33 - .../minecraft/world/item/SignItem.java.patch | 23 - .../world/item/SnowballItem.java.patch | 37 - .../world/item/SpawnEggItem.java.patch | 24 - .../item/StandingAndWallBlockItem.java.patch | 41 -- .../world/item/ThrowablePotionItem.java.patch | 34 - .../world/item/TridentItem.java.patch | 51 -- .../world/item/WindChargeItem.java.patch | 42 -- .../world/item/WrittenBookItem.java.patch | 11 - 64 files changed, 1134 insertions(+), 2053 deletions(-) create mode 100644 paper-server/patches/sources/net/minecraft/world/item/BlockItem.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/item/DebugStickItem.java.patch rename paper-server/patches/{unapplied => sources}/net/minecraft/world/item/ExperienceBottleItem.java.patch (50%) create mode 100644 paper-server/patches/sources/net/minecraft/world/item/FireChargeItem.java.patch rename paper-server/patches/{unapplied => sources}/net/minecraft/world/item/FireworkRocketItem.java.patch (53%) create mode 100644 paper-server/patches/sources/net/minecraft/world/item/FishingRodItem.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/item/FlintAndSteelItem.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/item/HangingEntityItem.java.patch rename paper-server/patches/{unapplied => sources}/net/minecraft/world/item/HoneycombItem.java.patch (71%) create mode 100644 paper-server/patches/sources/net/minecraft/world/item/ItemCooldowns.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/item/ItemStack.java.patch rename paper-server/patches/{unapplied => sources}/net/minecraft/world/item/ItemUtils.java.patch (52%) create mode 100644 paper-server/patches/sources/net/minecraft/world/item/LeadItem.java.patch rename paper-server/patches/{unapplied => sources}/net/minecraft/world/item/LingeringPotionItem.java.patch (54%) create mode 100644 paper-server/patches/sources/net/minecraft/world/item/MapItem.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/item/MinecartItem.java.patch rename paper-server/patches/{unapplied => sources}/net/minecraft/world/item/NameTagItem.java.patch (65%) create mode 100644 paper-server/patches/sources/net/minecraft/world/item/PotionItem.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/item/ProjectileWeaponItem.java.patch rename paper-server/patches/{unapplied => sources}/net/minecraft/world/item/ServerItemCooldowns.java.patch (86%) create mode 100644 paper-server/patches/sources/net/minecraft/world/item/ShovelItem.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/item/SignItem.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/item/SnowballItem.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/item/SpawnEggItem.java.patch rename paper-server/patches/{unapplied => sources}/net/minecraft/world/item/SplashPotionItem.java.patch (54%) create mode 100644 paper-server/patches/sources/net/minecraft/world/item/StandingAndWallBlockItem.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/item/ThrowablePotionItem.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/item/TridentItem.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/item/WindChargeItem.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/item/WrittenBookItem.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/item/ArmorStandItem.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/item/AxeItem.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/item/BlockItem.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/item/BoatItem.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/item/BoneMealItem.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/item/BucketItem.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/item/CrossbowItem.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/item/DebugStickItem.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/item/DyeItem.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/item/EggItem.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/item/EndCrystalItem.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/item/EnderEyeItem.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/item/EnderpearlItem.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/item/FireChargeItem.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/item/FishingRodItem.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/item/FlintAndSteelItem.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/item/HangingEntityItem.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/item/ItemCooldowns.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/item/ItemStack.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/item/LeadItem.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/item/MapItem.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/item/MinecartItem.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/item/PotionItem.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/item/ProjectileWeaponItem.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/item/ShovelItem.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/item/SignItem.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/item/SnowballItem.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/item/SpawnEggItem.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/item/StandingAndWallBlockItem.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/item/ThrowablePotionItem.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/item/TridentItem.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/item/WindChargeItem.java.patch delete mode 100644 paper-server/patches/unapplied/net/minecraft/world/item/WrittenBookItem.java.patch diff --git a/build-data/paper.at b/build-data/paper.at index 4b3b886b7f..c646267776 100644 --- a/build-data/paper.at +++ b/build-data/paper.at @@ -479,7 +479,6 @@ public net.minecraft.world.item.DebugStickItem handleInteraction(Lnet/minecraft/ public net.minecraft.world.item.ItemCooldowns cooldowns public net.minecraft.world.item.ItemCooldowns tickCount public net.minecraft.world.item.ItemCooldowns$CooldownInstance -public net.minecraft.world.item.ItemCooldowns$CooldownInstance endTime public net.minecraft.world.item.ItemStackLinkedSet TYPE_AND_TAG public net.minecraft.world.item.JukeboxSongPlayer song public net.minecraft.world.item.MapItem createNewSavedData(Lnet/minecraft/world/level/Level;IIIZZLnet/minecraft/resources/ResourceKey;)Lnet/minecraft/world/level/saveddata/maps/MapId; diff --git a/paper-server/patches/sources/net/minecraft/world/item/BlockItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/BlockItem.java.patch new file mode 100644 index 0000000000..1814a4c1bb --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/BlockItem.java.patch @@ -0,0 +1,13 @@ +--- a/net/minecraft/world/item/BlockItem.java ++++ b/net/minecraft/world/item/BlockItem.java +@@ -9,9 +_,9 @@ + import net.minecraft.core.registries.Registries; + import net.minecraft.nbt.CompoundTag; + import net.minecraft.network.chat.Component; ++import net.minecraft.server.level.ServerLevel; + import net.minecraft.server.level.ServerPlayer; + import net.minecraft.sounds.SoundEvent; +-import net.minecraft.sounds.SoundSource; + import net.minecraft.world.InteractionResult; + import net.minecraft.world.entity.item.ItemEntity; + import net.minecraft.world.entity.player.Player; diff --git a/paper-server/patches/sources/net/minecraft/world/item/DebugStickItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/DebugStickItem.java.patch new file mode 100644 index 0000000000..be32bd3b62 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/DebugStickItem.java.patch @@ -0,0 +1,7 @@ +--- a/net/minecraft/world/item/DebugStickItem.java ++++ b/net/minecraft/world/item/DebugStickItem.java +@@ -1,3 +_,4 @@ ++// mc-dev import + package net.minecraft.world.item; + + import java.util.Collection; diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/ExperienceBottleItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/ExperienceBottleItem.java.patch similarity index 50% rename from paper-server/patches/unapplied/net/minecraft/world/item/ExperienceBottleItem.java.patch rename to paper-server/patches/sources/net/minecraft/world/item/ExperienceBottleItem.java.patch index e16430df8d..51cfc0c1ed 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/item/ExperienceBottleItem.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/ExperienceBottleItem.java.patch @@ -1,53 +1,53 @@ --- a/net/minecraft/world/item/ExperienceBottleItem.java +++ b/net/minecraft/world/item/ExperienceBottleItem.java -@@ -21,22 +21,38 @@ +@@ -21,22 +_,38 @@ @Override - public InteractionResult use(Level world, Player user, InteractionHand hand) { - ItemStack itemStack = user.getItemInHand(hand); -- world.playSound( + public InteractionResult use(Level level, Player player, InteractionHand hand) { + ItemStack itemInHand = player.getItemInHand(hand); +- level.playSound( - null, -- user.getX(), -- user.getY(), -- user.getZ(), +- player.getX(), +- player.getY(), +- player.getZ(), - SoundEvents.EXPERIENCE_BOTTLE_THROW, - SoundSource.NEUTRAL, - 0.5F, -- 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F) +- 0.4F / (level.getRandom().nextFloat() * 0.4F + 0.8F) - ); + // Paper - PlayerLaunchProjectileEvent - moved down - if (world instanceof ServerLevel serverLevel) { -- Projectile.spawnProjectileFromRotation(ThrownExperienceBottle::new, serverLevel, itemStack, user, -20.0F, 0.7F, 1.0F); + if (level instanceof ServerLevel serverLevel) { +- Projectile.spawnProjectileFromRotation(ThrownExperienceBottle::new, serverLevel, itemInHand, player, -20.0F, 0.7F, 1.0F); + // Paper start - PlayerLaunchProjectileEvent -+ final Projectile.Delayed thrownExperienceBottle = Projectile.spawnProjectileFromRotationDelayed(ThrownExperienceBottle::new, serverLevel, itemStack, user, -20.0F, 0.7F, 1.0F); -+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Projectile) thrownExperienceBottle.projectile().getBukkitEntity()); ++ final Projectile.Delayed thrownExperienceBottle = Projectile.spawnProjectileFromRotationDelayed(ThrownExperienceBottle::new, serverLevel, itemInHand, player, -20.0F, 0.7F, 1.0F); ++ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) player.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemInHand), (org.bukkit.entity.Projectile) thrownExperienceBottle.projectile().getBukkitEntity()); + if (event.callEvent() && thrownExperienceBottle.attemptSpawn()) { + if (event.shouldConsume()) { -+ itemStack.consume(1, user); -+ } else if (user instanceof net.minecraft.server.level.ServerPlayer) { -+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); ++ itemInHand.consume(1, player); ++ } else if (player instanceof net.minecraft.server.level.ServerPlayer) { ++ ((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity().updateInventory(); + } + -+ world.playSound( ++ level.playSound( + null, -+ user.getX(), -+ user.getY(), -+ user.getZ(), ++ player.getX(), ++ player.getY(), ++ player.getZ(), + SoundEvents.EXPERIENCE_BOTTLE_THROW, + SoundSource.NEUTRAL, + 0.5F, -+ 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F) ++ 0.4F / (level.getRandom().nextFloat() * 0.4F + 0.8F) + ); + } else { -+ if (user instanceof net.minecraft.server.level.ServerPlayer) { -+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); ++ if (player instanceof net.minecraft.server.level.ServerPlayer) { ++ ((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity().updateInventory(); + } + return InteractionResult.FAIL; + } + // Paper end - PlayerLaunchProjectileEvent } -- user.awardStat(Stats.ITEM_USED.get(this)); -- itemStack.consume(1, user); +- player.awardStat(Stats.ITEM_USED.get(this)); +- itemInHand.consume(1, player); + // Paper - PlayerLaunchProjectileEvent - moved up return InteractionResult.SUCCESS; } diff --git a/paper-server/patches/sources/net/minecraft/world/item/FireChargeItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/FireChargeItem.java.patch new file mode 100644 index 0000000000..a182da8d73 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/FireChargeItem.java.patch @@ -0,0 +1,31 @@ +--- a/net/minecraft/world/item/FireChargeItem.java ++++ b/net/minecraft/world/item/FireChargeItem.java +@@ -35,12 +_,28 @@ + if (!CampfireBlock.canLight(blockState) && !CandleBlock.canLight(blockState) && !CandleCakeBlock.canLight(blockState)) { + clickedPos = clickedPos.relative(context.getClickedFace()); + if (BaseFireBlock.canBePlacedAt(level, clickedPos, context.getHorizontalDirection())) { ++ // CraftBukkit start - fire BlockIgniteEvent ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(level, clickedPos, org.bukkit.event.block.BlockIgniteEvent.IgniteCause.FIREBALL, context.getPlayer()).isCancelled()) { ++ if (!context.getPlayer().getAbilities().instabuild) { ++ context.getItemInHand().shrink(1); ++ } ++ return InteractionResult.PASS; ++ } ++ // CraftBukkit end + this.playSound(level, clickedPos); + level.setBlockAndUpdate(clickedPos, BaseFireBlock.getState(level, clickedPos)); + level.gameEvent(context.getPlayer(), GameEvent.BLOCK_PLACE, clickedPos); + flag = true; + } + } else { ++ // CraftBukkit start - fire BlockIgniteEvent ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(level, clickedPos, org.bukkit.event.block.BlockIgniteEvent.IgniteCause.FIREBALL, context.getPlayer()).isCancelled()) { ++ if (!context.getPlayer().getAbilities().instabuild) { ++ context.getItemInHand().shrink(1); ++ } ++ return InteractionResult.PASS; ++ } ++ // CraftBukkit end + this.playSound(level, clickedPos); + level.setBlockAndUpdate(clickedPos, blockState.setValue(BlockStateProperties.LIT, Boolean.valueOf(true))); + level.gameEvent(context.getPlayer(), GameEvent.BLOCK_CHANGE, clickedPos); diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/FireworkRocketItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/FireworkRocketItem.java.patch similarity index 53% rename from paper-server/patches/unapplied/net/minecraft/world/item/FireworkRocketItem.java.patch rename to paper-server/patches/sources/net/minecraft/world/item/FireworkRocketItem.java.patch index 9d8f816a26..a707470352 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/item/FireworkRocketItem.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/FireworkRocketItem.java.patch @@ -1,48 +1,48 @@ --- a/net/minecraft/world/item/FireworkRocketItem.java +++ b/net/minecraft/world/item/FireworkRocketItem.java -@@ -33,7 +33,7 @@ - ItemStack itemStack = context.getItemInHand(); - Vec3 vec3 = context.getClickLocation(); - Direction direction = context.getClickedFace(); +@@ -33,7 +_,7 @@ + ItemStack itemInHand = context.getItemInHand(); + Vec3 clickLocation = context.getClickLocation(); + Direction clickedFace = context.getClickedFace(); - Projectile.spawnProjectile( + final Projectile.Delayed fireworkRocketEntity = Projectile.spawnProjectileDelayed( // Paper - PlayerLaunchProjectileEvent new FireworkRocketEntity( level, context.getPlayer(), -@@ -43,9 +43,14 @@ - itemStack +@@ -43,9 +_,14 @@ + itemInHand ), serverLevel, -- itemStack -+ itemStack, f -> f.spawningEntity = context.getPlayer() == null ? null : context.getPlayer().getUUID() // Paper - firework api - assign spawning entity uuid +- itemInHand ++ itemInHand, f -> f.spawningEntity = context.getPlayer() == null ? null : context.getPlayer().getUUID() // Paper - firework api - assign spawning entity uuid ); -- itemStack.shrink(1); +- itemInHand.shrink(1); + // Paper start - PlayerLaunchProjectileEvent -+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) context.getPlayer().getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Firework) fireworkRocketEntity.projectile().getBukkitEntity()); ++ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) context.getPlayer().getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemInHand), (org.bukkit.entity.Firework) fireworkRocketEntity.projectile().getBukkitEntity()); + if (!event.callEvent() || !fireworkRocketEntity.attemptSpawn()) return InteractionResult.PASS; -+ if (event.shouldConsume() && !context.getPlayer().hasInfiniteMaterials()) itemStack.shrink(1); ++ if (event.shouldConsume() && !context.getPlayer().hasInfiniteMaterials()) itemInHand.shrink(1); + else if (context.getPlayer() instanceof net.minecraft.server.level.ServerPlayer) ((net.minecraft.server.level.ServerPlayer) context.getPlayer()).getBukkitEntity().updateInventory(); + // Paper end - PlayerLaunchProjectileEvent } return InteractionResult.SUCCESS; -@@ -56,9 +61,19 @@ - if (user.isFallFlying()) { - ItemStack itemStack = user.getItemInHand(hand); - if (world instanceof ServerLevel serverLevel) { -- Projectile.spawnProjectile(new FireworkRocketEntity(world, itemStack, user), serverLevel, itemStack); -- itemStack.consume(1, user); -- user.awardStat(Stats.ITEM_USED.get(this)); +@@ -56,9 +_,19 @@ + if (player.isFallFlying()) { + ItemStack itemInHand = player.getItemInHand(hand); + if (level instanceof ServerLevel serverLevel) { +- Projectile.spawnProjectile(new FireworkRocketEntity(level, itemInHand, player), serverLevel, itemInHand); +- itemInHand.consume(1, player); +- player.awardStat(Stats.ITEM_USED.get(this)); + // Paper start - PlayerElytraBoostEvent -+ final Projectile.Delayed delayed = Projectile.spawnProjectileDelayed(new FireworkRocketEntity(world, itemStack, user), serverLevel, itemStack, f -> f.spawningEntity = user.getUUID()); // Paper - firework api - assign spawning entity uuid -+ 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) delayed.projectile().getBukkitEntity(), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand)); ++ final Projectile.Delayed delayed = Projectile.spawnProjectileDelayed(new FireworkRocketEntity(level, itemInHand, player), serverLevel, itemInHand, f -> f.spawningEntity = player.getUUID()); // Paper - firework api - assign spawning entity uuid ++ com.destroystokyo.paper.event.player.PlayerElytraBoostEvent event = new com.destroystokyo.paper.event.player.PlayerElytraBoostEvent((org.bukkit.entity.Player) player.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemInHand), (org.bukkit.entity.Firework) delayed.projectile().getBukkitEntity(), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand)); + if (event.callEvent() && delayed.attemptSpawn()) { -+ user.awardStat(Stats.ITEM_USED.get(this)); // Moved up from below -+ if (event.shouldConsume() && !user.hasInfiniteMaterials()) { -+ itemStack.shrink(1); // Moved up from below -+ } else ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); ++ player.awardStat(Stats.ITEM_USED.get(this)); // Moved up from below ++ if (event.shouldConsume() && !player.hasInfiniteMaterials()) { ++ itemInHand.shrink(1); // Moved up from below ++ } else ((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity().updateInventory(); + } else { -+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); ++ ((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity().updateInventory(); + } + // Moved up consume/stat + // Paper end - PlayerElytraBoostEvent diff --git a/paper-server/patches/sources/net/minecraft/world/item/FishingRodItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/FishingRodItem.java.patch new file mode 100644 index 0000000000..e9d2feeb53 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/FishingRodItem.java.patch @@ -0,0 +1,54 @@ +--- a/net/minecraft/world/item/FishingRodItem.java ++++ b/net/minecraft/world/item/FishingRodItem.java +@@ -24,7 +_,7 @@ + ItemStack itemInHand = player.getItemInHand(hand); + if (player.fishing != null) { + if (!level.isClientSide) { +- int i = player.fishing.retrieve(itemInHand); ++ int i = player.fishing.retrieve(hand, itemInHand); // Paper - Add hand parameter to PlayerFishEvent + itemInHand.hurtAndBreak(i, player, LivingEntity.getSlotForHand(hand)); + } + +@@ -40,20 +_,31 @@ + ); + player.gameEvent(GameEvent.ITEM_INTERACT_FINISH); + } else { +- level.playSound( +- null, +- player.getX(), +- player.getY(), +- player.getZ(), +- SoundEvents.FISHING_BOBBER_THROW, +- SoundSource.NEUTRAL, +- 0.5F, +- 0.4F / (level.getRandom().nextFloat() * 0.4F + 0.8F) +- ); ++ // CraftBukkit - moved down + if (level instanceof ServerLevel serverLevel) { + int i1 = (int)(EnchantmentHelper.getFishingTimeReduction(serverLevel, itemInHand, player) * 20.0F); + int fishingLuckBonus = EnchantmentHelper.getFishingLuckBonus(serverLevel, itemInHand, player); +- Projectile.spawnProjectile(new FishingHook(player, level, fishingLuckBonus, i1), serverLevel, itemInHand); ++ // CraftBukkit start ++ FishingHook entityfishinghook = new FishingHook(player, level, fishingLuckBonus, i1); ++ org.bukkit.event.player.PlayerFishEvent playerFishEvent = new org.bukkit.event.player.PlayerFishEvent((org.bukkit.entity.Player) player.getBukkitEntity(), null, (org.bukkit.entity.FishHook) entityfishinghook.getBukkitEntity(), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand), org.bukkit.event.player.PlayerFishEvent.State.FISHING); ++ level.getCraftServer().getPluginManager().callEvent(playerFishEvent); ++ ++ if (playerFishEvent.isCancelled()) { ++ player.fishing = null; ++ return InteractionResult.PASS; ++ } ++ level.playSound( ++ null, ++ player.getX(), ++ player.getY(), ++ player.getZ(), ++ SoundEvents.FISHING_BOBBER_THROW, ++ SoundSource.NEUTRAL, ++ 0.5F, ++ 0.4F / (level.getRandom().nextFloat() * 0.4F + 0.8F) ++ ); ++ Projectile.spawnProjectile(entityfishinghook, serverLevel, itemInHand); ++ // CraftBukkit end + } + + player.awardStat(Stats.ITEM_USED.get(this)); diff --git a/paper-server/patches/sources/net/minecraft/world/item/FlintAndSteelItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/FlintAndSteelItem.java.patch new file mode 100644 index 0000000000..19ba3b4a20 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/FlintAndSteelItem.java.patch @@ -0,0 +1,28 @@ +--- a/net/minecraft/world/item/FlintAndSteelItem.java ++++ b/net/minecraft/world/item/FlintAndSteelItem.java +@@ -32,6 +_,12 @@ + if (!CampfireBlock.canLight(blockState) && !CandleBlock.canLight(blockState) && !CandleCakeBlock.canLight(blockState)) { + BlockPos blockPos = clickedPos.relative(context.getClickedFace()); + if (BaseFireBlock.canBePlacedAt(level, blockPos, context.getHorizontalDirection())) { ++ // CraftBukkit start - Store the clicked block ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(level, blockPos, org.bukkit.event.block.BlockIgniteEvent.IgniteCause.FLINT_AND_STEEL, player).isCancelled()) { ++ context.getItemInHand().hurtAndBreak(1, player, LivingEntity.getSlotForHand(context.getHand())); ++ return InteractionResult.PASS; ++ } ++ // CraftBukkit end + level.playSound(player, blockPos, SoundEvents.FLINTANDSTEEL_USE, SoundSource.BLOCKS, 1.0F, level.getRandom().nextFloat() * 0.4F + 0.8F); + BlockState state = BaseFireBlock.getState(level, blockPos); + level.setBlock(blockPos, state, 11); +@@ -47,6 +_,12 @@ + return InteractionResult.FAIL; + } + } else { ++ // CraftBukkit start - Store the clicked block ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(level, clickedPos, org.bukkit.event.block.BlockIgniteEvent.IgniteCause.FLINT_AND_STEEL, player).isCancelled()) { ++ context.getItemInHand().hurtAndBreak(1, player, LivingEntity.getSlotForHand(context.getHand())); ++ return InteractionResult.PASS; ++ } ++ // CraftBukkit end + level.playSound(player, clickedPos, SoundEvents.FLINTANDSTEEL_USE, SoundSource.BLOCKS, 1.0F, level.getRandom().nextFloat() * 0.4F + 0.8F); + level.setBlock(clickedPos, blockState.setValue(BlockStateProperties.LIT, Boolean.valueOf(true)), 11); + level.gameEvent(player, GameEvent.BLOCK_CHANGE, clickedPos); diff --git a/paper-server/patches/sources/net/minecraft/world/item/HangingEntityItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/HangingEntityItem.java.patch new file mode 100644 index 0000000000..f5c2f3dbb7 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/HangingEntityItem.java.patch @@ -0,0 +1,22 @@ +--- a/net/minecraft/world/item/HangingEntityItem.java ++++ b/net/minecraft/world/item/HangingEntityItem.java +@@ -66,6 +_,19 @@ + + if (hangingEntity.survives()) { + if (!level.isClientSide) { ++ // CraftBukkit start - fire HangingPlaceEvent ++ org.bukkit.entity.Player who = (context.getPlayer() == null) ? null : (org.bukkit.entity.Player) context.getPlayer().getBukkitEntity(); ++ org.bukkit.block.Block blockClicked = level.getWorld().getBlockAt(blockPos.getX(), blockPos.getY(), blockPos.getZ()); ++ org.bukkit.block.BlockFace blockFace = org.bukkit.craftbukkit.block.CraftBlock.notchToBlockFace(clickedFace); ++ org.bukkit.inventory.EquipmentSlot hand = org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(context.getHand()); ++ ++ org.bukkit.event.hanging.HangingPlaceEvent event = new org.bukkit.event.hanging.HangingPlaceEvent((org.bukkit.entity.Hanging) hangingEntity.getBukkitEntity(), who, blockClicked, blockFace, hand, org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(itemInHand)); ++ level.getCraftServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) { ++ return InteractionResult.FAIL; ++ } ++ // CraftBukkit end + hangingEntity.playPlacementSound(); + level.gameEvent(player, GameEvent.ENTITY_PLACE, hangingEntity.position()); + level.addFreshEntity(hangingEntity); diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/HoneycombItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/HoneycombItem.java.patch similarity index 71% rename from paper-server/patches/unapplied/net/minecraft/world/item/HoneycombItem.java.patch rename to paper-server/patches/sources/net/minecraft/world/item/HoneycombItem.java.patch index 02d0f745ad..9a4c3ee1c3 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/item/HoneycombItem.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/HoneycombItem.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/world/item/HoneycombItem.java +++ b/net/minecraft/world/item/HoneycombItem.java -@@ -74,6 +74,14 @@ - return getWaxed(blockState).map(state -> { +@@ -74,6 +_,14 @@ + return getWaxed(blockState).map(blockState1 -> { Player player = context.getPlayer(); - ItemStack itemStack = context.getItemInHand(); + ItemStack itemInHand = context.getItemInHand(); + // Paper start - EntityChangeBlockEvent -+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, blockPos, state)) { ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, clickedPos, blockState)) { + if (!player.isCreative()) { + player.containerMenu.sendAllDataToRemote(); + } @@ -13,5 +13,5 @@ + } + // Paper end if (player instanceof ServerPlayer serverPlayer) { - CriteriaTriggers.ITEM_USED_ON_BLOCK.trigger(serverPlayer, blockPos, itemStack); + CriteriaTriggers.ITEM_USED_ON_BLOCK.trigger(serverPlayer, clickedPos, itemInHand); } diff --git a/paper-server/patches/sources/net/minecraft/world/item/ItemCooldowns.java.patch b/paper-server/patches/sources/net/minecraft/world/item/ItemCooldowns.java.patch new file mode 100644 index 0000000000..4b0f5b2897 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/ItemCooldowns.java.patch @@ -0,0 +1,16 @@ +--- a/net/minecraft/world/item/ItemCooldowns.java ++++ b/net/minecraft/world/item/ItemCooldowns.java +@@ -56,6 +_,13 @@ + } + + public void addCooldown(ResourceLocation group, int cooldown) { ++ // Paper start - Item cooldown events ++ this.addCooldown(group, cooldown, true); ++ } ++ ++ public void addCooldown(ResourceLocation group, int cooldown, boolean callEvent) { ++ // Event called in server override ++ // Paper end - Item cooldown events + this.cooldowns.put(group, new ItemCooldowns.CooldownInstance(this.tickCount, this.tickCount + cooldown)); + this.onCooldownStarted(group, cooldown); + } diff --git a/paper-server/patches/sources/net/minecraft/world/item/ItemStack.java.patch b/paper-server/patches/sources/net/minecraft/world/item/ItemStack.java.patch new file mode 100644 index 0000000000..24e6257081 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/ItemStack.java.patch @@ -0,0 +1,404 @@ +--- a/net/minecraft/world/item/ItemStack.java ++++ b/net/minecraft/world/item/ItemStack.java +@@ -22,6 +_,7 @@ + import net.minecraft.ChatFormatting; + import net.minecraft.advancements.CriteriaTriggers; + import net.minecraft.core.BlockPos; ++import net.minecraft.core.Direction; + import net.minecraft.core.Holder; + import net.minecraft.core.HolderLookup; + import net.minecraft.core.HolderSet; +@@ -45,10 +_,12 @@ + import net.minecraft.network.chat.MutableComponent; + import net.minecraft.network.codec.ByteBufCodecs; + import net.minecraft.network.codec.StreamCodec; ++import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket; + import net.minecraft.resources.RegistryOps; + import net.minecraft.server.level.ServerLevel; + import net.minecraft.server.level.ServerPlayer; + import net.minecraft.sounds.SoundEvent; ++import net.minecraft.sounds.SoundSource; + import net.minecraft.stats.Stats; + import net.minecraft.tags.TagKey; + import net.minecraft.util.ExtraCodecs; +@@ -136,18 +_,35 @@ + } else { + Holder holder = ITEM_STREAM_CODEC.decode(buffer); + DataComponentPatch dataComponentPatch = DataComponentPatch.STREAM_CODEC.decode(buffer); +- return new ItemStack(holder, varInt, dataComponentPatch); ++ // CraftBukkit start ++ ItemStack stack = new ItemStack(holder, varInt, dataComponentPatch); ++ if (false && !dataComponentPatch.isEmpty()) { // Paper - This is no longer needed with raw NBT being handled in metadata ++ org.bukkit.craftbukkit.inventory.CraftItemStack.setItemMeta(stack, org.bukkit.craftbukkit.inventory.CraftItemStack.getItemMeta(stack)); ++ } ++ return stack; ++ // CraftBukkit end + } + } + + @Override + public void encode(RegistryFriendlyByteBuf buffer, ItemStack value) { +- if (value.isEmpty()) { ++ if (value.isEmpty() || value.getItem() == null) { // CraftBukkit - NPE fix itemstack.getItem() + buffer.writeVarInt(0); + } else { + buffer.writeVarInt(value.getCount()); + ITEM_STREAM_CODEC.encode(buffer, value.getItemHolder()); ++ // Spigot start - filter ++ // value = value.copy(); ++ // CraftItemStack.setItemMeta(value, CraftItemStack.getItemMeta(value)); // Paper - This is no longer with raw NBT being handled in metadata ++ // Paper start - adventure; conditionally render translatable components ++ boolean prev = net.minecraft.network.chat.ComponentSerialization.DONT_RENDER_TRANSLATABLES.get(); ++ try { ++ net.minecraft.network.chat.ComponentSerialization.DONT_RENDER_TRANSLATABLES.set(true); + DataComponentPatch.STREAM_CODEC.encode(buffer, value.components.asPatch()); ++ } finally { ++ net.minecraft.network.chat.ComponentSerialization.DONT_RENDER_TRANSLATABLES.set(prev); ++ } ++ // Paper end - adventure; conditionally render translatable components + } + } + }; +@@ -365,10 +_,180 @@ + return InteractionResult.PASS; + } else { + Item item = this.getItem(); +- InteractionResult interactionResult = item.useOn(context); ++ // InteractionResult interactionResult = item.useOn(context); ++ // CraftBukkit start - handle all block place event logic here ++ DataComponentPatch oldData = this.components.asPatch(); ++ int oldCount = this.getCount(); ++ ServerLevel serverLevel = (ServerLevel) context.getLevel(); ++ ++ if (!(item instanceof BucketItem/* || item instanceof SolidBucketItem*/)) { // if not bucket // Paper - Fix cancelled powdered snow bucket placement ++ serverLevel.captureBlockStates = true; ++ // special case bonemeal ++ if (item == Items.BONE_MEAL) { ++ serverLevel.captureTreeGeneration = true; ++ } ++ } ++ InteractionResult interactionResult; ++ try { ++ interactionResult = item.useOn(context); ++ } finally { ++ serverLevel.captureBlockStates = false; ++ } ++ DataComponentPatch newData = this.components.asPatch(); ++ int newCount = this.getCount(); ++ this.setCount(oldCount); ++ this.restorePatch(oldData); ++ if (interactionResult.consumesAction() && serverLevel.captureTreeGeneration && serverLevel.capturedBlockStates.size() > 0) { ++ serverLevel.captureTreeGeneration = false; ++ org.bukkit.Location location = org.bukkit.craftbukkit.util.CraftLocation.toBukkit(clickedPos, serverLevel.getWorld()); ++ org.bukkit.TreeType treeType = net.minecraft.world.level.block.SaplingBlock.treeType; ++ net.minecraft.world.level.block.SaplingBlock.treeType = null; ++ List blocks = new java.util.ArrayList<>(serverLevel.capturedBlockStates.values()); ++ serverLevel.capturedBlockStates.clear(); ++ org.bukkit.event.world.StructureGrowEvent structureEvent = null; ++ if (treeType != null) { ++ boolean isBonemeal = this.getItem() == Items.BONE_MEAL; ++ structureEvent = new org.bukkit.event.world.StructureGrowEvent(location, treeType, isBonemeal, (org.bukkit.entity.Player) player.getBukkitEntity(), (List) (List) blocks); ++ org.bukkit.Bukkit.getPluginManager().callEvent(structureEvent); ++ } ++ ++ org.bukkit.event.block.BlockFertilizeEvent fertilizeEvent = new org.bukkit.event.block.BlockFertilizeEvent(org.bukkit.craftbukkit.block.CraftBlock.at(serverLevel, clickedPos), (org.bukkit.entity.Player) player.getBukkitEntity(), (List) (List) blocks); ++ fertilizeEvent.setCancelled(structureEvent != null && structureEvent.isCancelled()); ++ org.bukkit.Bukkit.getPluginManager().callEvent(fertilizeEvent); ++ ++ if (!fertilizeEvent.isCancelled()) { ++ // Change the stack to its new contents if it hasn't been tampered with. ++ if (this.getCount() == oldCount && Objects.equals(this.components.asPatch(), oldData)) { ++ this.restorePatch(newData); ++ this.setCount(newCount); ++ } ++ for (org.bukkit.craftbukkit.block.CraftBlockState blockstate : blocks) { ++ // SPIGOT-7572 - Move fix for SPIGOT-7248 to CapturedBlockState, to allow bees in bee nest ++ org.bukkit.craftbukkit.block.CapturedBlockState.setBlockState(blockstate); ++ serverLevel.checkCapturedTreeStateForObserverNotify(clickedPos, blockstate); // Paper - notify observers even if grow failed ++ } ++ player.awardStat(Stats.ITEM_USED.get(item)); // SPIGOT-7236 - award stat ++ } ++ ++ SignItem.openSign = null; // SPIGOT-6758 - Reset on early return ++ return interactionResult; ++ } ++ serverLevel.captureTreeGeneration = false; + if (player != null && interactionResult instanceof InteractionResult.Success success && success.wasItemInteraction()) { +- player.awardStat(Stats.ITEM_USED.get(item)); ++ // player.awardStat(Stats.ITEM_USED.get(item)); ++ InteractionHand enumhand = context.getHand(); ++ org.bukkit.event.block.BlockPlaceEvent placeEvent = null; ++ List blocks = new java.util.ArrayList<>(serverLevel.capturedBlockStates.values()); ++ serverLevel.capturedBlockStates.clear(); ++ if (blocks.size() > 1) { ++ placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockMultiPlaceEvent(serverLevel, player, enumhand, blocks, clickedPos.getX(), clickedPos.getY(), clickedPos.getZ()); ++ } else if (blocks.size() == 1 && item != Items.POWDER_SNOW_BUCKET) { // Paper - Fix cancelled powdered snow bucket placement ++ placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPlaceEvent(serverLevel, player, enumhand, blocks.get(0), clickedPos.getX(), clickedPos.getY(), clickedPos.getZ()); ++ } ++ ++ if (placeEvent != null && (placeEvent.isCancelled() || !placeEvent.canBuild())) { ++ interactionResult = InteractionResult.FAIL; // cancel placement ++ // PAIL: Remove this when MC-99075 fixed ++ placeEvent.getPlayer().updateInventory(); ++ serverLevel.capturedTileEntities.clear(); // Paper - Allow chests to be placed with NBT data; clear out block entities as chests and such will pop loot ++ // revert back all captured blocks ++ serverLevel.preventPoiUpdated = true; // CraftBukkit - SPIGOT-5710 ++ serverLevel.isBlockPlaceCancelled = true; // Paper - prevent calling cleanup logic when undoing a block place upon a cancelled BlockPlaceEvent ++ for (org.bukkit.block.BlockState blockstate : blocks) { ++ blockstate.update(true, false); ++ } ++ serverLevel.isBlockPlaceCancelled = false; // Paper - prevent calling cleanup logic when undoing a block place upon a cancelled BlockPlaceEvent ++ serverLevel.preventPoiUpdated = false; ++ ++ // Brute force all possible updates ++ // Paper start - Don't resync blocks ++ // BlockPos placedPos = ((CraftBlock) placeEvent.getBlock()).getPosition(); ++ // for (Direction dir : Direction.values()) { ++ // ((ServerPlayer) entityhuman).connection.send(new ClientboundBlockUpdatePacket(world, placedPos.relative(dir))); ++ // } ++ // Paper end - Don't resync blocks ++ SignItem.openSign = null; // SPIGOT-6758 - Reset on early return ++ } else { ++ // Change the stack to its new contents if it hasn't been tampered with. ++ if (this.getCount() == oldCount && Objects.equals(this.components.asPatch(), oldData)) { ++ this.restorePatch(newData); ++ this.setCount(newCount); ++ } ++ ++ for (java.util.Map.Entry e : serverLevel.capturedTileEntities.entrySet()) { ++ serverLevel.setBlockEntity(e.getValue()); ++ } ++ ++ for (org.bukkit.block.BlockState blockstate : blocks) { ++ int updateFlag = ((org.bukkit.craftbukkit.block.CraftBlockState) blockstate).getFlag(); ++ net.minecraft.world.level.block.state.BlockState oldBlock = ((org.bukkit.craftbukkit.block.CraftBlockState) blockstate).getHandle(); ++ BlockPos newblockposition = ((org.bukkit.craftbukkit.block.CraftBlockState) blockstate).getPosition(); ++ net.minecraft.world.level.block.state.BlockState block = serverLevel.getBlockState(newblockposition); ++ ++ if (!(block.getBlock() instanceof net.minecraft.world.level.block.BaseEntityBlock)) { // Containers get placed automatically ++ block.onPlace(serverLevel, newblockposition, oldBlock, true, context); ++ } ++ ++ serverLevel.notifyAndUpdatePhysics(newblockposition, null, oldBlock, block, serverLevel.getBlockState(newblockposition), updateFlag, 512); // send null chunk as chunk.k() returns false by this point ++ } ++ ++ if (this.item == Items.WITHER_SKELETON_SKULL) { // Special case skulls to allow wither spawns to be cancelled ++ BlockPos bp = clickedPos; ++ if (!serverLevel.getBlockState(clickedPos).canBeReplaced()) { ++ if (!serverLevel.getBlockState(clickedPos).isSolid()) { ++ bp = null; ++ } else { ++ bp = bp.relative(context.getClickedFace()); ++ } ++ } ++ if (bp != null) { ++ net.minecraft.world.level.block.entity.BlockEntity te = serverLevel.getBlockEntity(bp); ++ if (te instanceof net.minecraft.world.level.block.entity.SkullBlockEntity) { ++ net.minecraft.world.level.block.WitherSkullBlock.checkSpawn(serverLevel, bp, (net.minecraft.world.level.block.entity.SkullBlockEntity) te); ++ } ++ } ++ } ++ ++ // SPIGOT-4678 ++ if (this.item instanceof SignItem && SignItem.openSign != null) { ++ try { ++ if (serverLevel.getBlockEntity(SignItem.openSign) instanceof net.minecraft.world.level.block.entity.SignBlockEntity tileentitysign) { ++ if (serverLevel.getBlockState(SignItem.openSign).getBlock() instanceof net.minecraft.world.level.block.SignBlock blocksign) { ++ blocksign.openTextEdit(player, tileentitysign, true, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause.PLACE); // Craftbukkit // Paper - Add PlayerOpenSignEvent ++ } ++ } ++ } finally { ++ SignItem.openSign = null; ++ } ++ } ++ ++ // SPIGOT-7315: Moved from BlockBed#setPlacedBy ++ if (placeEvent != null && this.item instanceof BedItem) { ++ BlockPos position = ((org.bukkit.craftbukkit.block.CraftBlock) placeEvent.getBlock()).getPosition(); ++ net.minecraft.world.level.block.state.BlockState blockData = serverLevel.getBlockState(position); ++ ++ if (blockData.getBlock() instanceof net.minecraft.world.level.block.BedBlock) { ++ serverLevel.blockUpdated(position, net.minecraft.world.level.block.Blocks.AIR); ++ blockData.updateNeighbourShapes(serverLevel, position, 3); ++ } ++ } ++ ++ // SPIGOT-1288 - play sound stripped from ItemBlock ++ if (this.item instanceof BlockItem) { ++ // Paper start - Fix spigot sound playing for BlockItem ItemStacks ++ BlockPos position = new net.minecraft.world.item.context.BlockPlaceContext(context).getClickedPos(); ++ net.minecraft.world.level.block.state.BlockState blockData = serverLevel.getBlockState(position); ++ net.minecraft.world.level.block.SoundType soundeffecttype = blockData.getSoundType(); ++ // Paper end - Fix spigot sound playing for BlockItem ItemStacks ++ serverLevel.playSound(player, clickedPos, soundeffecttype.getPlaceSound(), SoundSource.BLOCKS, (soundeffecttype.getVolume() + 1.0F) / 2.0F, soundeffecttype.getPitch() * 0.8F); ++ } ++ ++ player.awardStat(Stats.ITEM_USED.get(item)); ++ } + } ++ serverLevel.capturedTileEntities.clear(); ++ serverLevel.capturedBlockStates.clear(); ++ // CraftBukkit end + + return interactionResult; + } +@@ -470,30 +_,69 @@ + } + + public void hurtAndBreak(int damage, ServerLevel level, @Nullable ServerPlayer player, Consumer onBreak) { +- int i = this.processDurabilityChange(damage, level, player); ++ // Paper start - add force boolean overload ++ this.hurtAndBreak(damage, level, player, onBreak, false); ++ } ++ public void hurtAndBreak(int damage, ServerLevel level, @Nullable LivingEntity player, Consumer onBreak, boolean force) { // Paper - Add EntityDamageItemEvent ++ // Paper end ++ final int originalDamage = damage; // Paper - Expand PlayerItemDamageEvent ++ int i = this.processDurabilityChange(damage, level, player, force); // Paper ++ // CraftBukkit start ++ if (player instanceof final ServerPlayer serverPlayer) { // Paper - Add EntityDamageItemEvent ++ org.bukkit.event.player.PlayerItemDamageEvent event = new org.bukkit.event.player.PlayerItemDamageEvent(serverPlayer.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(this), i, originalDamage); // Paper - Add EntityDamageItemEvent ++ event.getPlayer().getServer().getPluginManager().callEvent(event); ++ ++ if (i != event.getDamage() || event.isCancelled()) { ++ event.getPlayer().updateInventory(); ++ } ++ if (event.isCancelled()) { ++ return; ++ } ++ ++ i = event.getDamage(); ++ // Paper start - Add EntityDamageItemEvent ++ } else if (player != null) { ++ io.papermc.paper.event.entity.EntityDamageItemEvent event = new io.papermc.paper.event.entity.EntityDamageItemEvent(player.getBukkitLivingEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(this), i); ++ if (!event.callEvent()) { ++ return; ++ } ++ i = event.getDamage(); ++ // Paper end - Add EntityDamageItemEvent ++ } ++ // CraftBukkit end + if (i != 0) { + this.applyDamage(this.getDamageValue() + i, player, onBreak); + } + } + +- private int processDurabilityChange(int damage, ServerLevel level, @Nullable ServerPlayer player) { ++ private int processDurabilityChange(int damage, ServerLevel level, @Nullable LivingEntity player) { // Paper - Add EntityDamageItemEvent ++ // Paper start - itemstack damage api ++ return processDurabilityChange(damage, level, player, false); ++ } ++ private int processDurabilityChange(int damage, ServerLevel level, @Nullable LivingEntity player, boolean force) { ++ // Paper end - itemstack damage api + if (!this.isDamageableItem()) { + return 0; +- } else if (player != null && player.hasInfiniteMaterials()) { ++ } else if (player instanceof ServerPlayer && player.hasInfiniteMaterials() && !force) { // Paper - Add EntityDamageItemEvent + return 0; + } else { + return damage > 0 ? EnchantmentHelper.processDurabilityChange(level, this, damage) : damage; + } + } + +- private void applyDamage(int damage, @Nullable ServerPlayer player, Consumer onBreak) { +- if (player != null) { +- CriteriaTriggers.ITEM_DURABILITY_CHANGED.trigger(player, this, damage); ++ private void applyDamage(int damage, @Nullable LivingEntity player, Consumer onBreak) { // Paper - Add EntityDamageItemEvent ++ if (player instanceof final ServerPlayer serverPlayer) { // Paper - Add EntityDamageItemEvent ++ CriteriaTriggers.ITEM_DURABILITY_CHANGED.trigger(serverPlayer, this, damage); // Paper - Add EntityDamageItemEvent + } + + this.setDamageValue(damage); + if (this.isBroken()) { + Item item = this.getItem(); ++ // CraftBukkit start - Check for item breaking ++ if (this.count == 1 && player instanceof final ServerPlayer serverPlayer) { // Paper - Add EntityDamageItemEvent ++ org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemBreakEvent(serverPlayer, this); // Paper - Add EntityDamageItemEvent ++ } ++ // CraftBukkit end + this.shrink(1); + onBreak.accept(item); + } +@@ -512,9 +_,14 @@ + } + + public void hurtAndBreak(int amount, LivingEntity entity, EquipmentSlot slot) { ++ // Paper start - add param to skip infinite mats check ++ this.hurtAndBreak(amount, entity, slot, false); ++ } ++ public void hurtAndBreak(int amount, LivingEntity entity, EquipmentSlot slot, boolean force) { ++ // Paper end - add param to skip infinite mats check + if (entity.level() instanceof ServerLevel serverLevel) { + this.hurtAndBreak( +- amount, serverLevel, entity instanceof ServerPlayer serverPlayer ? serverPlayer : null, item -> entity.onEquippedItemBroken(item, slot) ++ amount, serverLevel, entity, item -> {if (slot != null) entity.onEquippedItemBroken(item, slot); }, force // Paper - Add EntityDamageItemEvent & itemstack damage API - do not process entity related callbacks when damaging from API + ); + } + } +@@ -715,6 +_,12 @@ + return this.getItem().useOnRelease(this); + } + ++ // CraftBukkit start ++ public void restorePatch(DataComponentPatch datacomponentpatch) { ++ this.components.restorePatch(datacomponentpatch); ++ } ++ // CraftBukkit end ++ + @Nullable + public T set(DataComponentType component, @Nullable T value) { + return this.components.set(component, value); +@@ -748,6 +_,25 @@ + } + } + ++ // Paper start - (this is just a good no conflict location) ++ public org.bukkit.inventory.ItemStack asBukkitMirror() { ++ return org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(this); ++ } ++ public org.bukkit.inventory.ItemStack asBukkitCopy() { ++ return org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(this.copy()); ++ } ++ public static ItemStack fromBukkitCopy(org.bukkit.inventory.ItemStack itemstack) { ++ return org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(itemstack); ++ } ++ private org.bukkit.craftbukkit.inventory.CraftItemStack bukkitStack; ++ public org.bukkit.inventory.ItemStack getBukkitStack() { ++ if (bukkitStack == null || bukkitStack.handle != this) { ++ bukkitStack = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(this); ++ } ++ return bukkitStack; ++ } ++ // Paper end ++ + public void applyComponents(DataComponentPatch components) { + this.components.applyPatch(components); + this.getItem().verifyComponentsAfterLoad(this); +@@ -1016,6 +_,19 @@ + EnchantmentHelper.forEachModifier(this, equipmentSLot, action); + } + ++ // CraftBukkit start ++ @Deprecated ++ public void setItem(Item item) { ++ this.bukkitStack = null; // Paper ++ this.item = item; ++ // Paper start - change base component prototype ++ final DataComponentPatch patch = this.getComponentsPatch(); ++ this.components = new PatchedDataComponentMap(this.item.components()); ++ this.applyComponents(patch); ++ // Paper end - change base component prototype ++ } ++ // CraftBukkit end ++ + public Component getDisplayName() { + MutableComponent mutableComponent = Component.empty().append(this.getHoverName()); + if (this.has(DataComponents.CUSTOM_NAME)) { +@@ -1072,7 +_,7 @@ + } + + public void consume(int amount, @Nullable LivingEntity entity) { +- if (entity == null || !entity.hasInfiniteMaterials()) { ++ if ((entity == null || !entity.hasInfiniteMaterials()) && this != ItemStack.EMPTY) { // CraftBukkit + this.shrink(amount); + } + } diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/ItemUtils.java.patch b/paper-server/patches/sources/net/minecraft/world/item/ItemUtils.java.patch similarity index 52% rename from paper-server/patches/unapplied/net/minecraft/world/item/ItemUtils.java.patch rename to paper-server/patches/sources/net/minecraft/world/item/ItemUtils.java.patch index 163c53a0d4..0956357249 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/item/ItemUtils.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/ItemUtils.java.patch @@ -1,14 +1,14 @@ --- a/net/minecraft/world/item/ItemUtils.java +++ b/net/minecraft/world/item/ItemUtils.java -@@ -41,7 +41,15 @@ - public static void onContainerDestroyed(ItemEntity itemEntity, Iterable contents) { - Level level = itemEntity.level(); +@@ -41,7 +_,15 @@ + public static void onContainerDestroyed(ItemEntity container, Iterable contents) { + Level level = container.level(); if (!level.isClientSide) { -- contents.forEach(stack -> level.addFreshEntity(new ItemEntity(level, itemEntity.getX(), itemEntity.getY(), itemEntity.getZ(), stack))); +- contents.forEach(itemStack -> level.addFreshEntity(new ItemEntity(level, container.getX(), container.getY(), container.getZ(), itemStack))); + // Paper start - call EntityDropItemEvent + contents.forEach(stack -> { -+ ItemEntity droppedItem = new ItemEntity(level, itemEntity.getX(), itemEntity.getY(), itemEntity.getZ(), stack); -+ org.bukkit.event.entity.EntityDropItemEvent event = new org.bukkit.event.entity.EntityDropItemEvent(itemEntity.getBukkitEntity(), (org.bukkit.entity.Item) droppedItem.getBukkitEntity()); ++ ItemEntity droppedItem = new ItemEntity(level, container.getX(), container.getY(), container.getZ(), stack); ++ org.bukkit.event.entity.EntityDropItemEvent event = new org.bukkit.event.entity.EntityDropItemEvent(container.getBukkitEntity(), (org.bukkit.entity.Item) droppedItem.getBukkitEntity()); + if (event.callEvent()) { + level.addFreshEntity(droppedItem); + } diff --git a/paper-server/patches/sources/net/minecraft/world/item/LeadItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/LeadItem.java.patch new file mode 100644 index 0000000000..284a57db81 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/LeadItem.java.patch @@ -0,0 +1,70 @@ +--- a/net/minecraft/world/item/LeadItem.java ++++ b/net/minecraft/world/item/LeadItem.java +@@ -28,23 +_,43 @@ + if (blockState.is(BlockTags.FENCES)) { + Player player = context.getPlayer(); + if (!level.isClientSide && player != null) { +- return bindPlayerMobs(player, level, clickedPos); ++ return bindPlayerMobs(player, level, clickedPos, context.getHand()); // CraftBukkit - Pass hand + } + } + + return InteractionResult.PASS; + } + +- public static InteractionResult bindPlayerMobs(Player player, Level level, BlockPos pos) { ++ public static InteractionResult bindPlayerMobs(Player player, Level level, BlockPos pos, net.minecraft.world.InteractionHand interactionHand) { // CraftBukkit - Add InteractionHand + LeashFenceKnotEntity leashFenceKnotEntity = null; + List list = leashableInArea(level, pos, leashable1 -> leashable1.getLeashHolder() == player); + +- for (Leashable leashable : list) { ++ for (java.util.Iterator iterator = list.iterator(); iterator.hasNext();) { // Paper - use iterator to remove ++ Leashable leashable = iterator.next(); // Paper - use iterator to remove + if (leashFenceKnotEntity == null) { + leashFenceKnotEntity = LeashFenceKnotEntity.getOrCreateKnot(level, pos); ++ // CraftBukkit start - fire HangingPlaceEvent ++ org.bukkit.inventory.EquipmentSlot hand = org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(interactionHand); ++ org.bukkit.event.hanging.HangingPlaceEvent event = new org.bukkit.event.hanging.HangingPlaceEvent((org.bukkit.entity.Hanging) leashFenceKnotEntity.getBukkitEntity(), player != null ? (org.bukkit.entity.Player) player.getBukkitEntity() : null, org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), org.bukkit.block.BlockFace.SELF, hand); ++ level.getCraftServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) { ++ leashFenceKnotEntity.discard(null); // CraftBukkit - add Bukkit remove cause ++ return InteractionResult.PASS; ++ } ++ // CraftBukkit end + leashFenceKnotEntity.playPlacementSound(); + } + ++ // CraftBukkit start ++ if (leashable instanceof Entity leashed) { ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerLeashEntityEvent(leashed, leashFenceKnotEntity, player, interactionHand).isCancelled()) { ++ iterator.remove(); ++ continue; ++ } ++ } ++ // CraftBukkit end ++ + leashable.setLeashedTo(leashFenceKnotEntity, true); + } + +@@ -52,9 +_,20 @@ + level.gameEvent(GameEvent.BLOCK_ATTACH, pos, GameEvent.Context.of(player)); + return InteractionResult.SUCCESS_SERVER; + } else { ++ // CraftBukkit start - remove leash if we do not leash any entity because of the cancelled event ++ if (leashFenceKnotEntity != null) { ++ leashFenceKnotEntity.discard(null); ++ } ++ // CraftBukkit end + return InteractionResult.PASS; + } + } ++ ++ // CraftBukkit start ++ public static InteractionResult bindPlayerMobs(Player player, Level world, BlockPos pos) { ++ return LeadItem.bindPlayerMobs(player, world, pos, net.minecraft.world.InteractionHand.MAIN_HAND); ++ } ++ // CraftBukkit end + + public static List leashableInArea(Level level, BlockPos pos, Predicate predicate) { + double d = 7.0; diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/LingeringPotionItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/LingeringPotionItem.java.patch similarity index 54% rename from paper-server/patches/unapplied/net/minecraft/world/item/LingeringPotionItem.java.patch rename to paper-server/patches/sources/net/minecraft/world/item/LingeringPotionItem.java.patch index 04fd231da8..3c0c4271a4 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/item/LingeringPotionItem.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/LingeringPotionItem.java.patch @@ -1,21 +1,21 @@ --- a/net/minecraft/world/item/LingeringPotionItem.java +++ b/net/minecraft/world/item/LingeringPotionItem.java -@@ -24,6 +24,10 @@ +@@ -24,6 +_,10 @@ @Override - public InteractionResult use(Level world, Player user, InteractionHand hand) { + public InteractionResult use(Level level, Player player, InteractionHand hand) { + // Paper start - PlayerLaunchProjectileEvent -+ final InteractionResult wrapper = super.use(world, user, hand); ++ final InteractionResult wrapper = super.use(level, player, hand); + if (wrapper instanceof InteractionResult.Fail) return wrapper; + // Paper end - PlayerLaunchProjectileEvent - world.playSound( + level.playSound( null, - user.getX(), -@@ -34,6 +38,6 @@ + player.getX(), +@@ -34,6 +_,6 @@ 0.5F, - 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F) + 0.4F / (level.getRandom().nextFloat() * 0.4F + 0.8F) ); -- return super.use(world, user, hand); +- return super.use(level, player, hand); + return wrapper; // Paper - PlayerLaunchProjectileEvent } } diff --git a/paper-server/patches/sources/net/minecraft/world/item/MapItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/MapItem.java.patch new file mode 100644 index 0000000000..c31ec01d7b --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/MapItem.java.patch @@ -0,0 +1,22 @@ +--- a/net/minecraft/world/item/MapItem.java ++++ b/net/minecraft/world/item/MapItem.java +@@ -99,8 +_,8 @@ + int i9 = (i1 / i + i6 - 64) * i; + int i10 = (i2 / i + i7 - 64) * i; + Multiset multiset = LinkedHashMultiset.create(); +- LevelChunk chunk = level.getChunk(SectionPos.blockToSectionCoord(i9), SectionPos.blockToSectionCoord(i10)); +- if (!chunk.isEmpty()) { ++ LevelChunk chunk = level.getChunkIfLoaded(SectionPos.blockToSectionCoord(i9), SectionPos.blockToSectionCoord(i10)); // Paper - Maps shouldn't load chunks ++ if (chunk != null && !chunk.isEmpty()) { // Paper - Maps shouldn't load chunks + int i11 = 0; + double d1 = 0.0; + if (level.dimensionType().hasCeiling()) { +@@ -207,7 +_,7 @@ + + for (int i5 = 0; i5 < 128; i5++) { + for (int i6 = 0; i6 < 128; i6++) { +- Holder biome = serverLevel.getBiome(mutableBlockPos.set((i3 + i6) * i, 0, (i4 + i5) * i)); ++ Holder biome = serverLevel.getUncachedNoiseBiome((i3 + i6) * i, 0, (i4 + i5) * i); // Paper - Perf: Use seed based lookup for treasure maps + flags[i5 * 128 + i6] = biome.is(BiomeTags.WATER_ON_MAP_OUTLINES); + } + } diff --git a/paper-server/patches/sources/net/minecraft/world/item/MinecartItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/MinecartItem.java.patch new file mode 100644 index 0000000000..3af3872029 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/MinecartItem.java.patch @@ -0,0 +1,17 @@ +--- a/net/minecraft/world/item/MinecartItem.java ++++ b/net/minecraft/world/item/MinecartItem.java +@@ -57,7 +_,13 @@ + } + + if (level instanceof ServerLevel serverLevel) { +- serverLevel.addFreshEntity(abstractMinecart); ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPlaceEvent(context, abstractMinecart).isCancelled()) { ++ if (context.getPlayer() != null) context.getPlayer().containerMenu.sendAllDataToRemote(); // Paper - Fix inventory desync ++ return InteractionResult.FAIL; ++ } ++ // CraftBukkit end ++ if (!serverLevel.addFreshEntity(abstractMinecart)) return InteractionResult.PASS; // CraftBukkit + serverLevel.gameEvent( + GameEvent.ENTITY_PLACE, clickedPos, GameEvent.Context.of(context.getPlayer(), serverLevel.getBlockState(clickedPos.below())) + ); diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/NameTagItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/NameTagItem.java.patch similarity index 65% rename from paper-server/patches/unapplied/net/minecraft/world/item/NameTagItem.java.patch rename to paper-server/patches/sources/net/minecraft/world/item/NameTagItem.java.patch index 735436752e..37e96e3a20 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/item/NameTagItem.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/NameTagItem.java.patch @@ -1,13 +1,13 @@ --- a/net/minecraft/world/item/NameTagItem.java +++ b/net/minecraft/world/item/NameTagItem.java -@@ -18,8 +18,13 @@ +@@ -18,8 +_,13 @@ Component component = stack.get(DataComponents.CUSTOM_NAME); - if (component != null && entity.getType().canSerialize() && entity.canBeNameTagged()) { - if (!user.level().isClientSide && entity.isAlive()) { -- entity.setCustomName(component); -- if (entity instanceof Mob mob) { + if (component != null && target.getType().canSerialize() && target.canBeNameTagged()) { + if (!player.level().isClientSide && target.isAlive()) { +- target.setCustomName(component); +- if (target instanceof Mob mob) { + // Paper start - Add PlayerNameEntityEvent -+ io.papermc.paper.event.player.PlayerNameEntityEvent event = new io.papermc.paper.event.player.PlayerNameEntityEvent(((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity(), entity.getBukkitLivingEntity(), io.papermc.paper.adventure.PaperAdventure.asAdventure(stack.getHoverName()), true); ++ io.papermc.paper.event.player.PlayerNameEntityEvent event = new io.papermc.paper.event.player.PlayerNameEntityEvent(((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity(), target.getBukkitLivingEntity(), io.papermc.paper.adventure.PaperAdventure.asAdventure(stack.getHoverName()), true); + if (!event.callEvent()) return InteractionResult.PASS; + LivingEntity newEntity = ((org.bukkit.craftbukkit.entity.CraftLivingEntity) event.getEntity()).getHandle(); + newEntity.setCustomName(event.getName() != null ? io.papermc.paper.adventure.PaperAdventure.asVanilla(event.getName()) : null); diff --git a/paper-server/patches/sources/net/minecraft/world/item/PotionItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/PotionItem.java.patch new file mode 100644 index 0000000000..a253469109 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/PotionItem.java.patch @@ -0,0 +1,15 @@ +--- a/net/minecraft/world/item/PotionItem.java ++++ b/net/minecraft/world/item/PotionItem.java +@@ -42,6 +_,12 @@ + PotionContents potionContents = itemInHand.getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY); + BlockState blockState = level.getBlockState(clickedPos); + if (context.getClickedFace() != Direction.DOWN && blockState.is(BlockTags.CONVERTABLE_TO_MUD) && potionContents.is(Potions.WATER)) { ++ // Paper start ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, clickedPos, Blocks.MUD.defaultBlockState())) { ++ player.containerMenu.sendAllDataToRemote(); ++ return InteractionResult.PASS; ++ } ++ // Paper end + level.playSound(null, clickedPos, SoundEvents.GENERIC_SPLASH, SoundSource.BLOCKS, 1.0F, 1.0F); + player.setItemInHand(context.getHand(), ItemUtils.createFilledResult(itemInHand, player, new ItemStack(Items.GLASS_BOTTLE))); + player.awardStat(Stats.ITEM_USED.get(itemInHand.getItem())); diff --git a/paper-server/patches/sources/net/minecraft/world/item/ProjectileWeaponItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/ProjectileWeaponItem.java.patch new file mode 100644 index 0000000000..4e04b8e5b1 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/ProjectileWeaponItem.java.patch @@ -0,0 +1,55 @@ +--- a/net/minecraft/world/item/ProjectileWeaponItem.java ++++ b/net/minecraft/world/item/ProjectileWeaponItem.java +@@ -62,12 +_,25 @@ + float f4 = f2 + f3 * ((i + 1) / 2) * f1; + f3 = -f3; + int i1 = i; +- Projectile.spawnProjectile( +- this.createProjectile(level, shooter, weapon, itemStack, isCrit), +- level, +- itemStack, +- projectile -> this.shootProjectile(shooter, projectile, i1, velocity, inaccuracy, f4, target) +- ); ++ // CraftBukkit start ++ Projectile projectile = this.createProjectile(level, shooter, weapon, itemStack, isCrit); ++ this.shootProjectile(shooter, projectile, i1, velocity, inaccuracy, f4, target); ++ ++ org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(shooter, weapon, itemStack, projectile, hand, velocity, true); ++ if (event.isCancelled()) { ++ event.getProjectile().remove(); ++ return; ++ } ++ ++ if (event.getProjectile() == projectile.getBukkitEntity()) { ++ if (Projectile.spawnProjectile(projectile, level, itemStack).isRemoved()) { ++ if (shooter instanceof net.minecraft.server.level.ServerPlayer) { ++ ((net.minecraft.server.level.ServerPlayer) shooter).getBukkitEntity().updateInventory(); ++ } ++ return; ++ } ++ } ++ // CraftBukkit end + weapon.hurtAndBreak(this.getDurabilityUse(itemStack), shooter, LivingEntity.getSlotForHand(hand)); + if (weapon.isEmpty()) { + break; +@@ -95,6 +_,11 @@ + } + + protected static List draw(ItemStack weapon, ItemStack ammo, LivingEntity shooter) { ++ // Paper start ++ return draw(weapon, ammo, shooter, true); ++ } ++ protected static List draw(ItemStack weapon, ItemStack ammo, LivingEntity shooter, boolean consume) { ++ // Paper end + if (ammo.isEmpty()) { + return List.of(); + } else { +@@ -103,7 +_,7 @@ + ItemStack itemStack = ammo.copy(); + + for (int i1 = 0; i1 < i; i1++) { +- ItemStack itemStack1 = useAmmo(weapon, i1 == 0 ? ammo : itemStack, shooter, i1 > 0); ++ ItemStack itemStack1 = useAmmo(weapon, i1 == 0 ? ammo : itemStack, shooter, i1 > 0 || !consume); // Paper + if (!itemStack1.isEmpty()) { + list.add(itemStack1); + } diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/ServerItemCooldowns.java.patch b/paper-server/patches/sources/net/minecraft/world/item/ServerItemCooldowns.java.patch similarity index 86% rename from paper-server/patches/unapplied/net/minecraft/world/item/ServerItemCooldowns.java.patch rename to paper-server/patches/sources/net/minecraft/world/item/ServerItemCooldowns.java.patch index b9e17d595b..6e1f3fcec1 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/item/ServerItemCooldowns.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/ServerItemCooldowns.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/world/item/ServerItemCooldowns.java +++ b/net/minecraft/world/item/ServerItemCooldowns.java -@@ -11,7 +11,40 @@ +@@ -11,6 +_,39 @@ this.player = player; } + // Paper start - Add PlayerItemCooldownEvent - @Override ++ @Override + public void addCooldown(ItemStack item, int duration) { + final ResourceLocation cooldownGroup = this.getCooldownGroup(item); + final io.papermc.paper.event.player.PlayerItemCooldownEvent event = new io.papermc.paper.event.player.PlayerItemCooldownEvent( @@ -37,7 +37,6 @@ + } + // Paper end - Add PlayerItemCooldownEvent + -+ @Override - protected void onCooldownStarted(ResourceLocation groupId, int duration) { - super.onCooldownStarted(groupId, duration); - this.player.connection.send(new ClientboundCooldownPacket(groupId, duration)); + @Override + protected void onCooldownStarted(ResourceLocation group, int cooldown) { + super.onCooldownStarted(group, cooldown); diff --git a/paper-server/patches/sources/net/minecraft/world/item/ShovelItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/ShovelItem.java.patch new file mode 100644 index 0000000000..142d691825 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/ShovelItem.java.patch @@ -0,0 +1,33 @@ +--- a/net/minecraft/world/item/ShovelItem.java ++++ b/net/minecraft/world/item/ShovelItem.java +@@ -46,20 +_,29 @@ + Player player = context.getPlayer(); + BlockState blockState1 = FLATTENABLES.get(blockState.getBlock()); + BlockState blockState2 = null; ++ Runnable afterAction = null; // Paper + if (blockState1 != null && level.getBlockState(clickedPos.above()).isAir()) { +- level.playSound(player, clickedPos, SoundEvents.SHOVEL_FLATTEN, SoundSource.BLOCKS, 1.0F, 1.0F); ++ afterAction = () -> level.playSound(player, clickedPos, SoundEvents.SHOVEL_FLATTEN, SoundSource.BLOCKS, 1.0F, 1.0F); // Paper + blockState2 = blockState1; + } else if (blockState.getBlock() instanceof CampfireBlock && blockState.getValue(CampfireBlock.LIT)) { ++ afterAction = () -> { // Paper + if (!level.isClientSide()) { + level.levelEvent(null, 1009, clickedPos, 0); + } + + CampfireBlock.dowse(context.getPlayer(), level, clickedPos, blockState); ++ }; // Paper + blockState2 = blockState.setValue(CampfireBlock.LIT, Boolean.valueOf(false)); + } + + if (blockState2 != null) { + if (!level.isClientSide) { ++ // Paper start ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(context.getPlayer(), clickedPos, blockState2)) { ++ return InteractionResult.PASS; ++ } ++ afterAction.run(); ++ // Paper end + level.setBlock(clickedPos, blockState2, 11); + level.gameEvent(GameEvent.BLOCK_CHANGE, clickedPos, GameEvent.Context.of(player, blockState2)); + if (player != null) { diff --git a/paper-server/patches/sources/net/minecraft/world/item/SignItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/SignItem.java.patch new file mode 100644 index 0000000000..fe3d4a6926 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/SignItem.java.patch @@ -0,0 +1,22 @@ +--- a/net/minecraft/world/item/SignItem.java ++++ b/net/minecraft/world/item/SignItem.java +@@ -11,6 +_,7 @@ + import net.minecraft.world.level.block.state.BlockState; + + public class SignItem extends StandingAndWallBlockItem { ++ public static BlockPos openSign; // CraftBukkit + public SignItem(Block standingBlock, Block wallBlock, Item.Properties properties) { + super(standingBlock, wallBlock, Direction.DOWN, properties); + } +@@ -27,7 +_,10 @@ + && player != null + && level.getBlockEntity(pos) instanceof SignBlockEntity signBlockEntity + && level.getBlockState(pos).getBlock() instanceof SignBlock signBlock) { +- signBlock.openTextEdit(player, signBlockEntity, true); ++ // CraftBukkit start - SPIGOT-4678 ++ // signBlock.openTextEdit(player, signBlockEntity, true); ++ SignItem.openSign = pos; ++ // CraftBukkit end + } + + return flag; diff --git a/paper-server/patches/sources/net/minecraft/world/item/SnowballItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/SnowballItem.java.patch new file mode 100644 index 0000000000..77ff25b46f --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/SnowballItem.java.patch @@ -0,0 +1,54 @@ +--- a/net/minecraft/world/item/SnowballItem.java ++++ b/net/minecraft/world/item/SnowballItem.java +@@ -23,22 +_,38 @@ + @Override + public InteractionResult use(Level level, Player player, InteractionHand hand) { + ItemStack itemInHand = player.getItemInHand(hand); +- level.playSound( +- null, +- player.getX(), +- player.getY(), +- player.getZ(), +- SoundEvents.SNOWBALL_THROW, +- SoundSource.NEUTRAL, +- 0.5F, +- 0.4F / (level.getRandom().nextFloat() * 0.4F + 0.8F) +- ); ++ // CraftBukkit start - moved down + if (level instanceof ServerLevel serverLevel) { +- Projectile.spawnProjectileFromRotation(Snowball::new, serverLevel, itemInHand, player, 0.0F, PROJECTILE_SHOOT_POWER, 1.0F); ++ // Paper start - PlayerLaunchProjectileEvent ++ final Projectile.Delayed snowball = Projectile.spawnProjectileFromRotationDelayed(Snowball::new, serverLevel, itemInHand, player, 0.0F, SnowballItem.PROJECTILE_SHOOT_POWER, 1.0F); ++ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) player.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemInHand), (org.bukkit.entity.Projectile) snowball.projectile().getBukkitEntity()); ++ if (event.callEvent() && snowball.attemptSpawn()) { ++ player.awardStat(Stats.ITEM_USED.get(this)); ++ if (event.shouldConsume()) { ++ itemInHand.consume(1, player); ++ } else if (player instanceof net.minecraft.server.level.ServerPlayer) { ++ ((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity().updateInventory(); ++ } ++ // Paper end - PlayerLaunchProjectileEvent ++ ++ level.playSound( ++ null, ++ player.getX(), ++ player.getY(), ++ player.getZ(), ++ SoundEvents.SNOWBALL_THROW, ++ SoundSource.NEUTRAL, ++ 0.5F, ++ 0.4F / (level.getRandom().nextFloat() * 0.4F + 0.8F) ++ ); ++ } else { if (player instanceof net.minecraft.server.level.ServerPlayer) { // Paper - PlayerLaunchProjectileEvent - return fail ++ ((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity().updateInventory(); ++ } return InteractionResult.FAIL; } // Paper - PlayerLaunchProjectileEvent - return fail ++ // CraftBukkit end + } + +- player.awardStat(Stats.ITEM_USED.get(this)); +- itemInHand.consume(1, player); ++ // Paper - PlayerLaunchProjectileEvent - moved up ++ // itemInHand.consume(1, player); // CraftBukkit - moved up + return InteractionResult.SUCCESS; + } + diff --git a/paper-server/patches/sources/net/minecraft/world/item/SpawnEggItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/SpawnEggItem.java.patch new file mode 100644 index 0000000000..03672c4a17 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/SpawnEggItem.java.patch @@ -0,0 +1,19 @@ +--- a/net/minecraft/world/item/SpawnEggItem.java ++++ b/net/minecraft/world/item/SpawnEggItem.java +@@ -55,6 +_,7 @@ + Direction clickedFace = context.getClickedFace(); + BlockState blockState = level.getBlockState(clickedPos); + if (level.getBlockEntity(clickedPos) instanceof Spawner spawner) { ++ if (level.paperConfig().entities.spawning.disableMobSpawnerSpawnEggTransformation) return InteractionResult.FAIL; // Paper - Allow disabling mob spawner spawn egg transformation + EntityType type = this.getType(level.registryAccess(), itemInHand); + spawner.setEntityId(type, level.getRandom()); + level.sendBlockUpdated(clickedPos, blockState, blockState, 3); +@@ -169,7 +_,7 @@ + return Optional.empty(); + } else { + breedOffspring.moveTo(pos.x(), pos.y(), pos.z(), 0.0F, 0.0F); +- serverLevel.addFreshEntityWithPassengers(breedOffspring); ++ serverLevel.addFreshEntityWithPassengers(breedOffspring, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG); // CraftBukkit + breedOffspring.setCustomName(stack.get(DataComponents.CUSTOM_NAME)); + stack.consume(1, player); + return Optional.of(breedOffspring); diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/SplashPotionItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/SplashPotionItem.java.patch similarity index 54% rename from paper-server/patches/unapplied/net/minecraft/world/item/SplashPotionItem.java.patch rename to paper-server/patches/sources/net/minecraft/world/item/SplashPotionItem.java.patch index bdf8aca4d5..1744dbddc9 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/item/SplashPotionItem.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/SplashPotionItem.java.patch @@ -1,21 +1,21 @@ --- a/net/minecraft/world/item/SplashPotionItem.java +++ b/net/minecraft/world/item/SplashPotionItem.java -@@ -14,6 +14,10 @@ +@@ -14,6 +_,10 @@ @Override - public InteractionResult use(Level world, Player user, InteractionHand hand) { + public InteractionResult use(Level level, Player player, InteractionHand hand) { + // Paper start - PlayerLaunchProjectileEvent -+ final InteractionResult wrapper = super.use(world, user, hand); ++ final InteractionResult wrapper = super.use(level, player, hand); + if (wrapper instanceof InteractionResult.Fail) return wrapper; + // Paper end - PlayerLaunchProjectileEvent - world.playSound( + level.playSound( null, - user.getX(), -@@ -24,6 +28,6 @@ + player.getX(), +@@ -24,6 +_,6 @@ 0.5F, - 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F) + 0.4F / (level.getRandom().nextFloat() * 0.4F + 0.8F) ); -- return super.use(world, user, hand); +- return super.use(level, player, hand); + return wrapper; // Paper - PlayerLaunchProjectileEvent } } diff --git a/paper-server/patches/sources/net/minecraft/world/item/StandingAndWallBlockItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/StandingAndWallBlockItem.java.patch new file mode 100644 index 0000000000..65b7227e59 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/StandingAndWallBlockItem.java.patch @@ -0,0 +1,24 @@ +--- a/net/minecraft/world/item/StandingAndWallBlockItem.java ++++ b/net/minecraft/world/item/StandingAndWallBlockItem.java +@@ -42,7 +_,20 @@ + } + } + +- return blockState != null && level.isUnobstructed(blockState, clickedPos, CollisionContext.empty()) ? blockState : null; ++ // return blockState != null && level.isUnobstructed(blockState, clickedPos, CollisionContext.empty()) ? blockState : null; ++ // CraftBukkit start ++ if (blockState != null) { ++ boolean defaultReturn = level.isUnobstructed(blockState, clickedPos, CollisionContext.empty()); ++ org.bukkit.entity.Player player = (context.getPlayer() instanceof net.minecraft.server.level.ServerPlayer) ? (org.bukkit.entity.Player) context.getPlayer().getBukkitEntity() : null; ++ ++ org.bukkit.event.block.BlockCanBuildEvent event = new org.bukkit.event.block.BlockCanBuildEvent(org.bukkit.craftbukkit.block.CraftBlock.at(context.getLevel(), clickedPos), player, org.bukkit.craftbukkit.block.data.CraftBlockData.fromData(blockState), defaultReturn, org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(context.getHand())); // Paper - Expose hand in BlockCanBuildEvent ++ context.getLevel().getCraftServer().getPluginManager().callEvent(event); ++ ++ return (event.isBuildable()) ? blockState : null; ++ } else { ++ return null; ++ } ++ // CraftBukkit end + } + + @Override diff --git a/paper-server/patches/sources/net/minecraft/world/item/ThrowablePotionItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/ThrowablePotionItem.java.patch new file mode 100644 index 0000000000..b5afefd1a8 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/ThrowablePotionItem.java.patch @@ -0,0 +1,35 @@ +--- a/net/minecraft/world/item/ThrowablePotionItem.java ++++ b/net/minecraft/world/item/ThrowablePotionItem.java +@@ -22,11 +_,29 @@ + public InteractionResult use(Level level, Player player, InteractionHand hand) { + ItemStack itemInHand = player.getItemInHand(hand); + if (level instanceof ServerLevel serverLevel) { +- Projectile.spawnProjectileFromRotation(ThrownPotion::new, serverLevel, itemInHand, player, -20.0F, PROJECTILE_SHOOT_POWER, 1.0F); ++ // Projectile.spawnProjectileFromRotation(ThrownPotion::new, serverLevel, itemInHand, player, -20.0F, PROJECTILE_SHOOT_POWER, 1.0F); ++ // Paper start - PlayerLaunchProjectileEvent ++ final Projectile.Delayed thrownPotion = Projectile.spawnProjectileFromRotationDelayed(ThrownPotion::new, serverLevel, itemInHand, player, -20.0F, PROJECTILE_SHOOT_POWER, 1.0F); ++ // Paper start - PlayerLaunchProjectileEvent ++ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) player.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemInHand), (org.bukkit.entity.Projectile) thrownPotion.projectile().getBukkitEntity()); ++ if (event.callEvent() && thrownPotion.attemptSpawn()) { ++ if (event.shouldConsume()) { ++ itemInHand.consume(1, player); ++ } else if (player instanceof net.minecraft.server.level.ServerPlayer) { ++ ((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity().updateInventory(); ++ } ++ ++ player.awardStat(Stats.ITEM_USED.get(this)); ++ } else { ++ if (player instanceof net.minecraft.server.level.ServerPlayer) { ++ ((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity().updateInventory(); ++ } ++ return InteractionResult.FAIL; ++ } ++ // Paper end - PlayerLaunchProjectileEvent + } + +- player.awardStat(Stats.ITEM_USED.get(this)); +- itemInHand.consume(1, player); ++ // Paper - PlayerLaunchProjectileEvent - move up + return InteractionResult.SUCCESS; + } + diff --git a/paper-server/patches/sources/net/minecraft/world/item/TridentItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/TridentItem.java.patch new file mode 100644 index 0000000000..b07462cc0f --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/TridentItem.java.patch @@ -0,0 +1,51 @@ +--- a/net/minecraft/world/item/TridentItem.java ++++ b/net/minecraft/world/item/TridentItem.java +@@ -87,19 +_,37 @@ + .orElse(SoundEvents.TRIDENT_THROW); + player.awardStat(Stats.ITEM_USED.get(this)); + if (level instanceof ServerLevel serverLevel) { +- stack.hurtWithoutBreaking(1, player); ++ // stack.hurtWithoutBreaking(1, player); // CraftBukkit - moved down + if (tridentSpinAttackStrength == 0.0F) { +- ThrownTrident thrownTrident = Projectile.spawnProjectileFromRotation( ++ Projectile.Delayed tridentDelayed = Projectile.spawnProjectileFromRotationDelayed( // Paper - PlayerLaunchProjectileEvent + ThrownTrident::new, serverLevel, stack, player, 0.0F, 2.5F, 1.0F + ); ++ // Paper start - PlayerLaunchProjectileEvent ++ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) player.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(stack), (org.bukkit.entity.Projectile) tridentDelayed.projectile().getBukkitEntity()); ++ if (!event.callEvent() || !tridentDelayed.attemptSpawn()) { ++ // CraftBukkit start ++ // Paper end - PlayerLaunchProjectileEvent ++ if (player instanceof net.minecraft.server.level.ServerPlayer serverPlayer) { ++ serverPlayer.getBukkitEntity().updateInventory(); ++ } ++ return false; ++ } ++ ThrownTrident thrownTrident = tridentDelayed.projectile(); // Paper - PlayerLaunchProjectileEvent ++ if (event.shouldConsume()) stack.hurtWithoutBreaking(1, player); // Paper - PlayerLaunchProjectileEvent ++ thrownTrident.pickupItemStack = stack.copy(); // SPIGOT-4511 update since damage call moved ++ // CraftBukkit end + if (player.hasInfiniteMaterials()) { + thrownTrident.pickup = AbstractArrow.Pickup.CREATIVE_ONLY; +- } else { ++ } else if (event.shouldConsume()) { // Paper - PlayerLaunchProjectileEvent + player.getInventory().removeItem(stack); + } + + level.playSound(null, thrownTrident, holder.value(), SoundSource.PLAYERS, 1.0F, 1.0F); + return true; ++ // CraftBukkit start - SPIGOT-5458 also need in this branch :( ++ } else { ++ stack.hurtWithoutBreaking(1, player); ++ // CraftBukkit end + } + } + +@@ -113,6 +_,7 @@ + f *= tridentSpinAttackStrength / squareRoot; + f1 *= tridentSpinAttackStrength / squareRoot; + f2 *= tridentSpinAttackStrength / squareRoot; ++ org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerRiptideEvent(player, stack, f, f1, f2); // CraftBukkit + player.push(f, f1, f2); + player.startAutoSpinAttack(20, 8.0F, stack); + if (player.onGround()) { diff --git a/paper-server/patches/sources/net/minecraft/world/item/WindChargeItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/WindChargeItem.java.patch new file mode 100644 index 0000000000..26a26944da --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/WindChargeItem.java.patch @@ -0,0 +1,44 @@ +--- a/net/minecraft/world/item/WindChargeItem.java ++++ b/net/minecraft/world/item/WindChargeItem.java +@@ -27,7 +_,7 @@ + public InteractionResult use(Level level, Player player, InteractionHand hand) { + ItemStack itemInHand = player.getItemInHand(hand); + if (level instanceof ServerLevel serverLevel) { +- Projectile.spawnProjectileFromRotation( ++ final Projectile.Delayed windCharge = Projectile.spawnProjectileFromRotationDelayed( // Paper - PlayerLaunchProjectileEvent + (level1, owner, spawnedFrom) -> new WindCharge(player, level, player.position().x(), player.getEyePosition().y(), player.position().z()), + serverLevel, + itemInHand, +@@ -36,6 +_,22 @@ + PROJECTILE_SHOOT_POWER, + 1.0F + ); ++ // Paper start - PlayerLaunchProjectileEvent ++ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) player.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemInHand), (org.bukkit.entity.Projectile) windCharge.projectile().getBukkitEntity()); ++ if (!event.callEvent() || !windCharge.attemptSpawn()) { ++ player.containerMenu.sendAllDataToRemote(); ++ if (player instanceof net.minecraft.server.level.ServerPlayer serverPlayer) { ++ serverPlayer.connection.send(new net.minecraft.network.protocol.game.ClientboundCooldownPacket(player.getCooldowns().getCooldownGroup(itemInHand), 0)); // prevent visual desync of cooldown on the slot ++ } ++ return InteractionResult.FAIL; ++ } ++ ++ player.awardStat(Stats.ITEM_USED.get(this)); ++ if (event.shouldConsume()) itemInHand.consume(1, player); ++ else if (!player.hasInfiniteMaterials()) { ++ player.containerMenu.sendAllDataToRemote(); ++ } ++ // Paper end - PlayerLaunchProjectileEvent + } + + level.playSound( +@@ -48,8 +_,7 @@ + 0.5F, + 0.4F / (level.getRandom().nextFloat() * 0.4F + 0.8F) + ); +- player.awardStat(Stats.ITEM_USED.get(this)); +- itemInHand.consume(1, player); ++ // Paper - PlayerLaunchProjectileEvent; moved up + return InteractionResult.SUCCESS; + } + diff --git a/paper-server/patches/sources/net/minecraft/world/item/WrittenBookItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/WrittenBookItem.java.patch new file mode 100644 index 0000000000..a8a03bfeee --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/item/WrittenBookItem.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/item/WrittenBookItem.java ++++ b/net/minecraft/world/item/WrittenBookItem.java +@@ -41,7 +_,7 @@ + + public static boolean resolveBookComponents(ItemStack bookStack, CommandSourceStack resolvingSource, @Nullable Player resolvingPlayer) { + WrittenBookContent writtenBookContent = bookStack.get(DataComponents.WRITTEN_BOOK_CONTENT); +- if (writtenBookContent != null && !writtenBookContent.resolved()) { ++ if (io.papermc.paper.configuration.GlobalConfiguration.get().itemValidation.resolveSelectorsInBooks && writtenBookContent != null && !writtenBookContent.resolved()) { // Paper - Disable component selector resolving in books by default + WrittenBookContent writtenBookContent1 = writtenBookContent.resolve(resolvingSource, resolvingPlayer); + if (writtenBookContent1 != null) { + bookStack.set(DataComponents.WRITTEN_BOOK_CONTENT, writtenBookContent1); diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/ArmorStandItem.java.patch b/paper-server/patches/unapplied/net/minecraft/world/item/ArmorStandItem.java.patch deleted file mode 100644 index 5be546c2b6..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/item/ArmorStandItem.java.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- a/net/minecraft/world/item/ArmorStandItem.java -+++ b/net/minecraft/world/item/ArmorStandItem.java -@@ -53,6 +53,12 @@ - float f = (float) Mth.floor((Mth.wrapDegrees(context.getRotation() - 180.0F) + 22.5F) / 45.0F) * 45.0F; - - entityarmorstand.moveTo(entityarmorstand.getX(), entityarmorstand.getY(), entityarmorstand.getZ(), f, 0.0F); -+ // CraftBukkit start -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPlaceEvent(context, entityarmorstand).isCancelled()) { -+ if (context.getPlayer() != null) context.getPlayer().containerMenu.sendAllDataToRemote(); // Paper - Fix inventory desync -+ return InteractionResult.FAIL; -+ } -+ // CraftBukkit end - worldserver.addFreshEntityWithPassengers(entityarmorstand); - world.playSound((Player) null, entityarmorstand.getX(), entityarmorstand.getY(), entityarmorstand.getZ(), SoundEvents.ARMOR_STAND_PLACE, SoundSource.BLOCKS, 0.75F, 0.8F); - entityarmorstand.gameEvent(GameEvent.ENTITY_PLACE, context.getPlayer()); diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/AxeItem.java.patch b/paper-server/patches/unapplied/net/minecraft/world/item/AxeItem.java.patch deleted file mode 100644 index 858ea3302d..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/item/AxeItem.java.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- a/net/minecraft/world/item/AxeItem.java -+++ b/net/minecraft/world/item/AxeItem.java -@@ -67,6 +67,11 @@ - return InteractionResult.PASS; - } else { - ItemStack itemStack = context.getItemInHand(); -+ // Paper start - EntityChangeBlockEvent -+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, blockPos, optional.get())) { -+ return InteractionResult.PASS; -+ } -+ // Paper end - if (player instanceof ServerPlayer) { - CriteriaTriggers.ITEM_USED_ON_BLOCK.trigger((ServerPlayer)player, blockPos, itemStack); - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/BlockItem.java.patch b/paper-server/patches/unapplied/net/minecraft/world/item/BlockItem.java.patch deleted file mode 100644 index 52e43aa9e4..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/item/BlockItem.java.patch +++ /dev/null @@ -1,109 +0,0 @@ ---- a/net/minecraft/world/item/BlockItem.java -+++ b/net/minecraft/world/item/BlockItem.java -@@ -10,9 +10,9 @@ - import net.minecraft.core.registries.Registries; - import net.minecraft.nbt.CompoundTag; - import net.minecraft.network.chat.Component; -+import net.minecraft.server.level.ServerLevel; - import net.minecraft.server.level.ServerPlayer; - import net.minecraft.sounds.SoundEvent; --import net.minecraft.sounds.SoundSource; - import net.minecraft.world.InteractionResult; - import net.minecraft.world.entity.item.ItemEntity; - import net.minecraft.world.entity.player.Player; -@@ -31,6 +31,10 @@ - import net.minecraft.world.level.block.state.BlockState; - import net.minecraft.world.level.gameevent.GameEvent; - import net.minecraft.world.phys.shapes.CollisionContext; -+import org.bukkit.craftbukkit.block.CraftBlock; -+import org.bukkit.craftbukkit.block.data.CraftBlockData; -+import org.bukkit.event.block.BlockCanBuildEvent; -+// CraftBukkit end - - public class BlockItem extends Item { - -@@ -62,6 +66,13 @@ - return InteractionResult.FAIL; - } else { - BlockState iblockdata = this.getPlacementState(blockactioncontext1); -+ // CraftBukkit start - special case for handling block placement with water lilies and snow buckets -+ org.bukkit.block.BlockState blockstate = null; -+ if (this instanceof PlaceOnWaterBlockItem || this instanceof SolidBucketItem) { -+ blockstate = org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(blockactioncontext1.getLevel(), blockactioncontext1.getClickedPos()); -+ } -+ final org.bukkit.block.BlockState oldBlockstate = blockstate != null ? blockstate : org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(blockactioncontext1.getLevel(), blockactioncontext1.getClickedPos()); // Paper - Reset placed block on exception -+ // CraftBukkit end - - if (iblockdata == null) { - return InteractionResult.FAIL; -@@ -76,9 +87,34 @@ - - if (iblockdata1.is(iblockdata.getBlock())) { - iblockdata1 = this.updateBlockStateFromTag(blockposition, world, itemstack, iblockdata1); -+ // Paper start - Reset placed block on exception -+ try { - this.updateCustomBlockEntityTag(blockposition, world, entityhuman, itemstack, iblockdata1); - BlockItem.updateBlockEntityComponents(world, blockposition, itemstack); -+ } catch (Exception e) { -+ oldBlockstate.update(true, false); -+ if (entityhuman instanceof ServerPlayer player) { -+ org.apache.logging.log4j.LogManager.getLogger().error("Player {} tried placing invalid block", player.getScoreboardName(), e); -+ player.getBukkitEntity().kickPlayer("Packet processing error"); -+ return InteractionResult.FAIL; -+ } -+ throw e; // Rethrow exception if not placed by a player -+ } -+ // Paper end - Reset placed block on exception - iblockdata1.getBlock().setPlacedBy(world, blockposition, iblockdata1, entityhuman, itemstack); -+ // CraftBukkit start -+ if (blockstate != null) { -+ org.bukkit.event.block.BlockPlaceEvent placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPlaceEvent((ServerLevel) world, entityhuman, blockactioncontext1.getHand(), blockstate, blockposition.getX(), blockposition.getY(), blockposition.getZ()); -+ if (placeEvent != null && (placeEvent.isCancelled() || !placeEvent.canBuild())) { -+ blockstate.update(true, false); -+ -+ if (true) { // Paper - if the event is called here, the inventory should be updated -+ ((ServerPlayer) entityhuman).getBukkitEntity().updateInventory(); // SPIGOT-4541 -+ } -+ return InteractionResult.FAIL; -+ } -+ } -+ // CraftBukkit end - if (entityhuman instanceof ServerPlayer) { - CriteriaTriggers.PLACED_BLOCK.trigger((ServerPlayer) entityhuman, blockposition, itemstack); - } -@@ -86,7 +122,7 @@ - - SoundType soundeffecttype = iblockdata1.getSoundType(); - -- world.playSound(entityhuman, blockposition, this.getPlaceSound(iblockdata1), SoundSource.BLOCKS, (soundeffecttype.getVolume() + 1.0F) / 2.0F, soundeffecttype.getPitch() * 0.8F); -+ if (entityhuman == null) world.playSound(entityhuman, blockposition, this.getPlaceSound(iblockdata1), net.minecraft.sounds.SoundSource.BLOCKS, (soundeffecttype.getVolume() + 1.0F) / 2.0F, soundeffecttype.getPitch() * 0.8F); // Paper - Fix block place logic; reintroduce this for the dispenser (i.e the shulker) - world.gameEvent((Holder) GameEvent.BLOCK_PLACE, blockposition, GameEvent.Context.of(entityhuman, iblockdata1)); - itemstack.consume(1, entityhuman); - return InteractionResult.SUCCESS; -@@ -144,8 +180,16 @@ - protected boolean canPlace(BlockPlaceContext context, BlockState state) { - Player entityhuman = context.getPlayer(); - CollisionContext voxelshapecollision = entityhuman == null ? CollisionContext.empty() : CollisionContext.of(entityhuman); -+ // CraftBukkit start - store default return -+ Level world = context.getLevel(); // Paper - Cancel hit for vanished players -+ boolean defaultReturn = (!this.mustSurvive() || state.canSurvive(context.getLevel(), context.getClickedPos())) && world.checkEntityCollision(state, entityhuman, voxelshapecollision, context.getClickedPos(), true); // Paper - Cancel hit for vanished players -+ org.bukkit.entity.Player player = (context.getPlayer() instanceof ServerPlayer) ? (org.bukkit.entity.Player) context.getPlayer().getBukkitEntity() : null; - -- return (!this.mustSurvive() || state.canSurvive(context.getLevel(), context.getClickedPos())) && context.getLevel().isUnobstructed(state, context.getClickedPos(), voxelshapecollision); -+ BlockCanBuildEvent event = new BlockCanBuildEvent(CraftBlock.at(context.getLevel(), context.getClickedPos()), player, CraftBlockData.fromData(state), defaultReturn, org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(context.getHand())); // Paper - Expose hand in BlockCanBuildEvent -+ context.getLevel().getCraftServer().getPluginManager().callEvent(event); -+ -+ return event.isBuildable(); -+ // CraftBukkit end - } - - protected boolean mustSurvive() { -@@ -178,7 +222,7 @@ - return false; - } - -- if (tileentitytypes1.onlyOpCanSetNbt() && (player == null || !player.canUseGameMasterBlocks())) { -+ if (tileentitytypes1.onlyOpCanSetNbt() && (player == null || !(player.canUseGameMasterBlocks() || (player.getAbilities().instabuild && player.getBukkitEntity().hasPermission("minecraft.nbt.place"))))) { // Spigot - add permission - return false; - } - diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/BoatItem.java.patch b/paper-server/patches/unapplied/net/minecraft/world/item/BoatItem.java.patch deleted file mode 100644 index c8502fcea3..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/item/BoatItem.java.patch +++ /dev/null @@ -1,33 +0,0 @@ ---- a/net/minecraft/world/item/BoatItem.java -+++ b/net/minecraft/world/item/BoatItem.java -@@ -58,6 +58,13 @@ - } - - if (movingobjectpositionblock.getType() == HitResult.Type.BLOCK) { -+ // CraftBukkit start - Boat placement -+ org.bukkit.event.player.PlayerInteractEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent(user, org.bukkit.event.block.Action.RIGHT_CLICK_BLOCK, movingobjectpositionblock.getBlockPos(), movingobjectpositionblock.getDirection(), itemstack, false, hand, movingobjectpositionblock.getLocation()); -+ -+ if (event.isCancelled()) { -+ return InteractionResult.PASS; -+ } -+ // CraftBukkit end - AbstractBoat abstractboat = this.getBoat(world, movingobjectpositionblock, itemstack, user); - - if (abstractboat == null) { -@@ -68,7 +75,15 @@ - return InteractionResult.FAIL; - } else { - if (!world.isClientSide) { -- world.addFreshEntity(abstractboat); -+ // CraftBukkit start -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPlaceEvent(world, movingobjectpositionblock.getBlockPos(), movingobjectpositionblock.getDirection(), user, abstractboat, hand).isCancelled()) { -+ return InteractionResult.FAIL; -+ } -+ -+ if (!world.addFreshEntity(abstractboat)) { -+ return InteractionResult.PASS; -+ } -+ // CraftBukkit end - world.gameEvent((Entity) user, (Holder) GameEvent.ENTITY_PLACE, movingobjectpositionblock.getLocation()); - itemstack.consume(1, user); - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/BoneMealItem.java.patch b/paper-server/patches/unapplied/net/minecraft/world/item/BoneMealItem.java.patch deleted file mode 100644 index 4cf7f7eebf..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/item/BoneMealItem.java.patch +++ /dev/null @@ -1,41 +0,0 @@ ---- a/net/minecraft/world/item/BoneMealItem.java -+++ b/net/minecraft/world/item/BoneMealItem.java -@@ -35,24 +35,30 @@ - - @Override - public InteractionResult useOn(UseOnContext context) { -- Level world = context.getLevel(); -- BlockPos blockposition = context.getClickedPos(); -- BlockPos blockposition1 = blockposition.relative(context.getClickedFace()); -+ // CraftBukkit start - extract bonemeal application logic to separate, static method -+ return BoneMealItem.applyBonemeal(context); -+ } - -- if (BoneMealItem.growCrop(context.getItemInHand(), world, blockposition)) { -+ public static InteractionResult applyBonemeal(UseOnContext itemactioncontext) { -+ // CraftBukkit end -+ Level world = itemactioncontext.getLevel(); -+ BlockPos blockposition = itemactioncontext.getClickedPos(); -+ BlockPos blockposition1 = blockposition.relative(itemactioncontext.getClickedFace()); -+ -+ if (BoneMealItem.growCrop(itemactioncontext.getItemInHand(), world, blockposition)) { - if (!world.isClientSide) { -- context.getPlayer().gameEvent(GameEvent.ITEM_INTERACT_FINISH); -+ if (itemactioncontext.getPlayer() != null) itemactioncontext.getPlayer().gameEvent(GameEvent.ITEM_INTERACT_FINISH); // CraftBukkit - SPIGOT-7518 - world.levelEvent(1505, blockposition, 15); - } - - return InteractionResult.SUCCESS; - } else { - BlockState iblockdata = world.getBlockState(blockposition); -- boolean flag = iblockdata.isFaceSturdy(world, blockposition, context.getClickedFace()); -+ boolean flag = iblockdata.isFaceSturdy(world, blockposition, itemactioncontext.getClickedFace()); - -- if (flag && BoneMealItem.growWaterPlant(context.getItemInHand(), world, blockposition1, context.getClickedFace())) { -+ if (flag && BoneMealItem.growWaterPlant(itemactioncontext.getItemInHand(), world, blockposition1, itemactioncontext.getClickedFace())) { - if (!world.isClientSide) { -- context.getPlayer().gameEvent(GameEvent.ITEM_INTERACT_FINISH); -+ if (itemactioncontext.getPlayer() != null) itemactioncontext.getPlayer().gameEvent(GameEvent.ITEM_INTERACT_FINISH); // CraftBukkit - SPIGOT-7518 - world.levelEvent(1505, blockposition1, 15); - } - diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/BucketItem.java.patch b/paper-server/patches/unapplied/net/minecraft/world/item/BucketItem.java.patch deleted file mode 100644 index 6e51878d93..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/item/BucketItem.java.patch +++ /dev/null @@ -1,168 +0,0 @@ ---- a/net/minecraft/world/item/BucketItem.java -+++ b/net/minecraft/world/item/BucketItem.java -@@ -6,6 +6,8 @@ - import net.minecraft.core.Direction; - import net.minecraft.core.Holder; - import net.minecraft.core.particles.ParticleTypes; -+import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket; -+import net.minecraft.server.level.ServerLevel; - import net.minecraft.server.level.ServerPlayer; - import net.minecraft.sounds.SoundEvent; - import net.minecraft.sounds.SoundEvents; -@@ -29,9 +31,17 @@ - import net.minecraft.world.level.material.Fluids; - import net.minecraft.world.phys.BlockHitResult; - import net.minecraft.world.phys.HitResult; -+import org.bukkit.craftbukkit.event.CraftEventFactory; -+import org.bukkit.craftbukkit.inventory.CraftItemStack; -+import org.bukkit.craftbukkit.util.DummyGeneratorAccess; -+import org.bukkit.event.player.PlayerBucketEmptyEvent; -+import org.bukkit.event.player.PlayerBucketFillEvent; -+// CraftBukkit end - - public class BucketItem extends Item implements DispensibleContainerItem { - -+ private static @Nullable ItemStack itemLeftInHandAfterPlayerBucketEmptyEvent = null; // Paper - Fix PlayerBucketEmptyEvent result itemstack -+ - public final Fluid content; - - public BucketItem(Fluid fluid, Item.Properties settings) { -@@ -63,7 +73,18 @@ - - if (block instanceof BucketPickup) { - BucketPickup ifluidsource = (BucketPickup) block; -+ // CraftBukkit start -+ ItemStack dummyFluid = ifluidsource.pickupBlock(user, DummyGeneratorAccess.INSTANCE, blockposition, iblockdata); -+ if (dummyFluid.isEmpty()) return InteractionResult.FAIL; // Don't fire event if the bucket won't be filled. -+ PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent((ServerLevel) world, user, blockposition, blockposition, movingobjectpositionblock.getDirection(), itemstack, dummyFluid.getItem(), hand); - -+ if (event.isCancelled()) { -+ // ((ServerPlayer) user).connection.send(new ClientboundBlockUpdatePacket(world, blockposition)); // SPIGOT-5163 (see PlayerInteractManager) // Paper - Don't resend blocks -+ ((ServerPlayer) user).getBukkitEntity().updateInventory(); // SPIGOT-4541 -+ return InteractionResult.FAIL; -+ } -+ // CraftBukkit end -+ - itemstack1 = ifluidsource.pickupBlock(user, world, blockposition, iblockdata); - if (!itemstack1.isEmpty()) { - user.awardStat(Stats.ITEM_USED.get(this)); -@@ -71,7 +92,7 @@ - user.playSound(soundeffect, 1.0F, 1.0F); - }); - world.gameEvent((Entity) user, (Holder) GameEvent.FLUID_PICKUP, blockposition); -- ItemStack itemstack2 = ItemUtils.createFilledResult(itemstack, user, itemstack1); -+ ItemStack itemstack2 = ItemUtils.createFilledResult(itemstack, user, CraftItemStack.asNMSCopy(event.getItemStack())); // CraftBukkit - - if (!world.isClientSide) { - CriteriaTriggers.FILLED_BUCKET.trigger((ServerPlayer) user, itemstack1); -@@ -86,7 +107,7 @@ - iblockdata = world.getBlockState(blockposition); - BlockPos blockposition2 = iblockdata.getBlock() instanceof LiquidBlockContainer && this.content == Fluids.WATER ? blockposition : blockposition1; - -- if (this.emptyContents(user, world, blockposition2, movingobjectpositionblock)) { -+ if (this.emptyContents(user, world, blockposition2, movingobjectpositionblock, movingobjectpositionblock.getDirection(), blockposition, itemstack, hand)) { // CraftBukkit - this.checkExtraContent(user, world, itemstack, blockposition2); - if (user instanceof ServerPlayer) { - CriteriaTriggers.PLACED_BLOCK.trigger((ServerPlayer) user, blockposition2, itemstack); -@@ -106,6 +127,13 @@ - } - - public static ItemStack getEmptySuccessItem(ItemStack stack, Player player) { -+ // Paper start - Fix PlayerBucketEmptyEvent result itemstack -+ if (itemLeftInHandAfterPlayerBucketEmptyEvent != null) { -+ ItemStack itemInHand = itemLeftInHandAfterPlayerBucketEmptyEvent; -+ itemLeftInHandAfterPlayerBucketEmptyEvent = null; -+ return itemInHand; -+ } -+ // Paper end - Fix PlayerBucketEmptyEvent result itemstack - return !player.hasInfiniteMaterials() ? new ItemStack(Items.BUCKET) : stack; - } - -@@ -114,6 +142,12 @@ - - @Override - public boolean emptyContents(@Nullable Player player, Level world, BlockPos pos, @Nullable BlockHitResult hitResult) { -+ // CraftBukkit start -+ return this.emptyContents(player, world, pos, hitResult, null, null, null, InteractionHand.MAIN_HAND); -+ } -+ -+ public boolean emptyContents(Player entityhuman, Level world, BlockPos blockposition, @Nullable BlockHitResult movingobjectpositionblock, Direction enumdirection, BlockPos clicked, ItemStack itemstack, InteractionHand enumhand) { -+ // CraftBukkit end - Fluid fluidtype = this.content; - - if (!(fluidtype instanceof FlowingFluid fluidtypeflowing)) { -@@ -126,7 +160,7 @@ - boolean flag1; - label70: - { -- iblockdata = world.getBlockState(pos); -+ iblockdata = world.getBlockState(blockposition); - block = iblockdata.getBlock(); - flag = iblockdata.canBeReplaced(this.content); - if (!iblockdata.isAir() && !flag) { -@@ -134,7 +168,7 @@ - { - if (block instanceof LiquidBlockContainer) { - ifluidcontainer = (LiquidBlockContainer) block; -- if (ifluidcontainer.canPlaceLiquid(player, world, pos, iblockdata, this.content)) { -+ if (ifluidcontainer.canPlaceLiquid(entityhuman, world, blockposition, iblockdata, this.content)) { - break label67; - } - } -@@ -149,14 +183,25 @@ - - boolean flag2 = flag1; - -+ // CraftBukkit start -+ if (flag2 && entityhuman != null) { -+ PlayerBucketEmptyEvent event = CraftEventFactory.callPlayerBucketEmptyEvent((ServerLevel) world, entityhuman, blockposition, clicked, enumdirection, itemstack, enumhand); -+ if (event.isCancelled()) { -+ // ((ServerPlayer) entityhuman).connection.send(new ClientboundBlockUpdatePacket(world, blockposition)); // SPIGOT-4238: needed when looking through entity // Paper - Don't resend blocks -+ ((ServerPlayer) entityhuman).getBukkitEntity().updateInventory(); // SPIGOT-4541 -+ return false; -+ } -+ itemLeftInHandAfterPlayerBucketEmptyEvent = event.getItemStack() != null ? event.getItemStack().equals(CraftItemStack.asNewCraftStack(net.minecraft.world.item.Items.BUCKET)) ? null : CraftItemStack.asNMSCopy(event.getItemStack()) : ItemStack.EMPTY; // Paper - Fix PlayerBucketEmptyEvent result itemstack -+ } -+ // CraftBukkit end - if (!flag2) { -- return hitResult != null && this.emptyContents(player, world, hitResult.getBlockPos().relative(hitResult.getDirection()), (BlockHitResult) null); -+ return movingobjectpositionblock != null && this.emptyContents(entityhuman, world, movingobjectpositionblock.getBlockPos().relative(movingobjectpositionblock.getDirection()), (BlockHitResult) null, enumdirection, clicked, itemstack, enumhand); // CraftBukkit - } else if (world.dimensionType().ultraWarm() && this.content.is(FluidTags.WATER)) { -- int i = pos.getX(); -- int j = pos.getY(); -- int k = pos.getZ(); -+ int i = blockposition.getX(); -+ int j = blockposition.getY(); -+ int k = blockposition.getZ(); - -- world.playSound(player, pos, SoundEvents.FIRE_EXTINGUISH, SoundSource.BLOCKS, 0.5F, 2.6F + (world.random.nextFloat() - world.random.nextFloat()) * 0.8F); -+ world.playSound(entityhuman, blockposition, SoundEvents.FIRE_EXTINGUISH, SoundSource.BLOCKS, 0.5F, 2.6F + (world.random.nextFloat() - world.random.nextFloat()) * 0.8F); - - for (int l = 0; l < 8; ++l) { - world.addParticle(ParticleTypes.LARGE_SMOKE, (double) i + Math.random(), (double) j + Math.random(), (double) k + Math.random(), 0.0D, 0.0D, 0.0D); -@@ -167,20 +212,20 @@ - if (block instanceof LiquidBlockContainer) { - ifluidcontainer = (LiquidBlockContainer) block; - if (this.content == Fluids.WATER) { -- ifluidcontainer.placeLiquid(world, pos, iblockdata, fluidtypeflowing.getSource(false)); -- this.playEmptySound(player, world, pos); -+ ifluidcontainer.placeLiquid(world, blockposition, iblockdata, fluidtypeflowing.getSource(false)); -+ this.playEmptySound(entityhuman, world, blockposition); - return true; - } - } - - if (!world.isClientSide && flag && !iblockdata.liquid()) { -- world.destroyBlock(pos, true); -+ world.destroyBlock(blockposition, true); - } - -- if (!world.setBlock(pos, this.content.defaultFluidState().createLegacyBlock(), 11) && !iblockdata.getFluidState().isSource()) { -+ if (!world.setBlock(blockposition, this.content.defaultFluidState().createLegacyBlock(), 11) && !iblockdata.getFluidState().isSource()) { - return false; - } else { -- this.playEmptySound(player, world, pos); -+ this.playEmptySound(entityhuman, world, blockposition); - return true; - } - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/CrossbowItem.java.patch b/paper-server/patches/unapplied/net/minecraft/world/item/CrossbowItem.java.patch deleted file mode 100644 index d6f5a8f499..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/item/CrossbowItem.java.patch +++ /dev/null @@ -1,48 +0,0 @@ ---- a/net/minecraft/world/item/CrossbowItem.java -+++ b/net/minecraft/world/item/CrossbowItem.java -@@ -90,7 +90,14 @@ - public boolean releaseUsing(ItemStack stack, Level world, LivingEntity user, int remainingUseTicks) { - int i = this.getUseDuration(stack, user) - remainingUseTicks; - float f = getPowerForTime(i, stack, user); -- if (f >= 1.0F && !isCharged(stack) && tryLoadProjectiles(user, stack)) { -+ // Paper start - Add EntityLoadCrossbowEvent -+ if (f >= 1.0F && !isCharged(stack)) { -+ final io.papermc.paper.event.entity.EntityLoadCrossbowEvent event = new io.papermc.paper.event.entity.EntityLoadCrossbowEvent(user.getBukkitLivingEntity(), stack.asBukkitMirror(), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(user.getUsedItemHand())); -+ if (!event.callEvent() || !tryLoadProjectiles(user, stack, event.shouldConsumeItem()) || !event.shouldConsumeItem()) { -+ if (user instanceof ServerPlayer player) player.containerMenu.sendAllDataToRemote(); -+ return false; -+ } -+ // Paper end - Add EntityLoadCrossbowEvent - CrossbowItem.ChargingSounds chargingSounds = this.getChargingSounds(stack); - chargingSounds.end() - .ifPresent( -@@ -111,8 +118,14 @@ - } - } - -- private static boolean tryLoadProjectiles(LivingEntity shooter, ItemStack crossbow) { -- List list = draw(crossbow, shooter.getProjectile(crossbow), shooter); -+ @io.papermc.paper.annotation.DoNotUse // Paper - Add EntityLoadCrossbowEvent -+ private static boolean tryLoadProjectiles(LivingEntity shooter, ItemStack crossbow) { -+ // Paper start - Add EntityLoadCrossbowEvent -+ return CrossbowItem.tryLoadProjectiles(shooter, crossbow, true); -+ } -+ private static boolean tryLoadProjectiles(LivingEntity shooter, ItemStack crossbow, boolean consume) { -+ List list = draw(crossbow, shooter.getProjectile(crossbow), shooter, consume); -+ // Paper end - Add EntityLoadCrossbowEvent - if (!list.isEmpty()) { - crossbow.set(DataComponents.CHARGED_PROJECTILES, ChargedProjectiles.of(list)); - return true; -@@ -164,7 +177,11 @@ - @Override - protected Projectile createProjectile(Level world, LivingEntity shooter, ItemStack weaponStack, ItemStack projectileStack, boolean critical) { - if (projectileStack.is(Items.FIREWORK_ROCKET)) { -- return new FireworkRocketEntity(world, projectileStack, shooter, shooter.getX(), shooter.getEyeY() - 0.15F, shooter.getZ(), true); -+ // Paper start -+ FireworkRocketEntity entity = new FireworkRocketEntity(world, projectileStack, shooter, shooter.getX(), shooter.getEyeY() - 0.15F, shooter.getZ(), true); -+ entity.spawningEntity = shooter.getUUID(); // Paper -+ return entity; -+ // Paper end - } else { - Projectile projectile = super.createProjectile(world, shooter, weaponStack, projectileStack, critical); - if (projectile instanceof AbstractArrow abstractArrow) { diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/DebugStickItem.java.patch b/paper-server/patches/unapplied/net/minecraft/world/item/DebugStickItem.java.patch deleted file mode 100644 index b81a2063de..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/item/DebugStickItem.java.patch +++ /dev/null @@ -1,25 +0,0 @@ ---- a/net/minecraft/world/item/DebugStickItem.java -+++ b/net/minecraft/world/item/DebugStickItem.java -@@ -1,3 +1,4 @@ -+// mc-dev import - package net.minecraft.world.item; - - import java.util.Collection; -@@ -52,7 +53,7 @@ - } - - public boolean handleInteraction(Player player, BlockState state, LevelAccessor world, BlockPos pos, boolean update, ItemStack stack) { -- if (!player.canUseGameMasterBlocks()) { -+ if (!player.canUseGameMasterBlocks() && !(player.getAbilities().instabuild && player.getBukkitEntity().hasPermission("minecraft.debugstick")) && !player.getBukkitEntity().hasPermission("minecraft.debugstick.always")) { // Spigot - return false; - } else { - Holder holder = state.getBlockHolder(); -@@ -92,7 +93,7 @@ - } - - private static > BlockState cycleState(BlockState state, Property property, boolean inverse) { -- return (BlockState) state.setValue(property, (Comparable) DebugStickItem.getRelative(property.getPossibleValues(), state.getValue(property), inverse)); -+ return (BlockState) state.setValue(property, DebugStickItem.getRelative(property.getPossibleValues(), state.getValue(property), inverse)); // CraftBukkit - decompile error - } - - private static T getRelative(Iterable elements, @Nullable T current, boolean inverse) { diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/DyeItem.java.patch b/paper-server/patches/unapplied/net/minecraft/world/item/DyeItem.java.patch deleted file mode 100644 index ca96f3388a..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/item/DyeItem.java.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- a/net/minecraft/world/item/DyeItem.java -+++ b/net/minecraft/world/item/DyeItem.java -@@ -12,6 +12,7 @@ - import net.minecraft.world.entity.player.Player; - import net.minecraft.world.level.Level; - import net.minecraft.world.level.block.entity.SignBlockEntity; -+import org.bukkit.event.entity.SheepDyeWoolEvent; // CraftBukkit - - public class DyeItem extends Item implements SignApplicator { - -@@ -30,7 +31,17 @@ - if (entitysheep.isAlive() && !entitysheep.isSheared() && entitysheep.getColor() != this.dyeColor) { - entitysheep.level().playSound(user, (Entity) entitysheep, SoundEvents.DYE_USE, SoundSource.PLAYERS, 1.0F, 1.0F); - if (!user.level().isClientSide) { -- entitysheep.setColor(this.dyeColor); -+ // CraftBukkit start -+ byte bColor = (byte) this.dyeColor.getId(); -+ SheepDyeWoolEvent event = new SheepDyeWoolEvent((org.bukkit.entity.Sheep) entitysheep.getBukkitEntity(), org.bukkit.DyeColor.getByWoolData(bColor), (org.bukkit.entity.Player) user.getBukkitEntity()); -+ entitysheep.level().getCraftServer().getPluginManager().callEvent(event); -+ -+ if (event.isCancelled()) { -+ return InteractionResult.PASS; -+ } -+ -+ entitysheep.setColor(DyeColor.byId((byte) event.getColor().getWoolData())); -+ // CraftBukkit end - stack.shrink(1); - } - diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/EggItem.java.patch b/paper-server/patches/unapplied/net/minecraft/world/item/EggItem.java.patch deleted file mode 100644 index 6281e950e3..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/item/EggItem.java.patch +++ /dev/null @@ -1,40 +0,0 @@ ---- a/net/minecraft/world/item/EggItem.java -+++ b/net/minecraft/world/item/EggItem.java -@@ -25,13 +25,32 @@ - public InteractionResult use(Level world, Player user, InteractionHand hand) { - ItemStack itemstack = user.getItemInHand(hand); - -- world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.EGG_THROW, SoundSource.PLAYERS, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); -+ // world.playSound((EntityHuman) null, entityhuman.getX(), entityhuman.getY(), entityhuman.getZ(), SoundEffects.EGG_THROW, SoundCategory.PLAYERS, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); // CraftBukkit - moved down - if (world instanceof ServerLevel worldserver) { -- Projectile.spawnProjectileFromRotation(ThrownEgg::new, worldserver, itemstack, user, 0.0F, EggItem.PROJECTILE_SHOOT_POWER, 1.0F); -- } -+ // CraftBukkit start -+ // Paper start - PlayerLaunchProjectileEvent -+ final Projectile.Delayed thrownEgg = Projectile.spawnProjectileFromRotationDelayed(ThrownEgg::new, worldserver, itemstack, user, 0.0F, EggItem.PROJECTILE_SHOOT_POWER, 1.0F); -+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) thrownEgg.projectile().getBukkitEntity()); -+ if (event.callEvent() && thrownEgg.attemptSpawn()) { -+ if (event.shouldConsume()) { -+ itemstack.consume(1, user); -+ } else if (user instanceof net.minecraft.server.level.ServerPlayer) { -+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); -+ } - -- user.awardStat(Stats.ITEM_USED.get(this)); -- itemstack.consume(1, user); -+ world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.EGG_THROW, SoundSource.PLAYERS, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); -+ user.awardStat(Stats.ITEM_USED.get(this)); -+ } else { -+ // Paper end - PlayerLaunchProjectileEvent -+ if (user instanceof net.minecraft.server.level.ServerPlayer) { -+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); -+ } -+ return InteractionResult.FAIL; -+ } -+ // CraftBukkit end -+ } -+ world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.EGG_THROW, SoundSource.PLAYERS, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); -+ // Paper - PlayerLaunchProjectileEvent - moved up - return InteractionResult.SUCCESS; - } - diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/EndCrystalItem.java.patch b/paper-server/patches/unapplied/net/minecraft/world/item/EndCrystalItem.java.patch deleted file mode 100644 index 89844fdef2..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/item/EndCrystalItem.java.patch +++ /dev/null @@ -1,31 +0,0 @@ ---- a/net/minecraft/world/item/EndCrystalItem.java -+++ b/net/minecraft/world/item/EndCrystalItem.java -@@ -30,7 +30,7 @@ - if (!iblockdata.is(Blocks.OBSIDIAN) && !iblockdata.is(Blocks.BEDROCK)) { - return InteractionResult.FAIL; - } else { -- BlockPos blockposition1 = blockposition.above(); -+ BlockPos blockposition1 = blockposition.above(); final BlockPos aboveBlockPosition = blockposition1; // Paper - OBFHELPER - - if (!world.isEmptyBlock(blockposition1)) { - return InteractionResult.FAIL; -@@ -47,12 +47,18 @@ - EndCrystal entityendercrystal = new EndCrystal(world, d0 + 0.5D, d1, d2 + 0.5D); - - entityendercrystal.setShowBottom(false); -+ // CraftBukkit start -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPlaceEvent(context, entityendercrystal).isCancelled()) { -+ if (context.getPlayer() != null) context.getPlayer().containerMenu.sendAllDataToRemote(); // Paper - Fix inventory desync -+ return InteractionResult.FAIL; -+ } -+ // CraftBukkit end - world.addFreshEntity(entityendercrystal); - world.gameEvent((Entity) context.getPlayer(), (Holder) GameEvent.ENTITY_PLACE, blockposition1); - EndDragonFight enderdragonbattle = ((ServerLevel) world).getDragonFight(); - - if (enderdragonbattle != null) { -- enderdragonbattle.tryRespawn(); -+ enderdragonbattle.tryRespawn(aboveBlockPosition); // Paper - Perf: Do crystal-portal proximity check before entity lookup - } - } - diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/EnderEyeItem.java.patch b/paper-server/patches/unapplied/net/minecraft/world/item/EnderEyeItem.java.patch deleted file mode 100644 index c343069562..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/item/EnderEyeItem.java.patch +++ /dev/null @@ -1,56 +0,0 @@ ---- a/net/minecraft/world/item/EnderEyeItem.java -+++ b/net/minecraft/world/item/EnderEyeItem.java -@@ -45,6 +45,11 @@ - return InteractionResult.SUCCESS; - } else { - BlockState iblockdata1 = (BlockState) iblockdata.setValue(EndPortalFrameBlock.HAS_EYE, true); -+ // Paper start -+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(context.getPlayer(), blockposition, iblockdata1)) { -+ return InteractionResult.PASS; -+ } -+ // Paper end - - Block.pushEntitiesUp(iblockdata, iblockdata1, world, blockposition); - world.setBlock(blockposition, iblockdata1, 2); -@@ -62,7 +67,27 @@ - } - } - -- world.globalLevelEvent(1038, blockposition1.offset(1, 0, 1), 0); -+ // CraftBukkit start - Use relative location for far away sounds -+ // world.globalLevelEvent(1038, blockposition1.offset(1, 0, 1), 0); -+ int viewDistance = world.getCraftServer().getViewDistance() * 16; -+ BlockPos soundPos = blockposition1.offset(1, 0, 1); -+ final net.minecraft.server.level.ServerLevel serverLevel = (net.minecraft.server.level.ServerLevel) world; // Paper - respect global sound events gamerule - ensured by isClientSide check above -+ for (ServerPlayer player : serverLevel.getPlayersForGlobalSoundGamerule()) { // Paper - respect global sound events gamerule -+ double deltaX = soundPos.getX() - player.getX(); -+ double deltaZ = soundPos.getZ() - player.getZ(); -+ double distanceSquared = deltaX * deltaX + deltaZ * deltaZ; -+ final double soundRadiusSquared = serverLevel.getGlobalSoundRangeSquared(config -> config.endPortalSoundRadius); // Paper - respect global sound events gamerule -+ if (!serverLevel.getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_GLOBAL_SOUND_EVENTS) && distanceSquared > soundRadiusSquared) continue; // Spigot // Paper - respect global sound events gamerule -+ if (distanceSquared > viewDistance * viewDistance) { -+ double deltaLength = Math.sqrt(distanceSquared); -+ double relativeX = player.getX() + (deltaX / deltaLength) * viewDistance; -+ double relativeZ = player.getZ() + (deltaZ / deltaLength) * viewDistance; -+ player.connection.send(new net.minecraft.network.protocol.game.ClientboundLevelEventPacket(1038, new BlockPos((int) relativeX, (int) soundPos.getY(), (int) relativeZ), 0, true)); -+ } else { -+ player.connection.send(new net.minecraft.network.protocol.game.ClientboundLevelEventPacket(1038, soundPos, 0, true)); -+ } -+ } -+ // CraftBukkit end - } - - return InteractionResult.SUCCESS; -@@ -99,7 +124,11 @@ - entityendersignal.setItem(itemstack); - entityendersignal.signalTo(blockposition); - world.gameEvent((Holder) GameEvent.PROJECTILE_SHOOT, entityendersignal.position(), GameEvent.Context.of((Entity) user)); -- world.addFreshEntity(entityendersignal); -+ // CraftBukkit start -+ if (!world.addFreshEntity(entityendersignal)) { -+ return InteractionResult.FAIL; -+ } -+ // CraftBukkit end - if (user instanceof ServerPlayer) { - ServerPlayer entityplayer = (ServerPlayer) user; - diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/EnderpearlItem.java.patch b/paper-server/patches/unapplied/net/minecraft/world/item/EnderpearlItem.java.patch deleted file mode 100644 index e025880d4f..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/item/EnderpearlItem.java.patch +++ /dev/null @@ -1,39 +0,0 @@ ---- a/net/minecraft/world/item/EnderpearlItem.java -+++ b/net/minecraft/world/item/EnderpearlItem.java -@@ -23,13 +23,32 @@ - public InteractionResult use(Level world, Player user, InteractionHand hand) { - ItemStack itemstack = user.getItemInHand(hand); - -- world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.ENDER_PEARL_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); - if (world instanceof ServerLevel worldserver) { -- Projectile.spawnProjectileFromRotation(ThrownEnderpearl::new, worldserver, itemstack, user, 0.0F, EnderpearlItem.PROJECTILE_SHOOT_POWER, 1.0F); -+ // CraftBukkit start -+ // Paper start - PlayerLaunchProjectileEvent -+ final Projectile.Delayed thrownEnderpearl = Projectile.spawnProjectileFromRotationDelayed(ThrownEnderpearl::new, worldserver, itemstack, user, 0.0F, EnderpearlItem.PROJECTILE_SHOOT_POWER, 1.0F); -+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) thrownEnderpearl.projectile().getBukkitEntity()); -+ if (event.callEvent() && thrownEnderpearl.attemptSpawn()) { -+ if (event.shouldConsume()) { -+ itemstack.consume(1, user); -+ } else if (user instanceof net.minecraft.server.level.ServerPlayer) { -+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); -+ } -+ -+ world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.ENDER_PEARL_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); -+ user.awardStat(Stats.ITEM_USED.get(this)); -+ } else { -+ // Paper end - PlayerLaunchProjectileEvent -+ if (user instanceof net.minecraft.server.level.ServerPlayer) { -+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); -+ } -+ return InteractionResult.FAIL; -+ } - } -+ world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.ENDER_PEARL_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); -+ // CraftBukkit end - -- user.awardStat(Stats.ITEM_USED.get(this)); -- itemstack.consume(1, user); -+ // Paper - PlayerLaunchProjectileEvent - moved up - return InteractionResult.SUCCESS; - } - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/FireChargeItem.java.patch b/paper-server/patches/unapplied/net/minecraft/world/item/FireChargeItem.java.patch deleted file mode 100644 index ee72808622..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/item/FireChargeItem.java.patch +++ /dev/null @@ -1,31 +0,0 @@ ---- a/net/minecraft/world/item/FireChargeItem.java -+++ b/net/minecraft/world/item/FireChargeItem.java -@@ -40,12 +40,28 @@ - if (!CampfireBlock.canLight(iblockdata) && !CandleBlock.canLight(iblockdata) && !CandleCakeBlock.canLight(iblockdata)) { - blockposition = blockposition.relative(context.getClickedFace()); - if (BaseFireBlock.canBePlacedAt(world, blockposition, context.getHorizontalDirection())) { -+ // CraftBukkit start - fire BlockIgniteEvent -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(world, blockposition, org.bukkit.event.block.BlockIgniteEvent.IgniteCause.FIREBALL, context.getPlayer()).isCancelled()) { -+ if (!context.getPlayer().getAbilities().instabuild) { -+ context.getItemInHand().shrink(1); -+ } -+ return InteractionResult.PASS; -+ } -+ // CraftBukkit end - this.playSound(world, blockposition); - world.setBlockAndUpdate(blockposition, BaseFireBlock.getState(world, blockposition)); - world.gameEvent((Entity) context.getPlayer(), (Holder) GameEvent.BLOCK_PLACE, blockposition); - flag = true; - } - } else { -+ // CraftBukkit start - fire BlockIgniteEvent -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(world, blockposition, org.bukkit.event.block.BlockIgniteEvent.IgniteCause.FIREBALL, context.getPlayer()).isCancelled()) { -+ if (!context.getPlayer().getAbilities().instabuild) { -+ context.getItemInHand().shrink(1); -+ } -+ return InteractionResult.PASS; -+ } -+ // CraftBukkit end - this.playSound(world, blockposition); - world.setBlockAndUpdate(blockposition, (BlockState) iblockdata.setValue(BlockStateProperties.LIT, true)); - world.gameEvent((Entity) context.getPlayer(), (Holder) GameEvent.BLOCK_CHANGE, blockposition); diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/FishingRodItem.java.patch b/paper-server/patches/unapplied/net/minecraft/world/item/FishingRodItem.java.patch deleted file mode 100644 index 6c64321f95..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/item/FishingRodItem.java.patch +++ /dev/null @@ -1,50 +0,0 @@ ---- a/net/minecraft/world/item/FishingRodItem.java -+++ b/net/minecraft/world/item/FishingRodItem.java -@@ -14,6 +14,11 @@ - import net.minecraft.world.level.Level; - import net.minecraft.world.level.gameevent.GameEvent; - -+// CraftBukkit start -+import org.bukkit.event.player.PlayerFishEvent; -+import org.bukkit.craftbukkit.CraftEquipmentSlot; -+// CraftBukkit end -+ - public class FishingRodItem extends Item { - - public FishingRodItem(Item.Properties settings) { -@@ -26,7 +31,7 @@ - - if (user.fishing != null) { - if (!world.isClientSide) { -- int i = user.fishing.retrieve(itemstack); -+ int i = user.fishing.retrieve(hand, itemstack); // Paper - Add hand parameter to PlayerFishEvent - - itemstack.hurtAndBreak(i, user, LivingEntity.getSlotForHand(hand)); - } -@@ -34,13 +39,24 @@ - world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.FISHING_BOBBER_RETRIEVE, SoundSource.NEUTRAL, 1.0F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); - user.gameEvent(GameEvent.ITEM_INTERACT_FINISH); - } else { -- world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.FISHING_BOBBER_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); -+ // world.playSound((EntityHuman) null, entityhuman.getX(), entityhuman.getY(), entityhuman.getZ(), SoundEffects.FISHING_BOBBER_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); - if (world instanceof ServerLevel) { - ServerLevel worldserver = (ServerLevel) world; - int j = (int) (EnchantmentHelper.getFishingTimeReduction(worldserver, itemstack, user) * 20.0F); - int k = EnchantmentHelper.getFishingLuckBonus(worldserver, itemstack, user); - -- Projectile.spawnProjectile(new FishingHook(user, world, k, j), worldserver, itemstack); -+ // CraftBukkit start -+ FishingHook entityfishinghook = new FishingHook(user, world, k, j); -+ PlayerFishEvent playerFishEvent = new PlayerFishEvent((org.bukkit.entity.Player) user.getBukkitEntity(), null, (org.bukkit.entity.FishHook) entityfishinghook.getBukkitEntity(), CraftEquipmentSlot.getHand(hand), PlayerFishEvent.State.FISHING); -+ world.getCraftServer().getPluginManager().callEvent(playerFishEvent); -+ -+ if (playerFishEvent.isCancelled()) { -+ user.fishing = null; -+ return InteractionResult.PASS; -+ } -+ world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.FISHING_BOBBER_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); -+ Projectile.spawnProjectile(entityfishinghook, worldserver, itemstack); -+ // CraftBukkit end - } - - user.awardStat(Stats.ITEM_USED.get(this)); diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/FlintAndSteelItem.java.patch b/paper-server/patches/unapplied/net/minecraft/world/item/FlintAndSteelItem.java.patch deleted file mode 100644 index 0d633ff507..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/item/FlintAndSteelItem.java.patch +++ /dev/null @@ -1,28 +0,0 @@ ---- a/net/minecraft/world/item/FlintAndSteelItem.java -+++ b/net/minecraft/world/item/FlintAndSteelItem.java -@@ -37,6 +37,12 @@ - BlockPos blockposition1 = blockposition.relative(context.getClickedFace()); - - if (BaseFireBlock.canBePlacedAt(world, blockposition1, context.getHorizontalDirection())) { -+ // CraftBukkit start - Store the clicked block -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(world, blockposition1, org.bukkit.event.block.BlockIgniteEvent.IgniteCause.FLINT_AND_STEEL, entityhuman).isCancelled()) { -+ context.getItemInHand().hurtAndBreak(1, entityhuman, LivingEntity.getSlotForHand(context.getHand())); -+ return InteractionResult.PASS; -+ } -+ // CraftBukkit end - world.playSound(entityhuman, blockposition1, SoundEvents.FLINTANDSTEEL_USE, SoundSource.BLOCKS, 1.0F, world.getRandom().nextFloat() * 0.4F + 0.8F); - BlockState iblockdata1 = BaseFireBlock.getState(world, blockposition1); - -@@ -54,6 +60,12 @@ - return InteractionResult.FAIL; - } - } else { -+ // CraftBukkit start - Store the clicked block -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(world, blockposition, org.bukkit.event.block.BlockIgniteEvent.IgniteCause.FLINT_AND_STEEL, entityhuman).isCancelled()) { -+ context.getItemInHand().hurtAndBreak(1, entityhuman, LivingEntity.getSlotForHand(context.getHand())); -+ return InteractionResult.PASS; -+ } -+ // CraftBukkit end - world.playSound(entityhuman, blockposition, SoundEvents.FLINTANDSTEEL_USE, SoundSource.BLOCKS, 1.0F, world.getRandom().nextFloat() * 0.4F + 0.8F); - world.setBlock(blockposition, (BlockState) iblockdata.setValue(BlockStateProperties.LIT, true), 11); - world.gameEvent((Entity) entityhuman, (Holder) GameEvent.BLOCK_CHANGE, blockposition); diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/HangingEntityItem.java.patch b/paper-server/patches/unapplied/net/minecraft/world/item/HangingEntityItem.java.patch deleted file mode 100644 index 79e498f9a5..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/item/HangingEntityItem.java.patch +++ /dev/null @@ -1,67 +0,0 @@ ---- a/net/minecraft/world/item/HangingEntityItem.java -+++ b/net/minecraft/world/item/HangingEntityItem.java -@@ -19,12 +19,16 @@ - import net.minecraft.world.entity.decoration.ItemFrame; - import net.minecraft.world.entity.decoration.Painting; - import net.minecraft.world.entity.decoration.PaintingVariant; --import net.minecraft.world.entity.player.Player; - import net.minecraft.world.item.component.CustomData; - import net.minecraft.world.item.context.UseOnContext; - import net.minecraft.world.level.Level; - import net.minecraft.world.level.gameevent.GameEvent; - -+// CraftBukkit start -+import org.bukkit.entity.Player; -+import org.bukkit.event.hanging.HangingPlaceEvent; -+// CraftBukkit end -+ - public class HangingEntityItem extends Item { - - private static final Component TOOLTIP_RANDOM_VARIANT = Component.translatable("painting.random").withStyle(ChatFormatting.GRAY); -@@ -40,7 +44,7 @@ - BlockPos blockposition = context.getClickedPos(); - Direction enumdirection = context.getClickedFace(); - BlockPos blockposition1 = blockposition.relative(enumdirection); -- Player entityhuman = context.getPlayer(); -+ net.minecraft.world.entity.player.Player entityhuman = context.getPlayer(); - ItemStack itemstack = context.getItemInHand(); - - if (entityhuman != null && !this.mayPlace(entityhuman, enumdirection, itemstack, blockposition1)) { -@@ -75,6 +79,19 @@ - - if (((HangingEntity) object).survives()) { - if (!world.isClientSide) { -+ // CraftBukkit start - fire HangingPlaceEvent -+ Player who = (context.getPlayer() == null) ? null : (Player) context.getPlayer().getBukkitEntity(); -+ org.bukkit.block.Block blockClicked = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); -+ org.bukkit.block.BlockFace blockFace = org.bukkit.craftbukkit.block.CraftBlock.notchToBlockFace(enumdirection); -+ org.bukkit.inventory.EquipmentSlot hand = org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(context.getHand()); -+ -+ HangingPlaceEvent event = new HangingPlaceEvent((org.bukkit.entity.Hanging) ((HangingEntity) object).getBukkitEntity(), who, blockClicked, blockFace, hand, org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(itemstack)); -+ world.getCraftServer().getPluginManager().callEvent(event); -+ -+ if (event.isCancelled()) { -+ return InteractionResult.FAIL; -+ } -+ // CraftBukkit end - ((HangingEntity) object).playPlacementSound(); - world.gameEvent((Entity) entityhuman, (Holder) GameEvent.ENTITY_PLACE, ((HangingEntity) object).position()); - world.addFreshEntity((Entity) object); -@@ -88,7 +105,7 @@ - } - } - -- protected boolean mayPlace(Player player, Direction side, ItemStack stack, BlockPos pos) { -+ protected boolean mayPlace(net.minecraft.world.entity.player.Player player, Direction side, ItemStack stack, BlockPos pos) { - return !side.getAxis().isVertical() && player.mayUseItemAt(pos, side, stack); - } - -@@ -102,7 +119,7 @@ - - if (!customdata.isEmpty()) { - customdata.read(holderlookup_a.createSerializationContext(NbtOps.INSTANCE), Painting.VARIANT_MAP_CODEC).result().ifPresentOrElse((holder) -> { -- Optional optional = ((PaintingVariant) holder.value()).title(); -+ Optional optional = ((PaintingVariant) holder.value()).title(); // CraftBukkit - decompile error - - Objects.requireNonNull(tooltip); - optional.ifPresent(tooltip::add); diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/ItemCooldowns.java.patch b/paper-server/patches/unapplied/net/minecraft/world/item/ItemCooldowns.java.patch deleted file mode 100644 index f8d61e11c7..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/item/ItemCooldowns.java.patch +++ /dev/null @@ -1,16 +0,0 @@ ---- a/net/minecraft/world/item/ItemCooldowns.java -+++ b/net/minecraft/world/item/ItemCooldowns.java -@@ -56,6 +56,13 @@ - } - - public void addCooldown(ResourceLocation groupId, int duration) { -+ // Paper start - Item cooldown events -+ this.addCooldown(groupId, duration, true); -+ } -+ -+ public void addCooldown(ResourceLocation groupId, int duration, boolean callEvent) { -+ // Event called in server override -+ // Paper end - Item cooldown events - this.cooldowns.put(groupId, new ItemCooldowns.CooldownInstance(this.tickCount, this.tickCount + duration)); - this.onCooldownStarted(groupId, duration); - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/ItemStack.java.patch b/paper-server/patches/unapplied/net/minecraft/world/item/ItemStack.java.patch deleted file mode 100644 index 4409d94819..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/item/ItemStack.java.patch +++ /dev/null @@ -1,630 +0,0 @@ ---- a/net/minecraft/world/item/ItemStack.java -+++ b/net/minecraft/world/item/ItemStack.java -@@ -23,6 +23,7 @@ - import net.minecraft.ChatFormatting; - import net.minecraft.advancements.CriteriaTriggers; - import net.minecraft.core.BlockPos; -+import net.minecraft.core.Direction; - import net.minecraft.core.Holder; - import net.minecraft.core.HolderLookup; - import net.minecraft.core.HolderSet; -@@ -46,10 +47,12 @@ - import net.minecraft.network.chat.MutableComponent; - import net.minecraft.network.codec.ByteBufCodecs; - import net.minecraft.network.codec.StreamCodec; -+import net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket; - import net.minecraft.resources.RegistryOps; - import net.minecraft.server.level.ServerLevel; - import net.minecraft.server.level.ServerPlayer; - import net.minecraft.sounds.SoundEvent; -+import net.minecraft.sounds.SoundSource; - import net.minecraft.stats.Stats; - import net.minecraft.tags.TagKey; - import net.minecraft.util.ExtraCodecs; -@@ -70,7 +73,6 @@ - import net.minecraft.world.entity.ai.attributes.Attributes; - import net.minecraft.world.entity.decoration.ItemFrame; - import net.minecraft.world.entity.item.ItemEntity; --import net.minecraft.world.entity.player.Player; - import net.minecraft.world.flag.FeatureFlagSet; - import net.minecraft.world.inventory.ClickAction; - import net.minecraft.world.inventory.Slot; -@@ -88,26 +90,53 @@ - import net.minecraft.world.item.enchantment.EnchantmentHelper; - import net.minecraft.world.item.enchantment.ItemEnchantments; - import net.minecraft.world.item.enchantment.Repairable; --import net.minecraft.world.level.ItemLike; --import net.minecraft.world.level.Level; --import net.minecraft.world.level.block.state.BlockState; --import net.minecraft.world.level.block.state.pattern.BlockInWorld; - import net.minecraft.world.level.saveddata.maps.MapId; - import org.apache.commons.lang3.mutable.MutableBoolean; - import org.slf4j.Logger; - -+// CraftBukkit start -+import java.util.Map; -+import java.util.Objects; -+import net.minecraft.world.level.ItemLike; -+import net.minecraft.world.level.Level; -+import net.minecraft.world.level.block.BaseEntityBlock; -+import net.minecraft.world.level.block.BedBlock; -+import net.minecraft.world.level.block.Blocks; -+import net.minecraft.world.level.block.SaplingBlock; -+import net.minecraft.world.level.block.SignBlock; -+import net.minecraft.world.level.block.SoundType; -+import net.minecraft.world.level.block.WitherSkullBlock; -+import net.minecraft.world.level.block.entity.BlockEntity; -+import net.minecraft.world.level.block.entity.SignBlockEntity; -+import net.minecraft.world.level.block.entity.SkullBlockEntity; -+import net.minecraft.world.level.block.state.pattern.BlockInWorld; -+import net.minecraft.world.level.gameevent.GameEvent; -+import org.bukkit.Location; -+import org.bukkit.TreeType; -+import org.bukkit.block.BlockState; -+import org.bukkit.craftbukkit.block.CapturedBlockState; -+import org.bukkit.craftbukkit.block.CraftBlock; -+import org.bukkit.craftbukkit.block.CraftBlockState; -+import org.bukkit.craftbukkit.inventory.CraftItemStack; -+import org.bukkit.craftbukkit.util.CraftLocation; -+import org.bukkit.entity.Player; -+import org.bukkit.event.block.BlockFertilizeEvent; -+import org.bukkit.event.player.PlayerItemDamageEvent; -+import org.bukkit.event.world.StructureGrowEvent; -+// CraftBukkit end -+ - public final class ItemStack implements DataComponentHolder { - - private static final List OP_NBT_WARNING = List.of(Component.translatable("item.op_warning.line1").withStyle(ChatFormatting.RED, ChatFormatting.BOLD), Component.translatable("item.op_warning.line2").withStyle(ChatFormatting.RED), Component.translatable("item.op_warning.line3").withStyle(ChatFormatting.RED)); - public static final Codec CODEC = Codec.lazyInitialized(() -> { -- return RecordCodecBuilder.create((instance) -> { -+ return RecordCodecBuilder.create((instance) -> { // CraftBukkit - decompile error - return instance.group(Item.CODEC.fieldOf("id").forGetter(ItemStack::getItemHolder), ExtraCodecs.intRange(1, 99).fieldOf("count").orElse(1).forGetter(ItemStack::getCount), DataComponentPatch.CODEC.optionalFieldOf("components", DataComponentPatch.EMPTY).forGetter((itemstack) -> { - return itemstack.components.asPatch(); - })).apply(instance, ItemStack::new); - }); - }); - public static final Codec SINGLE_ITEM_CODEC = Codec.lazyInitialized(() -> { -- return RecordCodecBuilder.create((instance) -> { -+ return RecordCodecBuilder.create((instance) -> { // CraftBukkit - decompile error - return instance.group(Item.CODEC.fieldOf("id").forGetter(ItemStack::getItemHolder), DataComponentPatch.CODEC.optionalFieldOf("components", DataComponentPatch.EMPTY).forGetter((itemstack) -> { - return itemstack.components.asPatch(); - })).apply(instance, (holder, datacomponentpatch) -> { -@@ -132,20 +161,38 @@ - if (i <= 0) { - return ItemStack.EMPTY; - } else { -- Holder holder = (Holder) null.ITEM_STREAM_CODEC.decode(registryfriendlybytebuf); -+ Holder holder = (Holder) ITEM_STREAM_CODEC.decode(registryfriendlybytebuf); // CraftBukkit - decompile error - DataComponentPatch datacomponentpatch = (DataComponentPatch) DataComponentPatch.STREAM_CODEC.decode(registryfriendlybytebuf); - -- return new ItemStack(holder, i, datacomponentpatch); -+ // CraftBukkit start -+ ItemStack itemstack = new ItemStack(holder, i, datacomponentpatch); -+ if (false && !datacomponentpatch.isEmpty()) { // Paper - This is no longer needed with raw NBT being handled in metadata -+ CraftItemStack.setItemMeta(itemstack, CraftItemStack.getItemMeta(itemstack)); -+ } -+ return itemstack; -+ // CraftBukkit end - } - } - - public void encode(RegistryFriendlyByteBuf registryfriendlybytebuf, ItemStack itemstack) { -- if (itemstack.isEmpty()) { -+ if (itemstack.isEmpty() || itemstack.getItem() == null) { // CraftBukkit - NPE fix itemstack.getItem() - registryfriendlybytebuf.writeVarInt(0); - } else { - registryfriendlybytebuf.writeVarInt(itemstack.getCount()); -- null.ITEM_STREAM_CODEC.encode(registryfriendlybytebuf, itemstack.getItemHolder()); -+ // Spigot start - filter -+ // itemstack = itemstack.copy(); -+ // CraftItemStack.setItemMeta(itemstack, CraftItemStack.getItemMeta(itemstack)); // Paper - This is no longer with raw NBT being handled in metadata -+ // Spigot end -+ ITEM_STREAM_CODEC.encode(registryfriendlybytebuf, itemstack.getItemHolder()); // CraftBukkit - decompile error -+ // Paper start - adventure; conditionally render translatable components -+ boolean prev = net.minecraft.network.chat.ComponentSerialization.DONT_RENDER_TRANSLATABLES.get(); -+ try { -+ net.minecraft.network.chat.ComponentSerialization.DONT_RENDER_TRANSLATABLES.set(true); - DataComponentPatch.STREAM_CODEC.encode(registryfriendlybytebuf, itemstack.components.asPatch()); -+ } finally { -+ net.minecraft.network.chat.ComponentSerialization.DONT_RENDER_TRANSLATABLES.set(prev); -+ } -+ // Paper end - adventure; conditionally render translatable components - } - } - }; -@@ -187,7 +234,7 @@ - - return dataresult.isError() ? dataresult.map((unit) -> { - return stack; -- }) : (stack.getCount() > stack.getMaxStackSize() ? DataResult.error(() -> { -+ }) : (stack.getCount() > stack.getMaxStackSize() ? DataResult.error(() -> { // CraftBukkit - decompile error - int i = stack.getCount(); - - return "Item stack with stack size of " + i + " was larger than maximum: " + stack.getMaxStackSize(); -@@ -294,8 +341,9 @@ - j = itemstack.getMaxStackSize(); - } while (i <= j); - -+ int finalI = i, finalJ = j; // CraftBukkit - decompile error - return DataResult.error(() -> { -- return "Item stack with count of " + i + " was larger than maximum: " + j; -+ return "Item stack with count of " + finalI + " was larger than maximum: " + finalJ; // CraftBukkit - decompile error - }); - } - } -@@ -370,32 +418,200 @@ - } - - public InteractionResult useOn(UseOnContext context) { -- Player entityhuman = context.getPlayer(); -+ net.minecraft.world.entity.player.Player entityhuman = context.getPlayer(); - BlockPos blockposition = context.getClickedPos(); - - if (entityhuman != null && !entityhuman.getAbilities().mayBuild && !this.canPlaceOnBlockInAdventureMode(new BlockInWorld(context.getLevel(), blockposition, false))) { - return InteractionResult.PASS; - } else { - Item item = this.getItem(); -- InteractionResult enuminteractionresult = item.useOn(context); -+ // CraftBukkit start - handle all block place event logic here -+ DataComponentPatch oldData = this.components.asPatch(); -+ int oldCount = this.getCount(); -+ ServerLevel world = (ServerLevel) context.getLevel(); - -+ if (!(item instanceof BucketItem/* || item instanceof SolidBucketItem*/)) { // if not bucket // Paper - Fix cancelled powdered snow bucket placement -+ world.captureBlockStates = true; -+ // special case bonemeal -+ if (item == Items.BONE_MEAL) { -+ world.captureTreeGeneration = true; -+ } -+ } -+ InteractionResult enuminteractionresult; -+ try { -+ enuminteractionresult = item.useOn(context); -+ } finally { -+ world.captureBlockStates = false; -+ } -+ DataComponentPatch newData = this.components.asPatch(); -+ int newCount = this.getCount(); -+ this.setCount(oldCount); -+ this.restorePatch(oldData); -+ if (enuminteractionresult.consumesAction() && world.captureTreeGeneration && world.capturedBlockStates.size() > 0) { -+ world.captureTreeGeneration = false; -+ Location location = CraftLocation.toBukkit(blockposition, world.getWorld()); -+ TreeType treeType = SaplingBlock.treeType; -+ SaplingBlock.treeType = null; -+ List blocks = new java.util.ArrayList<>(world.capturedBlockStates.values()); -+ world.capturedBlockStates.clear(); -+ StructureGrowEvent structureEvent = null; -+ if (treeType != null) { -+ boolean isBonemeal = this.getItem() == Items.BONE_MEAL; -+ structureEvent = new StructureGrowEvent(location, treeType, isBonemeal, (Player) entityhuman.getBukkitEntity(), (List< BlockState>) (List) blocks); -+ org.bukkit.Bukkit.getPluginManager().callEvent(structureEvent); -+ } -+ -+ BlockFertilizeEvent fertilizeEvent = new BlockFertilizeEvent(CraftBlock.at(world, blockposition), (Player) entityhuman.getBukkitEntity(), (List< BlockState>) (List) blocks); -+ fertilizeEvent.setCancelled(structureEvent != null && structureEvent.isCancelled()); -+ org.bukkit.Bukkit.getPluginManager().callEvent(fertilizeEvent); -+ -+ if (!fertilizeEvent.isCancelled()) { -+ // Change the stack to its new contents if it hasn't been tampered with. -+ if (this.getCount() == oldCount && Objects.equals(this.components.asPatch(), oldData)) { -+ this.restorePatch(newData); -+ this.setCount(newCount); -+ } -+ for (CraftBlockState blockstate : blocks) { -+ // SPIGOT-7572 - Move fix for SPIGOT-7248 to CapturedBlockState, to allow bees in bee nest -+ CapturedBlockState.setBlockState(blockstate); -+ world.checkCapturedTreeStateForObserverNotify(blockposition, blockstate); // Paper - notify observers even if grow failed -+ } -+ entityhuman.awardStat(Stats.ITEM_USED.get(item)); // SPIGOT-7236 - award stat -+ } -+ -+ SignItem.openSign = null; // SPIGOT-6758 - Reset on early return -+ return enuminteractionresult; -+ } -+ world.captureTreeGeneration = false; -+ - if (entityhuman != null && enuminteractionresult instanceof InteractionResult.Success) { - InteractionResult.Success enuminteractionresult_d = (InteractionResult.Success) enuminteractionresult; - - if (enuminteractionresult_d.wasItemInteraction()) { -- entityhuman.awardStat(Stats.ITEM_USED.get(item)); -+ InteractionHand enumhand = context.getHand(); -+ org.bukkit.event.block.BlockPlaceEvent placeEvent = null; -+ List blocks = new java.util.ArrayList<>(world.capturedBlockStates.values()); -+ world.capturedBlockStates.clear(); -+ if (blocks.size() > 1) { -+ placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockMultiPlaceEvent(world, entityhuman, enumhand, blocks, blockposition.getX(), blockposition.getY(), blockposition.getZ()); -+ } else if (blocks.size() == 1 && item != Items.POWDER_SNOW_BUCKET) { // Paper - Fix cancelled powdered snow bucket placement -+ placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPlaceEvent(world, entityhuman, enumhand, blocks.get(0), blockposition.getX(), blockposition.getY(), blockposition.getZ()); -+ } -+ -+ if (placeEvent != null && (placeEvent.isCancelled() || !placeEvent.canBuild())) { -+ enuminteractionresult = InteractionResult.FAIL; // cancel placement -+ // PAIL: Remove this when MC-99075 fixed -+ placeEvent.getPlayer().updateInventory(); -+ world.capturedTileEntities.clear(); // Paper - Allow chests to be placed with NBT data; clear out block entities as chests and such will pop loot -+ // revert back all captured blocks -+ world.preventPoiUpdated = true; // CraftBukkit - SPIGOT-5710 -+ world.isBlockPlaceCancelled = true; // Paper - prevent calling cleanup logic when undoing a block place upon a cancelled BlockPlaceEvent -+ for (BlockState blockstate : blocks) { -+ blockstate.update(true, false); -+ } -+ world.isBlockPlaceCancelled = false; // Paper - prevent calling cleanup logic when undoing a block place upon a cancelled BlockPlaceEvent -+ world.preventPoiUpdated = false; -+ -+ // Brute force all possible updates -+ // Paper start - Don't resync blocks -+ // BlockPos placedPos = ((CraftBlock) placeEvent.getBlock()).getPosition(); -+ // for (Direction dir : Direction.values()) { -+ // ((ServerPlayer) entityhuman).connection.send(new ClientboundBlockUpdatePacket(world, placedPos.relative(dir))); -+ // } -+ // Paper end - Don't resync blocks -+ SignItem.openSign = null; // SPIGOT-6758 - Reset on early return -+ } else { -+ // Change the stack to its new contents if it hasn't been tampered with. -+ if (this.getCount() == oldCount && Objects.equals(this.components.asPatch(), oldData)) { -+ this.restorePatch(newData); -+ this.setCount(newCount); -+ } -+ -+ for (Map.Entry e : world.capturedTileEntities.entrySet()) { -+ world.setBlockEntity(e.getValue()); -+ } -+ -+ for (BlockState blockstate : blocks) { -+ int updateFlag = ((CraftBlockState) blockstate).getFlag(); -+ net.minecraft.world.level.block.state.BlockState oldBlock = ((CraftBlockState) blockstate).getHandle(); -+ BlockPos newblockposition = ((CraftBlockState) blockstate).getPosition(); -+ net.minecraft.world.level.block.state.BlockState block = world.getBlockState(newblockposition); -+ -+ if (!(block.getBlock() instanceof BaseEntityBlock)) { // Containers get placed automatically -+ block.onPlace(world, newblockposition, oldBlock, true, context); -+ } -+ -+ world.notifyAndUpdatePhysics(newblockposition, null, oldBlock, block, world.getBlockState(newblockposition), updateFlag, 512); // send null chunk as chunk.k() returns false by this point -+ } -+ -+ if (this.item == Items.WITHER_SKELETON_SKULL) { // Special case skulls to allow wither spawns to be cancelled -+ BlockPos bp = blockposition; -+ if (!world.getBlockState(blockposition).canBeReplaced()) { -+ if (!world.getBlockState(blockposition).isSolid()) { -+ bp = null; -+ } else { -+ bp = bp.relative(context.getClickedFace()); -+ } -+ } -+ if (bp != null) { -+ BlockEntity te = world.getBlockEntity(bp); -+ if (te instanceof SkullBlockEntity) { -+ WitherSkullBlock.checkSpawn(world, bp, (SkullBlockEntity) te); -+ } -+ } -+ } -+ -+ // SPIGOT-4678 -+ if (this.item instanceof SignItem && SignItem.openSign != null) { -+ try { -+ if (world.getBlockEntity(SignItem.openSign) instanceof SignBlockEntity tileentitysign) { -+ if (world.getBlockState(SignItem.openSign).getBlock() instanceof SignBlock blocksign) { -+ blocksign.openTextEdit(entityhuman, tileentitysign, true, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause.PLACE); // Craftbukkit // Paper - Add PlayerOpenSignEvent -+ } -+ } -+ } finally { -+ SignItem.openSign = null; -+ } -+ } -+ -+ // SPIGOT-7315: Moved from BlockBed#setPlacedBy -+ if (placeEvent != null && this.item instanceof BedItem) { -+ BlockPos position = ((CraftBlock) placeEvent.getBlock()).getPosition(); -+ net.minecraft.world.level.block.state.BlockState blockData = world.getBlockState(position); -+ -+ if (blockData.getBlock() instanceof BedBlock) { -+ world.blockUpdated(position, Blocks.AIR); -+ blockData.updateNeighbourShapes(world, position, 3); -+ } -+ } -+ -+ // SPIGOT-1288 - play sound stripped from ItemBlock -+ if (this.item instanceof BlockItem) { -+ // Paper start - Fix spigot sound playing for BlockItem ItemStacks -+ BlockPos position = new net.minecraft.world.item.context.BlockPlaceContext(context).getClickedPos(); -+ net.minecraft.world.level.block.state.BlockState blockData = world.getBlockState(position); -+ SoundType soundeffecttype = blockData.getSoundType(); -+ // Paper end - Fix spigot sound playing for BlockItem ItemStacks -+ world.playSound(entityhuman, blockposition, soundeffecttype.getPlaceSound(), SoundSource.BLOCKS, (soundeffecttype.getVolume() + 1.0F) / 2.0F, soundeffecttype.getPitch() * 0.8F); -+ } -+ -+ entityhuman.awardStat(Stats.ITEM_USED.get(item)); -+ } - } - } -+ world.capturedTileEntities.clear(); -+ world.capturedBlockStates.clear(); -+ // CraftBukkit end - - return enuminteractionresult; - } - } - -- public float getDestroySpeed(BlockState state) { -+ public float getDestroySpeed(net.minecraft.world.level.block.state.BlockState state) { - return this.getItem().getDestroySpeed(this, state); - } - -- public InteractionResult use(Level world, Player user, InteractionHand hand) { -+ public InteractionResult use(Level world, net.minecraft.world.entity.player.Player user, InteractionHand hand) { - ItemStack itemstack = this.copy(); - boolean flag = this.getUseDuration(user) <= 0; - InteractionResult enuminteractionresult = this.getItem().use(world, user, hand); -@@ -490,27 +706,66 @@ - return this.isDamageableItem() && this.getDamageValue() >= this.getMaxDamage() - 1; - } - -- public void hurtAndBreak(int amount, ServerLevel world, @Nullable ServerPlayer player, Consumer breakCallback) { -- int j = this.processDurabilityChange(amount, world, player); -+ public void hurtAndBreak(int amount, ServerLevel world, @Nullable LivingEntity player, Consumer breakCallback) { // Paper - Add EntityDamageItemEvent -+ // Paper start - add force boolean overload -+ this.hurtAndBreak(amount, world, player, breakCallback, false); -+ } -+ public void hurtAndBreak(int amount, ServerLevel world, @Nullable LivingEntity player, Consumer breakCallback, boolean force) { // Paper - Add EntityDamageItemEvent -+ // Paper end -+ int originalDamage = amount; // Paper - Expand PlayerItemDamageEvent -+ int j = this.processDurabilityChange(amount, world, player, force); // Paper -+ // CraftBukkit start -+ if (player instanceof final ServerPlayer serverPlayer) { // Paper - Add EntityDamageItemEvent -+ PlayerItemDamageEvent event = new PlayerItemDamageEvent(serverPlayer.getBukkitEntity(), CraftItemStack.asCraftMirror(this), j, originalDamage); // Paper - Add EntityDamageItemEvent -+ event.getPlayer().getServer().getPluginManager().callEvent(event); - -+ if (j != event.getDamage() || event.isCancelled()) { -+ event.getPlayer().updateInventory(); -+ } -+ if (event.isCancelled()) { -+ return; -+ } -+ -+ j = event.getDamage(); -+ // Paper start - Add EntityDamageItemEvent -+ } else if (player != null) { -+ io.papermc.paper.event.entity.EntityDamageItemEvent event = new io.papermc.paper.event.entity.EntityDamageItemEvent(player.getBukkitLivingEntity(), CraftItemStack.asCraftMirror(this), amount); -+ if (!event.callEvent()) { -+ return; -+ } -+ j = event.getDamage(); -+ // Paper end - Add EntityDamageItemEvent -+ } -+ // CraftBukkit end -+ - if (j != 0) { - this.applyDamage(this.getDamageValue() + j, player, breakCallback); - } - - } - -- private int processDurabilityChange(int baseDamage, ServerLevel world, @Nullable ServerPlayer player) { -- return !this.isDamageableItem() ? 0 : (player != null && player.hasInfiniteMaterials() ? 0 : (baseDamage > 0 ? EnchantmentHelper.processDurabilityChange(world, this, baseDamage) : baseDamage)); -+ private int processDurabilityChange(int baseDamage, ServerLevel world, @Nullable LivingEntity player) { // Paper - Add EntityDamageItemEvent -+ // Paper start - itemstack damage api -+ return processDurabilityChange(baseDamage, world, player, false); - } -+ private int processDurabilityChange(int baseDamage, ServerLevel world, @Nullable LivingEntity player, boolean force) { -+ return !this.isDamageableItem() ? 0 : (player instanceof ServerPlayer && player.hasInfiniteMaterials() && !force ? 0 : (baseDamage > 0 ? EnchantmentHelper.processDurabilityChange(world, this, baseDamage) : baseDamage)); // Paper - Add EntityDamageItemEvent -+ // Paper end - itemstack damage api -+ } - -- private void applyDamage(int damage, @Nullable ServerPlayer player, Consumer breakCallback) { -- if (player != null) { -- CriteriaTriggers.ITEM_DURABILITY_CHANGED.trigger(player, this, damage); -+ private void applyDamage(int damage, @Nullable LivingEntity player, Consumer breakCallback) { // Paper - Add EntityDamageItemEvent -+ if (player instanceof final ServerPlayer serverPlayer) { // Paper - Add EntityDamageItemEvent -+ CriteriaTriggers.ITEM_DURABILITY_CHANGED.trigger(serverPlayer, this, damage); // Paper - Add EntityDamageItemEvent - } - - this.setDamageValue(damage); - if (this.isBroken()) { - Item item = this.getItem(); -+ // CraftBukkit start - Check for item breaking -+ if (this.count == 1 && player instanceof final ServerPlayer serverPlayer) { // Paper - Add EntityDamageItemEvent -+ org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemBreakEvent(serverPlayer, this); // Paper - Add EntityDamageItemEvent -+ } -+ // CraftBukkit end - - this.shrink(1); - breakCallback.accept(item); -@@ -518,7 +773,7 @@ - - } - -- public void hurtWithoutBreaking(int amount, Player player) { -+ public void hurtWithoutBreaking(int amount, net.minecraft.world.entity.player.Player player) { - if (player instanceof ServerPlayer entityplayer) { - int j = this.processDurabilityChange(amount, entityplayer.serverLevel(), entityplayer); - -@@ -535,6 +790,11 @@ - } - - public void hurtAndBreak(int amount, LivingEntity entity, EquipmentSlot slot) { -+ // Paper start - add param to skip infinite mats check -+ this.hurtAndBreak(amount, entity, slot, false); -+ } -+ public void hurtAndBreak(int amount, LivingEntity entity, EquipmentSlot slot, boolean force) { -+ // Paper end - add param to skip infinite mats check - Level world = entity.level(); - - if (world instanceof ServerLevel worldserver) { -@@ -546,9 +806,9 @@ - entityplayer = null; - } - -- this.hurtAndBreak(amount, worldserver, entityplayer, (item) -> { -- entity.onEquippedItemBroken(item, slot); -- }); -+ this.hurtAndBreak(amount, worldserver, entity, (item) -> { // Paper - Add EntityDamageItemEvent -+ if (slot != null) entity.onEquippedItemBroken(item, slot); // Paper - itemstack damage API - do not process entity related callbacks when damaging from API -+ }, force); // Paper - itemstack damage API - } - - } -@@ -580,11 +840,11 @@ - return this.getItem().getBarColor(this); - } - -- public boolean overrideStackedOnOther(Slot slot, ClickAction clickType, Player player) { -+ public boolean overrideStackedOnOther(Slot slot, ClickAction clickType, net.minecraft.world.entity.player.Player player) { - return this.getItem().overrideStackedOnOther(this, slot, clickType, player); - } - -- public boolean overrideOtherStackedOnMe(ItemStack stack, Slot slot, ClickAction clickType, Player player, SlotAccess cursorStackReference) { -+ public boolean overrideOtherStackedOnMe(ItemStack stack, Slot slot, ClickAction clickType, net.minecraft.world.entity.player.Player player, SlotAccess cursorStackReference) { - return this.getItem().overrideOtherStackedOnMe(this, stack, slot, clickType, player, cursorStackReference); - } - -@@ -592,8 +852,8 @@ - Item item = this.getItem(); - - if (item.hurtEnemy(this, target, user)) { -- if (user instanceof Player) { -- Player entityhuman = (Player) user; -+ if (user instanceof net.minecraft.world.entity.player.Player) { -+ net.minecraft.world.entity.player.Player entityhuman = (net.minecraft.world.entity.player.Player) user; - - entityhuman.awardStat(Stats.ITEM_USED.get(item)); - } -@@ -608,7 +868,7 @@ - this.getItem().postHurtEnemy(this, target, user); - } - -- public void mineBlock(Level world, BlockState state, BlockPos pos, Player miner) { -+ public void mineBlock(Level world, net.minecraft.world.level.block.state.BlockState state, BlockPos pos, net.minecraft.world.entity.player.Player miner) { - Item item = this.getItem(); - - if (item.mineBlock(this, world, state, pos, miner)) { -@@ -617,11 +877,11 @@ - - } - -- public boolean isCorrectToolForDrops(BlockState state) { -+ public boolean isCorrectToolForDrops(net.minecraft.world.level.block.state.BlockState state) { - return this.getItem().isCorrectToolForDrops(this, state); - } - -- public InteractionResult interactLivingEntity(Player user, LivingEntity entity, InteractionHand hand) { -+ public InteractionResult interactLivingEntity(net.minecraft.world.entity.player.Player user, LivingEntity entity, InteractionHand hand) { - return this.getItem().interactLivingEntity(this, user, entity, hand); - } - -@@ -736,7 +996,7 @@ - - } - -- public void onCraftedBy(Level world, Player player, int amount) { -+ public void onCraftedBy(Level world, net.minecraft.world.entity.player.Player player, int amount) { - player.awardStat(Stats.ITEM_CRAFTED.get(this.getItem()), amount); - this.getItem().onCraftedBy(this, world, player); - } -@@ -768,7 +1028,13 @@ - - public boolean useOnRelease() { - return this.getItem().useOnRelease(this); -+ } -+ -+ // CraftBukkit start -+ public void restorePatch(DataComponentPatch datacomponentpatch) { -+ this.components.restorePatch(datacomponentpatch); - } -+ // CraftBukkit end - - @Nullable - public T set(DataComponentType type, @Nullable T value) { -@@ -805,6 +1071,25 @@ - this.getItem().verifyComponentsAfterLoad(this); - } - } -+ -+ // Paper start - (this is just a good no conflict location) -+ public org.bukkit.inventory.ItemStack asBukkitMirror() { -+ return CraftItemStack.asCraftMirror(this); -+ } -+ public org.bukkit.inventory.ItemStack asBukkitCopy() { -+ return CraftItemStack.asCraftMirror(this.copy()); -+ } -+ public static ItemStack fromBukkitCopy(org.bukkit.inventory.ItemStack itemstack) { -+ return CraftItemStack.asNMSCopy(itemstack); -+ } -+ private org.bukkit.craftbukkit.inventory.CraftItemStack bukkitStack; -+ public org.bukkit.inventory.ItemStack getBukkitStack() { -+ if (bukkitStack == null || bukkitStack.handle != this) { -+ bukkitStack = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(this); -+ } -+ return bukkitStack; -+ } -+ // Paper end - - public void applyComponents(DataComponentPatch changes) { - this.components.applyPatch(changes); -@@ -858,7 +1143,7 @@ - } - - private void addToTooltip(DataComponentType componentType, Item.TooltipContext context, Consumer textConsumer, TooltipFlag type) { -- T t0 = (TooltipProvider) this.get(componentType); -+ T t0 = (T) this.get(componentType); // CraftBukkit - decompile error - - if (t0 != null) { - t0.addToTooltip(context, textConsumer, type); -@@ -866,7 +1151,7 @@ - - } - -- public List getTooltipLines(Item.TooltipContext context, @Nullable Player player, TooltipFlag type) { -+ public List getTooltipLines(Item.TooltipContext context, @Nullable net.minecraft.world.entity.player.Player player, TooltipFlag type) { - boolean flag = this.getItem().shouldPrintOpWarning(this, player); - - if (!type.isCreative() && this.has(DataComponents.HIDE_TOOLTIP)) { -@@ -941,7 +1226,7 @@ - } - } - -- private void addAttributeTooltips(Consumer textConsumer, @Nullable Player player) { -+ private void addAttributeTooltips(Consumer textConsumer, @Nullable net.minecraft.world.entity.player.Player player) { - ItemAttributeModifiers itemattributemodifiers = (ItemAttributeModifiers) this.getOrDefault(DataComponents.ATTRIBUTE_MODIFIERS, ItemAttributeModifiers.EMPTY); - - if (itemattributemodifiers.showInTooltip()) { -@@ -966,7 +1251,7 @@ - } - } - -- private void addModifierTooltip(Consumer textConsumer, @Nullable Player player, Holder attribute, AttributeModifier modifier) { -+ private void addModifierTooltip(Consumer textConsumer, @Nullable net.minecraft.world.entity.player.Player player, Holder attribute, AttributeModifier modifier) { - double d0 = modifier.amount(); - boolean flag = false; - -@@ -1091,6 +1376,19 @@ - EnchantmentHelper.forEachModifier(this, slot, attributeModifierConsumer); - } - -+ // CraftBukkit start -+ @Deprecated -+ public void setItem(Item item) { -+ this.bukkitStack = null; // Paper -+ this.item = item; -+ // Paper start - change base component prototype -+ final DataComponentPatch patch = this.getComponentsPatch(); -+ this.components = new PatchedDataComponentMap(this.item.components()); -+ this.applyComponents(patch); -+ // Paper end - change base component prototype -+ } -+ // CraftBukkit end -+ - public Component getDisplayName() { - MutableComponent ichatmutablecomponent = Component.empty().append(this.getHoverName()); - -@@ -1153,7 +1451,7 @@ - } - - public void consume(int amount, @Nullable LivingEntity entity) { -- if (entity == null || !entity.hasInfiniteMaterials()) { -+ if ((entity == null || !entity.hasInfiniteMaterials()) && this != ItemStack.EMPTY) { // CraftBukkit - this.shrink(amount); - } - diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/LeadItem.java.patch b/paper-server/patches/unapplied/net/minecraft/world/item/LeadItem.java.patch deleted file mode 100644 index e45ad43774..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/item/LeadItem.java.patch +++ /dev/null @@ -1,92 +0,0 @@ ---- a/net/minecraft/world/item/LeadItem.java -+++ b/net/minecraft/world/item/LeadItem.java -@@ -18,6 +18,11 @@ - import net.minecraft.world.level.block.state.BlockState; - import net.minecraft.world.level.gameevent.GameEvent; - import net.minecraft.world.phys.AABB; -+// CraftBukkit start -+import org.bukkit.craftbukkit.CraftEquipmentSlot; -+import org.bukkit.craftbukkit.block.CraftBlock; -+import org.bukkit.event.hanging.HangingPlaceEvent; -+// CraftBukkit end - - public class LeadItem extends Item { - -@@ -35,37 +40,70 @@ - Player entityhuman = context.getPlayer(); - - if (!world.isClientSide && entityhuman != null) { -- return LeadItem.bindPlayerMobs(entityhuman, world, blockposition); -+ return LeadItem.bindPlayerMobs(entityhuman, world, blockposition, context.getHand()); // CraftBukkit - Pass hand - } - } - - return InteractionResult.PASS; - } - -- public static InteractionResult bindPlayerMobs(Player player, Level world, BlockPos pos) { -+ public static InteractionResult bindPlayerMobs(Player entityhuman, Level world, BlockPos blockposition, net.minecraft.world.InteractionHand enumhand) { // CraftBukkit - Add EnumHand - LeashFenceKnotEntity entityleash = null; -- List list = LeadItem.leashableInArea(world, pos, (leashable) -> { -- return leashable.getLeashHolder() == player; -+ List list = LeadItem.leashableInArea(world, blockposition, (leashable) -> { -+ return leashable.getLeashHolder() == entityhuman; - }); - - Leashable leashable; - -- for (Iterator iterator = list.iterator(); iterator.hasNext(); leashable.setLeashedTo(entityleash, true)) { -+ for (Iterator iterator = list.iterator(); iterator.hasNext();) { // CraftBukkit - handle setLeashedTo at end of loop - leashable = (Leashable) iterator.next(); - if (entityleash == null) { -- entityleash = LeashFenceKnotEntity.getOrCreateKnot(world, pos); -+ entityleash = LeashFenceKnotEntity.getOrCreateKnot(world, blockposition); -+ -+ // CraftBukkit start - fire HangingPlaceEvent -+ org.bukkit.inventory.EquipmentSlot hand = CraftEquipmentSlot.getHand(enumhand); -+ HangingPlaceEvent event = new HangingPlaceEvent((org.bukkit.entity.Hanging) entityleash.getBukkitEntity(), entityhuman != null ? (org.bukkit.entity.Player) entityhuman.getBukkitEntity() : null, CraftBlock.at(world, blockposition), org.bukkit.block.BlockFace.SELF, hand); -+ world.getCraftServer().getPluginManager().callEvent(event); -+ -+ if (event.isCancelled()) { -+ entityleash.discard(null); // CraftBukkit - add Bukkit remove cause -+ return InteractionResult.PASS; -+ } -+ // CraftBukkit end - entityleash.playPlacementSound(); - } -+ -+ // CraftBukkit start -+ if (leashable instanceof Entity leashed) { -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerLeashEntityEvent(leashed, entityleash, entityhuman, enumhand).isCancelled()) { -+ iterator.remove(); -+ continue; -+ } -+ } -+ -+ leashable.setLeashedTo(entityleash, true); -+ // CraftBukkit end - } - - if (!list.isEmpty()) { -- world.gameEvent((Holder) GameEvent.BLOCK_ATTACH, pos, GameEvent.Context.of((Entity) player)); -+ world.gameEvent((Holder) GameEvent.BLOCK_ATTACH, blockposition, GameEvent.Context.of((Entity) entityhuman)); - return InteractionResult.SUCCESS_SERVER; - } else { -+ // CraftBukkit start- remove leash if we do not leash any entity because of the cancelled event -+ if (entityleash != null) { -+ entityleash.discard(null); -+ } -+ // CraftBukkit end - return InteractionResult.PASS; - } - } - -+ // CraftBukkit start -+ public static InteractionResult bindPlayerMobs(Player player, Level world, BlockPos pos) { -+ return LeadItem.bindPlayerMobs(player, world, pos, net.minecraft.world.InteractionHand.MAIN_HAND); -+ } -+ // CraftBukkit end -+ - public static List leashableInArea(Level world, BlockPos pos, Predicate predicate) { - double d0 = 7.0D; - int i = pos.getX(); diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/MapItem.java.patch b/paper-server/patches/unapplied/net/minecraft/world/item/MapItem.java.patch deleted file mode 100644 index 5374da2aa0..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/item/MapItem.java.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- a/net/minecraft/world/item/MapItem.java -+++ b/net/minecraft/world/item/MapItem.java -@@ -97,8 +97,8 @@ - int r = (j / i + o - 64) * i; - int s = (k / i + p - 64) * i; - Multiset multiset = LinkedHashMultiset.create(); -- LevelChunk levelChunk = world.getChunk(SectionPos.blockToSectionCoord(r), SectionPos.blockToSectionCoord(s)); -- if (!levelChunk.isEmpty()) { -+ LevelChunk levelChunk = world.getChunkIfLoaded(SectionPos.blockToSectionCoord(r), SectionPos.blockToSectionCoord(s)); // Paper - Maps shouldn't load chunks -+ if (levelChunk != null && !levelChunk.isEmpty()) { // Paper - Maps shouldn't load chunks - int t = 0; - double e = 0.0; - if (world.dimensionType().hasCeiling()) { -@@ -205,7 +205,7 @@ - - for (int n = 0; n < 128; n++) { - for (int o = 0; o < 128; o++) { -- Holder holder = world.getBiome(mutableBlockPos.set((l + o) * i, 0, (m + n) * i)); -+ Holder holder = world.getUncachedNoiseBiome((l + o) * i, 0, (m + n) * i); // Paper - Perf: Use seed based lookup for treasure maps - bls[n * 128 + o] = holder.is(BiomeTags.WATER_ON_MAP_OUTLINES); - } - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/MinecartItem.java.patch b/paper-server/patches/unapplied/net/minecraft/world/item/MinecartItem.java.patch deleted file mode 100644 index f97004f5f9..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/item/MinecartItem.java.patch +++ /dev/null @@ -1,17 +0,0 @@ ---- a/net/minecraft/world/item/MinecartItem.java -+++ b/net/minecraft/world/item/MinecartItem.java -@@ -67,7 +67,13 @@ - if (world instanceof ServerLevel) { - ServerLevel worldserver = (ServerLevel) world; - -- worldserver.addFreshEntity(entityminecartabstract); -+ // CraftBukkit start -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPlaceEvent(context, entityminecartabstract).isCancelled()) { -+ if (context.getPlayer() != null) context.getPlayer().containerMenu.sendAllDataToRemote(); // Paper - Fix inventory desync -+ return InteractionResult.FAIL; -+ } -+ // CraftBukkit end -+ if (!worldserver.addFreshEntity(entityminecartabstract)) return InteractionResult.PASS; // CraftBukkit - worldserver.gameEvent((Holder) GameEvent.ENTITY_PLACE, blockposition, GameEvent.Context.of(context.getPlayer(), worldserver.getBlockState(blockposition.below()))); - } - diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/PotionItem.java.patch b/paper-server/patches/unapplied/net/minecraft/world/item/PotionItem.java.patch deleted file mode 100644 index 185bcf8992..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/item/PotionItem.java.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- a/net/minecraft/world/item/PotionItem.java -+++ b/net/minecraft/world/item/PotionItem.java -@@ -42,6 +42,12 @@ - PotionContents potionContents = itemStack.getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY); - BlockState blockState = level.getBlockState(blockPos); - if (context.getClickedFace() != Direction.DOWN && blockState.is(BlockTags.CONVERTABLE_TO_MUD) && potionContents.is(Potions.WATER)) { -+ // Paper start -+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, blockPos, Blocks.MUD.defaultBlockState())) { -+ player.containerMenu.sendAllDataToRemote(); -+ return InteractionResult.PASS; -+ } -+ // Paper end - level.playSound(null, blockPos, SoundEvents.GENERIC_SPLASH, SoundSource.BLOCKS, 1.0F, 1.0F); - player.setItemInHand(context.getHand(), ItemUtils.createFilledResult(itemStack, player, new ItemStack(Items.GLASS_BOTTLE))); - player.awardStat(Stats.ITEM_USED.get(itemStack.getItem())); diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/ProjectileWeaponItem.java.patch b/paper-server/patches/unapplied/net/minecraft/world/item/ProjectileWeaponItem.java.patch deleted file mode 100644 index dfdb8d27c6..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/item/ProjectileWeaponItem.java.patch +++ /dev/null @@ -1,52 +0,0 @@ ---- a/net/minecraft/world/item/ProjectileWeaponItem.java -+++ b/net/minecraft/world/item/ProjectileWeaponItem.java -@@ -54,9 +54,25 @@ - float f6 = f4 + f5 * (float) ((i + 1) / 2) * f3; - - f5 = -f5; -- Projectile.spawnProjectile(this.createProjectile(world, shooter, stack, itemstack1, critical), world, itemstack1, (iprojectile) -> { -- this.shootProjectile(shooter, iprojectile, i, speed, divergence, f6, target); -- }); -+ // CraftBukkit start -+ Projectile iprojectile = this.createProjectile(world, shooter, stack, itemstack1, critical); -+ this.shootProjectile(shooter, iprojectile, i, speed, divergence, f6, target); -+ -+ org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(shooter, stack, itemstack1, iprojectile, hand, speed, true); -+ if (event.isCancelled()) { -+ event.getProjectile().remove(); -+ return; -+ } -+ -+ if (event.getProjectile() == iprojectile.getBukkitEntity()) { -+ if (Projectile.spawnProjectile(iprojectile, world, itemstack1).isRemoved()) { -+ if (shooter instanceof net.minecraft.server.level.ServerPlayer) { -+ ((net.minecraft.server.level.ServerPlayer) shooter).getBukkitEntity().updateInventory(); -+ } -+ return; -+ } -+ } -+ // CraftBukkit end - stack.hurtAndBreak(this.getDurabilityUse(itemstack1), shooter, LivingEntity.getSlotForHand(hand)); - if (stack.isEmpty()) { - break; -@@ -93,6 +109,11 @@ - } - - protected static List draw(ItemStack stack, ItemStack projectileStack, LivingEntity shooter) { -+ // Paper start -+ return draw(stack, projectileStack, shooter, true); -+ } -+ protected static List draw(ItemStack stack, ItemStack projectileStack, LivingEntity shooter, boolean consume) { -+ // Paper end - if (projectileStack.isEmpty()) { - return List.of(); - } else { -@@ -112,7 +133,7 @@ - ItemStack itemstack2 = projectileStack.copy(); - - for (int k = 0; k < j; ++k) { -- ItemStack itemstack3 = ProjectileWeaponItem.useAmmo(stack, k == 0 ? projectileStack : itemstack2, shooter, k > 0); -+ ItemStack itemstack3 = ProjectileWeaponItem.useAmmo(stack, k == 0 ? projectileStack : itemstack2, shooter, k > 0 || !consume); // Paper - - if (!itemstack3.isEmpty()) { - list.add(itemstack3); diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/ShovelItem.java.patch b/paper-server/patches/unapplied/net/minecraft/world/item/ShovelItem.java.patch deleted file mode 100644 index 0840475938..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/item/ShovelItem.java.patch +++ /dev/null @@ -1,33 +0,0 @@ ---- a/net/minecraft/world/item/ShovelItem.java -+++ b/net/minecraft/world/item/ShovelItem.java -@@ -46,20 +46,29 @@ - Player player = context.getPlayer(); - BlockState blockState2 = FLATTENABLES.get(blockState.getBlock()); - BlockState blockState3 = null; -+ Runnable afterAction = null; // Paper - if (blockState2 != null && level.getBlockState(blockPos.above()).isAir()) { -- level.playSound(player, blockPos, SoundEvents.SHOVEL_FLATTEN, SoundSource.BLOCKS, 1.0F, 1.0F); -+ afterAction = () -> level.playSound(player, blockPos, SoundEvents.SHOVEL_FLATTEN, SoundSource.BLOCKS, 1.0F, 1.0F); // Paper - blockState3 = blockState2; - } else if (blockState.getBlock() instanceof CampfireBlock && blockState.getValue(CampfireBlock.LIT)) { -+ afterAction = () -> { // Paper - if (!level.isClientSide()) { - level.levelEvent(null, 1009, blockPos, 0); - } - - CampfireBlock.dowse(context.getPlayer(), level, blockPos, blockState); -+ }; // Paper - blockState3 = blockState.setValue(CampfireBlock.LIT, Boolean.valueOf(false)); - } - - if (blockState3 != null) { - if (!level.isClientSide) { -+ // Paper start -+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(context.getPlayer(), blockPos, blockState3)) { -+ return InteractionResult.PASS; -+ } -+ afterAction.run(); -+ // Paper end - level.setBlock(blockPos, blockState3, 11); - level.gameEvent(GameEvent.BLOCK_CHANGE, blockPos, GameEvent.Context.of(player, blockState3)); - if (player != null) { diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/SignItem.java.patch b/paper-server/patches/unapplied/net/minecraft/world/item/SignItem.java.patch deleted file mode 100644 index 50c0cdf7d1..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/item/SignItem.java.patch +++ /dev/null @@ -1,23 +0,0 @@ ---- a/net/minecraft/world/item/SignItem.java -+++ b/net/minecraft/world/item/SignItem.java -@@ -13,6 +13,8 @@ - - public class SignItem extends StandingAndWallBlockItem { - -+ public static BlockPos openSign; // CraftBukkit -+ - public SignItem(Block standingBlock, Block wallBlock, Item.Properties settings) { - super(standingBlock, wallBlock, Direction.DOWN, settings); - } -@@ -35,7 +37,10 @@ - if (block instanceof SignBlock) { - SignBlock blocksign = (SignBlock) block; - -- blocksign.openTextEdit(player, tileentitysign, true); -+ // CraftBukkit start - SPIGOT-4678 -+ // blocksign.openTextEdit(entityhuman, tileentitysign, true); -+ SignItem.openSign = pos; -+ // CraftBukkit end - } - } - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/SnowballItem.java.patch b/paper-server/patches/unapplied/net/minecraft/world/item/SnowballItem.java.patch deleted file mode 100644 index bb5a1788d6..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/item/SnowballItem.java.patch +++ /dev/null @@ -1,37 +0,0 @@ ---- a/net/minecraft/world/item/SnowballItem.java -+++ b/net/minecraft/world/item/SnowballItem.java -@@ -25,13 +25,30 @@ - public InteractionResult use(Level world, Player user, InteractionHand hand) { - ItemStack itemstack = user.getItemInHand(hand); - -- world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.SNOWBALL_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); -+ // CraftBukkit start - moved down -+ // world.playSound((EntityHuman) null, entityhuman.getX(), entityhuman.getY(), entityhuman.getZ(), SoundEffects.SNOWBALL_THROW, SoundCategory.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); - if (world instanceof ServerLevel worldserver) { -- Projectile.spawnProjectileFromRotation(Snowball::new, worldserver, itemstack, user, 0.0F, SnowballItem.PROJECTILE_SHOOT_POWER, 1.0F); -+ // Paper start - PlayerLaunchProjectileEvent -+ final Projectile.Delayed snowball = Projectile.spawnProjectileFromRotationDelayed(Snowball::new, worldserver, itemstack, user, 0.0F, SnowballItem.PROJECTILE_SHOOT_POWER, 1.0F); -+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) snowball.projectile().getBukkitEntity()); -+ if (event.callEvent() && snowball.attemptSpawn()) { -+ user.awardStat(Stats.ITEM_USED.get(this)); -+ if (event.shouldConsume()) { -+ itemstack.consume(1, user); -+ } else if (user instanceof net.minecraft.server.level.ServerPlayer) { -+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); -+ } -+ // Paper end - PlayerLaunchProjectileEvent -+ -+ world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.SNOWBALL_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); -+ } else { if (user instanceof net.minecraft.server.level.ServerPlayer) { // Paper - PlayerLaunchProjectileEvent - return fail -+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); -+ } return InteractionResult.FAIL; } // Paper - PlayerLaunchProjectileEvent - return fail -+ // CraftBukkit end - } - -- user.awardStat(Stats.ITEM_USED.get(this)); -- itemstack.consume(1, user); -+ // Paper - PlayerLaunchProjectileEvent - moved up -+ // itemstack.consume(1, entityhuman); // CraftBukkit - moved up - return InteractionResult.SUCCESS; - } - diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/SpawnEggItem.java.patch b/paper-server/patches/unapplied/net/minecraft/world/item/SpawnEggItem.java.patch deleted file mode 100644 index a33a635c7a..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/item/SpawnEggItem.java.patch +++ /dev/null @@ -1,24 +0,0 @@ ---- a/net/minecraft/world/item/SpawnEggItem.java -+++ b/net/minecraft/world/item/SpawnEggItem.java -@@ -63,6 +63,8 @@ - EntityType entitytypes; - - if (tileentity instanceof Spawner) { -+ if (world.paperConfig().entities.spawning.disableMobSpawnerSpawnEggTransformation) return InteractionResult.FAIL; // Paper - Allow disabling mob spawner spawn egg transformation -+ - Spawner spawner = (Spawner) tileentity; - - entitytypes = this.getType(world.registryAccess(), itemstack); -@@ -176,10 +178,10 @@ - return Optional.empty(); - } else { - ((Mob) object).moveTo(pos.x(), pos.y(), pos.z(), 0.0F, 0.0F); -- world.addFreshEntityWithPassengers((Entity) object); -+ world.addFreshEntityWithPassengers((Entity) object, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG); // CraftBukkit - ((Mob) object).setCustomName((Component) stack.get(DataComponents.CUSTOM_NAME)); - stack.consume(1, user); -- return Optional.of(object); -+ return Optional.of((Mob) object); // CraftBukkit - decompile error - } - } - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/StandingAndWallBlockItem.java.patch b/paper-server/patches/unapplied/net/minecraft/world/item/StandingAndWallBlockItem.java.patch deleted file mode 100644 index 9e1a576a36..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/item/StandingAndWallBlockItem.java.patch +++ /dev/null @@ -1,41 +0,0 @@ ---- a/net/minecraft/world/item/StandingAndWallBlockItem.java -+++ b/net/minecraft/world/item/StandingAndWallBlockItem.java -@@ -4,12 +4,17 @@ - import javax.annotation.Nullable; - import net.minecraft.core.BlockPos; - import net.minecraft.core.Direction; -+import net.minecraft.server.level.ServerPlayer; - import net.minecraft.world.item.context.BlockPlaceContext; - import net.minecraft.world.level.Level; - import net.minecraft.world.level.LevelReader; - import net.minecraft.world.level.block.Block; - import net.minecraft.world.level.block.state.BlockState; - import net.minecraft.world.phys.shapes.CollisionContext; -+import org.bukkit.craftbukkit.block.CraftBlock; -+import org.bukkit.craftbukkit.block.data.CraftBlockData; -+import org.bukkit.event.block.BlockCanBuildEvent; -+// CraftBukkit end - - public class StandingAndWallBlockItem extends BlockItem { - -@@ -49,7 +54,19 @@ - } - } - -- return iblockdata1 != null && world.isUnobstructed(iblockdata1, blockposition, CollisionContext.empty()) ? iblockdata1 : null; -+ // CraftBukkit start -+ if (iblockdata1 != null) { -+ boolean defaultReturn = world.isUnobstructed(iblockdata1, blockposition, CollisionContext.empty()); -+ org.bukkit.entity.Player player = (context.getPlayer() instanceof ServerPlayer) ? (org.bukkit.entity.Player) context.getPlayer().getBukkitEntity() : null; -+ -+ BlockCanBuildEvent event = new BlockCanBuildEvent(CraftBlock.at(world, blockposition), player, CraftBlockData.fromData(iblockdata1), defaultReturn, org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(context.getHand())); // Paper - Expose hand in BlockCanBuildEvent -+ context.getLevel().getCraftServer().getPluginManager().callEvent(event); -+ -+ return (event.isBuildable()) ? iblockdata1 : null; -+ } else { -+ return null; -+ } -+ // CraftBukkit end - } - - @Override diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/ThrowablePotionItem.java.patch b/paper-server/patches/unapplied/net/minecraft/world/item/ThrowablePotionItem.java.patch deleted file mode 100644 index 13c480eabd..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/item/ThrowablePotionItem.java.patch +++ /dev/null @@ -1,34 +0,0 @@ ---- a/net/minecraft/world/item/ThrowablePotionItem.java -+++ b/net/minecraft/world/item/ThrowablePotionItem.java -@@ -22,11 +22,28 @@ - public InteractionResult use(Level world, Player user, InteractionHand hand) { - ItemStack itemStack = user.getItemInHand(hand); - if (world instanceof ServerLevel serverLevel) { -- Projectile.spawnProjectileFromRotation(ThrownPotion::new, serverLevel, itemStack, user, -20.0F, PROJECTILE_SHOOT_POWER, 1.0F); -+ // Paper start - PlayerLaunchProjectileEvent -+ final Projectile.Delayed thrownPotion = Projectile.spawnProjectileFromRotationDelayed(ThrownPotion::new, serverLevel, itemStack, user, -20.0F, PROJECTILE_SHOOT_POWER, 1.0F); -+ // Paper start - PlayerLaunchProjectileEvent -+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Projectile) thrownPotion.projectile().getBukkitEntity()); -+ if (event.callEvent() && thrownPotion.attemptSpawn()) { -+ if (event.shouldConsume()) { -+ itemStack.consume(1, user); -+ } else if (user instanceof net.minecraft.server.level.ServerPlayer) { -+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); -+ } -+ -+ user.awardStat(Stats.ITEM_USED.get(this)); -+ } else { -+ if (user instanceof net.minecraft.server.level.ServerPlayer) { -+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); -+ } -+ return InteractionResult.FAIL; -+ } -+ // Paper end - PlayerLaunchProjectileEvent - } - -- user.awardStat(Stats.ITEM_USED.get(this)); -- itemStack.consume(1, user); -+ // Paper - PlayerLaunchProjectileEvent - move up - return InteractionResult.SUCCESS; - } - diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/TridentItem.java.patch b/paper-server/patches/unapplied/net/minecraft/world/item/TridentItem.java.patch deleted file mode 100644 index a23995cfe3..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/item/TridentItem.java.patch +++ /dev/null @@ -1,51 +0,0 @@ ---- a/net/minecraft/world/item/TridentItem.java -+++ b/net/minecraft/world/item/TridentItem.java -@@ -86,18 +86,37 @@ - if (world instanceof ServerLevel) { - ServerLevel worldserver = (ServerLevel) world; - -- stack.hurtWithoutBreaking(1, entityhuman); -+ // itemstack.hurtWithoutBreaking(1, entityhuman); // CraftBukkit - moved down - if (f == 0.0F) { -- ThrownTrident entitythrowntrident = (ThrownTrident) Projectile.spawnProjectileFromRotation(ThrownTrident::new, worldserver, stack, entityhuman, 0.0F, 2.5F, 1.0F); -+ // Paper start - PlayerLaunchProjectileEvent -+ Projectile.Delayed tridentDelayed = Projectile.spawnProjectileFromRotationDelayed(ThrownTrident::new, worldserver, stack, entityhuman, 0.0F, 2.5F, 1.0F); -+ // Paper start - PlayerLaunchProjectileEvent -+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(stack), (org.bukkit.entity.Projectile) tridentDelayed.projectile().getBukkitEntity()); -+ if (!event.callEvent() || !tridentDelayed.attemptSpawn()) { -+ // CraftBukkit start -+ // Paper end - PlayerLaunchProjectileEvent -+ if (entityhuman instanceof net.minecraft.server.level.ServerPlayer) { -+ ((net.minecraft.server.level.ServerPlayer) entityhuman).getBukkitEntity().updateInventory(); -+ } -+ return false; -+ } -+ ThrownTrident entitythrowntrident = tridentDelayed.projectile(); // Paper - PlayerLaunchProjectileEvent -+ if (event.shouldConsume()) stack.hurtWithoutBreaking(1, entityhuman); // Paper - PlayerLaunchProjectileEvent -+ entitythrowntrident.pickupItemStack = stack.copy(); // SPIGOT-4511 update since damage call moved -+ // CraftBukkit end - - if (entityhuman.hasInfiniteMaterials()) { - entitythrowntrident.pickup = AbstractArrow.Pickup.CREATIVE_ONLY; -- } else { -+ } else if (event.shouldConsume()) { // Paper - PlayerLaunchProjectileEvent - entityhuman.getInventory().removeItem(stack); - } - - world.playSound((Player) null, (Entity) entitythrowntrident, (SoundEvent) holder.value(), SoundSource.PLAYERS, 1.0F, 1.0F); - return true; -+ // CraftBukkit start - SPIGOT-5458 also need in this branch :( -+ } else { -+ stack.hurtWithoutBreaking(1, entityhuman); -+ // CraftBukkkit end - } - } - -@@ -112,6 +131,7 @@ - f3 *= f / f6; - f4 *= f / f6; - f5 *= f / f6; -+ org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerRiptideEvent(entityhuman, stack, f3, f4, f5); // CraftBukkit - entityhuman.push((double) f3, (double) f4, (double) f5); - entityhuman.startAutoSpinAttack(20, 8.0F, stack); - if (entityhuman.onGround()) { diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/WindChargeItem.java.patch b/paper-server/patches/unapplied/net/minecraft/world/item/WindChargeItem.java.patch deleted file mode 100644 index 8fd7be1352..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/item/WindChargeItem.java.patch +++ /dev/null @@ -1,42 +0,0 @@ ---- a/net/minecraft/world/item/WindChargeItem.java -+++ b/net/minecraft/world/item/WindChargeItem.java -@@ -27,7 +27,7 @@ - public InteractionResult use(Level world, Player user, InteractionHand hand) { - ItemStack itemStack = user.getItemInHand(hand); - if (world instanceof ServerLevel serverLevel) { -- Projectile.spawnProjectileFromRotation( -+ final Projectile.Delayed windCharge = Projectile.spawnProjectileFromRotationDelayed( // Paper - PlayerLaunchProjectileEvent - (world2, shooter, stack) -> new WindCharge(user, world, user.position().x(), user.getEyePosition().y(), user.position().z()), - serverLevel, - itemStack, -@@ -36,6 +36,21 @@ - PROJECTILE_SHOOT_POWER, - 1.0F - ); -+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Projectile) windCharge.projectile().getBukkitEntity()); -+ if (!event.callEvent() || !windCharge.attemptSpawn()) { -+ user.containerMenu.sendAllDataToRemote(); -+ if (user instanceof net.minecraft.server.level.ServerPlayer player) { -+ player.connection.send(new net.minecraft.network.protocol.game.ClientboundCooldownPacket(user.getCooldowns().getCooldownGroup(itemStack), 0)); // prevent visual desync of cooldown on the slot -+ } -+ return InteractionResult.FAIL; -+ } -+ -+ user.awardStat(Stats.ITEM_USED.get(this)); -+ if (event.shouldConsume()) itemStack.consume(1, user); -+ else if (!user.hasInfiniteMaterials()) { -+ user.containerMenu.sendAllDataToRemote(); -+ } -+ // Paper end - PlayerLaunchProjectileEvent - } - - world.playSound( -@@ -48,8 +63,6 @@ - 0.5F, - 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F) - ); -- user.awardStat(Stats.ITEM_USED.get(this)); -- itemStack.consume(1, user); - return InteractionResult.SUCCESS; - } - diff --git a/paper-server/patches/unapplied/net/minecraft/world/item/WrittenBookItem.java.patch b/paper-server/patches/unapplied/net/minecraft/world/item/WrittenBookItem.java.patch deleted file mode 100644 index f29d9ca860..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/item/WrittenBookItem.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/net/minecraft/world/item/WrittenBookItem.java -+++ b/net/minecraft/world/item/WrittenBookItem.java -@@ -41,7 +41,7 @@ - - public static boolean resolveBookComponents(ItemStack book, CommandSourceStack commandSource, @Nullable Player player) { - WrittenBookContent writtenBookContent = book.get(DataComponents.WRITTEN_BOOK_CONTENT); -- if (writtenBookContent != null && !writtenBookContent.resolved()) { -+ if (io.papermc.paper.configuration.GlobalConfiguration.get().itemValidation.resolveSelectorsInBooks && writtenBookContent != null && !writtenBookContent.resolved()) { // Paper - Disable component selector resolving in books by default - WrittenBookContent writtenBookContent2 = writtenBookContent.resolve(commandSource, player); - if (writtenBookContent2 != null) { - book.set(DataComponents.WRITTEN_BOOK_CONTENT, writtenBookContent2);