From 9346db284445325f06bf3a0933c8f14e400dc16d Mon Sep 17 00:00:00 2001 From: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Date: Sun, 15 Dec 2024 15:26:23 +0100 Subject: [PATCH] readd blockitem diff --- .../minecraft/world/item/BlockItem.java.patch | 107 ++++++++++++++++-- 1 file changed, 96 insertions(+), 11 deletions(-) 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 index 1814a4c1bb..dddf4b93f2 100644 --- a/paper-server/patches/sources/net/minecraft/world/item/BlockItem.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/BlockItem.java.patch @@ -1,13 +1,98 @@ --- 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; +@@ -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 @@ + return InteractionResult.FAIL; + } else { + BlockState placementState = this.getPlacementState(blockPlaceContext); ++ // CraftBukkit start - special case for handling block placement with water lilies and snow buckets ++ org.bukkit.block.BlockState bukkitState = null; ++ if (this instanceof PlaceOnWaterBlockItem || this instanceof SolidBucketItem) { ++ bukkitState = org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(blockPlaceContext.getLevel(), blockPlaceContext.getClickedPos()); ++ } ++ final org.bukkit.block.BlockState oldBukkitState = bukkitState != null ? bukkitState : org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(blockPlaceContext.getLevel(), blockPlaceContext.getClickedPos()); // Paper - Reset placed block on exception ++ // CraftBukkit end ++ + if (placementState == null) { + return InteractionResult.FAIL; + } else if (!this.placeBlock(blockPlaceContext, placementState)) { +@@ -71,15 +_,40 @@ + BlockState blockState = level.getBlockState(clickedPos); + if (blockState.is(placementState.getBlock())) { + blockState = this.updateBlockStateFromTag(clickedPos, level, itemInHand, blockState); ++ // Paper start - Reset placed block on exception ++ try { + this.updateCustomBlockEntityTag(clickedPos, level, player, itemInHand, blockState); + updateBlockEntityComponents(level, clickedPos, itemInHand); ++ } catch (Exception ex) { ++ oldBukkitState.update(true, false); ++ 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"); ++ return InteractionResult.FAIL; ++ } ++ throw ex; // Rethrow exception if not placed by a player ++ } ++ // Paper end - Reset placed block on exception + 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()); ++ if (placeEvent != null && (placeEvent.isCancelled() || !placeEvent.canBuild())) { ++ bukkitState.update(true, false); ++ ++ // Paper - if the event is called here, the inventory should be updated ++ player.containerMenu.sendAllDataToRemote(); // SPIGOT-4541 ++ return InteractionResult.FAIL; ++ } ++ } ++ // CraftBukkit end + if (player instanceof ServerPlayer) { + CriteriaTriggers.PLACED_BLOCK.trigger((ServerPlayer)player, clickedPos, itemInHand); + } + } + + SoundType soundType = blockState.getSoundType(); ++ if (player == null) // Paper - Fix block place logic; reintroduce this for the dispenser (i.e the shulker) + level.playSound( + player, + clickedPos, +@@ -140,8 +_,16 @@ + 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); ++ // 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 ++ 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 ++ world.getCraftServer().getPluginManager().callEvent(event); ++ ++ return event.isBuildable(); ++ // CraftBukkit end + } + + protected boolean mustSurvive() { +@@ -170,7 +_,7 @@ + return false; + } + +- if (!type.onlyOpCanSetNbt() || player != null && player.canUseGameMasterBlocks()) { ++ if (!type.onlyOpCanSetNbt() || player != null && (player.canUseGameMasterBlocks() || (player.getAbilities().instabuild && player.getBukkitEntity().hasPermission("minecraft.nbt.place")))) { // Spigot - add permission + return customData.loadInto(blockEntity, level.registryAccess()); + } +