Co-authored-by: Bjarne Koll <git@lynxplay.dev>
Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
Co-authored-by: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com>
Co-authored-by: MiniDigger | Martin <admin@minidigger.dev>
Co-authored-by: Nassim Jahnke <nassim@njahnke.dev>
Co-authored-by: Noah van der Aa <ndvdaa@gmail.com>
Co-authored-by: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Co-authored-by: Shane Freeder <theboyetronic@gmail.com>
Co-authored-by: Spottedleaf <Spottedleaf@users.noreply.github.com>
Co-authored-by: Tamion <70228790+notTamion@users.noreply.github.com>
Co-authored-by: Warrior <50800980+Warriorrrr@users.noreply.github.com>
This commit is contained in:
Nassim Jahnke
2025-04-12 17:26:44 +02:00
parent 0767902699
commit f00727c57e
2092 changed files with 50551 additions and 48729 deletions

View File

@@ -3,7 +3,7 @@
@@ -45,6 +_,12 @@
float f = Mth.floor((Mth.wrapDegrees(context.getRotation() - 180.0F) + 22.5F) / 45.0F) * 45.0F;
armorStand.moveTo(armorStand.getX(), armorStand.getY(), armorStand.getZ(), f, 0.0F);
armorStand.snapTo(armorStand.getX(), armorStand.getY(), armorStand.getZ(), f, 0.0F);
+ // CraftBukkit start
+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPlaceEvent(context, armorStand).isCancelled()) {
+ if (context.getPlayer() != null) context.getPlayer().containerMenu.sendAllDataToRemote(); // Paper - Fix inventory desync

View File

@@ -1,18 +1,6 @@
--- a/net/minecraft/world/item/BlockItem.java
+++ b/net/minecraft/world/item/BlockItem.java
@@ -30,6 +_,11 @@
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraft.world.phys.shapes.CollisionContext;
+// CraftBukkit start
+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 {
@Deprecated
@@ -59,6 +_,14 @@
@@ -57,6 +_,14 @@
return InteractionResult.FAIL;
} else {
BlockState placementState = this.getPlacementState(blockPlaceContext);
@@ -27,7 +15,7 @@
if (placementState == null) {
return InteractionResult.FAIL;
} else if (!this.placeBlock(blockPlaceContext, placementState)) {
@@ -71,15 +_,40 @@
@@ -69,15 +_,40 @@
BlockState blockState = level.getBlockState(clickedPos);
if (blockState.is(placementState.getBlock())) {
blockState = this.updateBlockStateFromTag(clickedPos, level, itemInHand, blockState);
@@ -36,7 +24,7 @@
this.updateCustomBlockEntityTag(clickedPos, level, player, itemInHand, blockState);
updateBlockEntityComponents(level, clickedPos, itemInHand);
+ } catch (Exception ex) {
+ oldBukkitState.update(true, false);
+ ((org.bukkit.craftbukkit.block.CraftBlockState) oldBukkitState).revertPlace();
+ if (player instanceof ServerPlayer serverPlayer) {
+ org.apache.logging.log4j.LogManager.getLogger().error("Player {} tried placing invalid block", player.getScoreboardName(), ex);
+ serverPlayer.getBukkitEntity().kickPlayer("Packet processing error");
@@ -48,9 +36,9 @@
blockState.getBlock().setPlacedBy(level, clickedPos, blockState, player, itemInHand);
+ // CraftBukkit start
+ if (bukkitState != null) {
+ org.bukkit.event.block.BlockPlaceEvent placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPlaceEvent((net.minecraft.server.level.ServerLevel) level, player, blockPlaceContext.getHand(), bukkitState, clickedPos.getX(), clickedPos.getY(), clickedPos.getZ());
+ org.bukkit.event.block.BlockPlaceEvent placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPlaceEvent((net.minecraft.server.level.ServerLevel) level, player, blockPlaceContext.getHand(), bukkitState, clickedPos);
+ if (placeEvent != null && (placeEvent.isCancelled() || !placeEvent.canBuild())) {
+ bukkitState.update(true, false);
+ ((org.bukkit.craftbukkit.block.CraftBlockState) bukkitState).revertPlace();
+
+ // Paper - if the event is called here, the inventory should be updated
+ player.containerMenu.sendAllDataToRemote(); // SPIGOT-4541
@@ -68,18 +56,21 @@
level.playSound(
player,
clickedPos,
@@ -140,8 +_,16 @@
@@ -137,8 +_,19 @@
protected boolean canPlace(BlockPlaceContext context, BlockState state) {
Player player = context.getPlayer();
CollisionContext collisionContext = player == null ? CollisionContext.empty() : CollisionContext.of(player);
- return (!this.mustSurvive() || state.canSurvive(context.getLevel(), context.getClickedPos()))
- && context.getLevel().isUnobstructed(state, context.getClickedPos(), collisionContext);
- && context.getLevel().isUnobstructed(state, context.getClickedPos(), CollisionContext.placementContext(player));
+ // CraftBukkit start
+ Level world = context.getLevel(); // Paper - Cancel hit for vanished players
+ boolean canBuild = (!this.mustSurvive() || state.canSurvive(world, context.getClickedPos())) && world.checkEntityCollision(state, player, collisionContext, context.getClickedPos(), true); // Paper - Cancel hit for vanished players
+ boolean canBuild = (!this.mustSurvive() || state.canSurvive(world, context.getClickedPos())) && world.checkEntityCollision(state, player, CollisionContext.placementContext(player), context.getClickedPos(), true); // Paper - Cancel hit for vanished players
+ org.bukkit.entity.Player bukkitPlayer = (context.getPlayer() instanceof ServerPlayer) ? (org.bukkit.entity.Player) context.getPlayer().getBukkitEntity() : null;
+
+ BlockCanBuildEvent event = new BlockCanBuildEvent(CraftBlock.at(world, context.getClickedPos()), bukkitPlayer, CraftBlockData.fromData(state), canBuild, org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(context.getHand())); // Paper - Expose hand in BlockCanBuildEvent
+ org.bukkit.event.block.BlockCanBuildEvent event = new org.bukkit.event.block.BlockCanBuildEvent(
+ org.bukkit.craftbukkit.block.CraftBlock.at(world, context.getClickedPos()), bukkitPlayer,
+ org.bukkit.craftbukkit.block.data.CraftBlockData.fromData(state), canBuild, org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(context.getHand())
+ );
+ world.getCraftServer().getPluginManager().callEvent(event);
+
+ return event.isBuildable();
@@ -87,7 +78,7 @@
}
protected boolean mustSurvive() {
@@ -170,7 +_,7 @@
@@ -167,7 +_,7 @@
return false;
}

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/item/BucketItem.java
+++ b/net/minecraft/world/item/BucketItem.java
@@ -29,6 +_,7 @@
@@ -30,6 +_,7 @@
import net.minecraft.world.phys.HitResult;
public class BucketItem extends Item implements DispensibleContainerItem {
@@ -8,18 +8,17 @@
public final Fluid content;
public BucketItem(Fluid content, Item.Properties properties) {
@@ -55,12 +_,23 @@
@@ -56,12 +_,22 @@
} else if (this.content == Fluids.EMPTY) {
BlockState blockState = level.getBlockState(blockPos);
if (blockState.getBlock() instanceof BucketPickup bucketPickup) {
+ // CraftBukkit start
+ ItemStack dummyFluid = bucketPickup.pickupBlock(player, org.bukkit.craftbukkit.util.DummyGeneratorAccess.INSTANCE, blockPos, blockState);
+ if (dummyFluid.isEmpty()) return InteractionResult.FAIL; // Don't fire event if the bucket won't be filled.
+ org.bukkit.event.player.PlayerBucketFillEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerBucketFillEvent((net.minecraft.server.level.ServerLevel) level, player, blockPos, blockPos, playerPovHitResult.getDirection(), itemInHand, dummyFluid.getItem(), hand);
+ org.bukkit.event.player.PlayerBucketFillEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerBucketFillEvent(level, player, blockPos, blockPos, playerPovHitResult.getDirection(), itemInHand, dummyFluid.getItem(), hand);
+
+ if (event.isCancelled()) {
+ // ((ServerPlayer) user).connection.send(new ClientboundBlockUpdatePacket(level, blockPos)); // SPIGOT-5163 (see PlayerInteractManager) // Paper - Don't resend blocks
+ ((ServerPlayer) player).getBukkitEntity().updateInventory(); // SPIGOT-4541
+ player.containerMenu.sendAllDataToRemote(); // SPIGOT-4541
+ return InteractionResult.FAIL;
+ }
+ // CraftBukkit end
@@ -33,7 +32,7 @@
if (!level.isClientSide) {
CriteriaTriggers.FILLED_BUCKET.trigger((ServerPlayer)player, itemStack);
}
@@ -73,7 +_,7 @@
@@ -74,7 +_,7 @@
} else {
BlockState blockState = level.getBlockState(blockPos);
BlockPos blockPos2 = blockState.getBlock() instanceof LiquidBlockContainer && this.content == Fluids.WATER ? blockPos : blockPos1;
@@ -42,7 +41,7 @@
this.checkExtraContent(player, level, itemInHand, blockPos2);
if (player instanceof ServerPlayer) {
CriteriaTriggers.PLACED_BLOCK.trigger((ServerPlayer)player, blockPos2, itemInHand);
@@ -90,6 +_,13 @@
@@ -91,6 +_,13 @@
}
public static ItemStack getEmptySuccessItem(ItemStack bucketStack, Player player) {
@@ -56,37 +55,37 @@
return !player.hasInfiniteMaterials() ? new ItemStack(Items.BUCKET) : bucketStack;
}
@@ -99,6 +_,12 @@
@@ -100,6 +_,12 @@
@Override
public boolean emptyContents(@Nullable Player player, Level level, BlockPos pos, @Nullable BlockHitResult result) {
public boolean emptyContents(@Nullable LivingEntity entity, Level level, BlockPos pos, @Nullable BlockHitResult hitResult) {
+ // CraftBukkit start
+ return this.emptyContents(player, level, pos, result, null, null, null, InteractionHand.MAIN_HAND);
+ return this.emptyContents(entity, level, pos, hitResult, null, null, null, InteractionHand.MAIN_HAND);
+ }
+
+ public boolean emptyContents(@Nullable Player player, Level level, BlockPos pos, @Nullable BlockHitResult result, Direction enumdirection, BlockPos clicked, ItemStack itemstack, InteractionHand enumhand) {
+ public boolean emptyContents(@Nullable LivingEntity entity, Level level, BlockPos pos, @Nullable BlockHitResult hitResult, Direction direction, BlockPos clicked, ItemStack itemstack, InteractionHand hand) {
+ // CraftBukkit end
if (!(this.content instanceof FlowingFluid flowingFluid)) {
return false;
} else {
@@ -109,8 +_,19 @@
@@ -110,8 +_,19 @@
|| canBeReplaced
|| block instanceof LiquidBlockContainer liquidBlockContainer
&& liquidBlockContainer.canPlaceLiquid(player, level, pos, blockState, this.content);
&& liquidBlockContainer.canPlaceLiquid(entity, level, pos, blockState, this.content);
+
+ // CraftBukkit start
+ if (flag && player != null) {
+ org.bukkit.event.player.PlayerBucketEmptyEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerBucketEmptyEvent((net.minecraft.server.level.ServerLevel) level, player, pos, clicked, enumdirection, itemstack, enumhand);
+ if (flag && entity instanceof Player player) {
+ org.bukkit.event.player.PlayerBucketEmptyEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerBucketEmptyEvent(level, player, pos, clicked, direction, itemstack, hand);
+ if (event.isCancelled()) {
+ // ((ServerPlayer) player).connection.send(new ClientboundBlockUpdatePacket(level, pos)); // SPIGOT-4238: needed when looking through entity // Paper - Don't resend blocks
+ ((ServerPlayer) player).getBukkitEntity().updateInventory(); // SPIGOT-4541
+ player.containerMenu.sendAllDataToRemote(); // SPIGOT-4541
+ return false;
+ }
+ itemLeftInHandAfterPlayerBucketEmptyEvent = event.getItemStack() != null ? event.getItemStack().equals(org.bukkit.craftbukkit.inventory.CraftItemStack.asNewCraftStack(net.minecraft.world.item.Items.BUCKET)) ? null : org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItemStack()) : ItemStack.EMPTY; // Paper - Fix PlayerBucketEmptyEvent result itemstack
+ }
+ // CraftBukkit end
if (!flag) {
- return result != null && this.emptyContents(player, level, result.getBlockPos().relative(result.getDirection()), null);
+ return result != null && this.emptyContents(player, level, result.getBlockPos().relative(result.getDirection()), null, enumdirection, clicked, itemstack, enumhand); // CraftBukkit
- return hitResult != null && this.emptyContents(entity, level, hitResult.getBlockPos().relative(hitResult.getDirection()), null);
+ return hitResult != null && this.emptyContents(entity, level, hitResult.getBlockPos().relative(hitResult.getDirection()), null, direction, clicked, itemstack, hand); // CraftBukkit
} else if (level.dimensionType().ultraWarm() && this.content.is(FluidTags.WATER)) {
int x = pos.getX();
int y = pos.getY();

View File

@@ -1,38 +1,23 @@
--- a/net/minecraft/world/item/CrossbowItem.java
+++ b/net/minecraft/world/item/CrossbowItem.java
@@ -90,7 +_,14 @@
public boolean releaseUsing(ItemStack stack, Level level, LivingEntity entity, int timeLeft) {
int i = this.getUseDuration(stack, entity) - timeLeft;
float powerForTime = getPowerForTime(i, stack, entity);
- if (powerForTime >= 1.0F && !isCharged(stack) && tryLoadProjectiles(entity, stack)) {
+ // Paper start - Add EntityLoadCrossbowEvent
+ if (powerForTime >= 1.0F && !isCharged(stack)) {
+ final io.papermc.paper.event.entity.EntityLoadCrossbowEvent event = new io.papermc.paper.event.entity.EntityLoadCrossbowEvent(entity.getBukkitLivingEntity(), stack.asBukkitMirror(), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(entity.getUsedItemHand()));
+ if (!event.callEvent() || !tryLoadProjectiles(entity, stack, event.shouldConsumeItem()) || !event.shouldConsumeItem()) {
+ if (entity instanceof ServerPlayer player) player.containerMenu.sendAllDataToRemote();
+ return false;
+ }
+ // Paper end - Add EntityLoadCrossbowEvent
CrossbowItem.ChargingSounds chargingSounds = this.getChargingSounds(stack);
chargingSounds.end()
.ifPresent(
@@ -111,8 +_,14 @@
}
@@ -88,8 +_,15 @@
return getPowerForTime(i, stack, entity) >= 1.0F && isCharged(stack);
}
+ @io.papermc.paper.annotation.DoNotUse // Paper - Add EntityLoadCrossbowEvent
+ @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - Add EntityLoadCrossbowEvent
private static boolean tryLoadProjectiles(LivingEntity shooter, ItemStack crossbowStack) {
- List<ItemStack> list = draw(crossbowStack, shooter.getProjectile(crossbowStack), shooter);
+ // Paper start - Add EntityLoadCrossbowEvent
+ return CrossbowItem.tryLoadProjectiles(shooter, crossbowStack, true);
+ return tryLoadProjectiles(shooter, crossbowStack, true);
+ }
+
+ private static boolean tryLoadProjectiles(LivingEntity shooter, ItemStack crossbowStack, boolean consume) {
+ List<ItemStack> list = draw(crossbowStack, shooter.getProjectile(crossbowStack), shooter, consume);
+ // Paper end - Add EntityLoadCrossbowEvent
if (!list.isEmpty()) {
crossbowStack.set(DataComponents.CHARGED_PROJECTILES, ChargedProjectiles.of(list));
return true;
@@ -164,7 +_,11 @@
@@ -141,7 +_,11 @@
@Override
protected Projectile createProjectile(Level level, LivingEntity shooter, ItemStack weapon, ItemStack ammo, boolean isCrit) {
if (ammo.is(Items.FIREWORK_ROCKET)) {
@@ -45,3 +30,19 @@
} else {
Projectile projectile = super.createProjectile(level, shooter, weapon, ammo, isCrit);
if (projectile instanceof AbstractArrow abstractArrow) {
@@ -211,7 +_,14 @@
);
}
- if (f >= 1.0F && !isCharged(stack) && tryLoadProjectiles(livingEntity, stack)) {
+ if (f >= 1.0F && !isCharged(stack)) {
+ // Paper start - Add EntityLoadCrossbowEvent
+ final io.papermc.paper.event.entity.EntityLoadCrossbowEvent event = new io.papermc.paper.event.entity.EntityLoadCrossbowEvent(livingEntity.getBukkitLivingEntity(), stack.asBukkitMirror(), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(livingEntity.getUsedItemHand()));
+ if (!event.callEvent() || !tryLoadProjectiles(livingEntity, stack, event.shouldConsumeItem()) || !event.shouldConsumeItem()) {
+ if (livingEntity instanceof ServerPlayer player) player.containerMenu.sendAllDataToRemote();
+ return;
+ }
+ // Paper end - Add EntityLoadCrossbowEvent
chargingSounds.end()
.ifPresent(
sound -> level.playSound(

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/item/EggItem.java
+++ b/net/minecraft/world/item/EggItem.java
@@ -23,22 +_,36 @@
@@ -23,22 +_,35 @@
@Override
public InteractionResult use(Level level, Player player, InteractionHand hand) {
ItemStack itemInHand = player.getItemInHand(hand);
@@ -14,19 +14,20 @@
- 0.5F,
- 0.4F / (level.getRandom().nextFloat() * 0.4F + 0.8F)
- );
if (level instanceof ServerLevel serverLevel) {
- Projectile.spawnProjectileFromRotation(ThrownEgg::new, serverLevel, itemInHand, player, 0.0F, PROJECTILE_SHOOT_POWER, 1.0F);
+ // CraftBukkit start
+ // Paper start - PlayerLaunchProjectileEvent
+ final Projectile.Delayed<ThrownEgg> thrownEgg = Projectile.spawnProjectileFromRotationDelayed(ThrownEgg::new, serverLevel, itemInHand, player, 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) player.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemInHand), (org.bukkit.entity.Projectile) thrownEgg.projectile().getBukkitEntity());
+ if (event.callEvent() && thrownEgg.attemptSpawn()) {
+ if (event.shouldConsume()) {
+ itemInHand.consume(1, player);
+ } else {
+ player.containerMenu.sendAllDataToRemote();
+ }
+ level.playSound(
- if (level instanceof ServerLevel serverLevel) {
- Projectile.spawnProjectileFromRotation(ThrownEgg::new, serverLevel, itemInHand, player, 0.0F, 1.5F, 1.0F);
- }
+ // Paper start
+ final Projectile.Delayed<ThrownEgg> thrownEgg = Projectile.spawnProjectileFromRotationDelayed(ThrownEgg::new, (ServerLevel) level, itemInHand, player, 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) player.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemInHand), (org.bukkit.entity.Projectile) thrownEgg.projectile().getBukkitEntity());
+ if (event.callEvent() && thrownEgg.attemptSpawn()) {
+ if (event.shouldConsume()) {
+ itemInHand.consume(1, player);
+ } else {
+ player.containerMenu.sendAllDataToRemote();
+ }
+ level.playSound(
+ // Paper end
+ null,
+ player.getX(),
+ player.getY(),
@@ -35,19 +36,18 @@
+ SoundSource.PLAYERS,
+ 0.5F,
+ 0.4F / (level.getRandom().nextFloat() * 0.4F + 0.8F)
+ );
+ player.awardStat(Stats.ITEM_USED.get(this));
+ } else {
+ // Paper end - PlayerLaunchProjectileEvent
+ player.containerMenu.sendAllDataToRemote();
+ return InteractionResult.FAIL;
+ }
+ // CraftBukkit end
}
-
+ );
+ // Paper - move up
- player.awardStat(Stats.ITEM_USED.get(this));
- itemInHand.consume(1, player);
+ // Paper - PlayerLaunchProjectileEvent - moved up
+ player.awardStat(Stats.ITEM_USED.get(this));
+ // Paper start
+ } else {
+ player.containerMenu.sendAllDataToRemote();
+ return InteractionResult.FAIL;
+ }
+ // CraftBukkit end
return InteractionResult.SUCCESS;
}

View File

@@ -5,7 +5,7 @@
return InteractionResult.FAIL;
} else {
- BlockPos blockPos = clickedPos.above();
+ BlockPos blockPos = clickedPos.above(); final BlockPos aboveBlockPosition = blockPos; // Paper - OBFHELPER
+ BlockPos blockPos = clickedPos.above(); final BlockPos aboveBlockPos = blockPos; // Paper - OBFHELPER
if (!level.isEmptyBlock(blockPos)) {
return InteractionResult.FAIL;
} else {
@@ -24,7 +24,7 @@
EndDragonFight dragonFight = ((ServerLevel)level).getDragonFight();
if (dragonFight != null) {
- dragonFight.tryRespawn();
+ dragonFight.tryRespawn(aboveBlockPosition); // Paper - Perf: Do crystal-portal proximity check before entity lookup
+ dragonFight.tryRespawn(aboveBlockPos); // Paper - Perf: Do crystal-portal proximity check before entity lookup
}
}

View File

@@ -3,7 +3,7 @@
@@ -42,6 +_,11 @@
return InteractionResult.SUCCESS;
} else {
BlockState blockState1 = blockState.setValue(EndPortalFrameBlock.HAS_EYE, Boolean.valueOf(true));
BlockState blockState1 = blockState.setValue(EndPortalFrameBlock.HAS_EYE, true);
+ // Paper start
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(context.getPlayer(), clickedPos, blockState1)) {
+ return InteractionResult.PASS;
@@ -12,7 +12,7 @@
Block.pushEntitiesUp(blockState, blockState1, level, clickedPos);
level.setBlock(clickedPos, blockState1, 2);
level.updateNeighbourForOutputSignal(clickedPos, Blocks.END_PORTAL_FRAME);
@@ -57,7 +_,27 @@
@@ -59,7 +_,27 @@
}
}
@@ -41,7 +41,7 @@
}
return InteractionResult.SUCCESS;
@@ -87,7 +_,11 @@
@@ -89,7 +_,11 @@
eyeOfEnder.setItem(itemInHand);
eyeOfEnder.signalTo(blockPos);
level.gameEvent(GameEvent.PROJECTILE_SHOOT, eyeOfEnder.position(), GameEvent.Context.of(player));

View File

@@ -27,5 +27,5 @@
+ }
+ // CraftBukkit end
this.playSound(level, clickedPos);
level.setBlockAndUpdate(clickedPos, blockState.setValue(BlockStateProperties.LIT, Boolean.valueOf(true)));
level.setBlockAndUpdate(clickedPos, blockState.setValue(BlockStateProperties.LIT, true));
level.gameEvent(context.getPlayer(), GameEvent.BLOCK_CHANGE, clickedPos);

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/item/FireworkRocketItem.java
+++ b/net/minecraft/world/item/FireworkRocketItem.java
@@ -33,7 +_,7 @@
@@ -29,7 +_,7 @@
ItemStack itemInHand = context.getItemInHand();
Vec3 clickLocation = context.getClickLocation();
Direction clickedFace = context.getClickedFace();
@@ -9,7 +9,7 @@
new FireworkRocketEntity(
level,
context.getPlayer(),
@@ -43,9 +_,14 @@
@@ -39,9 +_,14 @@
itemInHand
),
serverLevel,
@@ -26,7 +26,7 @@
}
return InteractionResult.SUCCESS;
@@ -56,9 +_,21 @@
@@ -52,9 +_,21 @@
if (player.isFallFlying()) {
ItemStack itemInHand = player.getItemInHand(hand);
if (level instanceof ServerLevel serverLevel) {

View File

@@ -5,7 +5,7 @@
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
+ int i = player.fishing.retrieve(itemInHand, hand); // Paper - Add hand parameter to PlayerFishEvent
itemInHand.hurtAndBreak(i, player, LivingEntity.getSlotForHand(hand));
}

View File

@@ -24,5 +24,5 @@
+ }
+ // 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.setBlock(clickedPos, blockState.setValue(BlockStateProperties.LIT, true), 11);
level.gameEvent(player, GameEvent.BLOCK_CHANGE, clickedPos);

View File

@@ -1,16 +1,16 @@
--- a/net/minecraft/world/item/HangingEntityItem.java
+++ b/net/minecraft/world/item/HangingEntityItem.java
@@ -66,6 +_,20 @@
@@ -62,6 +_,20 @@
EntityType.<HangingEntity>createDefaultStackConfig(level, itemInHand, player).accept(hangingEntity);
if (hangingEntity.survives()) {
if (!level.isClientSide) {
+ // CraftBukkit start - fire HangingPlaceEvent
+ org.bukkit.entity.Player who = player == null ? null : (org.bukkit.entity.Player) player.getBukkitEntity();
+ org.bukkit.entity.Player bukkitPlayer = player == null ? null : (org.bukkit.entity.Player) player.getBukkitEntity();
+ org.bukkit.block.Block blockClicked = org.bukkit.craftbukkit.block.CraftBlock.at(level, blockPos);
+ 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));
+ org.bukkit.event.hanging.HangingPlaceEvent event = new org.bukkit.event.hanging.HangingPlaceEvent((org.bukkit.entity.Hanging) hangingEntity.getBukkitEntity(), bukkitPlayer, blockClicked, blockFace, hand, org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(itemInHand));
+ level.getCraftServer().getPluginManager().callEvent(event);
+
+ if (event.isCancelled()) {

View File

@@ -1,45 +1,29 @@
--- a/net/minecraft/world/item/ItemStack.java
+++ b/net/minecraft/world/item/ItemStack.java
@@ -136,18 +_,35 @@
} else {
Holder<Item> 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
}
}
@@ -198,12 +_,20 @@
@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());
+ buffer.writeVarInt(io.papermc.paper.util.ItemComponentSanitizer.sanitizeCount(io.papermc.paper.util.ItemObfuscationSession.currentSession(), value, value.getCount())); // Paper - potentially sanitize count
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 (final io.papermc.paper.util.SafeAutoClosable ignored = io.papermc.paper.util.ItemObfuscationSession.withContext(c -> c.itemStack(value))) { // pass the itemstack as context to the obfuscation session
+ 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
@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());
+ buffer.writeVarInt(io.papermc.paper.util.sanitizer.ItemComponentSanitizer.sanitizeCount(io.papermc.paper.util.sanitizer.ItemObfuscationSession.currentSession(), value, value.getCount())); // Paper - potentially sanitize count
Item.STREAM_CODEC.encode(buffer, value.getItemHolder());
+ // Paper start - adventure; conditionally render translatable components
+ boolean prev = net.minecraft.network.chat.ComponentSerialization.DONT_RENDER_TRANSLATABLES.get();
+ try (final io.papermc.paper.util.SafeAutoClosable ignored = io.papermc.paper.util.sanitizer.ItemObfuscationSession.withContext(c -> c.itemStack(value))) { // pass the itemstack as context to the obfuscation session
+ net.minecraft.network.chat.ComponentSerialization.DONT_RENDER_TRANSLATABLES.set(true);
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 +_,171 @@
};
@@ -373,10 +_,167 @@
return InteractionResult.PASS;
} else {
Item item = this.getItem();
@@ -90,10 +74,10 @@
+ this.restorePatch(newPatch);
+ this.setCount(newCount);
+ }
+ for (org.bukkit.craftbukkit.block.CraftBlockState blockstate : blocks) {
+ for (org.bukkit.craftbukkit.block.CraftBlockState snapshot : 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
+ snapshot.place(snapshot.getFlags());
+ serverLevel.checkCapturedTreeStateForObserverNotify(clickedPos, snapshot); // Paper - notify observers even if grow failed
+ }
+ player.awardStat(Stats.ITEM_USED.get(item)); // SPIGOT-7236 - award stat
+ }
@@ -109,24 +93,20 @@
+ List<org.bukkit.block.BlockState> blocks = new java.util.ArrayList<>(serverLevel.capturedBlockStates.values());
+ serverLevel.capturedBlockStates.clear();
+ if (blocks.size() > 1) {
+ placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockMultiPlaceEvent(serverLevel, player, hand, blocks, clickedPos.getX(), clickedPos.getY(), clickedPos.getZ());
+ placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockMultiPlaceEvent(serverLevel, player, hand, blocks, clickedPos);
+ } 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, hand, blocks.getFirst(), clickedPos.getX(), clickedPos.getY(), clickedPos.getZ());
+ placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPlaceEvent(serverLevel, player, hand, blocks.getFirst(), clickedPos);
+ }
+
+ if (placeEvent != null && (placeEvent.isCancelled() || !placeEvent.canBuild())) {
+ interactionResult = InteractionResult.FAIL; // cancel placement
+ // PAIL: Remove this when MC-99075 fixed
+ placeEvent.getPlayer().updateInventory();
+ player.containerMenu.sendAllDataToRemote();
+ 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);
+ ((org.bukkit.craftbukkit.block.CraftBlockState) blockstate).revertPlace();
+ }
+ serverLevel.isBlockPlaceCancelled = false; // Paper - prevent calling cleanup logic when undoing a block place upon a cancelled BlockPlaceEvent
+ serverLevel.preventPoiUpdated = false;
+
+ SignItem.openSign = null; // SPIGOT-6758 - Reset on early return
+ } else {
@@ -141,7 +121,7 @@
+ }
+
+ for (org.bukkit.block.BlockState blockstate : blocks) {
+ int updateFlag = ((org.bukkit.craftbukkit.block.CraftBlockState) blockstate).getFlag();
+ int updateFlags = ((org.bukkit.craftbukkit.block.CraftBlockState) blockstate).getFlags();
+ net.minecraft.world.level.block.state.BlockState oldBlock = ((org.bukkit.craftbukkit.block.CraftBlockState) blockstate).getHandle();
+ BlockPos newPos = ((org.bukkit.craftbukkit.block.CraftBlockState) blockstate).getPosition();
+ net.minecraft.world.level.block.state.BlockState block = serverLevel.getBlockState(newPos);
@@ -150,7 +130,7 @@
+ block.onPlace(serverLevel, newPos, oldBlock, true, context);
+ }
+
+ serverLevel.notifyAndUpdatePhysics(newPos, null, oldBlock, block, serverLevel.getBlockState(newPos), updateFlag, net.minecraft.world.level.block.Block.UPDATE_LIMIT); // send null chunk as chunk.k() returns false by this point
+ serverLevel.notifyAndUpdatePhysics(newPos, null, oldBlock, block, serverLevel.getBlockState(newPos), updateFlags, net.minecraft.world.level.block.Block.UPDATE_LIMIT); // 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
@@ -183,25 +163,25 @@
+ }
+ }
+
+ // SPIGOT-7315: Moved from BlockBed#setPlacedBy
+ // SPIGOT-7315: Moved from BedBlock#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);
+ BlockPos pos = ((org.bukkit.craftbukkit.block.CraftBlock) placeEvent.getBlock()).getPosition();
+ net.minecraft.world.level.block.state.BlockState state = serverLevel.getBlockState(pos);
+
+ 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);
+ if (state.getBlock() instanceof net.minecraft.world.level.block.BedBlock) {
+ serverLevel.updateNeighborsAt(pos, net.minecraft.world.level.block.Blocks.AIR);
+ state.updateNeighbourShapes(serverLevel, pos, 3);
+ }
+ }
+
+ // SPIGOT-1288 - play sound stripped from ItemBlock
+ // SPIGOT-1288 - play sound stripped from BlockItem
+ 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();
+ BlockPos pos = new net.minecraft.world.item.context.BlockPlaceContext(context).getClickedPos();
+ net.minecraft.world.level.block.state.BlockState state = serverLevel.getBlockState(pos);
+ net.minecraft.world.level.block.SoundType soundType = state.getSoundType();
+ // Paper end - Fix spigot sound playing for BlockItem ItemStacks
+ serverLevel.playSound(player, clickedPos, soundeffecttype.getPlaceSound(), net.minecraft.sounds.SoundSource.BLOCKS, (soundeffecttype.getVolume() + 1.0F) / 2.0F, soundeffecttype.getPitch() * 0.8F);
+ serverLevel.playSound(player, clickedPos, soundType.getPlaceSound(), net.minecraft.sounds.SoundSource.BLOCKS, (soundType.getVolume() + 1.0F) / 2.0F, soundType.getPitch() * 0.8F);
+ }
+
+ player.awardStat(Stats.ITEM_USED.get(item));
@@ -213,7 +193,7 @@
return interactionResult;
}
@@ -469,31 +_,70 @@
@@ -473,31 +_,71 @@
return this.isDamageableItem() && this.getDamageValue() >= this.getMaxDamage() - 1;
}
@@ -224,6 +204,7 @@
+ // Paper start - add force boolean overload
+ this.hurtAndBreak(damage, level, player, onBreak, false);
+ }
+
+ public void hurtAndBreak(int damage, ServerLevel level, @Nullable LivingEntity player, Consumer<Item> onBreak, boolean force) { // Paper - Add EntityDamageItemEvent
+ // Paper end
+ final int originalDamage = damage; // Paper - Expand PlayerItemDamageEvent
@@ -234,7 +215,7 @@
+ event.getPlayer().getServer().getPluginManager().callEvent(event);
+
+ if (i != event.getDamage() || event.isCancelled()) {
+ event.getPlayer().updateInventory();
+ serverPlayer.containerMenu.sendAllDataToRemote();
+ }
+ if (event.isCancelled()) {
+ return;
@@ -292,7 +273,7 @@
this.shrink(1);
onBreak.accept(item);
}
@@ -506,15 +_,39 @@
@@ -510,15 +_,39 @@
return;
}
@@ -334,7 +315,7 @@
);
}
}
@@ -715,6 +_,12 @@
@@ -732,6 +_,12 @@
return this.getItem().useOnRelease(this);
}
@@ -345,35 +326,38 @@
+ // CraftBukkit end
+
@Nullable
public <T> T set(DataComponentType<? super T> component, @Nullable T value) {
public <T> T set(DataComponentType<T> component, @Nullable T value) {
return this.components.set(component, value);
@@ -748,6 +_,25 @@
}
@@ -779,6 +_,28 @@
this.getItem().verifyComponentsAfterLoad(this);
}
+ // 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;
+
+ private @Nullable 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);
+ if (this.bukkitStack == null || this.bukkitStack.handle != this) {
+ this.bukkitStack = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(this);
+ }
+ return bukkitStack;
+ return this.bukkitStack;
+ }
+ // Paper end
+
public void applyComponents(DataComponentPatch components) {
this.components.applyPatch(components);
this.getItem().verifyComponentsAfterLoad(this);
@@ -1016,6 +_,19 @@
public Component getHoverName() {
Component customName = this.getCustomName();
return customName != null ? customName : this.getItemName();
@@ -1054,6 +_,19 @@
EnchantmentHelper.forEachModifier(this, equipmentSLot, action);
}
@@ -393,7 +377,7 @@
public Component getDisplayName() {
MutableComponent mutableComponent = Component.empty().append(this.getHoverName());
if (this.has(DataComponents.CUSTOM_NAME)) {
@@ -1072,7 +_,7 @@
@@ -1109,7 +_,7 @@
}
public void consume(int amount, @Nullable LivingEntity entity) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/item/LingeringPotionItem.java
+++ b/net/minecraft/world/item/LingeringPotionItem.java
@@ -24,6 +_,10 @@
@@ -19,6 +_,10 @@
@Override
public InteractionResult use(Level level, Player player, InteractionHand hand) {
@@ -11,11 +11,12 @@
level.playSound(
null,
player.getX(),
@@ -34,6 +_,6 @@
@@ -29,7 +_,7 @@
0.5F,
0.4F / (level.getRandom().nextFloat() * 0.4F + 0.8F)
);
- return super.use(level, player, hand);
+ return wrapper; // Paper - PlayerLaunchProjectileEvent
}
}
@Override

View File

@@ -1,9 +1,9 @@
--- a/net/minecraft/world/item/MaceItem.java
+++ b/net/minecraft/world/item/MaceItem.java
@@ -61,7 +_,13 @@
@@ -52,7 +_,13 @@
@Override
public boolean hurtEnemy(ItemStack stack, LivingEntity target, LivingEntity attacker) {
public void hurtEnemy(ItemStack stack, LivingEntity target, LivingEntity attacker) {
- if (canSmashAttack(attacker)) {
+ // Paper start - Add EntityAttemptSmashAttackEvent
+ final boolean canSmashAttack = canSmashAttack(attacker);
@@ -15,7 +15,7 @@
ServerLevel serverLevel = (ServerLevel)attacker.level();
attacker.setDeltaMovement(attacker.getDeltaMovement().with(Direction.Axis.Y, 0.01F));
if (attacker instanceof ServerPlayer serverPlayer) {
@@ -139,7 +_,7 @@
@@ -127,7 +_,7 @@
double knockbackPower = getKnockbackPower(attacker, livingEntity, vec3);
Vec3 vec31 = vec3.normalize().scale(knockbackPower);
if (knockbackPower > 0.0) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/item/MapItem.java
+++ b/net/minecraft/world/item/MapItem.java
@@ -99,8 +_,8 @@
@@ -97,8 +_,8 @@
int i9 = (i1 / i + i6 - 64) * i;
int i10 = (i2 / i + i7 - 64) * i;
Multiset<MapColor> multiset = LinkedHashMultiset.create();
@@ -11,7 +11,7 @@
int i11 = 0;
double d1 = 0.0;
if (level.dimensionType().hasCeiling()) {
@@ -207,7 +_,7 @@
@@ -205,7 +_,7 @@
for (int i5 = 0; i5 < 128; i5++) {
for (int i6 = 0; i6 < 128; i6++) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/item/MobBucketItem.java
+++ b/net/minecraft/world/item/MobBucketItem.java
@@ -58,7 +_,7 @@
@@ -50,7 +_,7 @@
}
if (mob != null) {

View File

@@ -2,7 +2,7 @@
+++ b/net/minecraft/world/item/NameTagItem.java
@@ -18,8 +_,14 @@
Component component = stack.get(DataComponents.CUSTOM_NAME);
if (component != null && target.getType().canSerialize() && target.canBeNameTagged()) {
if (component != null && target.getType().canSerialize()) {
if (!player.level().isClientSide && target.isAlive()) {
- target.setCustomName(component);
- if (target instanceof Mob mob) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/item/PotionItem.java
+++ b/net/minecraft/world/item/PotionItem.java
@@ -42,6 +_,12 @@
@@ -41,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)) {

View File

@@ -27,7 +27,7 @@
+ itemStack
+ ).isRemoved()) {
+ if (shooter instanceof net.minecraft.server.level.ServerPlayer serverPlayer) {
+ serverPlayer.getBukkitEntity().updateInventory();
+ serverPlayer.containerMenu.sendAllDataToRemote();
+ }
+ return;
+ }

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/item/ShovelItem.java
+++ b/net/minecraft/world/item/ShovelItem.java
@@ -46,20 +_,29 @@
@@ -45,20 +_,29 @@
Player player = context.getPlayer();
BlockState blockState1 = FLATTENABLES.get(blockState.getBlock());
BlockState blockState2 = null;
@@ -17,7 +17,7 @@
CampfireBlock.dowse(context.getPlayer(), level, clickedPos, blockState);
+ }; // Paper
blockState2 = blockState.setValue(CampfireBlock.LIT, Boolean.valueOf(false));
blockState2 = blockState.setValue(CampfireBlock.LIT, false);
}
if (blockState2 != null) {

View File

@@ -8,12 +8,12 @@
EntityType<?> type = this.getType(level.registryAccess(), itemInHand);
spawner.setEntityId(type, level.getRandom());
level.sendBlockUpdated(clickedPos, blockState, blockState, 3);
@@ -169,7 +_,7 @@
return Optional.empty();
@@ -170,7 +_,7 @@
} else {
breedOffspring.moveTo(pos.x(), pos.y(), pos.z(), 0.0F, 0.0F);
breedOffspring.snapTo(pos.x(), pos.y(), pos.z(), 0.0F, 0.0F);
breedOffspring.applyComponentsFromItemStack(stack);
- 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);
}

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/item/SplashPotionItem.java
+++ b/net/minecraft/world/item/SplashPotionItem.java
@@ -14,6 +_,10 @@
@@ -19,6 +_,10 @@
@Override
public InteractionResult use(Level level, Player player, InteractionHand hand) {
@@ -11,11 +11,12 @@
level.playSound(
null,
player.getX(),
@@ -24,6 +_,6 @@
@@ -29,7 +_,7 @@
0.5F,
0.4F / (level.getRandom().nextFloat() * 0.4F + 0.8F)
);
- return super.use(level, player, hand);
+ return wrapper; // Paper - PlayerLaunchProjectileEvent
}
}
@Override

View File

@@ -1,12 +1,12 @@
--- a/net/minecraft/world/item/ThrowablePotionItem.java
+++ b/net/minecraft/world/item/ThrowablePotionItem.java
@@ -22,11 +_,25 @@
@@ -23,11 +_,24 @@
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(this::createPotion, serverLevel, itemInHand, player, -20.0F, PROJECTILE_SHOOT_POWER, 1.0F);
+ // Paper start - PlayerLaunchProjectileEvent
+ final Projectile.Delayed<ThrownPotion> thrownPotion = Projectile.spawnProjectileFromRotationDelayed(ThrownPotion::new, serverLevel, itemInHand, player, -20.0F, PROJECTILE_SHOOT_POWER, 1.0F);
+ final Projectile.Delayed<AbstractThrownPotion> thrownPotion = Projectile.spawnProjectileFromRotationDelayed(this::createPotion, serverLevel, itemInHand, player, -20.0F, 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) thrownPotion.projectile().getBukkitEntity());
+ if (event.callEvent() && thrownPotion.attemptSpawn()) {
+ if (event.shouldConsume()) {
@@ -14,8 +14,6 @@
+ } else {
+ player.containerMenu.sendAllDataToRemote();
+ }
+
+ player.awardStat(Stats.ITEM_USED.get(this));
+ } else {
+ player.containerMenu.sendAllDataToRemote();
+ return InteractionResult.FAIL;
@@ -23,7 +21,7 @@
+ // Paper end - PlayerLaunchProjectileEvent
}
- player.awardStat(Stats.ITEM_USED.get(this));
player.awardStat(Stats.ITEM_USED.get(this));
- itemInHand.consume(1, player);
+ // Paper - PlayerLaunchProjectileEvent - move up
return InteractionResult.SUCCESS;

View File

@@ -1,15 +1,17 @@
--- a/net/minecraft/world/item/TridentItem.java
+++ b/net/minecraft/world/item/TridentItem.java
@@ -87,19 +_,35 @@
@@ -79,18 +_,39 @@
.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) {
- ItemStack itemStack = stack.consumeAndReturn(1, player);
- ThrownTrident thrownTrident = Projectile.spawnProjectileFromRotation(
+ Projectile.Delayed<ThrownTrident> tridentDelayed = Projectile.spawnProjectileFromRotationDelayed( // Paper - PlayerLaunchProjectileEvent
ThrownTrident::new, serverLevel, stack, player, 0.0F, 2.5F, 1.0F
+ ItemStack itemStack = stack.copyWithCount(1); // Paper
+ Projectile.Delayed<ThrownTrident> tridentDelayed = Projectile.spawnProjectileFromRotationDelayed( // Paper - PlayerLaunchProjectileEvent(
ThrownTrident::new, serverLevel, itemStack, 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());
@@ -20,14 +22,16 @@
+ return false;
+ }
+ ThrownTrident thrownTrident = tridentDelayed.projectile(); // Paper - PlayerLaunchProjectileEvent
+ if (event.shouldConsume()) stack.hurtWithoutBreaking(1, player); // Paper - PlayerLaunchProjectileEvent
+ if (event.shouldConsume()) {
+ stack.hurtWithoutBreaking(1, player); // Paper - PlayerLaunchProjectileEvent
+ }
+ thrownTrident.pickupItemStack = stack.copy(); // SPIGOT-4511 update since damage call moved
+ if (event.shouldConsume()) {
+ stack.consume(1, player);
+ }
+ // 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);
@@ -39,7 +43,7 @@
}
}
@@ -113,6 +_,7 @@
@@ -104,6 +_,7 @@
f *= tridentSpinAttackStrength / squareRoot;
f1 *= tridentSpinAttackStrength / squareRoot;
f2 *= tridentSpinAttackStrength / squareRoot;

View File

@@ -1,11 +0,0 @@
--- 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);

View File

@@ -1,11 +1,11 @@
--- a/net/minecraft/world/item/alchemy/PotionContents.java
+++ b/net/minecraft/world/item/alchemy/PotionContents.java
@@ -158,7 +_,7 @@
if (mobEffectInstance.getEffect().value().isInstantenous()) {
mobEffectInstance.getEffect().value().applyInstantenousEffect(serverLevel, player1, player1, entity, mobEffectInstance.getAmplifier(), 1.0);
if (effect.getEffect().value().isInstantenous()) {
effect.getEffect().value().applyInstantenousEffect(serverLevel, player1, player1, entity, effect.getAmplifier(), 1.0);
} else {
- entity.addEffect(mobEffectInstance);
+ entity.addEffect(mobEffectInstance, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.POTION_DRINK); // CraftBukkit
- entity.addEffect(effect);
+ entity.addEffect(effect, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.POTION_DRINK); // CraftBukkit
}
});
}, durationScale);
}

View File

@@ -0,0 +1,18 @@
--- a/net/minecraft/world/item/component/BlocksAttacks.java
+++ b/net/minecraft/world/item/component/BlocksAttacks.java
@@ -86,10 +_,14 @@
);
}
- public void disable(ServerLevel level, LivingEntity entity, float duration, ItemStack stack) {
+ public void disable(ServerLevel level, LivingEntity entity, float duration, ItemStack stack, LivingEntity attacker) { // Paper
int i = this.disableBlockingForTicks(duration);
if (i > 0) {
if (entity instanceof Player player) {
+ // Paper start
+ final io.papermc.paper.event.player.PlayerShieldDisableEvent shieldDisableEvent = new io.papermc.paper.event.player.PlayerShieldDisableEvent((org.bukkit.entity.Player) player.getBukkitEntity(), attacker.getBukkitEntity(), i);
+ if (!shieldDisableEvent.callEvent()) return;
+ // Paper end
player.getCooldowns().addCooldown(stack, i);
}

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/item/component/ChargedProjectiles.java
+++ b/net/minecraft/world/item/component/ChargedProjectiles.java
@@ -16,6 +_,7 @@
@@ -22,6 +_,7 @@
.xmap(ChargedProjectiles::new, chargedProjectiles -> chargedProjectiles.items);
public static final StreamCodec<RegistryFriendlyByteBuf, ChargedProjectiles> STREAM_CODEC = ItemStack.STREAM_CODEC
.apply(ByteBufCodecs.list())

View File

@@ -1,13 +1,13 @@
--- a/net/minecraft/world/item/component/CustomData.java
+++ b/net/minecraft/world/item/component/CustomData.java
@@ -34,7 +_,17 @@
@@ -33,7 +_,17 @@
private static final Logger LOGGER = LogUtils.getLogger();
public static final CustomData EMPTY = new CustomData(new CompoundTag());
private static final String TYPE_TAG = "id";
- public static final Codec<CustomData> CODEC = Codec.withAlternative(CompoundTag.CODEC, TagParser.AS_CODEC)
- public static final Codec<CustomData> CODEC = Codec.withAlternative(CompoundTag.CODEC, TagParser.FLATTENED_CODEC)
+ // Paper start - Item serialization as json
+ public static ThreadLocal<Boolean> SERIALIZE_CUSTOM_AS_SNBT = ThreadLocal.withInitial(() -> false);
+ public static final Codec<CustomData> CODEC = Codec.either(CompoundTag.CODEC, TagParser.AS_CODEC)
+ public static final Codec<CustomData> CODEC = Codec.either(CompoundTag.CODEC, TagParser.FLATTENED_CODEC)
+ .xmap(com.mojang.datafixers.util.Either::unwrap, data -> { // Both will be used for deserialization, but we decide which one to use for serialization
+ if (!SERIALIZE_CUSTOM_AS_SNBT.get()) {
+ return com.mojang.datafixers.util.Either.left(data); // First codec
@@ -15,7 +15,7 @@
+ return com.mojang.datafixers.util.Either.right(data); // Second codec
+ }
+ })
+ // Paper end - Item serialization as json
+ // Paper end - Item serialization as json
.xmap(CustomData::new, customData -> customData.tag);
public static final Codec<CustomData> CODEC_WITH_ID = CODEC.validate(
data -> data.getUnsafe().contains("id", 8) ? DataResult.success(data) : DataResult.error(() -> "Missing id for entity in: " + data)
data -> data.getUnsafe().getString("id").isPresent() ? DataResult.success(data) : DataResult.error(() -> "Missing id for entity in: " + data)

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/item/component/ItemContainerContents.java
+++ b/net/minecraft/world/item/component/ItemContainerContents.java
@@ -22,6 +_,7 @@
@@ -28,6 +_,7 @@
.xmap(ItemContainerContents::fromSlots, ItemContainerContents::asSlots);
public static final StreamCodec<RegistryFriendlyByteBuf, ItemContainerContents> STREAM_CODEC = ItemStack.OPTIONAL_STREAM_CODEC
.apply(ByteBufCodecs.list(256))

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/item/component/OminousBottleAmplifier.java
+++ b/net/minecraft/world/item/component/OminousBottleAmplifier.java
@@ -28,8 +_,15 @@
@@ -29,8 +_,15 @@
@Override
public void onConsume(Level level, LivingEntity entity, ItemStack stack, Consumable consumable) {
@@ -17,4 +17,4 @@
+ // Paper end - properly resend entities - collect packets for bundle
@Override
public void addToTooltip(Item.TooltipContext context, Consumer<Component> tooltipAdder, TooltipFlag tooltipFlag) {
public void addToTooltip(Item.TooltipContext context, Consumer<Component> tooltipAdder, TooltipFlag flag, DataComponentGetter componentGetter) {

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/item/component/SuspiciousStewEffects.java
+++ b/net/minecraft/world/item/component/SuspiciousStewEffects.java
@@ -41,6 +_,15 @@
@@ -42,6 +_,15 @@
}
}
@@ -14,5 +14,5 @@
+ // CraftBukkit end
+
@Override
public void addToTooltip(Item.TooltipContext context, Consumer<Component> tooltipAdder, TooltipFlag tooltipFlag) {
if (tooltipFlag.isCreative()) {
public void addToTooltip(Item.TooltipContext context, Consumer<Component> tooltipAdder, TooltipFlag flag, DataComponentGetter componentGetter) {
if (flag.isCreative()) {

View File

@@ -0,0 +1,11 @@
--- a/net/minecraft/world/item/component/WrittenBookContent.java
+++ b/net/minecraft/world/item/component/WrittenBookContent.java
@@ -94,7 +_,7 @@
public static boolean resolveForItem(ItemStack stack, CommandSourceStack source, @Nullable Player player) {
WrittenBookContent writtenBookContent = stack.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(source, player);
if (writtenBookContent1 != null) {
stack.set(DataComponents.WRITTEN_BOOK_CONTENT, writtenBookContent1);

View File

@@ -1,6 +1,6 @@
--- a/net/minecraft/world/item/crafting/Recipe.java
+++ b/net/minecraft/world/item/crafting/Recipe.java
@@ -44,4 +_,6 @@
@@ -46,4 +_,6 @@
}
RecipeBookCategory recipeBookCategory();

View File

@@ -1,32 +1,31 @@
--- a/net/minecraft/world/item/crafting/SmithingTransformRecipe.java
+++ b/net/minecraft/world/item/crafting/SmithingTransformRecipe.java
@@ -21,8 +_,15 @@
final ItemStack result;
final TransmuteResult result;
@Nullable
private PlacementInfo placementInfo;
+ final boolean copyDataComponents; // Paper - Option to prevent data components copy
public SmithingTransformRecipe(Optional<Ingredient> template, Optional<Ingredient> base, Optional<Ingredient> addition, ItemStack result) {
+ // Paper start - Option to prevent data components copy
public SmithingTransformRecipe(Optional<Ingredient> template, Ingredient base, Optional<Ingredient> addition, TransmuteResult result) {
+ // Paper start - Option to prevent data components copy
+ this(template, base, addition, result, true);
+ }
+ public SmithingTransformRecipe(Optional<Ingredient> template, Optional<Ingredient> base, Optional<Ingredient> addition, ItemStack result, boolean copyDataComponents) {
+ public SmithingTransformRecipe(Optional<Ingredient> template, Ingredient base, Optional<Ingredient> addition, TransmuteResult result, boolean copyDataComponents) {
+ this.copyDataComponents = copyDataComponents;
+ // Paper end - Option to prevent data components copy
+ // Paper end - Option to prevent data components copy
this.template = template;
this.base = base;
this.addition = addition;
@@ -32,7 +_,9 @@
@@ -31,7 +_,7 @@
@Override
public ItemStack assemble(SmithingRecipeInput input, HolderLookup.Provider registries) {
ItemStack itemStack = input.base().transmuteCopy(this.result.getItem(), this.result.getCount());
+ if (this.copyDataComponents) { // Paper - Option to prevent data components copy
itemStack.applyComponents(this.result.getComponentsPatch());
+ } // Paper - Option to prevent data components copy
return itemStack;
- return this.result.apply(input.base());
+ return this.result.apply(input.base(), this.copyDataComponents); // Paper - Option to prevent data components copy
}
@@ -77,6 +_,17 @@
@Override
@@ -75,6 +_,17 @@
)
);
}
@@ -34,7 +33,7 @@
+ // CraftBukkit start
+ @Override
+ public org.bukkit.inventory.Recipe toBukkitRecipe(org.bukkit.NamespacedKey id) {
+ org.bukkit.craftbukkit.inventory.CraftItemStack result = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(this.result);
+ org.bukkit.craftbukkit.inventory.CraftItemStack result = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(new ItemStack(this.result.item(), this.result.count(), this.result.components()));
+
+ org.bukkit.craftbukkit.inventory.CraftSmithingTransformRecipe recipe = new org.bukkit.craftbukkit.inventory.CraftSmithingTransformRecipe(id, result, org.bukkit.craftbukkit.inventory.CraftRecipe.toBukkit(this.template), org.bukkit.craftbukkit.inventory.CraftRecipe.toBukkit(this.base), org.bukkit.craftbukkit.inventory.CraftRecipe.toBukkit(this.addition), this.copyDataComponents); // Paper - Option to prevent data components copy
+

View File

@@ -1,48 +1,48 @@
--- a/net/minecraft/world/item/crafting/SmithingTrimRecipe.java
+++ b/net/minecraft/world/item/crafting/SmithingTrimRecipe.java
@@ -27,8 +_,15 @@
final Optional<Ingredient> addition;
@@ -28,8 +_,15 @@
final Holder<TrimPattern> pattern;
@Nullable
private PlacementInfo placementInfo;
+ final boolean copyDataComponents; // Paper - Option to prevent data components copy
public SmithingTrimRecipe(Optional<Ingredient> template, Optional<Ingredient> base, Optional<Ingredient> addition) {
public SmithingTrimRecipe(Ingredient template, Ingredient base, Ingredient addition, Holder<TrimPattern> pattern) {
+ // Paper start - Option to prevent data components copy
+ this(template, base, addition, true);
+ this(template, base, addition, pattern, true);
+ }
+ public SmithingTrimRecipe(Optional<Ingredient> template, Optional<Ingredient> base, Optional<Ingredient> addition, boolean copyDataComponents) {
+ public SmithingTrimRecipe(Ingredient template, Ingredient base, Ingredient addition, Holder<TrimPattern> pattern, final boolean copyDataComponents) {
+ this.copyDataComponents = copyDataComponents;
+ // Paper end - Option to prevent data components copy
this.template = template;
this.base = base;
this.addition = addition;
@@ -36,10 +_,15 @@
@@ -38,10 +_,15 @@
@Override
public ItemStack assemble(SmithingRecipeInput input, HolderLookup.Provider registries) {
- return applyTrim(registries, input.base(), input.addition(), input.template());
+ return applyTrim(registries, input.base(), input.addition(), input.template(), this.copyDataComponents); // Paper - Option to prevent data components copy
- return applyTrim(registries, input.base(), input.addition(), this.pattern);
+ return applyTrim(registries, input.base(), input.addition(), this.pattern, this.copyDataComponents); // Paper start - Option to prevent data components copy
}
public static ItemStack applyTrim(HolderLookup.Provider registries, ItemStack base, ItemStack addition, ItemStack template) {
+ // Paper start - Option to prevent data components copy
+ return applyTrim(registries, base, addition, template, true);
public static ItemStack applyTrim(HolderLookup.Provider registries, ItemStack base, ItemStack addition, Holder<TrimPattern> pattern) {
+ // Paper start - Option to prevent data components copy
+ return applyTrim(registries, base, addition, pattern, true);
+ }
+ public static ItemStack applyTrim(HolderLookup.Provider registries, ItemStack base, ItemStack addition, ItemStack template, boolean copyDataComponents) {
+ // Paper end - Option to prevent data components copy
Optional<Holder.Reference<TrimMaterial>> fromIngredient = TrimMaterials.getFromIngredient(registries, addition);
Optional<Holder.Reference<TrimPattern>> fromTemplate = TrimPatterns.getFromTemplate(registries, template);
if (fromIngredient.isPresent() && fromTemplate.isPresent()) {
@@ -47,7 +_,7 @@
if (armorTrim != null && armorTrim.hasPatternAndMaterial(fromTemplate.get(), fromIngredient.get())) {
+ public static ItemStack applyTrim(HolderLookup.Provider registries, ItemStack base, ItemStack addition, Holder<TrimPattern> pattern, final boolean copyDataComponents) {
+ // Paper end - Option to prevent data components copy
Optional<Holder<TrimMaterial>> fromIngredient = TrimMaterials.getFromIngredient(registries, addition);
if (fromIngredient.isPresent()) {
ArmorTrim armorTrim = base.get(DataComponents.TRIM);
@@ -49,7 +_,7 @@
if (Objects.equals(armorTrim, armorTrim1)) {
return ItemStack.EMPTY;
} else {
- ItemStack itemStack = base.copyWithCount(1);
+ ItemStack itemStack = copyDataComponents ? base.copyWithCount(1) : new ItemStack(base.getItem(), 1); // Paper - Option to prevent data components copy
itemStack.set(DataComponents.TRIM, new ArmorTrim(fromIngredient.get(), fromTemplate.get()));
itemStack.set(DataComponents.TRIM, armorTrim1);
return itemStack;
}
@@ -100,6 +_,13 @@
@@ -102,6 +_,13 @@
)
);
}
@@ -50,7 +50,7 @@
+ // CraftBukkit start
+ @Override
+ public org.bukkit.inventory.Recipe toBukkitRecipe(org.bukkit.NamespacedKey id) {
+ return new org.bukkit.craftbukkit.inventory.CraftSmithingTrimRecipe(id, org.bukkit.craftbukkit.inventory.CraftRecipe.toBukkit(this.template), org.bukkit.craftbukkit.inventory.CraftRecipe.toBukkit(this.base), org.bukkit.craftbukkit.inventory.CraftRecipe.toBukkit(this.addition), this.copyDataComponents); // Paper - Option to prevent data components copy
+ return new org.bukkit.craftbukkit.inventory.CraftSmithingTrimRecipe(id, org.bukkit.craftbukkit.inventory.CraftRecipe.toBukkit(this.template), org.bukkit.craftbukkit.inventory.CraftRecipe.toBukkit(this.base), org.bukkit.craftbukkit.inventory.CraftRecipe.toBukkit(this.addition), org.bukkit.craftbukkit.inventory.trim.CraftTrimPattern.minecraftHolderToBukkit(this.pattern), this.copyDataComponents); // Paper - Option to prevent data components copy
+ }
+ // CraftBukkit end

View File

@@ -1,13 +1,13 @@
--- a/net/minecraft/world/item/crafting/TransmuteRecipe.java
+++ b/net/minecraft/world/item/crafting/TransmuteRecipe.java
@@ -88,6 +_,13 @@
@@ -85,6 +_,13 @@
);
}
+ // CraftBukkit start
+ @Override
+ public org.bukkit.inventory.Recipe toBukkitRecipe(org.bukkit.NamespacedKey id) {
+ return new org.bukkit.craftbukkit.inventory.CraftTransmuteRecipe(id, org.bukkit.craftbukkit.inventory.CraftItemType.minecraftToBukkit(this.result.value()), org.bukkit.craftbukkit.inventory.CraftRecipe.toBukkit(this.input), org.bukkit.craftbukkit.inventory.CraftRecipe.toBukkit(this.material));
+ return new org.bukkit.craftbukkit.inventory.CraftTransmuteRecipe(id, org.bukkit.craftbukkit.inventory.CraftItemType.minecraftToBukkit(this.result.item().value()), org.bukkit.craftbukkit.inventory.CraftRecipe.toBukkit(this.input), org.bukkit.craftbukkit.inventory.CraftRecipe.toBukkit(this.material));
+ }
+ // CraftBukkit end
+

View File

@@ -0,0 +1,17 @@
--- a/net/minecraft/world/item/crafting/TransmuteResult.java
+++ b/net/minecraft/world/item/crafting/TransmuteResult.java
@@ -45,8 +_,13 @@
}
public ItemStack apply(ItemStack stack) {
+ // Paper start - Option to prevent data components copy
+ return apply(stack, true);
+ }
+ public ItemStack apply(ItemStack stack, boolean applyComponents) {
+ // Paper end - Option to prevent data components copy
ItemStack itemStack = stack.transmuteCopy(this.item.value(), this.count);
- itemStack.applyComponents(this.components);
+ if (applyComponents) itemStack.applyComponents(this.components); // Paper - Option to prevent data components copy
return itemStack;
}

View File

@@ -1,54 +1,41 @@
--- a/net/minecraft/world/item/enchantment/ItemEnchantments.java
+++ b/net/minecraft/world/item/enchantment/ItemEnchantments.java
@@ -28,10 +_,19 @@
@@ -28,21 +_,24 @@
import net.minecraft.world.item.component.TooltipProvider;
public class ItemEnchantments implements TooltipProvider {
- public static final ItemEnchantments EMPTY = new ItemEnchantments(new Object2IntOpenHashMap<>(), true);
+ // Paper start
+ private static final java.util.Comparator<Holder<Enchantment>> ENCHANTMENT_ORDER = java.util.Comparator.comparing(Holder::getRegisteredName);
+ public static final ItemEnchantments EMPTY = new ItemEnchantments(new it.unimi.dsi.fastutil.objects.Object2IntAVLTreeMap<>(ENCHANTMENT_ORDER), true);
+ // Paper end
private static final Codec<Integer> LEVEL_CODEC = Codec.intRange(1, 255);
- private static final Codec<Object2IntOpenHashMap<Holder<Enchantment>>> LEVELS_CODEC = Codec.unboundedMap(Enchantment.CODEC, LEVEL_CODEC)
- .xmap(Object2IntOpenHashMap::new, Function.identity());
- public static final ItemEnchantments EMPTY = new ItemEnchantments(new Object2IntOpenHashMap<>());
+ // Paper start - sort enchantments
+ private static final Codec<it.unimi.dsi.fastutil.objects.Object2IntAVLTreeMap<Holder<Enchantment>>> LEVELS_CODEC = Codec.unboundedMap(Enchantment.CODEC, LEVEL_CODEC)
+ .xmap(m -> {
+ final it.unimi.dsi.fastutil.objects.Object2IntAVLTreeMap<Holder<Enchantment>> map = new it.unimi.dsi.fastutil.objects.Object2IntAVLTreeMap<>(ENCHANTMENT_ORDER);
+ map.putAll(m);
+ return map;
+ }, Function.identity());
+ private static final java.util.Comparator<Holder<Enchantment>> ENCHANTMENT_ORDER = java.util.Comparator.comparing(Holder::getRegisteredName);
+ public static final ItemEnchantments EMPTY = new ItemEnchantments(new it.unimi.dsi.fastutil.objects.Object2IntAVLTreeMap<>(ENCHANTMENT_ORDER));
+ // Paper end - sort enchantments
private static final Codec<ItemEnchantments> FULL_CODEC = RecordCodecBuilder.create(
instance -> instance.group(
LEVELS_CODEC.fieldOf("levels").forGetter(itemEnchantments -> itemEnchantments.enchantments),
@@ -41,16 +_,16 @@
);
public static final Codec<ItemEnchantments> CODEC = Codec.withAlternative(FULL_CODEC, LEVELS_CODEC, map -> new ItemEnchantments(map, true));
private static final Codec<Integer> LEVEL_CODEC = Codec.intRange(1, 255);
public static final Codec<ItemEnchantments> CODEC = Codec.unboundedMap(Enchantment.CODEC, LEVEL_CODEC)
.xmap(
- map -> new ItemEnchantments(new Object2IntOpenHashMap<>((Map<? extends Holder<Enchantment>, ? extends Integer>)map)),
+ map -> new net.minecraft.world.item.enchantment.ItemEnchantments(net.minecraft.Util.make(new it.unimi.dsi.fastutil.objects.Object2IntAVLTreeMap<>(ENCHANTMENT_ORDER), m -> m.putAll(map))), // Paper - sort enchantments
itemEnchantments -> itemEnchantments.enchantments
);
public static final StreamCodec<RegistryFriendlyByteBuf, ItemEnchantments> STREAM_CODEC = StreamCodec.composite(
- ByteBufCodecs.map(Object2IntOpenHashMap::new, Enchantment.STREAM_CODEC, ByteBufCodecs.VAR_INT),
+ ByteBufCodecs.map((v) -> new it.unimi.dsi.fastutil.objects.Object2IntAVLTreeMap<>(ENCHANTMENT_ORDER), Enchantment.STREAM_CODEC, ByteBufCodecs.VAR_INT), // Paper
itemEnchantments -> itemEnchantments.enchantments,
ByteBufCodecs.BOOL,
itemEnchantments -> itemEnchantments.showInTooltip,
ItemEnchantments::new
);
- final Object2IntOpenHashMap<Holder<Enchantment>> enchantments;
+ final it.unimi.dsi.fastutil.objects.Object2IntAVLTreeMap<Holder<Enchantment>> enchantments; // Paper
public final boolean showInTooltip;
- ItemEnchantments(Object2IntOpenHashMap<Holder<Enchantment>> enchantments, boolean showInTooltip) {
+ ItemEnchantments(it.unimi.dsi.fastutil.objects.Object2IntAVLTreeMap<Holder<Enchantment>> enchantments, boolean showInTooltip) { // Paper
- ItemEnchantments(Object2IntOpenHashMap<Holder<Enchantment>> enchantments) {
+ ItemEnchantments(it.unimi.dsi.fastutil.objects.Object2IntAVLTreeMap<Holder<Enchantment>> enchantments) { // Paper
this.enchantments = enchantments;
this.showInTooltip = showInTooltip;
@@ -139,7 +_,7 @@
for (Entry<Holder<Enchantment>> entry : enchantments.object2IntEntrySet()) {
@@ -120,7 +_,7 @@
}
public static class Mutable {
- private final Object2IntOpenHashMap<Holder<Enchantment>> enchantments = new Object2IntOpenHashMap<>();
+ private final it.unimi.dsi.fastutil.objects.Object2IntAVLTreeMap<Holder<Enchantment>> enchantments = new it.unimi.dsi.fastutil.objects.Object2IntAVLTreeMap<>(ENCHANTMENT_ORDER); // Paper
public boolean showInTooltip;
public Mutable(ItemEnchantments enchantments) {
this.enchantments.putAll(enchantments.enchantments);

View File

@@ -5,7 +5,7 @@
BlockPos blockPos = BlockPos.containing(origin).offset(this.offset);
if (this.predicate.map(blockPredicate -> blockPredicate.test(level, blockPos)).orElse(true)
- && level.setBlockAndUpdate(blockPos, this.blockState.getState(entity.getRandom(), blockPos))) {
+ && org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(level, blockPos, this.blockState.getState(entity.getRandom(), blockPos), entity)) { // CraftBukkit - Call EntityBlockFormEvent
+ && org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(level, blockPos, this.blockState.getState(entity.getRandom(), blockPos), 3, entity, true)) { // CraftBukkit - Call EntityBlockFormEvent
this.triggerGameEvent.ifPresent(holder -> level.gameEvent(entity, (Holder<GameEvent>)holder, blockPos));
}
}

View File

@@ -5,7 +5,7 @@
if (blockPos1.distToCenterSqr(origin.x(), blockPos1.getY() + 0.5, origin.z()) < Mth.square(i)
&& this.predicate.map(predicate -> predicate.test(level, blockPos1)).orElse(true)
- && level.setBlockAndUpdate(blockPos1, this.blockState.getState(random, blockPos1))) {
+ && org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(level, blockPos1, this.blockState.getState(random, blockPos1), entity)) { // CraftBukkit - Call EntityBlockFormEvent for Frost Walker
+ && org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(level, blockPos1, this.blockState.getState(random, blockPos1), 3, entity, true)) { // CraftBukkit - Call EntityBlockFormEvent for Frost Walker
this.triggerGameEvent.ifPresent(event -> level.gameEvent(entity, (Holder<GameEvent>)event, blockPos1));
}
}

View File

@@ -1,10 +1,11 @@
--- a/net/minecraft/world/item/trading/Merchant.java
+++ b/net/minecraft/world/item/trading/Merchant.java
@@ -19,6 +_,7 @@
@@ -19,6 +_,8 @@
void overrideOffers(MerchantOffers offers);
+ default void processTrade(MerchantOffer merchantRecipe, @Nullable io.papermc.paper.event.player.PlayerPurchaseEvent event) { this.notifyTrade(merchantRecipe); } // Paper
+ default void processTrade(MerchantOffer offer, @Nullable io.papermc.paper.event.player.PlayerPurchaseEvent event) { this.notifyTrade(offer); } // Paper
+
void notifyTrade(MerchantOffer offer);
void notifyTradeUpdated(ItemStack stack);

View File

@@ -1,9 +1,9 @@
--- a/net/minecraft/world/item/trading/MerchantOffer.java
+++ b/net/minecraft/world/item/trading/MerchantOffer.java
@@ -21,6 +_,7 @@
Codec.INT.lenientOptionalFieldOf("demand", Integer.valueOf(0)).forGetter(merchantOffer -> merchantOffer.demand),
Codec.FLOAT.lenientOptionalFieldOf("priceMultiplier", Float.valueOf(0.0F)).forGetter(merchantOffer -> merchantOffer.priceMultiplier),
Codec.INT.lenientOptionalFieldOf("xp", Integer.valueOf(1)).forGetter(merchantOffer -> merchantOffer.xp)
Codec.INT.lenientOptionalFieldOf("demand", 0).forGetter(merchantOffer -> merchantOffer.demand),
Codec.FLOAT.lenientOptionalFieldOf("priceMultiplier", 0.0F).forGetter(merchantOffer -> merchantOffer.priceMultiplier),
Codec.INT.lenientOptionalFieldOf("xp", 1).forGetter(merchantOffer -> merchantOffer.xp)
+ , Codec.BOOL.lenientOptionalFieldOf("Paper.IgnoreDiscounts", false).forGetter(merchantOffer -> merchantOffer.ignoreDiscounts) // Paper
)
.apply(instance, MerchantOffer::new)