diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/AbstractCandleBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/AbstractCandleBlock.java.patch new file mode 100644 index 0000000000..978c35863e --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/AbstractCandleBlock.java.patch @@ -0,0 +1,14 @@ +--- a/net/minecraft/world/level/block/AbstractCandleBlock.java ++++ b/net/minecraft/world/level/block/AbstractCandleBlock.java +@@ -44,6 +_,11 @@ + @Override + protected void onProjectileHit(Level level, BlockState state, BlockHitResult hit, Projectile projectile) { + if (!level.isClientSide && projectile.isOnFire() && this.canBeLit(state)) { ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(level, hit.getBlockPos(), projectile).isCancelled()) { ++ return; ++ } ++ // CraftBukkit end + setLit(level, state, hit.getBlockPos(), true); + } + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/AbstractCauldronBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/AbstractCauldronBlock.java.patch new file mode 100644 index 0000000000..506f6551ef --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/AbstractCauldronBlock.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/level/block/AbstractCauldronBlock.java ++++ b/net/minecraft/world/level/block/AbstractCauldronBlock.java +@@ -58,7 +_,7 @@ + ItemStack stack, BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hitResult + ) { + CauldronInteraction cauldronInteraction = this.interactions.map().get(stack.getItem()); +- return cauldronInteraction.interact(state, level, pos, player, hand, stack); ++ return cauldronInteraction.interact(state, level, pos, player, hand, stack, hitResult.getDirection()); // Paper - pass hit direction + } + + @Override diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/AnvilBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/AnvilBlock.java.patch similarity index 62% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/AnvilBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/AnvilBlock.java.patch index 81462ca698..8701c8ba8c 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/AnvilBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/AnvilBlock.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/world/level/block/AnvilBlock.java +++ b/net/minecraft/world/level/block/AnvilBlock.java -@@ -62,8 +62,9 @@ +@@ -62,8 +_,9 @@ @Override - protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { - if (!world.isClientSide) { -- player.openMenu(state.getMenuProvider(world, pos)); -+ if (player.openMenu(state.getMenuProvider(world, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation + protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) { + if (!level.isClientSide) { +- player.openMenu(state.getMenuProvider(level, pos)); ++ if (player.openMenu(state.getMenuProvider(level, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation player.awardStat(Stats.INTERACT_WITH_ANVIL); + } // Paper - Fix InventoryOpenEvent cancellation } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/BambooSaplingBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/BambooSaplingBlock.java.patch new file mode 100644 index 0000000000..df4b06991a --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/BambooSaplingBlock.java.patch @@ -0,0 +1,19 @@ +--- a/net/minecraft/world/level/block/BambooSaplingBlock.java ++++ b/net/minecraft/world/level/block/BambooSaplingBlock.java +@@ -43,7 +_,7 @@ + + @Override + protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { +- if (random.nextInt(3) == 0 && level.isEmptyBlock(pos.above()) && level.getRawBrightness(pos.above(), 0) >= 9) { ++ if (random.nextFloat() < (level.spigotConfig.bambooModifier / (100.0f * 3)) && level.isEmptyBlock(pos.above()) && level.getRawBrightness(pos.above(), 0) >= 9) { // Spigot - SPIGOT-7159: Better modifier resolution + this.growBamboo(level, pos); + } + } +@@ -99,6 +_,6 @@ + } + + protected void growBamboo(Level level, BlockPos state) { +- level.setBlock(state.above(), Blocks.BAMBOO.defaultBlockState().setValue(BambooStalkBlock.LEAVES, BambooLeaves.SMALL), 3); ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, state, state.above(), Blocks.BAMBOO.defaultBlockState().setValue(BambooStalkBlock.LEAVES, BambooLeaves.SMALL), 3); // CraftBukkit - BlockSpreadEvent + } + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/BambooStalkBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/BambooStalkBlock.java.patch new file mode 100644 index 0000000000..8560405814 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/BambooStalkBlock.java.patch @@ -0,0 +1,87 @@ +--- a/net/minecraft/world/level/block/BambooStalkBlock.java ++++ b/net/minecraft/world/level/block/BambooStalkBlock.java +@@ -130,9 +_,9 @@ + @Override + protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { + if (state.getValue(STAGE) == 0) { +- if (random.nextInt(3) == 0 && level.isEmptyBlock(pos.above()) && level.getRawBrightness(pos.above(), 0) >= 9) { ++ if (random.nextFloat() < (level.spigotConfig.bambooModifier / (100.0f * 3)) && level.isEmptyBlock(pos.above()) && level.getRawBrightness(pos.above(), 0) >= 9) { // Spigot - SPIGOT-7159: Better modifier resolution + int i = this.getHeightBelowUpToMax(level, pos) + 1; +- if (i < 16) { ++ if (i < level.paperConfig().maxGrowthHeight.bamboo.max) { // Paper - Configurable cactus/bamboo/reed growth height + this.growBamboo(state, level, pos, random, i); + } + } +@@ -168,7 +_,7 @@ + public boolean isValidBonemealTarget(LevelReader level, BlockPos pos, BlockState state) { + int heightAboveUpToMax = this.getHeightAboveUpToMax(level, pos); + int heightBelowUpToMax = this.getHeightBelowUpToMax(level, pos); +- return heightAboveUpToMax + heightBelowUpToMax + 1 < 16 && level.getBlockState(pos.above(heightAboveUpToMax)).getValue(STAGE) != 1; ++ return heightAboveUpToMax + heightBelowUpToMax + 1 < ((Level) level).paperConfig().maxGrowthHeight.bamboo.max && level.getBlockState(pos.above(heightAboveUpToMax)).getValue(STAGE) != 1; // Paper - Configurable cactus/bamboo/reed growth height + } + + @Override +@@ -186,7 +_,7 @@ + for (int i2 = 0; i2 < i1; i2++) { + BlockPos blockPos = pos.above(heightAboveUpToMax); + BlockState blockState = level.getBlockState(blockPos); +- if (i >= 16 || blockState.getValue(STAGE) == 1 || !level.isEmptyBlock(blockPos.above())) { ++ if (i >= level.paperConfig().maxGrowthHeight.bamboo.max || !blockState.is(Blocks.BAMBOO) || blockState.getValue(BambooStalkBlock.STAGE) == 1 || !level.isEmptyBlock(blockPos.above())) { // CraftBukkit - If the BlockSpreadEvent was cancelled, we have no bamboo here // Paper - Configurable cactus/bamboo/reed growth height + return; + } + +@@ -206,29 +_,38 @@ + BlockPos blockPos = pos.below(2); + BlockState blockState1 = level.getBlockState(blockPos); + BambooLeaves bambooLeaves = BambooLeaves.NONE; ++ boolean shouldUpdateOthers = false; // CraftBukkit + if (age >= 1) { + if (!blockState.is(Blocks.BAMBOO) || blockState.getValue(LEAVES) == BambooLeaves.NONE) { + bambooLeaves = BambooLeaves.SMALL; + } else if (blockState.is(Blocks.BAMBOO) && blockState.getValue(LEAVES) != BambooLeaves.NONE) { + bambooLeaves = BambooLeaves.LARGE; + if (blockState1.is(Blocks.BAMBOO)) { +- level.setBlock(pos.below(), blockState.setValue(LEAVES, BambooLeaves.SMALL), 3); +- level.setBlock(blockPos, blockState1.setValue(LEAVES, BambooLeaves.NONE), 3); ++ // CraftBukkit start - moved down ++ // world.setBlock(blockposition.below(), (IBlockData) iblockdata1.setValue(BlockBamboo.LEAVES, BlockPropertyBambooSize.SMALL), 3); ++ // world.setBlock(blockposition1, (IBlockData) iblockdata2.setValue(BlockBamboo.LEAVES, BlockPropertyBambooSize.NONE), 3); ++ shouldUpdateOthers = true; ++ // CraftBukkit end + } + } + } + + int i = state.getValue(AGE) != 1 && !blockState1.is(Blocks.BAMBOO) ? 0 : 1; +- int i1 = (age < 11 || !(random.nextFloat() < 0.25F)) && age != 15 ? 0 : 1; +- level.setBlock( +- pos.above(), this.defaultBlockState().setValue(AGE, Integer.valueOf(i)).setValue(LEAVES, bambooLeaves).setValue(STAGE, Integer.valueOf(i1)), 3 +- ); ++ int i1 = (age < level.paperConfig().maxGrowthHeight.bamboo.min || random.nextFloat() >= 0.25F) && age != (level.paperConfig().maxGrowthHeight.bamboo.max - 1) ? 0 : 1; // Paper - Configurable cactus/bamboo/reed growth height ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, pos, pos.above(), this.defaultBlockState().setValue(net.minecraft.world.level.block.BambooStalkBlock.AGE, i).setValue(BambooStalkBlock.LEAVES, bambooLeaves).setValue(net.minecraft.world.level.block.BambooStalkBlock.STAGE, i1), 3)) { ++ if (shouldUpdateOthers) { ++ level.setBlock(pos.below(), blockState.setValue(BambooStalkBlock.LEAVES, BambooLeaves.SMALL), 3); ++ level.setBlock(blockPos, blockState1.setValue(BambooStalkBlock.LEAVES, BambooLeaves.NONE), 3); ++ } ++ } ++ // CraftBukkit end + } + + protected int getHeightAboveUpToMax(BlockGetter level, BlockPos pos) { + int i = 0; + +- while (i < 16 && level.getBlockState(pos.above(i + 1)).is(Blocks.BAMBOO)) { ++ while (i < ((Level) level).paperConfig().maxGrowthHeight.bamboo.max && level.getBlockState(pos.above(i + 1)).is(Blocks.BAMBOO)) { // Paper - Configurable cactus/bamboo/reed growth height + i++; + } + +@@ -238,7 +_,7 @@ + protected int getHeightBelowUpToMax(BlockGetter level, BlockPos pos) { + int i = 0; + +- while (i < 16 && level.getBlockState(pos.below(i + 1)).is(Blocks.BAMBOO)) { ++ while (i < ((Level) level).paperConfig().maxGrowthHeight.bamboo.max && level.getBlockState(pos.below(i + 1)).is(Blocks.BAMBOO)) { // Paper - Configurable cactus/bamboo/reed growth height + i++; + } + diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/BarrelBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/BarrelBlock.java.patch similarity index 73% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/BarrelBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/BarrelBlock.java.patch index 349f801388..23b0b9718c 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/BarrelBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/BarrelBlock.java.patch @@ -1,12 +1,12 @@ --- a/net/minecraft/world/level/block/BarrelBlock.java +++ b/net/minecraft/world/level/block/BarrelBlock.java -@@ -41,8 +41,7 @@ +@@ -41,8 +_,7 @@ @Override - protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { -- if (world instanceof ServerLevel serverLevel && world.getBlockEntity(pos) instanceof BarrelBlockEntity barrelBlockEntity) { + protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) { +- if (level instanceof ServerLevel serverLevel && level.getBlockEntity(pos) instanceof BarrelBlockEntity barrelBlockEntity) { - player.openMenu(barrelBlockEntity); -+ if (world instanceof ServerLevel serverLevel && world.getBlockEntity(pos) instanceof BarrelBlockEntity barrelBlockEntity && player.openMenu(barrelBlockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation ++ if (level instanceof ServerLevel serverLevel && level.getBlockEntity(pos) instanceof BarrelBlockEntity barrelBlockEntity && player.openMenu(barrelBlockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation player.awardStat(Stats.OPEN_BARREL); PiglinAi.angerNearbyPiglins(serverLevel, player, true); } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/BaseFireBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/BaseFireBlock.java.patch similarity index 56% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/BaseFireBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/BaseFireBlock.java.patch index aeae088ca7..aa29a091f9 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/BaseFireBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/BaseFireBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/BaseFireBlock.java +++ b/net/minecraft/world/level/block/BaseFireBlock.java -@@ -12,6 +12,7 @@ +@@ -12,6 +_,7 @@ import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.context.BlockPlaceContext; @@ -8,22 +8,23 @@ import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.state.BlockBehaviour; -@@ -127,6 +128,7 @@ +@@ -128,6 +_,8 @@ @Override - protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { -+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent + protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) { ++ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent ++ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent if (!entity.fireImmune()) { if (entity.getRemainingFireTicks() < 0) { entity.setRemainingFireTicks(entity.getRemainingFireTicks() + 1); -@@ -137,7 +139,18 @@ +@@ -137,7 +_,18 @@ } if (entity.getRemainingFireTicks() >= 0) { - entity.igniteForSeconds(8.0F); + // CraftBukkit start -+ org.bukkit.event.entity.EntityCombustEvent event = new org.bukkit.event.entity.EntityCombustByBlockEvent(org.bukkit.craftbukkit.block.CraftBlock.at(world, pos), entity.getBukkitEntity(), 8.0F); -+ world.getCraftServer().getPluginManager().callEvent(event); ++ org.bukkit.event.entity.EntityCombustEvent event = new org.bukkit.event.entity.EntityCombustByBlockEvent(org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), entity.getBukkitEntity(), 8.0F); ++ level.getCraftServer().getPluginManager().callEvent(event); + + if (!event.isCancelled()) { + entity.igniteForSeconds(event.getDuration(), false); @@ -36,41 +37,36 @@ } } -@@ -146,26 +159,26 @@ +@@ -146,24 +_,24 @@ } @Override -- protected void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) { -- if (!oldState.is(state.getBlock())) { -+ protected void onPlace(BlockState iblockdata, Level world, BlockPos blockposition, BlockState iblockdata1, boolean flag, UseOnContext context) { // CraftBukkit - context -+ if (!iblockdata1.is(iblockdata.getBlock())) { - if (BaseFireBlock.inPortalDimension(world)) { -- Optional optional = PortalShape.findEmptyPortalShape(world, pos, Direction.Axis.X); -+ Optional optional = PortalShape.findEmptyPortalShape(world, blockposition, Direction.Axis.X); - +- protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean isMoving) { ++ protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean isMoving, UseOnContext context) { // CraftBukkit - context + if (!oldState.is(state.getBlock())) { + if (inPortalDimension(level)) { + Optional optional = PortalShape.findEmptyPortalShape(level, pos, Direction.Axis.X); if (optional.isPresent()) { -- ((PortalShape) optional.get()).createPortalBlocks(world); -+ ((PortalShape) optional.get()).createPortalBlocks(world, (context == null) ? null : context.getPlayer()); // CraftBukkit - player +- optional.get().createPortalBlocks(level); ++ optional.get().createPortalBlocks(level, (context == null) ? null : context.getPlayer()); // CraftBukkit - player return; } } -- if (!state.canSurvive(world, pos)) { -- world.removeBlock(pos, false); -+ if (!iblockdata.canSurvive(world, blockposition)) { -+ this.fireExtinguished(world, blockposition); // CraftBukkit - fuel block broke + if (!state.canSurvive(level, pos)) { +- level.removeBlock(pos, false); ++ this.fireExtinguished(level, pos); // CraftBukkit - fuel block broke } - } } - private static boolean inPortalDimension(Level world) { -- return world.dimension() == Level.OVERWORLD || world.dimension() == Level.NETHER; -+ return world.getTypeKey() == net.minecraft.world.level.dimension.LevelStem.OVERWORLD || world.getTypeKey() == net.minecraft.world.level.dimension.LevelStem.NETHER; // CraftBukkit - getTypeKey() + private static boolean inPortalDimension(Level level) { +- return level.dimension() == Level.OVERWORLD || level.dimension() == Level.NETHER; ++ return level.getTypeKey() == net.minecraft.world.level.dimension.LevelStem.OVERWORLD || level.getTypeKey() == net.minecraft.world.level.dimension.LevelStem.NETHER; // CraftBukkit - getTypeKey() } @Override -@@ -213,4 +226,12 @@ +@@ -208,4 +_,12 @@ } } } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/BasePressurePlateBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/BasePressurePlateBlock.java.patch new file mode 100644 index 0000000000..2cada56fbe --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/BasePressurePlateBlock.java.patch @@ -0,0 +1,45 @@ +--- a/net/minecraft/world/level/block/BasePressurePlateBlock.java ++++ b/net/minecraft/world/level/block/BasePressurePlateBlock.java +@@ -81,6 +_,7 @@ + + @Override + protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) { ++ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent + if (!level.isClientSide) { + int signalForState = this.getSignalForState(state); + if (signalForState == 0) { +@@ -93,6 +_,19 @@ + int signalStrength = this.getSignalStrength(level, pos); + boolean flag = currentSignal > 0; + boolean flag1 = signalStrength > 0; ++ ++ // CraftBukkit start - Interact Pressure Plate ++ org.bukkit.World bworld = level.getWorld(); ++ org.bukkit.plugin.PluginManager manager = level.getCraftServer().getPluginManager(); ++ ++ if (flag != flag1) { ++ org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(bworld.getBlockAt(pos.getX(), pos.getY(), pos.getZ()), currentSignal, signalStrength); ++ manager.callEvent(eventRedstone); ++ ++ flag1 = eventRedstone.getNewCurrent() > 0; ++ signalStrength = eventRedstone.getNewCurrent(); ++ } ++ // CraftBukkit end + if (currentSignal != signalStrength) { + BlockState blockState = this.setSignalForState(state, signalStrength); + level.setBlock(pos, blockState, 2); +@@ -145,7 +_,13 @@ + } + + protected static int getEntityCount(Level level, AABB box, Class entityClass) { +- return level.getEntitiesOfClass(entityClass, box, EntitySelector.NO_SPECTATORS.and(entity -> !entity.isIgnoringBlockTriggers())).size(); ++ // CraftBukkit start ++ return BasePressurePlateBlock.getEntities(level, box, entityClass).size(); ++ } ++ ++ protected static java.util.List getEntities(Level level, AABB box, Class entityClass) { ++ return level.getEntitiesOfClass(entityClass, box, EntitySelector.NO_SPECTATORS.and(entity -> !entity.isIgnoringBlockTriggers())); ++ // CraftBukkit end + } + + protected abstract int getSignalStrength(Level level, BlockPos pos); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/BaseRailBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/BaseRailBlock.java.patch new file mode 100644 index 0000000000..d8e5440b15 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/BaseRailBlock.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/world/level/block/BaseRailBlock.java ++++ b/net/minecraft/world/level/block/BaseRailBlock.java +@@ -71,6 +_,7 @@ + state = this.updateDir(level, pos, state, true); + if (this.isStraight) { + level.neighborChanged(state, pos, this, null, movedByPiston); ++ state = level.getBlockState(pos); // Paper - Fix some rails connecting improperly + } + + return state; diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/BeaconBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/BeaconBlock.java.patch similarity index 69% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/BeaconBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/BeaconBlock.java.patch index b23b55da23..3a2da5d64c 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/BeaconBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/BeaconBlock.java.patch @@ -1,12 +1,12 @@ --- a/net/minecraft/world/level/block/BeaconBlock.java +++ b/net/minecraft/world/level/block/BeaconBlock.java -@@ -46,8 +46,7 @@ +@@ -46,8 +_,7 @@ @Override - protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { -- if (!world.isClientSide && world.getBlockEntity(pos) instanceof BeaconBlockEntity beaconBlockEntity) { + protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) { +- if (!level.isClientSide && level.getBlockEntity(pos) instanceof BeaconBlockEntity beaconBlockEntity) { - player.openMenu(beaconBlockEntity); -+ if (!world.isClientSide && world.getBlockEntity(pos) instanceof BeaconBlockEntity beaconBlockEntity && player.openMenu(beaconBlockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation ++ if (!level.isClientSide && level.getBlockEntity(pos) instanceof BeaconBlockEntity beaconBlockEntity && player.openMenu(beaconBlockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation player.awardStat(Stats.INTERACT_WITH_BEACON); } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/BedBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/BedBlock.java.patch similarity index 55% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/BedBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/BedBlock.java.patch index 09946b2d9f..dd115140b2 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/BedBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/BedBlock.java.patch @@ -1,21 +1,20 @@ --- a/net/minecraft/world/level/block/BedBlock.java +++ b/net/minecraft/world/level/block/BedBlock.java -@@ -95,7 +95,8 @@ +@@ -92,7 +_,7 @@ } } -- if (!BedBlock.canSetSpawn(world)) { -+ // CraftBukkit - moved world and biome check into EntityHuman -+ if (false && !BedBlock.canSetSpawn(world)) { - world.removeBlock(pos, false); - BlockPos blockposition1 = pos.relative(((Direction) state.getValue(BedBlock.FACING)).getOpposite()); - -@@ -108,25 +109,65 @@ - world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); +- if (!canSetSpawn(level)) { ++ if (false && !canSetSpawn(level)) { // CraftBukkit - moved world and biome check into EntityHuman + level.removeBlock(pos, false); + BlockPos blockPos = pos.relative(state.getValue(FACING).getOpposite()); + if (level.getBlockState(blockPos).is(this)) { +@@ -103,22 +_,63 @@ + level.explode(null, level.damageSources().badRespawnPointExplosion(center), null, center, 5.0F, true, Level.ExplosionInteraction.BLOCK); return InteractionResult.SUCCESS_SERVER; - } else if ((Boolean) state.getValue(BedBlock.OCCUPIED)) { -+ if (!BedBlock.canSetSpawn(world)) return this.explodeBed(state, world, pos); // Paper - check explode first - if (!this.kickVillagerOutOfBed(world, pos)) { + } else if (state.getValue(OCCUPIED)) { ++ if (!BedBlock.canSetSpawn(level)) return this.explodeBed(state, level, pos); // Paper - check explode first + if (!this.kickVillagerOutOfBed(level, pos)) { player.displayClientMessage(Component.translatable("block.minecraft.bed.occupied"), true); } @@ -25,10 +24,10 @@ + BlockState finaliblockdata = state; + BlockPos finalblockposition = pos; + // CraftBukkit end - player.startSleepInBed(pos).ifLeft((entityhuman_enumbedresult) -> { + player.startSleepInBed(pos).ifLeft(bedSleepingProblem -> { + // Paper start - PlayerBedFailEnterEvent -+ if (entityhuman_enumbedresult != null) { -+ io.papermc.paper.event.player.PlayerBedFailEnterEvent event = new io.papermc.paper.event.player.PlayerBedFailEnterEvent((org.bukkit.entity.Player) player.getBukkitEntity(), io.papermc.paper.event.player.PlayerBedFailEnterEvent.FailReason.values()[entityhuman_enumbedresult.ordinal()], org.bukkit.craftbukkit.block.CraftBlock.at(world, finalblockposition), !world.dimensionType().bedWorks(), io.papermc.paper.adventure.PaperAdventure.asAdventure(entityhuman_enumbedresult.getMessage())); ++ if (bedSleepingProblem != null) { ++ io.papermc.paper.event.player.PlayerBedFailEnterEvent event = new io.papermc.paper.event.player.PlayerBedFailEnterEvent((org.bukkit.entity.Player) player.getBukkitEntity(), io.papermc.paper.event.player.PlayerBedFailEnterEvent.FailReason.values()[bedSleepingProblem.ordinal()], org.bukkit.craftbukkit.block.CraftBlock.at(level, finalblockposition), !level.dimensionType().bedWorks(), io.papermc.paper.adventure.PaperAdventure.asAdventure(bedSleepingProblem.getMessage())); + if (!event.callEvent()) { + return; + } @@ -38,19 +37,18 @@ + this.explodeBed(finaliblockdata, world, finalblockposition); + } else + // CraftBukkit end - if (entityhuman_enumbedresult.getMessage() != null) { -- player.displayClientMessage(entityhuman_enumbedresult.getMessage(), true); + if (bedSleepingProblem.getMessage() != null) { + player.displayClientMessage(bedSleepingProblem.getMessage(), true); + final net.kyori.adventure.text.Component message = event.getMessage(); // Paper - PlayerBedFailEnterEvent + if (message != null) player.displayClientMessage(io.papermc.paper.adventure.PaperAdventure.asVanilla(message), true); // Paper - PlayerBedFailEnterEvent } + } // Paper - PlayerBedFailEnterEvent - }); return InteractionResult.SUCCESS_SERVER; -+ } -+ } -+ } -+ + } + } + } + + // CraftBukkit start + private InteractionResult explodeBed(BlockState iblockdata, Level world, BlockPos blockposition) { + { @@ -65,28 +63,25 @@ + + Vec3 vec3d = blockposition.getCenter(); + -+ world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, blockState), (ExplosionDamageCalculator) null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); // CraftBukkit - add state ++ world.explode(null, world.damageSources().badRespawnPointExplosion(vec3d, blockState), null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); // CraftBukkit - add state + return InteractionResult.SUCCESS; - } - } - } ++ } ++ } ++ } + // CraftBukkit end - - public static boolean canSetSpawn(Level world) { -- return world.dimensionType().bedWorks(); -+ return world.dimensionType().bedWorks(); // Paper - actually check if the bed works ++ + public static boolean canSetSpawn(Level level) { + return level.dimensionType().bedWorks(); } - - private boolean kickVillagerOutOfBed(Level world, BlockPos pos) { -@@ -320,6 +361,11 @@ - BlockPos blockposition1 = pos.relative((Direction) state.getValue(BedBlock.FACING)); - - world.setBlock(blockposition1, (BlockState) state.setValue(BedBlock.PART, BedPart.HEAD), 3); +@@ -311,6 +_,11 @@ + if (!level.isClientSide) { + BlockPos blockPos = pos.relative(state.getValue(FACING)); + level.setBlock(blockPos, state.setValue(PART, BedPart.HEAD), 3); + // CraftBukkit start - SPIGOT-7315: Don't updated if we capture block states -+ if (world.captureBlockStates) { ++ if (level.captureBlockStates) { + return; + } + // CraftBukkit end - world.blockUpdated(pos, Blocks.AIR); - state.updateNeighbourShapes(world, pos, 3); + level.blockUpdated(pos, Blocks.AIR); + state.updateNeighbourShapes(level, pos, 3); } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/BeehiveBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/BeehiveBlock.java.patch new file mode 100644 index 0000000000..221e36c665 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/BeehiveBlock.java.patch @@ -0,0 +1,60 @@ +--- a/net/minecraft/world/level/block/BeehiveBlock.java ++++ b/net/minecraft/world/level/block/BeehiveBlock.java +@@ -91,8 +_,8 @@ + } + + @Override +- public void playerDestroy(Level level, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity te, ItemStack stack) { +- super.playerDestroy(level, player, pos, state, te, stack); ++ public void playerDestroy(Level level, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity te, ItemStack stack, boolean includeDrops, boolean dropExp) { // Paper - fix drops not preventing stats/food exhaustion ++ super.playerDestroy(level, player, pos, state, te, stack, includeDrops, dropExp); // Paper - fix drops not preventing stats/food exhaustion + if (!level.isClientSide && te instanceof BeehiveBlockEntity beehiveBlockEntity) { + if (!EnchantmentHelper.hasTag(stack, EnchantmentTags.PREVENTS_BEE_SPAWNS_WHEN_MINING)) { + beehiveBlockEntity.emptyAllLivingFromHive(player, state, BeehiveBlockEntity.BeeReleaseStatus.EMERGENCY); +@@ -100,7 +_,7 @@ + this.angerNearbyBees(level, pos); + } + +- CriteriaTriggers.BEE_NEST_DESTROYED.trigger((ServerPlayer)player, state, stack, beehiveBlockEntity.getOccupantCount()); ++ // CriteriaTriggers.BEE_NEST_DESTROYED.trigger((ServerPlayer)player, state, stack, beehiveBlockEntity.getOccupantCount()); // Paper - Trigger bee_nest_destroyed trigger in the correct place; moved until after items are dropped + } + } + +@@ -122,14 +_,14 @@ + for (Bee bee : entitiesOfClass) { + if (bee.getTarget() == null) { + Player player = Util.getRandom(entitiesOfClass1, level.random); +- bee.setTarget(player); ++ bee.setTarget(player, org.bukkit.event.entity.EntityTargetEvent.TargetReason.CLOSEST_PLAYER, true); // CraftBukkit + } + } + } + } + + public static void dropHoneycomb(Level level, BlockPos pos) { +- popResource(level, pos, new ItemStack(Items.HONEYCOMB, 3)); ++ popResource(level, pos, new ItemStack(Items.HONEYCOMB, 3)); // Paper - Add PlayerShearBlockEvent; conflict on change, item needs to be set below + } + + @Override +@@ -141,8 +_,19 @@ + if (honeyLevelValue >= 5) { + Item item = stack.getItem(); + if (stack.is(Items.SHEARS)) { ++ // Paper start - Add PlayerShearBlockEvent ++ io.papermc.paper.event.block.PlayerShearBlockEvent event = new io.papermc.paper.event.block.PlayerShearBlockEvent((org.bukkit.entity.Player) player.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(stack), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand), new java.util.ArrayList<>()); ++ event.getDrops().add(org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(new ItemStack(Items.HONEYCOMB, 3))); ++ if (!event.callEvent()) { ++ return InteractionResult.PASS; ++ } ++ // Paper end + level.playSound(player, player.getX(), player.getY(), player.getZ(), SoundEvents.BEEHIVE_SHEAR, SoundSource.BLOCKS, 1.0F, 1.0F); +- dropHoneycomb(level, pos); ++ // Paper start - Add PlayerShearBlockEvent ++ for (org.bukkit.inventory.ItemStack itemDrop : event.getDrops()) { ++ popResource(level, pos, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(itemDrop)); ++ } ++ // Paper end - Add PlayerShearBlockEvent + stack.hurtAndBreak(1, player, LivingEntity.getSlotForHand(hand)); + flag = true; + level.gameEvent(player, GameEvent.SHEAR, pos); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/BellBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/BellBlock.java.patch new file mode 100644 index 0000000000..67deb9015b --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/BellBlock.java.patch @@ -0,0 +1,14 @@ +--- a/net/minecraft/world/level/block/BellBlock.java ++++ b/net/minecraft/world/level/block/BellBlock.java +@@ -142,6 +_,11 @@ + direction = level.getBlockState(pos).getValue(FACING); + } + ++ // CraftBukkit start ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBellRingEvent(level, pos, direction, entity)) { ++ return false; ++ } ++ // CraftBukkit end + ((BellBlockEntity)blockEntity).onHit(direction); + level.playSound(null, pos, SoundEvents.BELL_BLOCK, SoundSource.BLOCKS, 2.0F, 1.0F); + level.gameEvent(entity, GameEvent.BLOCK_CHANGE, pos); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/BigDripleafBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/BigDripleafBlock.java.patch new file mode 100644 index 0000000000..8f4e70e47f --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/BigDripleafBlock.java.patch @@ -0,0 +1,88 @@ +--- a/net/minecraft/world/level/block/BigDripleafBlock.java ++++ b/net/minecraft/world/level/block/BigDripleafBlock.java +@@ -136,7 +_,7 @@ + + @Override + protected void onProjectileHit(Level level, BlockState state, BlockHitResult hit, Projectile projectile) { +- this.setTiltAndScheduleTick(state, level, hit.getBlockPos(), Tilt.FULL, SoundEvents.BIG_DRIPLEAF_TILT_DOWN); ++ this.setTiltAndScheduleTick(state, level, hit.getBlockPos(), Tilt.FULL, SoundEvents.BIG_DRIPLEAF_TILT_DOWN, projectile); // CraftBukkit + } + + @Override +@@ -199,9 +_,23 @@ + + @Override + protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) { ++ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent + if (!level.isClientSide) { + if (state.getValue(TILT) == Tilt.NONE && canEntityTilt(pos, entity) && !level.hasNeighborSignal(pos)) { +- this.setTiltAndScheduleTick(state, level, pos, Tilt.UNSTABLE, null); ++ // CraftBukkit start - tilt dripleaf ++ org.bukkit.event.Cancellable cancellable; ++ if (entity instanceof net.minecraft.world.entity.player.Player) { ++ cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((net.minecraft.world.entity.player.Player) entity, org.bukkit.event.block.Action.PHYSICAL, pos, null, null, null); ++ } else { ++ cancellable = new org.bukkit.event.entity.EntityInteractEvent(entity.getBukkitEntity(), level.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ())); ++ level.getCraftServer().getPluginManager().callEvent((org.bukkit.event.entity.EntityInteractEvent) cancellable); ++ } ++ ++ if (cancellable.isCancelled()) { ++ return; ++ } ++ this.setTiltAndScheduleTick(state, level, pos, Tilt.UNSTABLE, null, entity); ++ // CraftBukkit end + } + } + } +@@ -213,9 +_,9 @@ + } else { + Tilt tilt = state.getValue(TILT); + if (tilt == Tilt.UNSTABLE) { +- this.setTiltAndScheduleTick(state, level, pos, Tilt.PARTIAL, SoundEvents.BIG_DRIPLEAF_TILT_DOWN); ++ this.setTiltAndScheduleTick(state, level, pos, Tilt.PARTIAL, SoundEvents.BIG_DRIPLEAF_TILT_DOWN, null); // CraftBukkit + } else if (tilt == Tilt.PARTIAL) { +- this.setTiltAndScheduleTick(state, level, pos, Tilt.FULL, SoundEvents.BIG_DRIPLEAF_TILT_DOWN); ++ this.setTiltAndScheduleTick(state, level, pos, Tilt.FULL, SoundEvents.BIG_DRIPLEAF_TILT_DOWN, null); // CraftBukkit + } else if (tilt == Tilt.FULL) { + resetTilt(state, level, pos); + } +@@ -238,8 +_,9 @@ + return entity.onGround() && entity.position().y > pos.getY() + 0.6875F; + } + +- private void setTiltAndScheduleTick(BlockState state, Level level, BlockPos pos, Tilt tilt, @Nullable SoundEvent sound) { +- setTilt(state, level, pos, tilt); ++ private void setTiltAndScheduleTick(BlockState state, Level level, BlockPos pos, Tilt tilt, @Nullable SoundEvent sound, @Nullable Entity entity) { ++ if (!BigDripleafBlock.setTilt(state, level, pos, tilt, entity)) return; ++ // CraftBukkit end + if (sound != null) { + playTiltSound(level, pos, sound); + } +@@ -251,18 +_,25 @@ + } + + private static void resetTilt(BlockState state, Level level, BlockPos pos) { +- setTilt(state, level, pos, Tilt.NONE); ++ setTilt(state, level, pos, Tilt.NONE, null); // CraftBukkit + if (state.getValue(TILT) != Tilt.NONE) { + playTiltSound(level, pos, SoundEvents.BIG_DRIPLEAF_TILT_UP); + } + } + +- private static void setTilt(BlockState state, Level level, BlockPos pos, Tilt tilt) { ++ private static boolean setTilt(BlockState state, Level level, BlockPos pos, Tilt tilt, @Nullable Entity entity) { // CraftBukkit ++ if (entity != null) { ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, state.setValue(BigDripleafBlock.TILT, tilt))) { ++ return false; ++ } ++ } ++ // CraftBukkit end + Tilt tilt1 = state.getValue(TILT); + level.setBlock(pos, state.setValue(TILT, tilt), 2); + if (tilt.causesVibration() && tilt != tilt1) { + level.gameEvent(null, GameEvent.BLOCK_CHANGE, pos); + } ++ return true; // CraftBukkit + } + + @Override diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/BlastFurnaceBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/BlastFurnaceBlock.java.patch similarity index 78% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/BlastFurnaceBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/BlastFurnaceBlock.java.patch index 3317c55a37..11ef775f5e 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/BlastFurnaceBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/BlastFurnaceBlock.java.patch @@ -1,9 +1,9 @@ --- a/net/minecraft/world/level/block/BlastFurnaceBlock.java +++ b/net/minecraft/world/level/block/BlastFurnaceBlock.java -@@ -45,8 +45,7 @@ +@@ -45,8 +_,7 @@ @Override - protected void openContainer(Level world, BlockPos pos, Player player) { - BlockEntity blockEntity = world.getBlockEntity(pos); + protected void openContainer(Level level, BlockPos pos, Player player) { + BlockEntity blockEntity = level.getBlockEntity(pos); - if (blockEntity instanceof BlastFurnaceBlockEntity) { - player.openMenu((MenuProvider)blockEntity); + if (blockEntity instanceof BlastFurnaceBlockEntity && player.openMenu((MenuProvider)blockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/Block.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/Block.java.patch similarity index 57% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/Block.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/Block.java.patch index c1060afc42..06e6874b95 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/Block.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/Block.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/Block.java +++ b/net/minecraft/world/level/block/Block.java -@@ -88,6 +88,21 @@ +@@ -90,6 +_,21 @@ public static final int UPDATE_LIMIT = 512; protected final StateDefinition stateDefinition; private BlockState defaultBlockState; @@ -22,8 +22,8 @@ @Nullable private Item item; private static final int CACHE_SIZE = 256; -@@ -295,12 +310,38 @@ - +@@ -272,6 +_,27 @@ + return state.getDrops(builder); } + // Paper start - Add BlockBreakBlockEvent @@ -47,91 +47,92 @@ + } + // Paper end - Add BlockBreakBlockEvent + - public static void dropResources(BlockState state, Level world, BlockPos pos, @Nullable BlockEntity blockEntity, @Nullable Entity entity, ItemStack tool) { + public static void dropResources(BlockState state, Level level, BlockPos pos) { + if (level instanceof ServerLevel) { + getDrops(state, (ServerLevel)level, pos, null).forEach(itemStack -> popResource(level, pos, itemStack)); +@@ -287,9 +_,14 @@ + } + + public static void dropResources(BlockState state, Level level, BlockPos pos, @Nullable BlockEntity blockEntity, @Nullable Entity entity, ItemStack tool) { + // Paper start - Properly handle xp dropping -+ dropResources(state, world, pos, blockEntity, entity, tool, true); ++ dropResources(state, level, pos, blockEntity, entity, tool, true); + } -+ public static void dropResources(BlockState state, Level world, BlockPos pos, @Nullable BlockEntity blockEntity, @Nullable Entity entity, ItemStack tool, boolean dropExperience) { ++ public static void dropResources(BlockState state, Level level, BlockPos pos, @Nullable BlockEntity blockEntity, @Nullable Entity entity, ItemStack tool, boolean dropExperience) { + // Paper end - Properly handle xp dropping - if (world instanceof ServerLevel) { - Block.getDrops(state, (ServerLevel) world, pos, blockEntity, entity, tool).forEach((itemstack1) -> { - Block.popResource(world, pos, itemstack1); - }); -- state.spawnAfterBreak((ServerLevel) world, pos, tool, true); -+ state.spawnAfterBreak((ServerLevel) world, pos, tool, dropExperience); // Paper - Properly handle xp dropping + if (level instanceof ServerLevel) { + getDrops(state, (ServerLevel)level, pos, blockEntity, entity, tool).forEach(itemStack -> popResource(level, pos, itemStack)); +- state.spawnAfterBreak((ServerLevel)level, pos, tool, true); ++ state.spawnAfterBreak((ServerLevel) level, pos, tool, dropExperience); // Paper - Properly handle xp dropping } - - } -@@ -340,7 +381,13 @@ - ItemEntity entityitem = (ItemEntity) itemEntitySupplier.get(); - - entityitem.setDefaultPickUpDelay(); -- world.addFreshEntity(entityitem); -+ // CraftBukkit start -+ if (world.captureDrops != null) { -+ world.captureDrops.add(entityitem); -+ } else { -+ world.addFreshEntity(entityitem); -+ } -+ // CraftBukkit end - return; - } - } -@@ -348,8 +395,13 @@ } - public void popExperience(ServerLevel world, BlockPos pos, int size) { +@@ -320,13 +_,24 @@ + if (level instanceof ServerLevel serverLevel && !stack.isEmpty() && serverLevel.getGameRules().getBoolean(GameRules.RULE_DOBLOCKDROPS)) { + ItemEntity itemEntity = itemEntitySupplier.get(); + itemEntity.setDefaultPickUpDelay(); +- level.addFreshEntity(itemEntity); ++ // CraftBukkit start ++ if (level.captureDrops != null) { ++ level.captureDrops.add(itemEntity); ++ } else { ++ level.addFreshEntity(itemEntity); ++ } ++ // CraftBukkit end + } + } + + public void popExperience(ServerLevel level, BlockPos pos, int amount) { + // Paper start - add entity parameter -+ popExperience(world, pos, size, null); ++ popExperience(level, pos, amount, null); + } -+ public void popExperience(ServerLevel world, BlockPos pos, int size, net.minecraft.world.entity.Entity entity) { -+ // Paper end - add entity parameter - if (world.getGameRules().getBoolean(GameRules.RULE_DOBLOCKDROPS)) { -- ExperienceOrb.award(world, Vec3.atCenterOf(pos), size); -+ ExperienceOrb.award(world, Vec3.atCenterOf(pos), size, org.bukkit.entity.ExperienceOrb.SpawnReason.BLOCK_BREAK, entity); // Paper ++ public void popExperience(ServerLevel level, BlockPos pos, int amount, net.minecraft.world.entity.Entity entity) { ++ // Paper end - add entity paramete + if (level.getGameRules().getBoolean(GameRules.RULE_DOBLOCKDROPS)) { +- ExperienceOrb.award(level, Vec3.atCenterOf(pos), amount); ++ ExperienceOrb.award(level, Vec3.atCenterOf(pos), amount, entity); // Paper } - } -@@ -367,10 +419,18 @@ + +@@ -345,10 +_,18 @@ return this.defaultBlockState(); } + @io.papermc.paper.annotation.DoNotUse @Deprecated // Paper - fix drops not preventing stats/food exhaustion - public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool) { -+ // Paper start - fix drops not preventing stats/food exhaustion -+ this.playerDestroy(world, player, pos, state, blockEntity, tool, true, true); + public void playerDestroy(Level level, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool) { ++ // Paper start - fix drops not preventing stats/food exhaustion ++ this.playerDestroy(level, player, pos, state, blockEntity, tool, true, true); + } -+ public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool, boolean includeDrops, boolean dropExp) { -+ // Paper end - fix drops not preventing stats/food exhaustion ++ public void playerDestroy(Level level, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool, boolean includeDrops, boolean dropExp) { ++ // Paper end - fix drops not preventing stats/food exhaustion player.awardStat(Stats.BLOCK_MINED.get(this)); - player.causeFoodExhaustion(0.005F); -- Block.dropResources(state, world, pos, blockEntity, player, tool); +- dropResources(state, level, pos, blockEntity, player, tool); + player.causeFoodExhaustion(0.005F, org.bukkit.event.entity.EntityExhaustionEvent.ExhaustionReason.BLOCK_MINED); // CraftBukkit - EntityExhaustionEvent + if (includeDrops) { // Paper - fix drops not preventing stats/food exhaustion -+ Block.dropResources(state, world, pos, blockEntity, player, tool, dropExp); // Paper - Properly handle xp dropping ++ Block.dropResources(state, level, pos, blockEntity, player, tool, dropExp); // Paper - Properly handle xp dropping + } // Paper - fix drops not preventing stats/food exhaustion } - public void setPlacedBy(Level world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack itemStack) {} -@@ -490,15 +550,35 @@ + public void setPlacedBy(Level level, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) { +@@ -469,12 +_,33 @@ return this.builtInRegistryHolder; } -- protected void tryDropExperience(ServerLevel world, BlockPos pos, ItemStack tool, IntProvider experience) { -- int i = EnchantmentHelper.processBlockExperience(world, tool, experience.sample(world.getRandom())); -+ // CraftBukkit start -+ protected int tryDropExperience(ServerLevel worldserver, BlockPos blockposition, ItemStack itemstack, IntProvider intprovider) { -+ int i = EnchantmentHelper.processBlockExperience(worldserver, itemstack, intprovider.sample(worldserver.getRandom())); - +- protected void tryDropExperience(ServerLevel level, BlockPos pos, ItemStack heldItem, IntProvider amount) { ++ protected int tryDropExperience(ServerLevel level, BlockPos pos, ItemStack heldItem, IntProvider amount) { // CraftBukkit + int i = EnchantmentHelper.processBlockExperience(level, heldItem, amount.sample(level.getRandom())); if (i > 0) { -- this.popExperience(world, pos, i); -+ // this.popExperience(worldserver, blockposition, i); +- this.popExperience(level, pos, i); +- } +- } ++ // CraftBukkit start ++ //this.popExperience(level, pos, i); + return i; - } - -+ return 0; - } - ++ // Craftbukkit end ++ } ++ return 0; // CraftBukkit ++ } ++ // CraftBukkit start + public int getExpDrop(BlockState iblockdata, ServerLevel worldserver, BlockPos blockposition, ItemStack itemstack, boolean flag) { + return 0; + } @@ -148,7 +149,6 @@ + return value; + } + // Spigot end -+ - private static record ShapePairKey(VoxelShape first, VoxelShape second) { - public boolean equals(Object object) { + record ShapePairKey(VoxelShape first, VoxelShape second) { + @Override diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/BrewingStandBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/BrewingStandBlock.java.patch similarity index 72% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/BrewingStandBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/BrewingStandBlock.java.patch index ad19f46261..e2bbf75753 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/BrewingStandBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/BrewingStandBlock.java.patch @@ -1,12 +1,12 @@ --- a/net/minecraft/world/level/block/BrewingStandBlock.java +++ b/net/minecraft/world/level/block/BrewingStandBlock.java -@@ -68,8 +68,7 @@ +@@ -68,8 +_,7 @@ @Override - protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { -- if (!world.isClientSide && world.getBlockEntity(pos) instanceof BrewingStandBlockEntity brewingStandBlockEntity) { + protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) { +- if (!level.isClientSide && level.getBlockEntity(pos) instanceof BrewingStandBlockEntity brewingStandBlockEntity) { - player.openMenu(brewingStandBlockEntity); -+ if (!world.isClientSide && world.getBlockEntity(pos) instanceof BrewingStandBlockEntity brewingStandBlockEntity && player.openMenu(brewingStandBlockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation ++ if (!level.isClientSide && level.getBlockEntity(pos) instanceof BrewingStandBlockEntity brewingStandBlockEntity && player.openMenu(brewingStandBlockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation player.awardStat(Stats.INTERACT_WITH_BREWINGSTAND); } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/BubbleColumnBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/BubbleColumnBlock.java.patch similarity index 66% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/BubbleColumnBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/BubbleColumnBlock.java.patch index aa97c1238d..1ca54afa47 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/BubbleColumnBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/BubbleColumnBlock.java.patch @@ -1,10 +1,10 @@ --- a/net/minecraft/world/level/block/BubbleColumnBlock.java +++ b/net/minecraft/world/level/block/BubbleColumnBlock.java -@@ -48,6 +48,7 @@ +@@ -48,6 +_,7 @@ @Override - protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { -+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent - BlockState blockState = world.getBlockState(pos.above()); + protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) { ++ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent + BlockState blockState = level.getBlockState(pos.above()); if (blockState.isAir()) { entity.onAboveBubbleCol(state.getValue(DRAG_DOWN)); diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/BuddingAmethystBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/BuddingAmethystBlock.java.patch similarity index 51% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/BuddingAmethystBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/BuddingAmethystBlock.java.patch index ee6f708bf9..e6ad3e837b 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/BuddingAmethystBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/BuddingAmethystBlock.java.patch @@ -1,17 +1,17 @@ --- a/net/minecraft/world/level/block/BuddingAmethystBlock.java +++ b/net/minecraft/world/level/block/BuddingAmethystBlock.java -@@ -45,7 +45,13 @@ - if (block != null) { - BlockState iblockdata2 = (BlockState) ((BlockState) block.defaultBlockState().setValue(AmethystClusterBlock.FACING, enumdirection)).setValue(AmethystClusterBlock.WATERLOGGED, iblockdata1.getFluidState().getType() == Fluids.WATER); - -- world.setBlockAndUpdate(blockposition1, iblockdata2); +@@ -44,7 +_,13 @@ + BlockState blockState1 = block.defaultBlockState() + .setValue(AmethystClusterBlock.FACING, direction) + .setValue(AmethystClusterBlock.WATERLOGGED, Boolean.valueOf(blockState.getFluidState().getType() == Fluids.WATER)); +- level.setBlockAndUpdate(blockPos, blockState1); + // Paper start - Have Amethyst throw both spread and grow events + if (block == Blocks.SMALL_AMETHYST_BUD) { -+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(world, pos, blockposition1, iblockdata2); // CraftBukkit ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, pos, blockPos, blockState1); // CraftBukkit + } else { -+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(world, blockposition1, iblockdata2); ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, blockPos, blockState1); + } + // Paper end - Have Amethyst throw both spread and grow events } - } + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/BushBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/BushBlock.java.patch new file mode 100644 index 0000000000..709e307ca3 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/BushBlock.java.patch @@ -0,0 +1,29 @@ +--- a/net/minecraft/world/level/block/BushBlock.java ++++ b/net/minecraft/world/level/block/BushBlock.java +@@ -6,6 +_,7 @@ + import net.minecraft.tags.BlockTags; + import net.minecraft.util.RandomSource; + import net.minecraft.world.level.BlockGetter; ++import net.minecraft.world.level.Level; + import net.minecraft.world.level.LevelReader; + import net.minecraft.world.level.ScheduledTickAccess; + import net.minecraft.world.level.block.state.BlockBehaviour; +@@ -35,9 +_,15 @@ + BlockState neighborState, + RandomSource random + ) { +- return !state.canSurvive(level, pos) +- ? Blocks.AIR.defaultBlockState() +- : super.updateShape(state, level, scheduledTickAccess, pos, direction, neighborPos, neighborState, random); ++ // CraftBukkit start ++ if (!state.canSurvive(level, pos)) { ++ // Suppress during worldgen ++ if (!(level instanceof net.minecraft.server.level.ServerLevel world1 && world1.hasPhysicsEvent) || !org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPhysicsEvent(world1, pos).isCancelled()) { // Paper ++ return Blocks.AIR.defaultBlockState(); ++ } ++ } ++ return super.updateShape(state, level, scheduledTickAccess, pos, direction, neighborPos, neighborState, random); ++ // CraftBukkit end + } + + @Override diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/ButtonBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/ButtonBlock.java.patch new file mode 100644 index 0000000000..956c25b452 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/ButtonBlock.java.patch @@ -0,0 +1,62 @@ +--- a/net/minecraft/world/level/block/ButtonBlock.java ++++ b/net/minecraft/world/level/block/ButtonBlock.java +@@ -114,6 +_,19 @@ + if (state.getValue(POWERED)) { + return InteractionResult.CONSUME; + } else { ++ // CraftBukkit start ++ boolean powered = state.getValue(ButtonBlock.POWERED); ++ org.bukkit.block.Block block = level.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); ++ int old = (powered) ? 15 : 0; ++ int current = (!powered) ? 15 : 0; ++ ++ org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(block, old, current); ++ level.getCraftServer().getPluginManager().callEvent(eventRedstone); ++ ++ if ((eventRedstone.getNewCurrent() > 0) != (!powered)) { ++ return InteractionResult.SUCCESS; ++ } ++ // CraftBukkit end + this.press(state, level, pos, player); + return InteractionResult.SUCCESS; + } +@@ -179,6 +_,7 @@ + + @Override + protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) { ++ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent + if (!level.isClientSide && this.type.canButtonBeActivatedByArrows() && !state.getValue(POWERED)) { + this.checkPressed(state, level, pos); + } +@@ -190,7 +_,31 @@ + : null; + boolean flag = abstractArrow != null; + boolean poweredValue = state.getValue(POWERED); ++ // CraftBukkit start - Call interact event when arrows turn on wooden buttons ++ if (poweredValue != flag && flag) { ++ org.bukkit.block.Block block = level.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); ++ org.bukkit.event.entity.EntityInteractEvent event = new org.bukkit.event.entity.EntityInteractEvent(abstractArrow.getBukkitEntity(), block); ++ level.getCraftServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) { ++ return; ++ } ++ } ++ // CraftBukkit end + if (flag != poweredValue) { ++ // CraftBukkit start ++ boolean powered = poweredValue; ++ org.bukkit.block.Block block = level.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); ++ int old = (powered) ? 15 : 0; ++ int current = (!powered) ? 15 : 0; ++ ++ org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(block, old, current); ++ level.getCraftServer().getPluginManager().callEvent(eventRedstone); ++ ++ if ((flag && eventRedstone.getNewCurrent() <= 0) || (!flag && eventRedstone.getNewCurrent() > 0)) { ++ return; ++ } ++ // CraftBukkit end + level.setBlock(pos, state.setValue(POWERED, Boolean.valueOf(flag)), 3); + this.updateNeighbours(state, level, pos); + this.playSound(null, level, pos, flag); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/CactusBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/CactusBlock.java.patch new file mode 100644 index 0000000000..acde2470f8 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/CactusBlock.java.patch @@ -0,0 +1,12 @@ +--- a/net/minecraft/world/level/block/CactusBlock.java ++++ b/net/minecraft/world/level/block/CactusBlock.java +@@ -113,7 +_,8 @@ + + @Override + protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) { +- entity.hurt(level.damageSources().cactus(), 1.0F); ++ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent ++ entity.hurt(level.damageSources().cactus().directBlock(level, pos), 1.0F); // CraftBukkit + } + + @Override diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/CakeBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/CakeBlock.java.patch similarity index 51% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/CakeBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/CakeBlock.java.patch index 346de8857c..d564317a09 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/CakeBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/CakeBlock.java.patch @@ -1,25 +1,25 @@ --- a/net/minecraft/world/level/block/CakeBlock.java +++ b/net/minecraft/world/level/block/CakeBlock.java -@@ -66,6 +66,12 @@ - if (block instanceof CandleBlock) { - CandleBlock candleblock = (CandleBlock) block; - -+ // Paper start - call change block event -+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, pos, CandleCakeBlock.byCandle(candleblock))) { -+ player.containerMenu.sendAllDataToRemote(); // update inv because candle could decrease -+ return InteractionResult.TRY_WITH_EMPTY_HAND; -+ } -+ // Paper end - call change block event - stack.consume(1, player); - world.playSound((Player) null, pos, SoundEvents.CAKE_ADD_CANDLE, SoundSource.BLOCKS, 1.0F, 1.0F); - world.setBlockAndUpdate(pos, CandleCakeBlock.byCandle(candleblock)); -@@ -97,10 +103,29 @@ +@@ -67,6 +_,12 @@ + ) { + Item item = stack.getItem(); + if (stack.is(ItemTags.CANDLES) && state.getValue(BITES) == 0 && Block.byItem(item) instanceof CandleBlock candleBlock) { ++ // Paper start - call change block event ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, pos, CandleCakeBlock.byCandle(candleBlock))) { ++ player.containerMenu.sendAllDataToRemote(); // update inv because candle could decrease ++ return InteractionResult.TRY_WITH_EMPTY_HAND; ++ } ++ // Paper end - call change block event + stack.consume(1, player); + level.playSound(null, pos, SoundEvents.CAKE_ADD_CANDLE, SoundSource.BLOCKS, 1.0F, 1.0F); + level.setBlockAndUpdate(pos, CandleCakeBlock.byCandle(candleBlock)); +@@ -97,9 +_,28 @@ if (!player.canEat(false)) { return InteractionResult.PASS; } else { + // Paper start - call change block event -+ int i = state.getValue(CakeBlock.BITES); -+ final BlockState newState = i < MAX_BITES ? state.setValue(CakeBlock.BITES, i + 1) : world.getFluidState(pos).createLegacyBlock(); ++ int bitesValue = state.getValue(CakeBlock.BITES); ++ final BlockState newState = bitesValue < MAX_BITES ? state.setValue(CakeBlock.BITES, bitesValue + 1) : level.getFluidState(pos).createLegacyBlock(); + if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(player, pos, newState)) { + ((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity().sendHealthUpdate(); + return InteractionResult.PASS; // return a non-consume result to cake blocks don't drop their candles @@ -27,11 +27,11 @@ + // Paper end - call change block event player.awardStat(Stats.EAT_CAKE_SLICE); - player.getFoodData().eat(2, 0.1F); -- int i = (Integer) state.getValue(CakeBlock.BITES); +- int bitesValue = state.getValue(BITES); + // CraftBukkit start + // entityhuman.getFoodData().eat(2, 0.1F); + int oldFoodLevel = player.getFoodData().foodLevel; - ++ + org.bukkit.event.entity.FoodLevelChangeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callFoodLevelChangeEvent(player, 2 + oldFoodLevel); + + if (!event.isCancelled()) { @@ -41,7 +41,6 @@ + ((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity().sendHealthUpdate(); + // CraftBukkit end + // Paper - move up -+ - world.gameEvent((Entity) player, (Holder) GameEvent.EAT, pos); - if (i < 6) { - world.setBlock(pos, (BlockState) state.setValue(CakeBlock.BITES, i + 1), 3); + level.gameEvent(player, GameEvent.EAT, pos); + if (bitesValue < 6) { + level.setBlock(pos, state.setValue(BITES, Integer.valueOf(bitesValue + 1)), 3); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/CampfireBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/CampfireBlock.java.patch new file mode 100644 index 0000000000..0663b2c497 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/CampfireBlock.java.patch @@ -0,0 +1,25 @@ +--- a/net/minecraft/world/level/block/CampfireBlock.java ++++ b/net/minecraft/world/level/block/CampfireBlock.java +@@ -112,8 +_,9 @@ + + @Override + protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) { ++ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent + if (state.getValue(LIT) && entity instanceof LivingEntity) { +- entity.hurt(level.damageSources().campfire(), this.fireDamage); ++ entity.hurt(level.damageSources().campfire().directBlock(level, pos), (float) this.fireDamage); // CraftBukkit + } + + super.entityInside(state, level, pos, entity); +@@ -242,6 +_,11 @@ + && projectile.mayInteract(serverLevel, blockPos) + && !state.getValue(LIT) + && !state.getValue(WATERLOGGED)) { ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(level, blockPos, projectile).isCancelled()) { ++ return; ++ } ++ // CraftBukkit end + level.setBlock(blockPos, state.setValue(BlockStateProperties.LIT, Boolean.valueOf(true)), 11); + } + } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/CartographyTableBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/CartographyTableBlock.java.patch similarity index 64% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/CartographyTableBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/CartographyTableBlock.java.patch index 237e4da1be..2aa0c9dd39 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/CartographyTableBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/CartographyTableBlock.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/world/level/block/CartographyTableBlock.java +++ b/net/minecraft/world/level/block/CartographyTableBlock.java -@@ -32,8 +32,9 @@ +@@ -32,8 +_,9 @@ @Override - protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { - if (!world.isClientSide) { -- player.openMenu(state.getMenuProvider(world, pos)); -+ if (player.openMenu(state.getMenuProvider(world, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation + protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) { + if (!level.isClientSide) { +- player.openMenu(state.getMenuProvider(level, pos)); ++ if (player.openMenu(state.getMenuProvider(level, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation player.awardStat(Stats.INTERACT_WITH_CARTOGRAPHY_TABLE); + } // Paper - Fix InventoryOpenEvent cancellation } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/CarvedPumpkinBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/CarvedPumpkinBlock.java.patch new file mode 100644 index 0000000000..4343b42a31 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/CarvedPumpkinBlock.java.patch @@ -0,0 +1,18 @@ +--- a/net/minecraft/world/level/block/CarvedPumpkinBlock.java ++++ b/net/minecraft/world/level/block/CarvedPumpkinBlock.java +@@ -79,9 +_,13 @@ + } + + private static void spawnGolemInWorld(Level level, BlockPattern.BlockPatternMatch patternMatch, Entity golem, BlockPos pos) { +- clearPatternBlocks(level, patternMatch); ++ // clearPatternBlocks(level, patternMatch); // CraftBukkit - moved down + golem.moveTo(pos.getX() + 0.5, pos.getY() + 0.05, pos.getZ() + 0.5, 0.0F, 0.0F); +- level.addFreshEntity(golem); ++ if (!level.addFreshEntity(golem, (golem.getType() == EntityType.SNOW_GOLEM) ? org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BUILD_SNOWMAN : org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BUILD_IRONGOLEM)) { ++ return; ++ } ++ clearPatternBlocks(level, patternMatch); // CraftBukkit - from above ++ // CraftBukkit end + + for (ServerPlayer serverPlayer : level.getEntitiesOfClass(ServerPlayer.class, golem.getBoundingBox().inflate(5.0))) { + CriteriaTriggers.SUMMONED_ENTITY.trigger(serverPlayer, golem); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/CauldronBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/CauldronBlock.java.patch new file mode 100644 index 0000000000..e420669453 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/CauldronBlock.java.patch @@ -0,0 +1,46 @@ +--- a/net/minecraft/world/level/block/CauldronBlock.java ++++ b/net/minecraft/world/level/block/CauldronBlock.java +@@ -40,9 +_,19 @@ + public void handlePrecipitation(BlockState state, Level level, BlockPos pos, Biome.Precipitation precipitation) { + if (shouldHandlePrecipitation(level, precipitation)) { + if (precipitation == Biome.Precipitation.RAIN) { ++ // Paper start - Call CauldronLevelChangeEvent ++ if (!LayeredCauldronBlock.changeLevel(state, level, pos, Blocks.WATER_CAULDRON.defaultBlockState(), null, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL, false)) { // avoid duplicate game event ++ return; ++ } ++ // Paper end - Call CauldronLevelChangeEvent + level.setBlockAndUpdate(pos, Blocks.WATER_CAULDRON.defaultBlockState()); + level.gameEvent(null, GameEvent.BLOCK_CHANGE, pos); + } else if (precipitation == Biome.Precipitation.SNOW) { ++ // Paper start - Call CauldronLevelChangeEvent ++ if (!LayeredCauldronBlock.changeLevel(state, level, pos, Blocks.POWDER_SNOW_CAULDRON.defaultBlockState(), null, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL, false)) { // avoid duplicate game event ++ return; ++ } ++ // Paper end - Call CauldronLevelChangeEvent + level.setBlockAndUpdate(pos, Blocks.POWDER_SNOW_CAULDRON.defaultBlockState()); + level.gameEvent(null, GameEvent.BLOCK_CHANGE, pos); + } +@@ -58,13 +_,19 @@ + protected void receiveStalactiteDrip(BlockState state, Level level, BlockPos pos, Fluid fluid) { + if (fluid == Fluids.WATER) { + BlockState blockState = Blocks.WATER_CAULDRON.defaultBlockState(); +- level.setBlockAndUpdate(pos, blockState); +- level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(blockState)); ++ // Paper start - Call CauldronLevelChangeEvent; don't send level event or game event if cancelled ++ if (!LayeredCauldronBlock.changeLevel(state, level, pos, blockState, null, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL)) { // CraftBukkit ++ return; ++ } ++ // Paper end - Call CauldronLevelChangeEvent + level.levelEvent(1047, pos, 0); + } else if (fluid == Fluids.LAVA) { + BlockState blockState = Blocks.LAVA_CAULDRON.defaultBlockState(); +- level.setBlockAndUpdate(pos, blockState); +- level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(blockState)); ++ // Paper start - Call CauldronLevelChangeEvent; don't send level event or game event if cancelled ++ if (!LayeredCauldronBlock.changeLevel(state, level, pos, blockState, null, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL)) { // CraftBukkit ++ return; ++ } ++ // Paper end - Call CauldronLevelChangeEvent + level.levelEvent(1046, pos, 0); + } + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/CaveVines.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/CaveVines.java.patch new file mode 100644 index 0000000000..6355a6f4b2 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/CaveVines.java.patch @@ -0,0 +1,27 @@ +--- a/net/minecraft/world/level/block/CaveVines.java ++++ b/net/minecraft/world/level/block/CaveVines.java +@@ -23,7 +_,23 @@ + + static InteractionResult use(@Nullable Entity entity, BlockState state, Level level, BlockPos pos) { + if (state.getValue(BERRIES)) { +- Block.popResource(level, pos, new ItemStack(Items.GLOW_BERRIES, 1)); ++ // CraftBukkit start ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, (BlockState) state.setValue(CaveVines.BERRIES, false))) { ++ return InteractionResult.SUCCESS; ++ } ++ ++ if (entity instanceof net.minecraft.world.entity.player.Player) { ++ org.bukkit.event.player.PlayerHarvestBlockEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerHarvestBlockEvent(level, pos, (net.minecraft.world.entity.player.Player) entity, net.minecraft.world.InteractionHand.MAIN_HAND, java.util.Collections.singletonList(new ItemStack(Items.GLOW_BERRIES, 1))); ++ if (event.isCancelled()) { ++ return InteractionResult.SUCCESS; // We need to return a success either way, because making it PASS or FAIL will result in a bug where cancelling while harvesting w/ block in hand places block ++ } ++ for (org.bukkit.inventory.ItemStack itemStack : event.getItemsHarvested()) { ++ Block.popResource(level, pos, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(itemStack)); ++ } ++ } else { ++ Block.popResource(level, pos, new ItemStack(Items.GLOW_BERRIES, 1)); ++ } ++ // CraftBukkit end + float f = Mth.randomBetween(level.random, 0.8F, 1.2F); + level.playSound(null, pos, SoundEvents.CAVE_VINES_PICK_BERRIES, SoundSource.BLOCKS, 1.0F, f); + BlockState blockState = state.setValue(BERRIES, Boolean.valueOf(false)); diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/CaveVinesBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/CaveVinesBlock.java.patch similarity index 72% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/CaveVinesBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/CaveVinesBlock.java.patch index 511200af88..7f52226493 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/CaveVinesBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/CaveVinesBlock.java.patch @@ -1,22 +1,23 @@ --- a/net/minecraft/world/level/block/CaveVinesBlock.java +++ b/net/minecraft/world/level/block/CaveVinesBlock.java -@@ -50,9 +50,18 @@ - return to.setValue(BERRIES, from.getValue(BERRIES)); +@@ -52,7 +_,7 @@ + + @Override + protected BlockState getGrowIntoState(BlockState state, RandomSource random) { +- return super.getGrowIntoState(state, random).setValue(BERRIES, Boolean.valueOf(random.nextFloat() < 0.11F)); ++ return this.getGrowIntoState(state, random, null); // Paper - Fix Spigot growth modifiers } -+ // Paper start - Fix Spigot growth modifiers @Override +@@ -85,4 +_,11 @@ + public void performBonemeal(ServerLevel level, RandomSource random, BlockPos pos, BlockState state) { + level.setBlock(pos, state.setValue(BERRIES, Boolean.valueOf(true)), 2); + } ++ // Paper start - Fix Spigot growth modifiers ++ @Override + protected BlockState getGrowIntoState(BlockState state, RandomSource random, @javax.annotation.Nullable Level level) { + final boolean value = random.nextFloat() < (level != null ? (0.11F * (level.spigotConfig.glowBerryModifier / 100.0F)) : 0.11F); + return (BlockState) super.getGrowIntoState(state, random).setValue(CaveVinesBlock.BERRIES, value); + } + // Paper end - Fix Spigot growth modifiers -+ -+ @Override - protected BlockState getGrowIntoState(BlockState state, RandomSource random) { -- return super.getGrowIntoState(state, random).setValue(BERRIES, Boolean.valueOf(random.nextFloat() < 0.11F)); -+ // Paper start - Fix Spigot growth modifiers -+ return this.getGrowIntoState(state, random, null); - } - - @Override + } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/CeilingHangingSignBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/CeilingHangingSignBlock.java.patch similarity index 61% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/CeilingHangingSignBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/CeilingHangingSignBlock.java.patch index b85ba5b3dc..64f4e71297 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/CeilingHangingSignBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/CeilingHangingSignBlock.java.patch @@ -1,10 +1,10 @@ --- a/net/minecraft/world/level/block/CeilingHangingSignBlock.java +++ b/net/minecraft/world/level/block/CeilingHangingSignBlock.java -@@ -159,6 +159,6 @@ +@@ -184,6 +_,6 @@ @Nullable @Override - public BlockEntityTicker getTicker(Level world, BlockState state, BlockEntityType type) { -- return createTickerHelper(type, BlockEntityType.HANGING_SIGN, SignBlockEntity::tick); + public BlockEntityTicker getTicker(Level level, BlockState state, BlockEntityType blockEntityType) { +- return createTickerHelper(blockEntityType, BlockEntityType.HANGING_SIGN, SignBlockEntity::tick); + return null; // Craftbukkit - remove unnecessary sign ticking } } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/ChangeOverTimeBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/ChangeOverTimeBlock.java.patch new file mode 100644 index 0000000000..6601a243af --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/ChangeOverTimeBlock.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/level/block/ChangeOverTimeBlock.java ++++ b/net/minecraft/world/level/block/ChangeOverTimeBlock.java +@@ -16,7 +_,7 @@ + default void changeOverTime(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { + float f = 0.05688889F; + if (random.nextFloat() < 0.05688889F) { +- this.getNextState(state, level, pos, random).ifPresent(blockState -> level.setBlockAndUpdate(pos, blockState)); ++ this.getNextState(state, level, pos, random).ifPresent(blockState -> org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(level, pos, blockState)); // CraftBukkit + } + } + diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/ChestBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/ChestBlock.java.patch new file mode 100644 index 0000000000..5200deab3e --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/ChestBlock.java.patch @@ -0,0 +1,79 @@ +--- a/net/minecraft/world/level/block/ChestBlock.java ++++ b/net/minecraft/world/level/block/ChestBlock.java +@@ -120,6 +_,38 @@ + } + }; + ++ // CraftBukkit start ++ public static class DoubleInventory implements MenuProvider { ++ ++ private final ChestBlockEntity tileentitychest; ++ private final ChestBlockEntity tileentitychest1; ++ public final CompoundContainer inventorylargechest; ++ ++ public DoubleInventory(ChestBlockEntity tileentitychest, ChestBlockEntity tileentitychest1, CompoundContainer inventorylargechest) { ++ this.tileentitychest = tileentitychest; ++ this.tileentitychest1 = tileentitychest1; ++ this.inventorylargechest = inventorylargechest; ++ } ++ ++ @Nullable ++ @Override ++ public AbstractContainerMenu createMenu(int syncId, Inventory playerInventory, Player player) { ++ if (this.tileentitychest.canOpen(player) && this.tileentitychest1.canOpen(player)) { ++ this.tileentitychest.unpackLootTable(playerInventory.player); ++ this.tileentitychest1.unpackLootTable(playerInventory.player); ++ return ChestMenu.sixRows(syncId, playerInventory, this.inventorylargechest); ++ } else { ++ return null; ++ } ++ } ++ ++ @Override ++ public Component getDisplayName() { ++ return (Component) (this.tileentitychest.hasCustomName() ? this.tileentitychest.getDisplayName() : (this.tileentitychest1.hasCustomName() ? this.tileentitychest1.getDisplayName() : Component.translatable("container.chestDouble"))); ++ } ++ }; ++ // CraftBukkit end ++ + @Override + public MapCodec codec() { + return CODEC; +@@ -245,8 +_,7 @@ + protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) { + if (level instanceof ServerLevel serverLevel) { + MenuProvider menuProvider = this.getMenuProvider(state, level, pos); +- if (menuProvider != null) { +- player.openMenu(menuProvider); ++ if (menuProvider != null && player.openMenu(menuProvider).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation + player.awardStat(this.getOpenChestStat()); + PiglinAi.angerNearbyPiglins(serverLevel, player, true); + } +@@ -285,7 +_,14 @@ + @Nullable + @Override + protected MenuProvider getMenuProvider(BlockState state, Level level, BlockPos pos) { +- return this.combine(state, level, pos, false).apply(MENU_PROVIDER_COMBINER).orElse(null); ++ // CraftBukkit start ++ return this.getMenuProvider(state, level, pos, false); ++ } ++ ++ @Nullable ++ public MenuProvider getMenuProvider(BlockState state, Level level, BlockPos pos, boolean ignoreObstructions) { ++ return this.combine(state, level, pos, ignoreObstructions).apply(MENU_PROVIDER_COMBINER).orElse(null); ++ // CraftBukkit end + } + + public static DoubleBlockCombiner.Combiner opennessCombiner(final LidBlockEntity lid) { +@@ -328,6 +_,11 @@ + } + + private static boolean isCatSittingOnChest(LevelAccessor level, BlockPos pos) { ++ // Paper start - Option to disable chest cat detection ++ if (level.getMinecraftWorld().paperConfig().entities.behavior.disableChestCatDetection) { ++ return false; ++ } ++ // Paper end - Option to disable chest cat detection + List entitiesOfClass = level.getEntitiesOfClass( + Cat.class, new AABB(pos.getX(), pos.getY() + 1, pos.getZ(), pos.getX() + 1, pos.getY() + 2, pos.getZ() + 1) + ); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/ChorusFlowerBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/ChorusFlowerBlock.java.patch new file mode 100644 index 0000000000..7909effb3a --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/ChorusFlowerBlock.java.patch @@ -0,0 +1,24 @@ +--- a/net/minecraft/world/level/block/ChorusFlowerBlock.java ++++ b/net/minecraft/world/level/block/ChorusFlowerBlock.java +@@ -96,8 +_,10 @@ + } + + if (flag && allNeighborsEmpty(level, blockPos, null) && level.isEmptyBlock(pos.above(2))) { ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, pos, blockPos, this.defaultBlockState().setValue(ChorusFlowerBlock.AGE, ageValue), 2)) { // CraftBukkit - add event + level.setBlock(pos, ChorusPlantBlock.getStateWithConnections(level, pos, this.plant.defaultBlockState()), 2); + this.placeGrownFlower(level, blockPos, ageValue); ++ } // CraftBukkit + } else if (ageValue < 4) { + int i = random.nextInt(4); + if (flag1) { +@@ -112,8 +_,10 @@ + if (level.isEmptyBlock(blockPos1) + && level.isEmptyBlock(blockPos1.below()) + && allNeighborsEmpty(level, blockPos1, randomDirection.getOpposite())) { ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, pos, blockPos1, this.defaultBlockState().setValue(ChorusFlowerBlock.AGE, ageValue + 1), 2)) { // CraftBukkit - add event + this.placeGrownFlower(level, blockPos1, ageValue + 1); + flag2 = true; ++ } // CraftBukkit + } + } + diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/ChorusPlantBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/ChorusPlantBlock.java.patch similarity index 56% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/ChorusPlantBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/ChorusPlantBlock.java.patch index 80c24699ea..f73493ba87 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/ChorusPlantBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/ChorusPlantBlock.java.patch @@ -1,34 +1,34 @@ --- a/net/minecraft/world/level/block/ChorusPlantBlock.java +++ b/net/minecraft/world/level/block/ChorusPlantBlock.java -@@ -38,6 +38,7 @@ +@@ -38,6 +_,7 @@ @Override - public BlockState getStateForPlacement(BlockPlaceContext ctx) { + public BlockState getStateForPlacement(BlockPlaceContext context) { + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableChorusPlantUpdates) return this.defaultBlockState(); // Paper - add option to disable block updates - return getStateWithConnections(ctx.getLevel(), ctx.getClickedPos(), this.defaultBlockState()); + return getStateWithConnections(context.getLevel(), context.getClickedPos(), this.defaultBlockState()); } -@@ -68,6 +69,7 @@ +@@ -68,6 +_,7 @@ BlockState neighborState, RandomSource random ) { + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableChorusPlantUpdates) return state; // Paper - add option to disable block updates - if (!state.canSurvive(world, pos)) { - tickView.scheduleTick(pos, this, 1); - return super.updateShape(state, world, tickView, pos, direction, neighborPos, neighborState, random); -@@ -79,6 +81,7 @@ + if (!state.canSurvive(level, pos)) { + scheduledTickAccess.scheduleTick(pos, this, 1); + return super.updateShape(state, level, scheduledTickAccess, pos, direction, neighborPos, neighborState, random); +@@ -81,6 +_,7 @@ @Override - protected void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { + protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableChorusPlantUpdates) return; // Paper - add option to disable block updates - if (!state.canSurvive(world, pos)) { - world.destroyBlock(pos, true); + if (!state.canSurvive(level, pos)) { + level.destroyBlock(pos, true); } -@@ -86,6 +89,7 @@ +@@ -88,6 +_,7 @@ @Override - protected boolean canSurvive(BlockState state, LevelReader world, BlockPos pos) { + protected boolean canSurvive(BlockState state, LevelReader level, BlockPos pos) { + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableChorusPlantUpdates) return true; // Paper - add option to disable block updates - BlockState blockState = world.getBlockState(pos.below()); - boolean bl = !world.getBlockState(pos.above()).isAir() && !blockState.isAir(); + BlockState blockState = level.getBlockState(pos.below()); + boolean flag = !level.getBlockState(pos.above()).isAir() && !blockState.isAir(); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/CocoaBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/CocoaBlock.java.patch new file mode 100644 index 0000000000..1b46405a40 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/CocoaBlock.java.patch @@ -0,0 +1,24 @@ +--- a/net/minecraft/world/level/block/CocoaBlock.java ++++ b/net/minecraft/world/level/block/CocoaBlock.java +@@ -64,10 +_,10 @@ + + @Override + protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { +- if (level.random.nextInt(5) == 0) { ++ if (level.random.nextFloat() < (level.spigotConfig.cocoaModifier / (100.0f * 5))) { // Spigot - SPIGOT-7159: Better modifier resolution + int ageValue = state.getValue(AGE); + if (ageValue < 2) { +- level.setBlock(pos, state.setValue(AGE, Integer.valueOf(ageValue + 1)), 2); ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, pos, state.setValue(CocoaBlock.AGE, ageValue + 1), 2); // CraftBukkkit + } + } + } +@@ -141,7 +_,7 @@ + + @Override + public void performBonemeal(ServerLevel level, RandomSource random, BlockPos pos, BlockState state) { +- level.setBlock(pos, state.setValue(AGE, Integer.valueOf(state.getValue(AGE) + 1)), 2); ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, pos, state.setValue(CocoaBlock.AGE, state.getValue(CocoaBlock.AGE) + 1), 2); // CraftBukkit + } + + @Override diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/CommandBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/CommandBlock.java.patch new file mode 100644 index 0000000000..f285e643af --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/CommandBlock.java.patch @@ -0,0 +1,27 @@ +--- a/net/minecraft/world/level/block/CommandBlock.java ++++ b/net/minecraft/world/level/block/CommandBlock.java +@@ -70,6 +_,15 @@ + + private void setPoweredAndUpdate(Level level, BlockPos pos, CommandBlockEntity blockEntity, boolean powered) { + boolean isPowered = blockEntity.isPowered(); ++ // CraftBukkit start ++ org.bukkit.block.Block bukkitBlock = level.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); ++ int old = isPowered ? 15 : 0; ++ int current = powered ? 15 : 0; ++ ++ org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(bukkitBlock, old, current); ++ level.getCraftServer().getPluginManager().callEvent(eventRedstone); ++ powered = eventRedstone.getNewCurrent() > 0; ++ // CraftBukkit end + if (powered != isPowered) { + blockEntity.setPowered(powered); + if (powered) { +@@ -126,7 +_,7 @@ + @Override + protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) { + BlockEntity blockEntity = level.getBlockEntity(pos); +- if (blockEntity instanceof CommandBlockEntity && player.canUseGameMasterBlocks()) { ++ if (blockEntity instanceof CommandBlockEntity && (player.canUseGameMasterBlocks() || (player.isCreative() && player.getBukkitEntity().hasPermission("minecraft.commandblock")))) { // Paper - command block permission + player.openCommandBlock((CommandBlockEntity)blockEntity); + return InteractionResult.SUCCESS; + } else { diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/ComparatorBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/ComparatorBlock.java.patch new file mode 100644 index 0000000000..713361e2bd --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/ComparatorBlock.java.patch @@ -0,0 +1,21 @@ +--- a/net/minecraft/world/level/block/ComparatorBlock.java ++++ b/net/minecraft/world/level/block/ComparatorBlock.java +@@ -170,8 +_,18 @@ + boolean shouldTurnOn = this.shouldTurnOn(level, pos, state); + boolean poweredValue = state.getValue(POWERED); + if (poweredValue && !shouldTurnOn) { ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, 15, 0).getNewCurrent() != 0) { ++ return; ++ } ++ // CraftBukkit end + level.setBlock(pos, state.setValue(POWERED, Boolean.valueOf(false)), 2); + } else if (!poweredValue && shouldTurnOn) { ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, 0, 15).getNewCurrent() != 15) { ++ return; ++ } ++ // CraftBukkit end + level.setBlock(pos, state.setValue(POWERED, Boolean.valueOf(true)), 2); + } + diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/ComposterBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/ComposterBlock.java.patch new file mode 100644 index 0000000000..2f9e73d103 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/ComposterBlock.java.patch @@ -0,0 +1,148 @@ +--- a/net/minecraft/world/level/block/ComposterBlock.java ++++ b/net/minecraft/world/level/block/ComposterBlock.java +@@ -243,6 +_,11 @@ + if (levelValue < 8 && COMPOSTABLES.containsKey(stack.getItem())) { + if (levelValue < 7 && !level.isClientSide) { + BlockState blockState = addItem(player, state, level, pos, stack); ++ // Paper start - handle cancelled events ++ if (blockState == null) { ++ return InteractionResult.PASS; ++ } ++ // Paper end + level.levelEvent(1500, pos, state != blockState ? 1 : 0); + player.awardStat(Stats.ITEM_USED.get(stack.getItem())); + stack.consume(1, player); +@@ -268,7 +_,19 @@ + public static BlockState insertItem(Entity entity, BlockState state, ServerLevel level, ItemStack stack, BlockPos pos) { + int levelValue = state.getValue(LEVEL); + if (levelValue < 7 && COMPOSTABLES.containsKey(stack.getItem())) { +- BlockState blockState = addItem(entity, state, level, pos, stack); ++ // CraftBukkit start ++ double rand = level.getRandom().nextDouble(); ++ BlockState blockState = null; // Paper ++ if (false && (state == blockState || !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, blockState))) { // Paper - move event call into addItem ++ return state; ++ } ++ blockState = ComposterBlock.addItem(entity, state, level, pos, stack, rand); ++ // Paper start - handle cancelled events ++ if (blockState == null) { ++ return state; ++ } ++ // Paper end ++ // CraftBukkit end + stack.shrink(1); + return blockState; + } else { +@@ -277,6 +_,14 @@ + } + + public static BlockState extractProduce(Entity entity, BlockState state, Level level, BlockPos pos) { ++ // CraftBukkit start ++ if (entity != null && !(entity instanceof Player)) { ++ BlockState iblockdata1 = ComposterBlock.empty(entity, state, org.bukkit.craftbukkit.util.DummyGeneratorAccess.INSTANCE, pos); ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, iblockdata1)) { ++ return state; ++ } ++ } ++ // CraftBukkit end + if (!level.isClientSide) { + Vec3 vec3 = Vec3.atLowerCornerWithOffset(pos, 0.5, 1.01, 0.5).offsetRandom(level.random, 0.7F); + ItemEntity itemEntity = new ItemEntity(level, vec3.x(), vec3.y(), vec3.z(), new ItemStack(Items.BONE_MEAL)); +@@ -296,14 +_,39 @@ + return blockState; + } + ++ @Nullable // Paper + static BlockState addItem(@Nullable Entity entity, BlockState state, LevelAccessor level, BlockPos pos, ItemStack stack) { ++ // CraftBukkit start ++ return ComposterBlock.addItem(entity, state, level, pos, stack, level.getRandom().nextDouble()); ++ } ++ @Nullable // Paper - make it nullable ++ static BlockState addItem(@Nullable Entity entity, BlockState state, LevelAccessor level, BlockPos pos, ItemStack stack, double rand) { + int levelValue = state.getValue(LEVEL); + float _float = COMPOSTABLES.getFloat(stack.getItem()); +- if ((levelValue != 0 || !(_float > 0.0F)) && !(level.getRandom().nextDouble() < _float)) { ++ // Paper start - Add CompostItemEvent and EntityCompostItemEvent ++ boolean willRaiseLevel = !((levelValue != 0 || _float <= 0.0F) && rand >= (double) _float); ++ final io.papermc.paper.event.block.CompostItemEvent event; ++ if (entity == null) { ++ event = new io.papermc.paper.event.block.CompostItemEvent(org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), stack.getBukkitStack(), willRaiseLevel); ++ } else { ++ event = new io.papermc.paper.event.entity.EntityCompostItemEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), stack.getBukkitStack(), willRaiseLevel); ++ } ++ if (!event.callEvent()) { // check for cancellation of entity event (non entity event can't be cancelled cause of hoppers) ++ return null; ++ } ++ willRaiseLevel = event.willRaiseLevel(); ++ ++ if (!willRaiseLevel) { ++ // Paper end - Add CompostItemEvent and EntityCompostItemEvent + return state; + } else { + int i = levelValue + 1; + BlockState blockState = state.setValue(LEVEL, Integer.valueOf(i)); ++ // Paper start - move the EntityChangeBlockEvent here to avoid conflict later for the compost events ++ if (entity != null && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, blockState)) { ++ return null; ++ } ++ // Paper end + level.setBlock(pos, blockState, 3); + level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(entity, blockState)); + if (i == 7) { +@@ -348,13 +_,14 @@ + if (levelValue == 8) { + return new ComposterBlock.OutputContainer(state, level, pos, new ItemStack(Items.BONE_MEAL)); + } else { +- return (WorldlyContainer)(levelValue < 7 ? new ComposterBlock.InputContainer(state, level, pos) : new ComposterBlock.EmptyContainer()); ++ return (WorldlyContainer)(levelValue < 7 ? new ComposterBlock.InputContainer(state, level, pos) : new ComposterBlock.EmptyContainer(level, pos)); // CraftBukkit - empty generatoraccess, blockposition + } + } + + public static class EmptyContainer extends SimpleContainer implements WorldlyContainer { +- public EmptyContainer() { ++ public EmptyContainer(LevelAccessor generatoraccess, BlockPos blockposition) { // CraftBukkit + super(0); ++ this.bukkitOwner = new org.bukkit.craftbukkit.inventory.CraftBlockInventoryHolder(generatoraccess, blockposition, this); // CraftBukkit + } + + @Override +@@ -381,9 +_,11 @@ + + public InputContainer(BlockState state, LevelAccessor level, BlockPos pos) { + super(1); ++ this.bukkitOwner = new org.bukkit.craftbukkit.inventory.CraftBlockInventoryHolder(level, pos, this); // CraftBukkit + this.state = state; + this.level = level; + this.pos = pos; ++ this.bukkitOwner = new org.bukkit.craftbukkit.inventory.CraftBlockInventoryHolder(level, pos, this); // CraftBukkit + } + + @Override +@@ -412,6 +_,11 @@ + if (!item.isEmpty()) { + this.changed = true; + BlockState blockState = ComposterBlock.addItem(null, this.state, this.level, this.pos, item); ++ // Paper start - Add CompostItemEvent and EntityCompostItemEvent ++ if (blockState == null) { ++ return; ++ } ++ // Paper end - Add CompostItemEvent and EntityCompostItemEvent + this.level.levelEvent(1500, this.pos, blockState != this.state ? 1 : 0); + this.removeItemNoUpdate(0); + } +@@ -453,8 +_,15 @@ + + @Override + public void setChanged() { ++ // CraftBukkit start - allow putting items back (eg cancelled InventoryMoveItemEvent) ++ if (this.isEmpty()) { + ComposterBlock.empty(null, this.state, this.level, this.pos); + this.changed = true; ++ } else { ++ this.level.setBlock(this.pos, this.state, 3); ++ this.changed = false; ++ } ++ // CraftBukkit end + } + } + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/ConcretePowderBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/ConcretePowderBlock.java.patch new file mode 100644 index 0000000000..09d88b80ed --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/ConcretePowderBlock.java.patch @@ -0,0 +1,66 @@ +--- a/net/minecraft/world/level/block/ConcretePowderBlock.java ++++ b/net/minecraft/world/level/block/ConcretePowderBlock.java +@@ -38,7 +_,7 @@ + @Override + public void onLand(Level level, BlockPos pos, BlockState state, BlockState replaceableState, FallingBlockEntity fallingBlock) { + if (shouldSolidify(level, pos, replaceableState)) { +- level.setBlock(pos, this.concrete.defaultBlockState(), 3); ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(level, pos, this.concrete.defaultBlockState(), 3); // CraftBukkit + } + } + +@@ -47,7 +_,24 @@ + BlockGetter level = context.getLevel(); + BlockPos clickedPos = context.getClickedPos(); + BlockState blockState = level.getBlockState(clickedPos); +- return shouldSolidify(level, clickedPos, blockState) ? this.concrete.defaultBlockState() : super.getStateForPlacement(context); ++ // CraftBukkit start ++ if (!ConcretePowderBlock.shouldSolidify(level, clickedPos, blockState)) { ++ return super.getStateForPlacement(context); ++ } ++ ++ // TODO: An event factory call for methods like this ++ org.bukkit.craftbukkit.block.CraftBlockState craftBlockState = org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState((net.minecraft.world.level.LevelAccessor) level, clickedPos); ++ craftBlockState.setData(this.concrete.defaultBlockState()); ++ ++ org.bukkit.event.block.BlockFormEvent event = new org.bukkit.event.block.BlockFormEvent(craftBlockState.getBlock(), craftBlockState); ++ level.getServer().server.getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) { ++ return craftBlockState.getHandle(); ++ } ++ ++ return super.getStateForPlacement(context); ++ // CraftBukkit end + } + + private static boolean shouldSolidify(BlockGetter level, BlockPos pos, BlockState state) { +@@ -88,9 +_,25 @@ + BlockState neighborState, + RandomSource random + ) { +- return touchesLiquid(level, pos) +- ? this.concrete.defaultBlockState() +- : super.updateShape(state, level, scheduledTickAccess, pos, direction, neighborPos, neighborState, random); ++ // CraftBukkit start ++ if (ConcretePowderBlock.touchesLiquid(level, pos)) { ++ // Suppress during worldgen ++ if (!(level instanceof Level world1)) { ++ return this.concrete.defaultBlockState(); ++ } ++ org.bukkit.craftbukkit.block.CraftBlockState blockState = org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(world1, pos); ++ blockState.setData(this.concrete.defaultBlockState()); ++ ++ org.bukkit.event.block.BlockFormEvent event = new org.bukkit.event.block.BlockFormEvent(blockState.getBlock(), blockState); ++ world1.getCraftServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) { ++ return blockState.getHandle(); ++ } ++ } ++ ++ return super.updateShape(state, level, scheduledTickAccess, pos, direction, neighborPos, neighborState, random); ++ // CraftBukkit end + } + + @Override diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/CoralBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/CoralBlock.java.patch similarity index 58% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/CoralBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/CoralBlock.java.patch index 389b3b96ec..87d67142fb 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/CoralBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/CoralBlock.java.patch @@ -1,14 +1,14 @@ --- a/net/minecraft/world/level/block/CoralBlock.java +++ b/net/minecraft/world/level/block/CoralBlock.java -@@ -40,6 +40,11 @@ +@@ -37,6 +_,11 @@ @Override - protected void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { - if (!this.scanForWater(world, pos)) { + protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { + if (!this.scanForWater(level, pos)) { + // CraftBukkit start -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, pos, this.deadBlock.defaultBlockState()).isCancelled()) { ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(level, pos, this.deadBlock.defaultBlockState()).isCancelled()) { + return; + } + // CraftBukkit end - world.setBlock(pos, this.deadBlock.defaultBlockState(), 2); + level.setBlock(pos, this.deadBlock.defaultBlockState(), 2); } - + } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/CoralFanBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/CoralFanBlock.java.patch similarity index 55% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/CoralFanBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/CoralFanBlock.java.patch index 295f4f0049..ff375bb06b 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/CoralFanBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/CoralFanBlock.java.patch @@ -1,14 +1,14 @@ --- a/net/minecraft/world/level/block/CoralFanBlock.java +++ b/net/minecraft/world/level/block/CoralFanBlock.java -@@ -41,6 +41,11 @@ +@@ -38,6 +_,11 @@ @Override - protected void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { - if (!scanForWater(state, world, pos)) { + protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { + if (!scanForWater(state, level, pos)) { + // CraftBukkit start -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, pos, this.deadBlock.defaultBlockState().setValue(CoralFanBlock.WATERLOGGED, false)).isCancelled()) { ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(level, pos, this.deadBlock.defaultBlockState().setValue(CoralFanBlock.WATERLOGGED, false)).isCancelled()) { + return; + } + // CraftBukkit end - world.setBlock(pos, (BlockState) this.deadBlock.defaultBlockState().setValue(CoralFanBlock.WATERLOGGED, false), 2); + level.setBlock(pos, this.deadBlock.defaultBlockState().setValue(WATERLOGGED, Boolean.valueOf(false)), 2); } - + } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/CoralPlantBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/CoralPlantBlock.java.patch similarity index 55% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/CoralPlantBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/CoralPlantBlock.java.patch index bccf3cd4a0..c768b4c634 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/CoralPlantBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/CoralPlantBlock.java.patch @@ -1,14 +1,14 @@ --- a/net/minecraft/world/level/block/CoralPlantBlock.java +++ b/net/minecraft/world/level/block/CoralPlantBlock.java -@@ -46,6 +46,11 @@ +@@ -43,6 +_,11 @@ @Override - protected void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { - if (!scanForWater(state, world, pos)) { + protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { + if (!scanForWater(state, level, pos)) { + // CraftBukkit start -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, pos, this.deadBlock.defaultBlockState().setValue(CoralPlantBlock.WATERLOGGED, false)).isCancelled()) { ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(level, pos, this.deadBlock.defaultBlockState().setValue(CoralPlantBlock.WATERLOGGED, false)).isCancelled()) { + return; + } + // CraftBukkit end - world.setBlock(pos, (BlockState) this.deadBlock.defaultBlockState().setValue(CoralPlantBlock.WATERLOGGED, false), 2); + level.setBlock(pos, this.deadBlock.defaultBlockState().setValue(WATERLOGGED, Boolean.valueOf(false)), 2); } - + } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/CoralWallFanBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/CoralWallFanBlock.java.patch similarity index 53% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/CoralWallFanBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/CoralWallFanBlock.java.patch index 172e22d8b2..7ac0a5182f 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/CoralWallFanBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/CoralWallFanBlock.java.patch @@ -1,14 +1,14 @@ --- a/net/minecraft/world/level/block/CoralWallFanBlock.java +++ b/net/minecraft/world/level/block/CoralWallFanBlock.java -@@ -41,6 +41,11 @@ +@@ -38,6 +_,11 @@ @Override - protected void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { - if (!scanForWater(state, world, pos)) { + protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { + if (!scanForWater(state, level, pos)) { + // CraftBukkit start -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, pos, this.deadBlock.defaultBlockState().setValue(CoralWallFanBlock.WATERLOGGED, false).setValue(CoralWallFanBlock.FACING, state.getValue(CoralWallFanBlock.FACING))).isCancelled()) { ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(level, pos, this.deadBlock.defaultBlockState().setValue(CoralWallFanBlock.WATERLOGGED, false).setValue(CoralWallFanBlock.FACING, state.getValue(CoralWallFanBlock.FACING))).isCancelled()) { + return; + } + // CraftBukkit end - world.setBlock(pos, (BlockState) ((BlockState) this.deadBlock.defaultBlockState().setValue(CoralWallFanBlock.WATERLOGGED, false)).setValue(CoralWallFanBlock.FACING, (Direction) state.getValue(CoralWallFanBlock.FACING)), 2); + level.setBlock(pos, this.deadBlock.defaultBlockState().setValue(WATERLOGGED, Boolean.valueOf(false)).setValue(FACING, state.getValue(FACING)), 2); } - + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/CrafterBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/CrafterBlock.java.patch new file mode 100644 index 0000000000..b592d3f859 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/CrafterBlock.java.patch @@ -0,0 +1,76 @@ +--- a/net/minecraft/world/level/block/CrafterBlock.java ++++ b/net/minecraft/world/level/block/CrafterBlock.java +@@ -11,6 +_,7 @@ + import net.minecraft.server.level.ServerLevel; + import net.minecraft.server.level.ServerPlayer; + import net.minecraft.util.RandomSource; ++import net.minecraft.world.CompoundContainer; + import net.minecraft.world.Container; + import net.minecraft.world.Containers; + import net.minecraft.world.InteractionResult; +@@ -159,6 +_,13 @@ + } else { + RecipeHolder recipeHolder = potentialResults.get(); + ItemStack itemStack = recipeHolder.value().assemble(var11, level.registryAccess()); ++ // CraftBukkit start ++ org.bukkit.event.block.CrafterCraftEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callCrafterCraftEvent(pos, level, crafterBlockEntity, itemStack, recipeHolder); ++ if (event.isCancelled()) { ++ return; ++ } ++ itemStack = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getResult()); ++ // CraftBukkit end + if (itemStack.isEmpty()) { + level.levelEvent(1050, pos, 0); + } else { +@@ -193,7 +_,25 @@ + Container containerAt = HopperBlockEntity.getContainerAt(level, pos.relative(direction)); + ItemStack itemStack = stack.copy(); + if (containerAt != null && (containerAt instanceof CrafterBlockEntity || stack.getCount() > containerAt.getMaxStackSize(stack))) { ++ // CraftBukkit start - InventoryMoveItemEvent ++ org.bukkit.craftbukkit.inventory.CraftItemStack oitemstack = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack); ++ ++ org.bukkit.inventory.Inventory destinationInventory; ++ // Have to special case large chests as they work oddly ++ if (containerAt instanceof CompoundContainer) { ++ destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((CompoundContainer) containerAt); ++ } else { ++ destinationInventory = containerAt.getOwner().getInventory(); ++ } ++ ++ org.bukkit.event.inventory.InventoryMoveItemEvent event = new org.bukkit.event.inventory.InventoryMoveItemEvent(crafter.getOwner().getInventory(), oitemstack, destinationInventory, true); ++ level.getCraftServer().getPluginManager().callEvent(event); ++ itemStack = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItem()); + while (!itemStack.isEmpty()) { ++ if (event.isCancelled()) { ++ break; ++ } ++ // CraftBukkit end + ItemStack itemStack1 = itemStack.copyWithCount(1); + ItemStack itemStack2 = HopperBlockEntity.addItem(crafter, containerAt, itemStack1, direction.getOpposite()); + if (!itemStack2.isEmpty()) { +@@ -203,7 +_,25 @@ + itemStack.shrink(1); + } + } else if (containerAt != null) { ++ // CraftBukkit start - InventoryMoveItemEvent ++ org.bukkit.craftbukkit.inventory.CraftItemStack oitemstack = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack); ++ ++ org.bukkit.inventory.Inventory destinationInventory; ++ // Have to special case large chests as they work oddly ++ if (containerAt instanceof CompoundContainer) { ++ destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((CompoundContainer) containerAt); ++ } else { ++ destinationInventory = containerAt.getOwner().getInventory(); ++ } ++ ++ org.bukkit.event.inventory.InventoryMoveItemEvent event = new org.bukkit.event.inventory.InventoryMoveItemEvent(crafter.getOwner().getInventory(), oitemstack, destinationInventory, true); ++ level.getCraftServer().getPluginManager().callEvent(event); ++ itemStack = org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItem()); + while (!itemStack.isEmpty()) { ++ if (event.isCancelled()) { ++ break; ++ } ++ // CraftBukkit end + int count = itemStack.getCount(); + itemStack = HopperBlockEntity.addItem(crafter, containerAt, itemStack, direction.getOpposite()); + if (count == itemStack.getCount()) { diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/CraftingTableBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/CraftingTableBlock.java.patch similarity index 62% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/CraftingTableBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/CraftingTableBlock.java.patch index e611ea83b5..3285cee056 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/CraftingTableBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/CraftingTableBlock.java.patch @@ -1,11 +1,10 @@ --- a/net/minecraft/world/level/block/CraftingTableBlock.java +++ b/net/minecraft/world/level/block/CraftingTableBlock.java -@@ -31,8 +31,9 @@ - @Override - protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { - if (!world.isClientSide) { -- player.openMenu(state.getMenuProvider(world, pos)); -+ if (player.openMenu(state.getMenuProvider(world, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation +@@ -32,7 +_,9 @@ + protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) { + if (!level.isClientSide) { + player.openMenu(state.getMenuProvider(level, pos)); ++ if (player.openMenu(state.getMenuProvider(level, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation player.awardStat(Stats.INTERACT_WITH_CRAFTING_TABLE); + } // Paper - Fix InventoryOpenEvent cancellation } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/CropBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/CropBlock.java.patch new file mode 100644 index 0000000000..2e9c06c89a --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/CropBlock.java.patch @@ -0,0 +1,49 @@ +--- a/net/minecraft/world/level/block/CropBlock.java ++++ b/net/minecraft/world/level/block/CropBlock.java +@@ -88,8 +_,25 @@ + int age = this.getAge(state); + if (age < this.getMaxAge()) { + float growthSpeed = getGrowthSpeed(this, level, pos); +- if (random.nextInt((int)(25.0F / growthSpeed) + 1) == 0) { +- level.setBlock(pos, this.getStateForAge(age + 1), 2); ++ // Spigot start ++ int modifier; ++ if (this == Blocks.BEETROOTS) { ++ modifier = level.spigotConfig.beetrootModifier; ++ } else if (this == Blocks.CARROTS) { ++ modifier = level.spigotConfig.carrotModifier; ++ } else if (this == Blocks.POTATOES) { ++ modifier = level.spigotConfig.potatoModifier; ++ // Paper start - Fix Spigot growth modifiers ++ } else if (this == Blocks.TORCHFLOWER_CROP) { ++ modifier = level.spigotConfig.torchFlowerModifier; ++ // Paper end - Fix Spigot growth modifiers ++ } else { ++ modifier = level.spigotConfig.wheatModifier; ++ } ++ ++ if (random.nextFloat() < (modifier / (100.0f * (Math.floor((25.0F / growthSpeed) + 1))))) { // Spigot - SPIGOT-7159: Better modifier resolution ++ // Spigot end ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, pos, this.getStateForAge(age + 1), 2); // CraftBukkit + } + } + } +@@ -102,7 +_,7 @@ + i = maxAge; + } + +- level.setBlock(pos, this.getStateForAge(i), 2); ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, pos, this.getStateForAge(i), 2); // CraftBukkit + } + + protected int getBonemealAgeIncrease(Level level) { +@@ -164,7 +_,8 @@ + + @Override + protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) { +- if (level instanceof ServerLevel serverLevel && entity instanceof Ravager && serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { ++ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent ++ if (level instanceof ServerLevel serverLevel && entity instanceof Ravager && org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState(), !serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit + serverLevel.destroyBlock(pos, true, entity); + } + diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/DaylightDetectorBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/DaylightDetectorBlock.java.patch new file mode 100644 index 0000000000..eee537faaa --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/DaylightDetectorBlock.java.patch @@ -0,0 +1,10 @@ +--- a/net/minecraft/world/level/block/DaylightDetectorBlock.java ++++ b/net/minecraft/world/level/block/DaylightDetectorBlock.java +@@ -70,6 +_,7 @@ + + i = Mth.clamp(i, 0, 15); + if (state.getValue(POWER) != i) { ++ i = org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, state.getValue(DaylightDetectorBlock.POWER), i).getNewCurrent(); // CraftBukkit - Call BlockRedstoneEvent + level.setBlock(pos, state.setValue(POWER, Integer.valueOf(i)), 3); + } + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/DecoratedPotBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/DecoratedPotBlock.java.patch new file mode 100644 index 0000000000..492d3d7e78 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/DecoratedPotBlock.java.patch @@ -0,0 +1,14 @@ +--- a/net/minecraft/world/level/block/DecoratedPotBlock.java ++++ b/net/minecraft/world/level/block/DecoratedPotBlock.java +@@ -237,6 +_,11 @@ + protected void onProjectileHit(Level level, BlockState state, BlockHitResult hit, Projectile projectile) { + BlockPos blockPos = hit.getBlockPos(); + if (level instanceof ServerLevel serverLevel && projectile.mayInteract(serverLevel, blockPos) && projectile.mayBreak(serverLevel)) { ++ // CraftBukkit start - call EntityChangeBlockEvent ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(projectile, blockPos, this.getFluidState(state).createLegacyBlock())) { ++ return; ++ } ++ // CraftBukkit end + level.setBlock(blockPos, state.setValue(CRACKED, Boolean.valueOf(true)), 4); + level.destroyBlock(blockPos, true, projectile); + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/DetectorRailBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/DetectorRailBlock.java.patch new file mode 100644 index 0000000000..3dcaa1506e --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/DetectorRailBlock.java.patch @@ -0,0 +1,35 @@ +--- a/net/minecraft/world/level/block/DetectorRailBlock.java ++++ b/net/minecraft/world/level/block/DetectorRailBlock.java +@@ -54,6 +_,7 @@ + + @Override + protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) { ++ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent + if (!level.isClientSide) { + if (!state.getValue(POWERED)) { + this.checkPressed(level, pos, state); +@@ -84,6 +_,7 @@ + + private void checkPressed(Level level, BlockPos pos, BlockState state) { + if (this.canSurvive(state, level, pos)) { ++ if (state.getBlock() != this) { return; } // Paper - Fix some rails connecting improperly + boolean poweredValue = state.getValue(POWERED); + boolean flag = false; + List interactingMinecartOfType = this.getInteractingMinecartOfType(level, pos, AbstractMinecart.class, entity -> true); +@@ -91,6 +_,16 @@ + flag = true; + } + ++ // CraftBukkit start ++ if (poweredValue != flag) { ++ org.bukkit.block.Block block = level.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); ++ ++ org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(block, flag ? 15 : 0, flag ? 15 : 0); ++ level.getCraftServer().getPluginManager().callEvent(eventRedstone); ++ ++ flag = eventRedstone.getNewCurrent() > 0; ++ } ++ // CraftBukkit end + if (flag && !poweredValue) { + BlockState blockState = state.setValue(POWERED, Boolean.valueOf(true)); + level.setBlock(pos, blockState, 3); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/DiodeBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/DiodeBlock.java.patch new file mode 100644 index 0000000000..bde27499c8 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/DiodeBlock.java.patch @@ -0,0 +1,21 @@ +--- a/net/minecraft/world/level/block/DiodeBlock.java ++++ b/net/minecraft/world/level/block/DiodeBlock.java +@@ -56,8 +_,18 @@ + boolean poweredValue = state.getValue(POWERED); + boolean shouldTurnOn = this.shouldTurnOn(level, pos, state); + if (poweredValue && !shouldTurnOn) { ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, 15, 0).getNewCurrent() != 0) { ++ return; ++ } ++ // CraftBukkit end + level.setBlock(pos, state.setValue(POWERED, Boolean.valueOf(false)), 2); + } else if (!poweredValue) { ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, 0, 15).getNewCurrent() != 15) { ++ return; ++ } ++ // CraftBukkit end + level.setBlock(pos, state.setValue(POWERED, Boolean.valueOf(true)), 2); + if (!shouldTurnOn) { + level.scheduleTick(pos, this, this.getDelay(state), TickPriority.VERY_HIGH); diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/DirtPathBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/DirtPathBlock.java.patch similarity index 61% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/DirtPathBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/DirtPathBlock.java.patch index b394c4adfa..bc73d1c956 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/DirtPathBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/DirtPathBlock.java.patch @@ -1,14 +1,14 @@ --- a/net/minecraft/world/level/block/DirtPathBlock.java +++ b/net/minecraft/world/level/block/DirtPathBlock.java -@@ -51,6 +51,11 @@ +@@ -60,6 +_,11 @@ @Override - protected void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { + protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { + // CraftBukkit start - do not fade if the block is valid here -+ if (state.canSurvive(world, pos)) { ++ if (state.canSurvive(level, pos)) { + return; + } + // CraftBukkit end - FarmBlock.turnToDirt((Entity) null, state, world, pos); + FarmBlock.turnToDirt(null, state, level, pos); } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/DispenserBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/DispenserBlock.java.patch new file mode 100644 index 0000000000..1660450641 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/DispenserBlock.java.patch @@ -0,0 +1,47 @@ +--- a/net/minecraft/world/level/block/DispenserBlock.java ++++ b/net/minecraft/world/level/block/DispenserBlock.java +@@ -50,6 +_,7 @@ + private static final DefaultDispenseItemBehavior DEFAULT_BEHAVIOR = new DefaultDispenseItemBehavior(); + public static final Map DISPENSER_REGISTRY = new IdentityHashMap<>(); + private static final int TRIGGER_DURATION = 4; ++ public static boolean eventFired = false; // CraftBukkit + + @Override + public MapCodec codec() { +@@ -71,8 +_,7 @@ + + @Override + protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) { +- if (!level.isClientSide && level.getBlockEntity(pos) instanceof DispenserBlockEntity dispenserBlockEntity) { +- player.openMenu(dispenserBlockEntity); ++ if (!level.isClientSide && level.getBlockEntity(pos) instanceof DispenserBlockEntity dispenserBlockEntity && player.openMenu(dispenserBlockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation + player.awardStat(dispenserBlockEntity instanceof DropperBlockEntity ? Stats.INSPECT_DROPPER : Stats.INSPECT_DISPENSER); + } + +@@ -87,18 +_,26 @@ + BlockSource blockSource = new BlockSource(level, pos, state, dispenserBlockEntity); + int randomSlot = dispenserBlockEntity.getRandomSlot(level.random); + if (randomSlot < 0) { ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFailedDispenseEvent(level, pos)) { // Paper - Add BlockFailedDispenseEvent + level.levelEvent(1001, pos, 0); + level.gameEvent(GameEvent.BLOCK_ACTIVATE, pos, GameEvent.Context.of(dispenserBlockEntity.getBlockState())); ++ } // Paper - Add BlockFailedDispenseEvent + } else { + ItemStack item = dispenserBlockEntity.getItem(randomSlot); + DispenseItemBehavior dispenseMethod = this.getDispenseMethod(level, item); + if (dispenseMethod != DispenseItemBehavior.NOOP) { ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockPreDispenseEvent(level, pos, item, randomSlot)) return; // Paper - Add BlockPreDispenseEvent + dispenserBlockEntity.setItem(randomSlot, dispenseMethod.dispense(blockSource, item)); + } + } + } + } + ++ // Paper start - Fix NPE with equippable and items without behavior ++ public static DispenseItemBehavior getDispenseBehavior(BlockSource pointer, ItemStack stack) { ++ return ((DispenserBlock) pointer.state().getBlock()).getDispenseMethod(pointer.level(), stack); ++ } ++ // Paper end - Fix NPE with equippable and items without behavior + protected DispenseItemBehavior getDispenseMethod(Level level, ItemStack item) { + if (!item.isItemEnabled(level.enabledFeatures())) { + return DEFAULT_BEHAVIOR; diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/DoorBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/DoorBlock.java.patch new file mode 100644 index 0000000000..87099f1713 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/DoorBlock.java.patch @@ -0,0 +1,29 @@ +--- a/net/minecraft/world/level/block/DoorBlock.java ++++ b/net/minecraft/world/level/block/DoorBlock.java +@@ -229,9 +_,23 @@ + + @Override + protected void neighborChanged(BlockState state, Level level, BlockPos pos, Block neighborBlock, @Nullable Orientation orientation, boolean movedByPiston) { +- boolean flag = level.hasNeighborSignal(pos) +- || level.hasNeighborSignal(pos.relative(state.getValue(HALF) == DoubleBlockHalf.LOWER ? Direction.UP : Direction.DOWN)); +- if (!this.defaultBlockState().is(neighborBlock) && flag != state.getValue(POWERED)) { ++ // CraftBukkit start ++ BlockPos otherHalf = pos.relative(state.getValue(DoorBlock.HALF) == DoubleBlockHalf.LOWER ? Direction.UP : Direction.DOWN); ++ org.bukkit.World bworld = level.getWorld(); ++ org.bukkit.block.Block bukkitBlock = bworld.getBlockAt(pos.getX(), pos.getY(), pos.getZ()); ++ org.bukkit.block.Block blockTop = bworld.getBlockAt(otherHalf.getX(), otherHalf.getY(), otherHalf.getZ()); ++ ++ int power = bukkitBlock.getBlockPower(); ++ int powerTop = blockTop.getBlockPower(); ++ if (powerTop > power) power = powerTop; ++ int oldPower = (Boolean) state.getValue(DoorBlock.POWERED) ? 15 : 0; ++ ++ if (oldPower == 0 ^ power == 0) { ++ org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(bukkitBlock, oldPower, power); ++ level.getCraftServer().getPluginManager().callEvent(eventRedstone); ++ ++ boolean flag = eventRedstone.getNewCurrent() > 0; ++ // CraftBukkit end + if (flag != state.getValue(OPEN)) { + this.playSound(null, level, pos, flag); + level.gameEvent(null, flag ? GameEvent.BLOCK_OPEN : GameEvent.BLOCK_CLOSE, pos); diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/DoubleBlockCombiner.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/DoubleBlockCombiner.java.patch similarity index 63% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/DoubleBlockCombiner.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/DoubleBlockCombiner.java.patch index 657fe3fb50..3416e7d85d 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/DoubleBlockCombiner.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/DoubleBlockCombiner.java.patch @@ -1,16 +1,16 @@ --- a/net/minecraft/world/level/block/DoubleBlockCombiner.java +++ b/net/minecraft/world/level/block/DoubleBlockCombiner.java -@@ -34,7 +34,12 @@ +@@ -34,7 +_,12 @@ return new DoubleBlockCombiner.NeighborCombineResult.Single<>(blockEntity); } else { - BlockPos blockPos = pos.relative(directionMapper.apply(state)); -- BlockState blockState = world.getBlockState(blockPos); + BlockPos blockPos = pos.relative(directionGetter.apply(state)); +- BlockState blockState = level.getBlockState(blockPos); + // Paper start - Don't load Chunks from Hoppers and other things -+ BlockState blockState = world.getBlockStateIfLoaded(blockPos); ++ BlockState blockState = level.getBlockStateIfLoaded(blockPos); + if (blockState == null) { + return new DoubleBlockCombiner.NeighborCombineResult.Single<>(blockEntity); + } + // Paper end - Don't load Chunks from Hoppers and other things if (blockState.is(state.getBlock())) { - DoubleBlockCombiner.BlockType blockType2 = typeMapper.apply(blockState); - if (blockType2 != DoubleBlockCombiner.BlockType.SINGLE + DoubleBlockCombiner.BlockType blockType1 = doubleBlockTypeGetter.apply(blockState); + if (blockType1 != DoubleBlockCombiner.BlockType.SINGLE diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/DoublePlantBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/DoublePlantBlock.java.patch new file mode 100644 index 0000000000..f57b086e6a --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/DoublePlantBlock.java.patch @@ -0,0 +1,21 @@ +--- a/net/minecraft/world/level/block/DoublePlantBlock.java ++++ b/net/minecraft/world/level/block/DoublePlantBlock.java +@@ -112,11 +_,16 @@ + } + + @Override +- public void playerDestroy(Level level, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity te, ItemStack stack) { +- super.playerDestroy(level, player, pos, Blocks.AIR.defaultBlockState(), te, stack); ++ public void playerDestroy(Level level, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity te, ItemStack stack, boolean includeDrops, boolean dropExp) { // Paper - fix drops not preventing stats/food exhaustion ++ super.playerDestroy(level, player, pos, Blocks.AIR.defaultBlockState(), te, stack, includeDrops, dropExp); // Paper - fix drops not preventing stats/food exhaustion; + } + + protected static void preventDropFromBottomPart(Level level, BlockPos pos, BlockState state, Player player) { ++ // CraftBukkit start ++ if (((net.minecraft.server.level.ServerLevel)level).hasPhysicsEvent && org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPhysicsEvent(level, pos).isCancelled()) { // Paper ++ return; ++ } ++ // CraftBukkit end + DoubleBlockHalf doubleBlockHalf = state.getValue(HALF); + if (doubleBlockHalf == DoubleBlockHalf.UPPER) { + BlockPos blockPos = pos.below(); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/DragonEggBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/DragonEggBlock.java.patch new file mode 100644 index 0000000000..4d35f93eec --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/DragonEggBlock.java.patch @@ -0,0 +1,21 @@ +--- a/net/minecraft/world/level/block/DragonEggBlock.java ++++ b/net/minecraft/world/level/block/DragonEggBlock.java +@@ -55,6 +_,18 @@ + level.random.nextInt(16) - level.random.nextInt(16) + ); + if (level.getBlockState(blockPos).isAir() && worldBorder.isWithinBounds(blockPos)) { ++ // CraftBukkit start ++ org.bukkit.block.Block from = level.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); ++ org.bukkit.block.Block to = level.getWorld().getBlockAt(blockPos.getX(), blockPos.getY(), blockPos.getZ()); ++ org.bukkit.event.block.BlockFromToEvent event = new org.bukkit.event.block.BlockFromToEvent(from, to); ++ org.bukkit.Bukkit.getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) { ++ return; ++ } ++ ++ blockPos = new BlockPos(event.getToBlock().getX(), event.getToBlock().getY(), event.getToBlock().getZ()); ++ // CraftBukkit end + if (level.isClientSide) { + for (int i1 = 0; i1 < 128; i1++) { + double randomDouble = level.random.nextDouble(); diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/DropExperienceBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/DropExperienceBlock.java.patch similarity index 71% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/DropExperienceBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/DropExperienceBlock.java.patch index 4d0a4875d4..1487606ce5 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/DropExperienceBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/DropExperienceBlock.java.patch @@ -1,11 +1,12 @@ --- a/net/minecraft/world/level/block/DropExperienceBlock.java +++ b/net/minecraft/world/level/block/DropExperienceBlock.java -@@ -31,9 +31,16 @@ +@@ -31,8 +_,16 @@ @Override - protected void spawnAfterBreak(BlockState state, ServerLevel world, BlockPos pos, ItemStack tool, boolean dropExperience) { - super.spawnAfterBreak(state, world, pos, tool, dropExperience); + protected void spawnAfterBreak(BlockState state, ServerLevel level, BlockPos pos, ItemStack stack, boolean dropExperience) { + super.spawnAfterBreak(state, level, pos, stack, dropExperience); - if (dropExperience) { -- this.tryDropExperience(world, pos, tool, this.xpRange); +- this.tryDropExperience(level, pos, stack, this.xpRange); +- } + // CraftBukkit start - Delegate to getExpDrop + } + @@ -13,8 +14,8 @@ + public int getExpDrop(BlockState iblockdata, ServerLevel worldserver, BlockPos blockposition, ItemStack itemstack, boolean flag) { + if (flag) { + return this.tryDropExperience(worldserver, blockposition, itemstack, this.xpRange); - } - ++ } ++ + return 0; + // CraftBukkit end } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/DropperBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/DropperBlock.java.patch new file mode 100644 index 0000000000..047ee9babb --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/DropperBlock.java.patch @@ -0,0 +1,59 @@ +--- a/net/minecraft/world/level/block/DropperBlock.java ++++ b/net/minecraft/world/level/block/DropperBlock.java +@@ -8,6 +_,7 @@ + import net.minecraft.core.dispenser.DefaultDispenseItemBehavior; + import net.minecraft.core.dispenser.DispenseItemBehavior; + import net.minecraft.server.level.ServerLevel; ++import net.minecraft.world.CompoundContainer; + import net.minecraft.world.Container; + import net.minecraft.world.item.ItemStack; + import net.minecraft.world.level.Level; +@@ -23,7 +_,7 @@ + public class DropperBlock extends DispenserBlock { + private static final Logger LOGGER = LogUtils.getLogger(); + public static final MapCodec CODEC = simpleCodec(DropperBlock::new); +- private static final DispenseItemBehavior DISPENSE_BEHAVIOUR = new DefaultDispenseItemBehavior(); ++ private static final DispenseItemBehavior DISPENSE_BEHAVIOUR = new DefaultDispenseItemBehavior(true); // CraftBukkit + + @Override + public MapCodec codec() { +@@ -53,6 +_,7 @@ + BlockSource blockSource = new BlockSource(level, pos, state, dispenserBlockEntity); + int randomSlot = dispenserBlockEntity.getRandomSlot(level.random); + if (randomSlot < 0) { ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFailedDispenseEvent(level, pos)) // Paper - Add BlockFailedDispenseEvent + level.levelEvent(1001, pos, 0); + } else { + ItemStack item = dispenserBlockEntity.getItem(randomSlot); +@@ -61,10 +_,29 @@ + Container containerAt = HopperBlockEntity.getContainerAt(level, pos.relative(direction)); + ItemStack itemStack; + if (containerAt == null) { ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockPreDispenseEvent(level, pos, item, randomSlot)) return; // Paper - Add BlockPreDispenseEvent + itemStack = DISPENSE_BEHAVIOUR.dispense(blockSource, item); + } else { +- itemStack = HopperBlockEntity.addItem(dispenserBlockEntity, containerAt, item.copyWithCount(1), direction.getOpposite()); +- if (itemStack.isEmpty()) { ++ // CraftBukkit start - Fire event when pushing items into other inventories ++ org.bukkit.craftbukkit.inventory.CraftItemStack oitemstack = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(item.copyWithCount(1)); ++ ++ org.bukkit.inventory.Inventory destinationInventory; ++ // Have to special case large chests as they work oddly ++ if (containerAt instanceof CompoundContainer) { ++ destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((CompoundContainer) containerAt); ++ } else { ++ destinationInventory = containerAt.getOwner().getInventory(); ++ } ++ ++ org.bukkit.event.inventory.InventoryMoveItemEvent event = new org.bukkit.event.inventory.InventoryMoveItemEvent(containerAt.getOwner().getInventory(), oitemstack, destinationInventory, true); ++ level.getCraftServer().getPluginManager().callEvent(event); ++ if (event.isCancelled()) { ++ return; ++ } ++ itemStack = HopperBlockEntity.addItem(dispenserBlockEntity, containerAt, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItem()), direction.getOpposite()); ++ if (event.getItem().equals(oitemstack) && itemStack.isEmpty()) { ++ // CraftBukkit end ++ + itemStack = item.copy(); + itemStack.shrink(1); + } else { diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/EndGatewayBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/EndGatewayBlock.java.patch new file mode 100644 index 0000000000..2b564a8c31 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/EndGatewayBlock.java.patch @@ -0,0 +1,30 @@ +--- a/net/minecraft/world/level/block/EndGatewayBlock.java ++++ b/net/minecraft/world/level/block/EndGatewayBlock.java +@@ -89,10 +_,15 @@ + + @Override + protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) { ++ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent + if (entity.canUsePortal(false) + && !level.isClientSide + && level.getBlockEntity(pos) instanceof TheEndGatewayBlockEntity theEndGatewayBlockEntity + && !theEndGatewayBlockEntity.isCoolingDown()) { ++ // Paper start - call EntityPortalEnterEvent ++ org.bukkit.event.entity.EntityPortalEnterEvent event = new org.bukkit.event.entity.EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(level.getWorld(), pos.getX(), pos.getY(), pos.getZ()), org.bukkit.PortalType.END_GATEWAY); // Paper - add portal type ++ if (!event.callEvent()) return; ++ // Paper end - call EntityPortalEnterEvent + entity.setAsInsidePortal(this, pos); + TheEndGatewayBlockEntity.triggerCooldown(level, pos, state, theEndGatewayBlockEntity); + } +@@ -107,9 +_,9 @@ + return null; + } else { + return entity instanceof ThrownEnderpearl +- ? new TeleportTransition(level, portalPosition, Vec3.ZERO, 0.0F, 0.0F, Set.of(), TeleportTransition.PLACE_PORTAL_TICKET) ++ ? new TeleportTransition(level, portalPosition, Vec3.ZERO, 0.0F, 0.0F, Set.of(), TeleportTransition.PLACE_PORTAL_TICKET, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.END_GATEWAY) // CraftBukkit + : new TeleportTransition( +- level, portalPosition, Vec3.ZERO, 0.0F, 0.0F, Relative.union(Relative.DELTA, Relative.ROTATION), TeleportTransition.PLACE_PORTAL_TICKET ++ level, portalPosition, Vec3.ZERO, 0.0F, 0.0F, Relative.union(Relative.DELTA, Relative.ROTATION), TeleportTransition.PLACE_PORTAL_TICKET, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.END_GATEWAY // CraftBukkit + ); + } + } else { diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/EndPortalBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/EndPortalBlock.java.patch new file mode 100644 index 0000000000..436949f5f8 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/EndPortalBlock.java.patch @@ -0,0 +1,62 @@ +--- a/net/minecraft/world/level/block/EndPortalBlock.java ++++ b/net/minecraft/world/level/block/EndPortalBlock.java +@@ -56,8 +_,15 @@ + + @Override + protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) { ++ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent + if (entity.canUsePortal(false)) { ++ // CraftBukkit start - Entity in portal ++ org.bukkit.event.entity.EntityPortalEnterEvent event = new org.bukkit.event.entity.EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(level.getWorld(), pos.getX(), pos.getY(), pos.getZ()), org.bukkit.PortalType.ENDER); // Paper - add portal type ++ level.getCraftServer().getPluginManager().callEvent(event); ++ if (event.isCancelled()) return; // Paper - make cancellable ++ // CraftBukkit end + if (!level.isClientSide && level.dimension() == Level.END && entity instanceof ServerPlayer serverPlayer && !serverPlayer.seenCredits) { ++ if (level.paperConfig().misc.disableEndCredits) {serverPlayer.seenCredits = true; return;} // Paper - Option to disable end credits + serverPlayer.showEndCredits(); + } else { + entity.setAsInsidePortal(this, pos); +@@ -67,7 +_,7 @@ + + @Override + public TeleportTransition getPortalDestination(ServerLevel level, Entity entity, BlockPos pos) { +- ResourceKey resourceKey = level.dimension() == Level.END ? Level.OVERWORLD : Level.END; ++ ResourceKey resourceKey = level.getTypeKey() == net.minecraft.world.level.dimension.LevelStem.END ? Level.OVERWORLD : Level.END; // CraftBukkit - SPIGOT-6152: send back to main overworld in custom ends + ServerLevel level1 = level.getServer().getLevel(resourceKey); + if (level1 == null) { + return null; +@@ -78,7 +_,7 @@ + float f; + Set set; + if (flag) { +- EndPlatformFeature.createEndPlatform(level1, BlockPos.containing(bottomCenter).below(), true); ++ EndPlatformFeature.createEndPlatform(level1, BlockPos.containing(bottomCenter).below(), true, entity); // CraftBukkit + f = Direction.WEST.toYRot(); + set = Relative.union(Relative.DELTA, Set.of(Relative.X_ROT)); + if (entity instanceof ServerPlayer) { +@@ -88,15 +_,21 @@ + f = 0.0F; + set = Relative.union(Relative.DELTA, Relative.ROTATION); + if (entity instanceof ServerPlayer serverPlayer) { +- return serverPlayer.findRespawnPositionAndUseSpawnBlock(false, TeleportTransition.DO_NOTHING); ++ return serverPlayer.findRespawnPositionAndUseSpawnBlock(false, TeleportTransition.DO_NOTHING, org.bukkit.event.player.PlayerRespawnEvent.RespawnReason.END_PORTAL); // CraftBukkit + } + + bottomCenter = entity.adjustSpawnLocation(level1, blockPos).getBottomCenter(); + } + +- return new TeleportTransition( +- level1, bottomCenter, Vec3.ZERO, f, 0.0F, set, TeleportTransition.PLAY_PORTAL_SOUND.then(TeleportTransition.PLACE_PORTAL_TICKET) +- ); ++ // CraftBukkit start ++ org.bukkit.craftbukkit.event.CraftPortalEvent event = entity.callPortalEvent(entity, org.bukkit.craftbukkit.util.CraftLocation.toBukkit(bottomCenter, level1.getWorld(), f, entity.getXRot()), org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.END_PORTAL, 0, 0); ++ if (event == null) { ++ return null; ++ } ++ org.bukkit.Location to = event.getTo(); ++ ++ return new TeleportTransition(((org.bukkit.craftbukkit.CraftWorld) to.getWorld()).getHandle(), org.bukkit.craftbukkit.util.CraftLocation.toVec3D(to), entity.getDeltaMovement(), to.getYaw(), to.getPitch(), set, TeleportTransition.PLAY_PORTAL_SOUND.then(TeleportTransition.PLACE_PORTAL_TICKET), org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.END_PORTAL); ++ // CraftBukkit end + } + } + diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/EnderChestBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/EnderChestBlock.java.patch new file mode 100644 index 0000000000..cc9bee614b --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/EnderChestBlock.java.patch @@ -0,0 +1,26 @@ +--- a/net/minecraft/world/level/block/EnderChestBlock.java ++++ b/net/minecraft/world/level/block/EnderChestBlock.java +@@ -78,16 +_,15 @@ + PlayerEnderChestContainer enderChestInventory = player.getEnderChestInventory(); + if (enderChestInventory != null && level.getBlockEntity(pos) instanceof EnderChestBlockEntity enderChestBlockEntity) { + BlockPos blockPos = pos.above(); +- if (level.getBlockState(blockPos).isRedstoneConductor(level, blockPos)) { ++ if (level.getBlockState(blockPos).isRedstoneConductor(level, blockPos)) { // Paper - diff on change; make sure that EnderChest#isBlocked uses the same logic + return InteractionResult.SUCCESS; + } else { +- if (level instanceof ServerLevel serverLevel) { +- enderChestInventory.setActiveChest(enderChestBlockEntity); +- player.openMenu( +- new SimpleMenuProvider( +- (containerId, playerInventory, player1) -> ChestMenu.threeRows(containerId, playerInventory, enderChestInventory), CONTAINER_TITLE +- ) +- ); ++ // Paper start - Fix InventoryOpenEvent cancellation - moved up; ++ enderChestInventory.setActiveChest(enderChestBlockEntity); // Needs to happen before ChestMenu.threeRows as it is required for opening animations ++ if (level instanceof ServerLevel serverLevel && player.openMenu( ++ new SimpleMenuProvider((i, inventory, playerx) -> ChestMenu.threeRows(i, inventory, enderChestInventory), CONTAINER_TITLE) ++ ).isPresent()) { ++ // Paper end - Fix InventoryOpenEvent cancellation - moved up; + player.awardStat(Stats.OPEN_ENDERCHEST); + PiglinAi.angerNearbyPiglins(serverLevel, player, true); + } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/EyeblossomBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/EyeblossomBlock.java.patch similarity index 59% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/EyeblossomBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/EyeblossomBlock.java.patch index 0f677874ee..a7765e31cc 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/EyeblossomBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/EyeblossomBlock.java.patch @@ -1,10 +1,10 @@ --- a/net/minecraft/world/level/block/EyeblossomBlock.java +++ b/net/minecraft/world/level/block/EyeblossomBlock.java -@@ -100,6 +100,7 @@ +@@ -99,6 +_,7 @@ @Override - protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { -+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent - if (!world.isClientSide() - && world.getDifficulty() != Difficulty.PEACEFUL + protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) { ++ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent + if (!level.isClientSide() + && level.getDifficulty() != Difficulty.PEACEFUL && entity instanceof Bee bee diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/FarmBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/FarmBlock.java.patch new file mode 100644 index 0000000000..fb670445d2 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/FarmBlock.java.patch @@ -0,0 +1,93 @@ +--- a/net/minecraft/world/level/block/FarmBlock.java ++++ b/net/minecraft/world/level/block/FarmBlock.java +@@ -95,31 +_,56 @@ + @Override + protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { + int moistureValue = state.getValue(MOISTURE); ++ if (moistureValue > 0 && level.paperConfig().tickRates.wetFarmland != 1 && (level.paperConfig().tickRates.wetFarmland < 1 || (net.minecraft.server.MinecraftServer.currentTick + pos.hashCode()) % level.paperConfig().tickRates.wetFarmland != 0)) { return; } // Paper - Configurable random tick rates for blocks ++ if (moistureValue == 0 && level.paperConfig().tickRates.dryFarmland != 1 && (level.paperConfig().tickRates.dryFarmland < 1 || (net.minecraft.server.MinecraftServer.currentTick + pos.hashCode()) % level.paperConfig().tickRates.dryFarmland != 0)) { return; } // Paper - Configurable random tick rates for blocks + if (!isNearWater(level, pos) && !level.isRainingAt(pos.above())) { + if (moistureValue > 0) { +- level.setBlock(pos, state.setValue(MOISTURE, Integer.valueOf(moistureValue - 1)), 2); ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleMoistureChangeEvent(level, pos, state.setValue(FarmBlock.MOISTURE, moistureValue - 1), 2); // CraftBukkit + } else if (!shouldMaintainFarmland(level, pos)) { + turnToDirt(null, state, level, pos); + } + } else if (moistureValue < 7) { +- level.setBlock(pos, state.setValue(MOISTURE, Integer.valueOf(7)), 2); ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleMoistureChangeEvent(level, pos, state.setValue(FarmBlock.MOISTURE, 7), 2); // CraftBukkit + } + } + + @Override + public void fallOn(Level level, BlockState state, BlockPos pos, Entity entity, float fallDistance) { ++ super.fallOn(level, state, pos, entity, fallDistance); // CraftBukkit - moved here as game rules / events shouldn't affect fall damage. + if (level instanceof ServerLevel serverLevel + && level.random.nextFloat() < fallDistance - 0.5F + && entity instanceof LivingEntity + && (entity instanceof Player || serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) + && entity.getBbWidth() * entity.getBbWidth() * entity.getBbHeight() > 0.512F) { ++ // CraftBukkit start - Interact soil ++ org.bukkit.event.Cancellable cancellable; ++ if (entity instanceof Player) { ++ cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((Player) entity, org.bukkit.event.block.Action.PHYSICAL, pos, null, null, null); ++ } else { ++ cancellable = new org.bukkit.event.entity.EntityInteractEvent(entity.getBukkitEntity(), level.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ())); ++ level.getCraftServer().getPluginManager().callEvent((org.bukkit.event.entity.EntityInteractEvent) cancellable); ++ } ++ ++ if (cancellable.isCancelled()) { ++ return; ++ } ++ ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.DIRT.defaultBlockState())) { ++ return; ++ } ++ // CraftBukkit end + turnToDirt(entity, state, level, pos); + } + +- super.fallOn(level, state, pos, entity, fallDistance); ++ // super.fallOn(level, state, pos, entity, fallDistance); // CraftBukkit - moved up + } + + public static void turnToDirt(@Nullable Entity entity, BlockState state, Level level, BlockPos pos) { ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(level, pos, Blocks.DIRT.defaultBlockState()).isCancelled()) { ++ return; ++ } ++ // CraftBukkit end + BlockState blockState = pushEntitiesUp(state, Blocks.DIRT.defaultBlockState(), level, pos); + level.setBlockAndUpdate(pos, blockState); + level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(entity, blockState)); +@@ -130,13 +_,27 @@ + } + + private static boolean isNearWater(LevelReader level, BlockPos pos) { +- for (BlockPos blockPos : BlockPos.betweenClosed(pos.offset(-4, 0, -4), pos.offset(4, 1, 4))) { +- if (level.getFluidState(blockPos).is(FluidTags.WATER)) { +- return true; ++ // Paper start - Perf: remove abstract block iteration ++ int xOff = pos.getX(); ++ int yOff = pos.getY(); ++ int zOff = pos.getZ(); ++ for (int dz = -4; dz <= 4; ++dz) { ++ int z = dz + zOff; ++ for (int dx = -4; dx <= 4; ++dx) { ++ int x = xOff + dx; ++ for (int dy = 0; dy <= 1; ++dy) { ++ int y = dy + yOff; ++ net.minecraft.world.level.chunk.LevelChunk chunk = (net.minecraft.world.level.chunk.LevelChunk)level.getChunk(x >> 4, z >> 4); ++ net.minecraft.world.level.material.FluidState fluid = chunk.getBlockStateFinal(x, y, z).getFluidState(); ++ if (fluid.is(FluidTags.WATER)) { ++ return true; ++ } ++ } + } + } + + return false; ++ // Paper end - Perf: remove abstract block iteration + } + + @Override diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/FenceGateBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/FenceGateBlock.java.patch new file mode 100644 index 0000000000..718a99aac2 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/FenceGateBlock.java.patch @@ -0,0 +1,20 @@ +--- a/net/minecraft/world/level/block/FenceGateBlock.java ++++ b/net/minecraft/world/level/block/FenceGateBlock.java +@@ -213,6 +_,17 @@ + protected void neighborChanged(BlockState state, Level level, BlockPos pos, Block neighborBlock, @Nullable Orientation orientation, boolean movedByPiston) { + if (!level.isClientSide) { + boolean hasNeighborSignal = level.hasNeighborSignal(pos); ++ // CraftBukkit start ++ boolean oldPowered = state.getValue(FenceGateBlock.POWERED); ++ if (oldPowered != hasNeighborSignal) { ++ int newPower = hasNeighborSignal ? 15 : 0; ++ int oldPower = oldPowered ? 15 : 0; ++ org.bukkit.block.Block bukkitBlock = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos); ++ org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(bukkitBlock, oldPower, newPower); ++ level.getCraftServer().getPluginManager().callEvent(eventRedstone); ++ hasNeighborSignal = eventRedstone.getNewCurrent() > 0; ++ } ++ // CraftBukkit end + if (state.getValue(POWERED) != hasNeighborSignal) { + level.setBlock(pos, state.setValue(POWERED, Boolean.valueOf(hasNeighborSignal)).setValue(OPEN, Boolean.valueOf(hasNeighborSignal)), 2); + if (state.getValue(OPEN) != hasNeighborSignal) { diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/FireBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/FireBlock.java.patch new file mode 100644 index 0000000000..ac0a574cbf --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/FireBlock.java.patch @@ -0,0 +1,169 @@ +--- a/net/minecraft/world/level/block/FireBlock.java ++++ b/net/minecraft/world/level/block/FireBlock.java +@@ -14,6 +_,7 @@ + import net.minecraft.tags.BiomeTags; + import net.minecraft.util.RandomSource; + import net.minecraft.world.item.context.BlockPlaceContext; ++import net.minecraft.world.item.context.UseOnContext; + import net.minecraft.world.level.BlockGetter; + import net.minecraft.world.level.GameRules; + import net.minecraft.world.level.Level; +@@ -122,7 +_,25 @@ + BlockState neighborState, + RandomSource random + ) { +- return this.canSurvive(state, level, pos) ? this.getStateWithAge(level, pos, state.getValue(AGE)) : Blocks.AIR.defaultBlockState(); ++ // CraftBukkit start ++ if (!(level instanceof ServerLevel)) return this.canSurvive(state, level, pos) ? (BlockState) this.getStateWithAge(level, pos, (Integer) state.getValue(FireBlock.AGE)) : Blocks.AIR.defaultBlockState(); // Paper - don't fire events in world generation ++ if (!this.canSurvive(state, level, pos)) { ++ // Suppress during worldgen ++ if (!(level instanceof Level world1)) { ++ return Blocks.AIR.defaultBlockState(); ++ } ++ org.bukkit.craftbukkit.block.CraftBlockState blockState = org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(world1, pos); ++ blockState.setData(Blocks.AIR.defaultBlockState()); ++ ++ org.bukkit.event.block.BlockFadeEvent event = new org.bukkit.event.block.BlockFadeEvent(blockState.getBlock(), blockState); ++ world1.getCraftServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) { ++ return blockState.getHandle(); ++ } ++ } ++ return this.getStateWithAge(level, pos, (Integer) state.getValue(FireBlock.AGE)); // Paper - don't fire events in world generation; diff on change, see "don't fire events in world generation" ++ // CraftBukkit end + } + + @Override +@@ -162,10 +_,10 @@ + + @Override + protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { +- level.scheduleTick(pos, this, getFireTickDelay(level.random)); ++ level.scheduleTick(pos, (Block) this, FireBlock.getFireTickDelay(level)); // Paper - Add fire-tick-delay option + if (level.getGameRules().getBoolean(GameRules.RULE_DOFIRETICK)) { + if (!state.canSurvive(level, pos)) { +- level.removeBlock(pos, false); ++ this.fireExtinguished(level, pos); // CraftBukkit - invalid place location + } + + BlockState blockState = level.getBlockState(pos.below()); +@@ -184,26 +_,28 @@ + if (!this.isValidFireLocation(level, pos)) { + BlockPos blockPos = pos.below(); + if (!level.getBlockState(blockPos).isFaceSturdy(level, blockPos, Direction.UP) || ageValue > 3) { +- level.removeBlock(pos, false); ++ this.fireExtinguished(level, pos); // CraftBukkit - extinguished by rain + } + + return; + } + + if (ageValue == 15 && random.nextInt(4) == 0 && !this.canBurn(level.getBlockState(pos.below()))) { +- level.removeBlock(pos, false); ++ this.fireExtinguished(level, pos); // CraftBukkit + return; + } + } + + boolean isIncreasedFireBurnout = level.getBiome(pos).is(BiomeTags.INCREASED_FIRE_BURNOUT); + int i = isIncreasedFireBurnout ? -50 : 0; +- this.checkBurnOut(level, pos.east(), 300 + i, random, ageValue); +- this.checkBurnOut(level, pos.west(), 300 + i, random, ageValue); +- this.checkBurnOut(level, pos.below(), 250 + i, random, ageValue); +- this.checkBurnOut(level, pos.above(), 250 + i, random, ageValue); +- this.checkBurnOut(level, pos.north(), 300 + i, random, ageValue); +- this.checkBurnOut(level, pos.south(), 300 + i, random, ageValue); ++ // CraftBukkit start - add source blockposition to burn calls ++ this.checkBurnOut(level, pos.east(), 300 + i, random, ageValue, pos); ++ this.checkBurnOut(level, pos.west(), 300 + i, random, ageValue, pos); ++ this.checkBurnOut(level, pos.below(), 250 + i, random, ageValue, pos); ++ this.checkBurnOut(level, pos.above(), 250 + i, random, ageValue, pos); ++ this.checkBurnOut(level, pos.north(), 300 + i, random, ageValue, pos); ++ this.checkBurnOut(level, pos.south(), 300 + i, random, ageValue, pos); ++ // CraftBukkit end + BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos(); + + for (int i1 = -1; i1 <= 1; i1++) { +@@ -225,7 +_,15 @@ + + if (i5 > 0 && random.nextInt(i4) <= i5 && (!level.isRaining() || !this.isNearRain(level, mutableBlockPos))) { + int min1 = Math.min(15, ageValue + random.nextInt(5) / 4); +- level.setBlock(mutableBlockPos, this.getStateWithAge(level, mutableBlockPos, min1), 3); ++ // CraftBukkit start - Call to stop spread of fire ++ if (level.getBlockState(mutableBlockPos).getBlock() != Blocks.FIRE) { ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(level, mutableBlockPos, pos).isCancelled()) { ++ continue; ++ } ++ ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, pos, mutableBlockPos, this.getStateWithAge(level, mutableBlockPos, min1), 3); // CraftBukkit ++ } ++ // CraftBukkit end + } + } + } +@@ -256,19 +_,42 @@ + : this.igniteOdds.getInt(state.getBlock()); + } + +- private void checkBurnOut(Level level, BlockPos pos, int chance, RandomSource random, int age) { ++ private void checkBurnOut(Level level, BlockPos pos, int chance, RandomSource random, int age, BlockPos sourceposition) { // CraftBukkit add sourceposition + int burnOdds = this.getBurnOdds(level.getBlockState(pos)); + if (random.nextInt(chance) < burnOdds) { + BlockState blockState = level.getBlockState(pos); ++ ++ // CraftBukkit start ++ org.bukkit.block.Block theBlock = level.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); ++ org.bukkit.block.Block sourceBlock = level.getWorld().getBlockAt(sourceposition.getX(), sourceposition.getY(), sourceposition.getZ()); ++ ++ org.bukkit.event.block.BlockBurnEvent event = new org.bukkit.event.block.BlockBurnEvent(theBlock, sourceBlock); ++ level.getCraftServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) { ++ return; ++ } ++ ++ if (blockState.getBlock() instanceof TntBlock && !org.bukkit.craftbukkit.event.CraftEventFactory.callTNTPrimeEvent(level, pos, org.bukkit.event.block.TNTPrimeEvent.PrimeCause.FIRE, null, sourceposition)) { ++ return; ++ } ++ // CraftBukkit end + if (random.nextInt(age + 10) < 5 && !level.isRainingAt(pos)) { + int min = Math.min(age + random.nextInt(5) / 4, 15); + level.setBlock(pos, this.getStateWithAge(level, pos, min), 3); + } else { +- level.removeBlock(pos, false); ++ if(blockState.getBlock() != Blocks.TNT) level.removeBlock(pos, false); // Paper - TNTPrimeEvent; We might be cancelling it below, move the setAir down + } + + Block block = blockState.getBlock(); + if (block instanceof TntBlock) { ++ // Paper start - TNTPrimeEvent ++ org.bukkit.block.Block tntBlock = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos); ++ if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.FIRE, null).callEvent()) { ++ return; ++ } ++ level.removeBlock(pos, false); ++ // Paper end - TNTPrimeEvent + TntBlock.explode(level, pos); + } + } +@@ -310,13 +_,14 @@ + } + + @Override +- protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean isMoving) { +- super.onPlace(state, level, pos, oldState, isMoving); +- level.scheduleTick(pos, this, getFireTickDelay(level.random)); ++ protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean isMoving, UseOnContext context) { ++ super.onPlace(state, level, pos, oldState, isMoving, context); ++ // CraftBukkit end ++ level.scheduleTick(pos, this, FireBlock.getFireTickDelay(level)); // Paper - Add fire-tick-delay option + } + +- private static int getFireTickDelay(RandomSource random) { +- return 30 + random.nextInt(10); ++ private static int getFireTickDelay(Level world) { // Paper - Add fire-tick-delay option ++ return world.paperConfig().environment.fireTickDelay + world.random.nextInt(10); // Paper - Add fire-tick-delay option + } + + @Override diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/FlowerPotBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/FlowerPotBlock.java.patch similarity index 91% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/FlowerPotBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/FlowerPotBlock.java.patch index a2ee2e43ae..bf55cfd303 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/FlowerPotBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/FlowerPotBlock.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/world/level/block/FlowerPotBlock.java +++ b/net/minecraft/world/level/block/FlowerPotBlock.java -@@ -63,6 +63,18 @@ +@@ -67,6 +_,18 @@ } else if (!this.isEmpty()) { return InteractionResult.CONSUME; } else { + // Paper start - Add PlayerFlowerPotManipulateEvent -+ org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(world, pos); ++ org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos); + org.bukkit.inventory.ItemStack placedStack = org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(stack); + + io.papermc.paper.event.player.PlayerFlowerPotManipulateEvent event = new io.papermc.paper.event.player.PlayerFlowerPotManipulateEvent((org.bukkit.entity.Player) player.getBukkitEntity(), block, placedStack, true); @@ -16,10 +16,10 @@ + return InteractionResult.CONSUME; + } + // Paper end - Add PlayerFlowerPotManipulateEvent - world.setBlock(pos, blockState, 3); - world.gameEvent(player, GameEvent.BLOCK_CHANGE, pos); + level.setBlock(pos, blockState, 3); + level.gameEvent(player, GameEvent.BLOCK_CHANGE, pos); player.awardStat(Stats.POT_FLOWER); -@@ -77,6 +89,18 @@ +@@ -81,6 +_,18 @@ return InteractionResult.CONSUME; } else { ItemStack itemStack = new ItemStack(this.potted); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/FrogspawnBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/FrogspawnBlock.java.patch new file mode 100644 index 0000000000..961a62ea3e --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/FrogspawnBlock.java.patch @@ -0,0 +1,31 @@ +--- a/net/minecraft/world/level/block/FrogspawnBlock.java ++++ b/net/minecraft/world/level/block/FrogspawnBlock.java +@@ -89,6 +_,7 @@ + + @Override + protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) { ++ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent + if (entity.getType().equals(EntityType.FALLING_BLOCK)) { + this.destroyBlock(level, pos); + } +@@ -101,6 +_,11 @@ + } + + private void hatchFrogspawn(ServerLevel level, BlockPos pos, RandomSource random) { ++ // Paper start - Call BlockFadeEvent ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(level, pos, Blocks.AIR.defaultBlockState()).isCancelled()) { ++ return; ++ } ++ // Paper end - Call BlockFadeEven + this.destroyBlock(level, pos); + level.playSound(null, pos, SoundEvents.FROGSPAWN_HATCH, SoundSource.BLOCKS, 1.0F, 1.0F); + this.spawnTadpoles(level, pos, random); +@@ -121,7 +_,7 @@ + int randomInt1 = random.nextInt(1, 361); + tadpole.moveTo(d, pos.getY() - 0.5, d1, randomInt1, 0.0F); + tadpole.setPersistenceRequired(); +- level.addFreshEntity(tadpole); ++ level.addFreshEntity(tadpole, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.EGG); // Paper - use correct spawn reason + } + } + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/FrostedIceBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/FrostedIceBlock.java.patch new file mode 100644 index 0000000000..0f1075049a --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/FrostedIceBlock.java.patch @@ -0,0 +1,24 @@ +--- a/net/minecraft/world/level/block/FrostedIceBlock.java ++++ b/net/minecraft/world/level/block/FrostedIceBlock.java +@@ -42,6 +_,7 @@ + + @Override + protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { ++ if (!level.paperConfig().environment.frostedIce.enabled) return; // Paper - Frosted ice options + if ((random.nextInt(3) == 0 || this.fewerNeigboursThan(level, pos, 4)) + && level.getMaxLocalRawBrightness(pos) > 11 - state.getValue(AGE) - state.getLightBlock() + && this.slightlyMelt(state, level, pos)) { +@@ -51,11 +_,11 @@ + mutableBlockPos.setWithOffset(pos, direction); + BlockState blockState = level.getBlockState(mutableBlockPos); + if (blockState.is(this) && !this.slightlyMelt(blockState, level, mutableBlockPos)) { +- level.scheduleTick(mutableBlockPos, this, Mth.nextInt(random, 20, 40)); ++ level.scheduleTick(mutableBlockPos, this, Mth.nextInt(random, level.paperConfig().environment.frostedIce.delay.min, level.paperConfig().environment.frostedIce.delay.max)); // Paper - Frosted ice options + } + } + } else { +- level.scheduleTick(pos, this, Mth.nextInt(random, 20, 40)); ++ level.scheduleTick(pos, this, Mth.nextInt(random, level.paperConfig().environment.frostedIce.delay.min, level.paperConfig().environment.frostedIce.delay.max)); // Paper - Frosted ice options + } + } + diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/FungusBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/FungusBlock.java.patch new file mode 100644 index 0000000000..1e6860b8a1 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/FungusBlock.java.patch @@ -0,0 +1,21 @@ +--- a/net/minecraft/world/level/block/FungusBlock.java ++++ b/net/minecraft/world/level/block/FungusBlock.java +@@ -72,6 +_,17 @@ + + @Override + public void performBonemeal(ServerLevel level, RandomSource random, BlockPos pos, BlockState state) { +- this.getFeature(level).ifPresent(holder -> holder.value().place(level, level.getChunkSource().getGenerator(), random, pos)); ++ this.getFeature(level) ++ // CraftBukkit start ++ .map((value) -> { ++ if (this == Blocks.WARPED_FUNGUS) { ++ SaplingBlock.treeType = org.bukkit.TreeType.WARPED_FUNGUS; ++ } else if (this == Blocks.CRIMSON_FUNGUS) { ++ SaplingBlock.treeType = org.bukkit.TreeType.CRIMSON_FUNGUS; ++ } ++ return value; ++ }) ++ .ifPresent(holder -> holder.value().place(level, level.getChunkSource().getGenerator(), random, pos)); ++ // CraftBukkit end + } + } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/FurnaceBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/FurnaceBlock.java.patch similarity index 77% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/FurnaceBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/FurnaceBlock.java.patch index ffebc4893d..c383a4b8f2 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/FurnaceBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/FurnaceBlock.java.patch @@ -1,9 +1,9 @@ --- a/net/minecraft/world/level/block/FurnaceBlock.java +++ b/net/minecraft/world/level/block/FurnaceBlock.java -@@ -45,8 +45,7 @@ +@@ -45,8 +_,7 @@ @Override - protected void openContainer(Level world, BlockPos pos, Player player) { - BlockEntity blockEntity = world.getBlockEntity(pos); + protected void openContainer(Level level, BlockPos pos, Player player) { + BlockEntity blockEntity = level.getBlockEntity(pos); - if (blockEntity instanceof FurnaceBlockEntity) { - player.openMenu((MenuProvider)blockEntity); + if (blockEntity instanceof FurnaceBlockEntity && player.openMenu((MenuProvider)blockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/GrindstoneBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/GrindstoneBlock.java.patch new file mode 100644 index 0000000000..f242c126d6 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/GrindstoneBlock.java.patch @@ -0,0 +1,12 @@ +--- a/net/minecraft/world/level/block/GrindstoneBlock.java ++++ b/net/minecraft/world/level/block/GrindstoneBlock.java +@@ -151,8 +_,7 @@ + + @Override + protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) { +- if (!level.isClientSide) { +- player.openMenu(state.getMenuProvider(level, pos)); ++ if (!level.isClientSide && player.openMenu(state.getMenuProvider(level, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation + player.awardStat(Stats.INTERACT_WITH_GRINDSTONE); + } + diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/GrowingPlantHeadBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/GrowingPlantHeadBlock.java.patch new file mode 100644 index 0000000000..ddbe3daa0a --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/GrowingPlantHeadBlock.java.patch @@ -0,0 +1,36 @@ +--- a/net/minecraft/world/level/block/GrowingPlantHeadBlock.java ++++ b/net/minecraft/world/level/block/GrowingPlantHeadBlock.java +@@ -44,14 +_,31 @@ + + @Override + protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { +- if (state.getValue(AGE) < 25 && random.nextDouble() < this.growPerTickProbability) { ++ // Spigot start ++ int modifier; ++ if (this == Blocks.KELP) { ++ modifier = level.spigotConfig.kelpModifier; ++ } else if (this == Blocks.TWISTING_VINES) { ++ modifier = level.spigotConfig.twistingVinesModifier; ++ } else if (this == Blocks.WEEPING_VINES) { ++ modifier = level.spigotConfig.weepingVinesModifier; ++ } else { ++ modifier = level.spigotConfig.caveVinesModifier; ++ } ++ if ((Integer) state.getValue(GrowingPlantHeadBlock.AGE) < 25 && random.nextDouble() < ((modifier / 100.0D) * this.growPerTickProbability)) { // Spigot - SPIGOT-7159: Better modifier resolution ++ // Spigot end + BlockPos blockPos = pos.relative(this.growthDirection); + if (this.canGrowInto(level.getBlockState(blockPos))) { +- level.setBlockAndUpdate(blockPos, this.getGrowIntoState(state, level.random)); ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, pos, blockPos, this.getGrowIntoState(state, level.random, level)); // CraftBukkit // Paper - Fix Spigot growth modifiers + } + } + } + ++ // Paper start - Fix Spigot growth modifiers ++ protected BlockState getGrowIntoState(BlockState state, RandomSource random, @javax.annotation.Nullable Level level) { ++ return this.getGrowIntoState(state, random); ++ } ++ // Paper end - Fix Spigot growth modifiers + protected BlockState getGrowIntoState(BlockState state, RandomSource random) { + return state.cycle(AGE); + } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/HoneyBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/HoneyBlock.java.patch similarity index 75% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/HoneyBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/HoneyBlock.java.patch index 4609ae3eee..36a0794c0b 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/HoneyBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/HoneyBlock.java.patch @@ -1,10 +1,10 @@ --- a/net/minecraft/world/level/block/HoneyBlock.java +++ b/net/minecraft/world/level/block/HoneyBlock.java -@@ -60,6 +60,7 @@ +@@ -60,6 +_,7 @@ @Override - protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { -+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent + protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) { ++ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent if (this.isSlidingDown(pos, entity)) { this.maybeDoSlideAchievement(entity, pos); this.doSlideMovement(entity); diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/HopperBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/HopperBlock.java.patch similarity index 61% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/HopperBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/HopperBlock.java.patch index 3e829e33d0..b33d6bde71 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/HopperBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/HopperBlock.java.patch @@ -1,20 +1,20 @@ --- a/net/minecraft/world/level/block/HopperBlock.java +++ b/net/minecraft/world/level/block/HopperBlock.java -@@ -125,8 +125,7 @@ +@@ -125,8 +_,7 @@ @Override - protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { -- if (!world.isClientSide && world.getBlockEntity(pos) instanceof HopperBlockEntity hopperBlockEntity) { + protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) { +- if (!level.isClientSide && level.getBlockEntity(pos) instanceof HopperBlockEntity hopperBlockEntity) { - player.openMenu(hopperBlockEntity); -+ if (!world.isClientSide && world.getBlockEntity(pos) instanceof HopperBlockEntity hopperBlockEntity && player.openMenu(hopperBlockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation ++ if (!level.isClientSide && level.getBlockEntity(pos) instanceof HopperBlockEntity hopperBlockEntity && player.openMenu(hopperBlockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation player.awardStat(Stats.INSPECT_HOPPER); } -@@ -178,6 +177,7 @@ +@@ -178,6 +_,7 @@ @Override - protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { -+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent - BlockEntity blockEntity = world.getBlockEntity(pos); + protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) { ++ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent + BlockEntity blockEntity = level.getBlockEntity(pos); if (blockEntity instanceof HopperBlockEntity) { - HopperBlockEntity.entityInside(world, pos, state, entity, (HopperBlockEntity)blockEntity); + HopperBlockEntity.entityInside(level, pos, state, entity, (HopperBlockEntity)blockEntity); diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/HugeMushroomBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/HugeMushroomBlock.java.patch similarity index 66% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/HugeMushroomBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/HugeMushroomBlock.java.patch index fb60ae21d7..9a4c3e64c9 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/HugeMushroomBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/HugeMushroomBlock.java.patch @@ -1,30 +1,30 @@ --- a/net/minecraft/world/level/block/HugeMushroomBlock.java +++ b/net/minecraft/world/level/block/HugeMushroomBlock.java -@@ -45,6 +45,7 @@ +@@ -45,6 +_,7 @@ @Override - public BlockState getStateForPlacement(BlockPlaceContext ctx) { + public BlockState getStateForPlacement(BlockPlaceContext context) { + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableMushroomBlockUpdates) return this.defaultBlockState(); // Paper - add option to disable block updates - BlockGetter blockGetter = ctx.getLevel(); - BlockPos blockPos = ctx.getClickedPos(); + BlockGetter level = context.getLevel(); + BlockPos clickedPos = context.getClickedPos(); return this.defaultBlockState() -@@ -67,6 +68,7 @@ +@@ -67,6 +_,7 @@ BlockState neighborState, RandomSource random ) { + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableMushroomBlockUpdates) return state; // Paper - add option to disable block updates return neighborState.is(this) ? state.setValue(PROPERTY_BY_DIRECTION.get(direction), Boolean.valueOf(false)) - : super.updateShape(state, world, tickView, pos, direction, neighborPos, neighborState, random); -@@ -74,6 +76,7 @@ + : super.updateShape(state, level, scheduledTickAccess, pos, direction, neighborPos, neighborState, random); +@@ -74,6 +_,7 @@ @Override - protected BlockState rotate(BlockState state, Rotation rotation) { + protected BlockState rotate(BlockState state, Rotation rot) { + if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableMushroomBlockUpdates) return state; // Paper - add option to disable block updates - return state.setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.NORTH)), state.getValue(NORTH)) - .setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.SOUTH)), state.getValue(SOUTH)) - .setValue(PROPERTY_BY_DIRECTION.get(rotation.rotate(Direction.EAST)), state.getValue(EAST)) -@@ -84,6 +87,7 @@ + return state.setValue(PROPERTY_BY_DIRECTION.get(rot.rotate(Direction.NORTH)), state.getValue(NORTH)) + .setValue(PROPERTY_BY_DIRECTION.get(rot.rotate(Direction.SOUTH)), state.getValue(SOUTH)) + .setValue(PROPERTY_BY_DIRECTION.get(rot.rotate(Direction.EAST)), state.getValue(EAST)) +@@ -84,6 +_,7 @@ @Override protected BlockState mirror(BlockState state, Mirror mirror) { diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/IceBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/IceBlock.java.patch new file mode 100644 index 0000000000..b89beb8bf6 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/IceBlock.java.patch @@ -0,0 +1,30 @@ +--- a/net/minecraft/world/level/block/IceBlock.java ++++ b/net/minecraft/world/level/block/IceBlock.java +@@ -32,8 +_,13 @@ + } + + @Override +- public void playerDestroy(Level level, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity te, ItemStack stack) { +- super.playerDestroy(level, player, pos, state, te, stack); ++ public void playerDestroy(Level level, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity te, ItemStack stack, boolean includeDrops, boolean dropExp) { // Paper - fix drops not preventing stats/food exhaustion ++ super.playerDestroy(level, player, pos, state, te, stack, includeDrops, dropExp); // Paper - fix drops not preventing stats/food exhaustion ++ // Paper start - Improve Block#breakNaturally API ++ this.afterDestroy(level, pos, stack); ++ } ++ public void afterDestroy(Level level, BlockPos pos, ItemStack stack) { ++ // Paper end - Improve Block#breakNaturally API + if (!EnchantmentHelper.hasTag(stack, EnchantmentTags.PREVENTS_ICE_MELTING)) { + if (level.dimensionType().ultraWarm()) { + level.removeBlock(pos, false); +@@ -55,6 +_,11 @@ + } + + protected void melt(BlockState state, Level level, BlockPos pos) { ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(level, pos, level.dimensionType().ultraWarm() ? Blocks.AIR.defaultBlockState() : Blocks.WATER.defaultBlockState()).isCancelled()) { ++ return; ++ } ++ // CraftBukkit end + if (level.dimensionType().ultraWarm()) { + level.removeBlock(pos, false); + } else { diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/InfestedBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/InfestedBlock.java.patch new file mode 100644 index 0000000000..23815e6bfd --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/InfestedBlock.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/level/block/InfestedBlock.java ++++ b/net/minecraft/world/level/block/InfestedBlock.java +@@ -52,7 +_,7 @@ + Silverfish silverfish = EntityType.SILVERFISH.create(level, EntitySpawnReason.TRIGGERED); + if (silverfish != null) { + silverfish.moveTo(pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5, 0.0F, 0.0F); +- level.addFreshEntity(silverfish); ++ level.addFreshEntity(silverfish, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SILVERFISH_BLOCK); // CraftBukkit - add SpawnReason + silverfish.spawnAnim(); + } + } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/LavaCauldronBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/LavaCauldronBlock.java.patch similarity index 74% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/LavaCauldronBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/LavaCauldronBlock.java.patch index b8db542f5e..4c96395fdf 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/LavaCauldronBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/LavaCauldronBlock.java.patch @@ -1,10 +1,10 @@ --- a/net/minecraft/world/level/block/LavaCauldronBlock.java +++ b/net/minecraft/world/level/block/LavaCauldronBlock.java -@@ -32,6 +32,7 @@ +@@ -32,6 +_,7 @@ @Override - protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { -+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent + protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) { ++ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent if (this.isEntityInsideContent(state, pos, entity)) { entity.lavaHurt(); } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/LayeredCauldronBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/LayeredCauldronBlock.java.patch new file mode 100644 index 0000000000..3bd7696353 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/LayeredCauldronBlock.java.patch @@ -0,0 +1,109 @@ +--- a/net/minecraft/world/level/block/LayeredCauldronBlock.java ++++ b/net/minecraft/world/level/block/LayeredCauldronBlock.java +@@ -61,35 +_,79 @@ + + @Override + protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) { ++ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent + if (level instanceof ServerLevel serverLevel && entity.isOnFire() && this.isEntityInsideContent(state, pos, entity)) { +- entity.clearFire(); +- if (entity.mayInteract(serverLevel, pos)) { +- this.handleEntityOnFireInside(state, level, pos); ++ // CraftBukkit start - moved down ++ // entity.clearFire(); ++ if ((entity instanceof net.minecraft.world.entity.player.Player || serverLevel.getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_MOBGRIEFING)) && entity.mayInteract(serverLevel, pos)) { // Paper - Fixes MC-248588 ++ if (this.handleEntityOnFireInsideWithEvent(state, level, pos, entity)) { // Paper - fix powdered snow cauldron extinguishing entities ++ entity.clearFire(); ++ } ++ // CraftBukkit end + } + } + } + +- private void handleEntityOnFireInside(BlockState state, Level level, BlockPos pos) { ++ // CraftBukkit start ++ @io.papermc.paper.annotation.DoNotUse @Deprecated // Paper - fix powdered snow cauldron extinguishing entities; use #handleEntityOnFireInsideWithEvent ++ private boolean handleEntityOnFireInside(BlockState state, Level level, BlockPos pos, Entity entity) { + if (this.precipitationType == Biome.Precipitation.SNOW) { +- lowerFillLevel(Blocks.WATER_CAULDRON.defaultBlockState().setValue(LEVEL, state.getValue(LEVEL)), level, pos); ++ return LayeredCauldronBlock.lowerFillLevel((BlockState) Blocks.WATER_CAULDRON.defaultBlockState().setValue(LayeredCauldronBlock.LEVEL, (Integer) state.getValue(LayeredCauldronBlock.LEVEL)), level, pos, entity, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason.EXTINGUISH); // CraftBukkit + } else { +- lowerFillLevel(state, level, pos); ++ return LayeredCauldronBlock.lowerFillLevel(state, level, pos, entity, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason.EXTINGUISH); // CraftBukkit + } + } + + public static void lowerFillLevel(BlockState state, Level level, BlockPos pos) { +- int i = state.getValue(LEVEL) - 1; +- BlockState blockState = i == 0 ? Blocks.CAULDRON.defaultBlockState() : state.setValue(LEVEL, Integer.valueOf(i)); +- level.setBlockAndUpdate(pos, blockState); +- level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(blockState)); +- } ++ // CraftBukkit start ++ LayeredCauldronBlock.lowerFillLevel(state, level, pos, null, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason.UNKNOWN); ++ } ++ public static boolean lowerFillLevel(BlockState state, Level level, BlockPos BlockPos, Entity entity, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason reason) { ++ int i = (Integer) state.getValue(LayeredCauldronBlock.LEVEL) - 1; ++ BlockState iblockdata1 = i == 0 ? Blocks.CAULDRON.defaultBlockState() : (BlockState) state.setValue(LayeredCauldronBlock.LEVEL, i); ++ ++ return LayeredCauldronBlock.changeLevel(state, level, BlockPos, iblockdata1, entity, reason); ++ } ++ // Paper start - fix powdered snow cauldron extinguishing entities ++ protected boolean handleEntityOnFireInsideWithEvent(BlockState state, Level world, BlockPos pos, Entity entity) { ++ if (this.precipitationType == Biome.Precipitation.SNOW) { ++ return LayeredCauldronBlock.lowerFillLevel((BlockState) Blocks.WATER_CAULDRON.defaultBlockState().setValue(LayeredCauldronBlock.LEVEL, (Integer) state.getValue(LayeredCauldronBlock.LEVEL)), world, pos, entity, CauldronLevelChangeEvent.ChangeReason.EXTINGUISH); ++ } else { ++ return LayeredCauldronBlock.lowerFillLevel(state, world, pos, entity, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason.EXTINGUISH); ++ } ++ } ++ // Paper end - fix powdered snow cauldron extinguishing entities ++ ++ // CraftBukkit start ++ // Paper start - Call CauldronLevelChangeEvent ++ public static boolean changeLevel(BlockState iblockdata, Level world, BlockPos blockposition, BlockState newBlock, @javax.annotation.Nullable Entity entity, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason reason) { // Paper - entity is nullable ++ return changeLevel(iblockdata, world, blockposition, newBlock, entity, reason, true); ++ } ++ ++ public static boolean changeLevel(BlockState iblockdata, Level world, BlockPos blockposition, BlockState newBlock, @javax.annotation.Nullable Entity entity, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason reason, boolean sendGameEvent) { // Paper - entity is nullable ++ // Paper end - Call CauldronLevelChangeEvent ++ org.bukkit.craftbukkit.block.CraftBlockState newState = org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(world, blockposition); ++ newState.setData(newBlock); ++ ++ org.bukkit.event.block.CauldronLevelChangeEvent event = new org.bukkit.event.block.CauldronLevelChangeEvent( ++ world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), ++ (entity == null) ? null : entity.getBukkitEntity(), reason, newState ++ ); ++ world.getCraftServer().getPluginManager().callEvent(event); ++ if (event.isCancelled()) { ++ return false; ++ } ++ newState.update(true); ++ if (sendGameEvent) world.gameEvent(GameEvent.BLOCK_CHANGE, blockposition, GameEvent.Context.of(newBlock)); // Paper - Call CauldronLevelChangeEvent ++ return true; ++ } ++ // CraftBukkit end + + @Override + public void handlePrecipitation(BlockState state, Level level, BlockPos pos, Biome.Precipitation precipitation) { + if (CauldronBlock.shouldHandlePrecipitation(level, precipitation) && state.getValue(LEVEL) != 3 && precipitation == this.precipitationType) { + BlockState blockState = state.cycle(LEVEL); +- level.setBlockAndUpdate(pos, blockState); +- level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(blockState)); ++ LayeredCauldronBlock.changeLevel(state, level, pos, blockState, null, org.bukkit.event.block.CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL); // CraftBukkit + } + } + +@@ -107,8 +_,11 @@ + protected void receiveStalactiteDrip(BlockState state, Level level, BlockPos pos, Fluid fluid) { + if (!this.isFull(state)) { + BlockState blockState = state.setValue(LEVEL, Integer.valueOf(state.getValue(LEVEL) + 1)); +- level.setBlockAndUpdate(pos, blockState); +- level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(blockState)); ++ // CraftBukkit start ++ if (!LayeredCauldronBlock.changeLevel(state, level, pos, blockState, null, CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL)) { ++ return; ++ } ++ // CraftBukkit end + level.levelEvent(1047, pos, 0); + } + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/LeavesBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/LeavesBlock.java.patch new file mode 100644 index 0000000000..b186e88130 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/LeavesBlock.java.patch @@ -0,0 +1,17 @@ +--- a/net/minecraft/world/level/block/LeavesBlock.java ++++ b/net/minecraft/world/level/block/LeavesBlock.java +@@ -63,6 +_,14 @@ + @Override + protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { + if (this.decaying(state)) { ++ // CraftBukkit start ++ org.bukkit.event.block.LeavesDecayEvent event = new org.bukkit.event.block.LeavesDecayEvent(level.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ())); ++ level.getCraftServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled() || level.getBlockState(pos).getBlock() != this) { ++ return; ++ } ++ // CraftBukkit end + dropResources(state, level, pos); + level.removeBlock(pos, false); + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/LecternBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/LecternBlock.java.patch new file mode 100644 index 0000000000..fffc21a6fe --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/LecternBlock.java.patch @@ -0,0 +1,67 @@ +--- a/net/minecraft/world/level/block/LecternBlock.java ++++ b/net/minecraft/world/level/block/LecternBlock.java +@@ -169,7 +_,24 @@ + + private static void placeBook(@Nullable LivingEntity entity, Level level, BlockPos pos, BlockState state, ItemStack stack) { + if (level.getBlockEntity(pos) instanceof LecternBlockEntity lecternBlockEntity) { +- lecternBlockEntity.setBook(stack.consumeAndReturn(1, entity)); ++ // Paper start - Add PlayerInsertLecternBookEvent ++ ItemStack eventSourcedBookStack = null; ++ if (entity instanceof final net.minecraft.server.level.ServerPlayer serverPlayer) { ++ final io.papermc.paper.event.player.PlayerInsertLecternBookEvent event = new io.papermc.paper.event.player.PlayerInsertLecternBookEvent( ++ serverPlayer.getBukkitEntity(), ++ org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), ++ org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(stack.copyWithCount(1)) ++ ); ++ if (!event.callEvent()) return; ++ eventSourcedBookStack = org.bukkit.craftbukkit.inventory.CraftItemStack.unwrap(event.getBook()); ++ } ++ if (eventSourcedBookStack == null) { ++ eventSourcedBookStack = stack.consumeAndReturn(1, entity); ++ } else { ++ stack.consume(1, entity); ++ } ++ lecternBlockEntity.setBook(eventSourcedBookStack); ++ // Paper end - Add PlayerInsertLecternBookEvent + resetBookState(entity, level, pos, state, true); + level.playSound(null, pos, SoundEvents.BOOK_PUT, SoundSource.BLOCKS, 1.0F, 1.0F); + } +@@ -189,6 +_,16 @@ + } + + private static void changePowered(Level level, BlockPos pos, BlockState state, boolean powered) { ++ // Paper start - Call BlockRedstoneEvent properly ++ final int currentRedstoneLevel = state.getValue(LecternBlock.POWERED) ? 15 : 0, targetRedstoneLevel = powered ? 15 : 0; ++ if (currentRedstoneLevel != targetRedstoneLevel) { ++ final org.bukkit.event.block.BlockRedstoneEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, currentRedstoneLevel, targetRedstoneLevel); ++ ++ if (event.getNewCurrent() != targetRedstoneLevel) { ++ return; ++ } ++ } ++ // Paper end - Call BlockRedstoneEvent properly + level.setBlock(pos, state.setValue(POWERED, Boolean.valueOf(powered)), 3); + updateBelow(level, pos, state); + } +@@ -218,9 +_,10 @@ + } + + private void popBook(BlockState state, Level level, BlockPos pos) { +- if (level.getBlockEntity(pos) instanceof LecternBlockEntity lecternBlockEntity) { ++ if (level.getBlockEntity(pos, false) instanceof LecternBlockEntity lecternBlockEntity) { // CraftBukkit - don't validate, type may be changed already + Direction direction = state.getValue(FACING); + ItemStack itemStack = lecternBlockEntity.getBook().copy(); ++ if (itemStack.isEmpty()) return; // CraftBukkit - SPIGOT-5500 + float f = 0.25F * direction.getStepX(); + float f1 = 0.25F * direction.getStepZ(); + ItemEntity itemEntity = new ItemEntity(level, pos.getX() + 0.5 + f, pos.getY() + 1, pos.getZ() + 0.5 + f1, itemStack); +@@ -296,8 +_,7 @@ + + private void openScreen(Level level, BlockPos pos, Player player) { + BlockEntity blockEntity = level.getBlockEntity(pos); +- if (blockEntity instanceof LecternBlockEntity) { +- player.openMenu((LecternBlockEntity)blockEntity); ++ if (blockEntity instanceof LecternBlockEntity lecternBlockEntity && player.openMenu(lecternBlockEntity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation + player.awardStat(Stats.INTERACT_WITH_LECTERN); + } + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/LeverBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/LeverBlock.java.patch new file mode 100644 index 0000000000..98f131c9db --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/LeverBlock.java.patch @@ -0,0 +1,22 @@ +--- a/net/minecraft/world/level/block/LeverBlock.java ++++ b/net/minecraft/world/level/block/LeverBlock.java +@@ -100,6 +_,19 @@ + makeParticle(blockState, level, pos, 1.0F); + } + } else { ++ // CraftBukkit start - Interact Lever ++ boolean powered = state.getValue(LeverBlock.POWERED); // Old powered state ++ org.bukkit.block.Block block = level.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); ++ int old = (powered) ? 15 : 0; ++ int current = (!powered) ? 15 : 0; ++ ++ org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(block, old, current); ++ level.getCraftServer().getPluginManager().callEvent(eventRedstone); ++ ++ if ((eventRedstone.getNewCurrent() > 0) != (!powered)) { ++ return InteractionResult.SUCCESS; ++ } ++ // CraftBukkit end + this.pull(state, level, pos, null); + } + diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/LightBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/LightBlock.java.patch similarity index 82% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/LightBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/LightBlock.java.patch index 4e34991e01..c9fda343b0 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/LightBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/LightBlock.java.patch @@ -1,18 +1,16 @@ --- a/net/minecraft/world/level/block/LightBlock.java +++ b/net/minecraft/world/level/block/LightBlock.java -@@ -50,7 +50,15 @@ +@@ -49,6 +_,13 @@ + protected void createBlockStateDefinition(StateDefinition.Builder builder) { builder.add(LEVEL, WATERLOGGED); } - + // Paper start - prevent unintended light block manipulation - @Override ++ @Override + protected InteractionResult useItemOn(ItemStack stack, BlockState state, Level world, BlockPos pos, Player player, net.minecraft.world.InteractionHand hand, BlockHitResult hit) { + if (player.getItemInHand(hand).getItem() != Items.LIGHT || (world instanceof final net.minecraft.server.level.ServerLevel serverLevel && !player.mayInteract(serverLevel, pos)) || !player.mayUseItemAt(pos, hit.getDirection(), player.getItemInHand(hand))) { return net.minecraft.world.InteractionResult.PASS; } // Paper - Prevent unintended light block manipulation + return super.useItemOn(stack, state, world, pos, player, hand, hit); + } + // Paper end - prevent unintended light block manipulation -+ -+ @Override - protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { - if (!world.isClientSide && player.canUseGameMasterBlocks()) { - world.setBlock(pos, state.cycle(LEVEL), 2); + + @Override + protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) { diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/LightningRodBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/LightningRodBlock.java.patch new file mode 100644 index 0000000000..7480d6343d --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/LightningRodBlock.java.patch @@ -0,0 +1,21 @@ +--- a/net/minecraft/world/level/block/LightningRodBlock.java ++++ b/net/minecraft/world/level/block/LightningRodBlock.java +@@ -84,6 +_,18 @@ + } + + public void onLightningStrike(BlockState state, Level level, BlockPos pos) { ++ // CraftBukkit start ++ boolean powered = state.getValue(LightningRodBlock.POWERED); ++ int old = (powered) ? 15 : 0; ++ int current = (!powered) ? 15 : 0; ++ ++ org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(org.bukkit.craftbukkit.block.CraftBlock.at(level, pos), old, current); ++ level.getCraftServer().getPluginManager().callEvent(eventRedstone); ++ ++ if (eventRedstone.getNewCurrent() <= 0) { ++ return; ++ } ++ // CraftBukkit end + level.setBlock(pos, state.setValue(POWERED, Boolean.valueOf(true)), 3); + this.updateNeighbours(state, level, pos); + level.scheduleTick(pos, this, 8); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/LiquidBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/LiquidBlock.java.patch new file mode 100644 index 0000000000..3589e09e7d --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/LiquidBlock.java.patch @@ -0,0 +1,67 @@ +--- a/net/minecraft/world/level/block/LiquidBlock.java ++++ b/net/minecraft/world/level/block/LiquidBlock.java +@@ -135,9 +_,28 @@ + @Override + protected void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldState, boolean isMoving) { + if (this.shouldSpreadLiquid(level, pos, state)) { +- level.scheduleTick(pos, state.getFluidState().getType(), this.fluid.getTickDelay(level)); +- } +- } ++ level.scheduleTick(pos, state.getFluidState().getType(), this.getFlowSpeed(level, pos)); // Paper - Configurable speed for water flowing over lava ++ } ++ } ++ // Paper start - Configurable speed for water flowing over lava ++ public int getFlowSpeed(Level world, BlockPos blockposition) { ++ if (net.minecraft.core.registries.BuiltInRegistries.FLUID.wrapAsHolder(this.fluid).is(FluidTags.WATER)) { ++ if ( ++ isLava(world, blockposition.north(1)) || ++ isLava(world, blockposition.south(1)) || ++ isLava(world, blockposition.west(1)) || ++ isLava(world, blockposition.east(1)) ++ ) { ++ return world.paperConfig().environment.waterOverLavaFlowSpeed; ++ } ++ } ++ return this.fluid.getTickDelay(world); ++ } ++ private static boolean isLava(Level world, BlockPos blockPos) { ++ final FluidState fluidState = world.getFluidIfLoaded(blockPos); ++ return fluidState != null && fluidState.is(FluidTags.LAVA); ++ } ++ // Paper end - Configurable speed for water flowing over lava + + @Override + protected BlockState updateShape( +@@ -160,7 +_,7 @@ + @Override + protected void neighborChanged(BlockState state, Level level, BlockPos pos, Block neighborBlock, @Nullable Orientation orientation, boolean movedByPiston) { + if (this.shouldSpreadLiquid(level, pos, state)) { +- level.scheduleTick(pos, state.getFluidState().getType(), this.fluid.getTickDelay(level)); ++ level.scheduleTick(pos, state.getFluidState().getType(), this.getFlowSpeed(level, pos)); // Paper - Configurable speed for water flowing over lava + } + } + +@@ -173,13 +_,21 @@ + if (level.getFluidState(blockPos).is(FluidTags.WATER)) { + Block block = level.getFluidState(pos).isSource() ? Blocks.OBSIDIAN : Blocks.COBBLESTONE; + level.setBlockAndUpdate(pos, block.defaultBlockState()); +- this.fizz(level, pos); ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(level, pos, block.defaultBlockState())) { ++ this.fizz(level, pos); ++ } ++ // CraftBukkit end + return false; + } + + if (isSoulSoil && level.getBlockState(blockPos).is(Blocks.BLUE_ICE)) { + level.setBlockAndUpdate(pos, Blocks.BASALT.defaultBlockState()); +- this.fizz(level, pos); ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(level, pos, Blocks.BASALT.defaultBlockState())) { ++ this.fizz(level, pos); ++ } ++ // CraftBukkit end + return false; + } + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/LoomBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/LoomBlock.java.patch new file mode 100644 index 0000000000..04d34f0a8c --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/LoomBlock.java.patch @@ -0,0 +1,12 @@ +--- a/net/minecraft/world/level/block/LoomBlock.java ++++ b/net/minecraft/world/level/block/LoomBlock.java +@@ -32,8 +_,7 @@ + + @Override + protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) { +- if (!level.isClientSide) { +- player.openMenu(state.getMenuProvider(level, pos)); ++ if (!level.isClientSide && player.openMenu(state.getMenuProvider(level, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation + player.awardStat(Stats.INTERACT_WITH_LOOM); + } + diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/MagmaBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/MagmaBlock.java.patch new file mode 100644 index 0000000000..ae7d0a7fd6 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/MagmaBlock.java.patch @@ -0,0 +1,11 @@ +--- a/net/minecraft/world/level/block/MagmaBlock.java ++++ b/net/minecraft/world/level/block/MagmaBlock.java +@@ -29,7 +_,7 @@ + @Override + public void stepOn(Level level, BlockPos pos, BlockState state, Entity entity) { + if (!entity.isSteppingCarefully() && entity instanceof LivingEntity) { +- entity.hurt(level.damageSources().hotFloor(), 1.0F); ++ entity.hurt(level.damageSources().hotFloor().directBlock(level, pos), 1.0F); // CraftBukkit + } + + super.stepOn(level, pos, state, entity); diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/MangrovePropaguleBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/MangrovePropaguleBlock.java.patch similarity index 56% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/MangrovePropaguleBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/MangrovePropaguleBlock.java.patch index 8a2e3114dc..0ebbe0b613 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/MangrovePropaguleBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/MangrovePropaguleBlock.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/world/level/block/MangrovePropaguleBlock.java +++ b/net/minecraft/world/level/block/MangrovePropaguleBlock.java -@@ -123,7 +123,7 @@ +@@ -123,7 +_,7 @@ @Override - protected void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { + protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { if (!isHanging(state)) { - if (random.nextInt(7) == 0) { -+ if (random.nextFloat() < (world.spigotConfig.saplingModifier / (100.0F * 7))) { // Paper - Fix Spigot growth modifiers - this.advanceTree(world, pos, state, random); ++ if (random.nextFloat() < (level.spigotConfig.saplingModifier / (100.0F * 7))) { // Paper - Fix Spigot growth modifiers + this.advanceTree(level, pos, state, random); } } else { diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/MultifaceSpreader.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/MultifaceSpreader.java.patch new file mode 100644 index 0000000000..20085ae07e --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/MultifaceSpreader.java.patch @@ -0,0 +1,42 @@ +--- a/net/minecraft/world/level/block/MultifaceSpreader.java ++++ b/net/minecraft/world/level/block/MultifaceSpreader.java +@@ -154,14 +_,14 @@ + level.getChunk(pos.pos()).markPosForPostprocessing(pos.pos()); + } + +- return level.setBlock(pos.pos(), stateForPlacement, 2); ++ return org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, pos.source(), pos.pos(), stateForPlacement, 2); // CraftBukkit + } else { + return false; + } + } + } + +- public record SpreadPos(BlockPos pos, Direction face) { ++ public record SpreadPos(BlockPos pos, Direction face, BlockPos source) { // CraftBukkit + } + + @FunctionalInterface +@@ -173,19 +_,19 @@ + SAME_POSITION { + @Override + public MultifaceSpreader.SpreadPos getSpreadPos(BlockPos pos, Direction face, Direction spreadDirection) { +- return new MultifaceSpreader.SpreadPos(pos, face); ++ return new MultifaceSpreader.SpreadPos(pos, face, pos); // CraftBukkit + } + }, + SAME_PLANE { + @Override + public MultifaceSpreader.SpreadPos getSpreadPos(BlockPos pos, Direction face, Direction spreadDirection) { +- return new MultifaceSpreader.SpreadPos(pos.relative(face), spreadDirection); ++ return new MultifaceSpreader.SpreadPos(pos.relative(face), spreadDirection, pos); // CraftBukkit + } + }, + WRAP_AROUND { + @Override + public MultifaceSpreader.SpreadPos getSpreadPos(BlockPos pos, Direction face, Direction spreadDirection) { +- return new MultifaceSpreader.SpreadPos(pos.relative(face).relative(spreadDirection), face.getOpposite()); ++ return new MultifaceSpreader.SpreadPos(pos.relative(face).relative(spreadDirection), face.getOpposite(), pos); // CraftBukkit + } + }; + diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/MushroomBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/MushroomBlock.java.patch new file mode 100644 index 0000000000..188da77aec --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/MushroomBlock.java.patch @@ -0,0 +1,36 @@ +--- a/net/minecraft/world/level/block/MushroomBlock.java ++++ b/net/minecraft/world/level/block/MushroomBlock.java +@@ -47,7 +_,7 @@ + + @Override + protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { +- if (random.nextInt(25) == 0) { ++ if (random.nextFloat() < (level.spigotConfig.mushroomModifier / (100.0f * 25))) { // Spigot - SPIGOT-7159: Better modifier resolution + int i = 5; + int i1 = 4; + +@@ -60,6 +_,7 @@ + } + + BlockPos blockPos1 = pos.offset(random.nextInt(3) - 1, random.nextInt(2) - random.nextInt(2), random.nextInt(3) - 1); ++ final BlockPos sourcePos = pos; // Paper - Use correct source for mushroom block spread event + + for (int i2 = 0; i2 < 4; i2++) { + if (level.isEmptyBlock(blockPos1) && state.canSurvive(level, blockPos1)) { +@@ -70,7 +_,7 @@ + } + + if (level.isEmptyBlock(blockPos1) && state.canSurvive(level, blockPos1)) { +- level.setBlock(blockPos1, state, 2); ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, sourcePos, blockPos1, state, 2); // CraftBukkit // Paper - Use correct source for mushroom block spread event + } + } + } +@@ -93,6 +_,7 @@ + return false; + } else { + level.removeBlock(pos, false); ++ SaplingBlock.treeType = (this == Blocks.BROWN_MUSHROOM) ? org.bukkit.TreeType.BROWN_MUSHROOM : org.bukkit.TreeType.RED_MUSHROOM; // CraftBukkit + if (optional.get().value().place(level, level.getChunkSource().getGenerator(), random, pos)) { + return true; + } else { diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/NetherPortalBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/NetherPortalBlock.java.patch new file mode 100644 index 0000000000..d6707c3b66 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/NetherPortalBlock.java.patch @@ -0,0 +1,126 @@ +--- a/net/minecraft/world/level/block/NetherPortalBlock.java ++++ b/net/minecraft/world/level/block/NetherPortalBlock.java +@@ -70,7 +_,7 @@ + + @Override + protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { +- if (level.dimensionType().natural() ++ if (level.spigotConfig.enableZombiePigmenPortalSpawns && level.dimensionType().natural() // Spigot + && level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) + && random.nextInt(2000) < level.getDifficulty().getId()) { + while (level.getBlockState(pos).is(this)) { +@@ -78,9 +_,13 @@ + } + + if (level.getBlockState(pos).isValidSpawn(level, pos, EntityType.ZOMBIFIED_PIGLIN)) { +- Entity entity = EntityType.ZOMBIFIED_PIGLIN.spawn(level, pos.above(), EntitySpawnReason.STRUCTURE); ++ Entity entity = EntityType.ZOMBIFIED_PIGLIN.spawn(level, pos.above(), EntitySpawnReason.STRUCTURE, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NETHER_PORTAL); // CraftBukkit - set spawn reason to NETHER_PORTAL + if (entity != null) { + entity.setPortalCooldown(); ++ // Paper start - Add option to nerf pigmen from nether portals ++ entity.fromNetherPortal = true; ++ if (level.paperConfig().entities.behavior.nerfPigmenFromNetherPortals) ((net.minecraft.world.entity.Mob) entity).aware = false; ++ // Paper end - Add option to nerf pigmen from nether portals + Entity vehicle = entity.getVehicle(); + if (vehicle != null) { + vehicle.setPortalCooldown(); +@@ -111,7 +_,13 @@ + + @Override + protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) { ++ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent + if (entity.canUsePortal(false)) { ++ // CraftBukkit start - Entity in portal ++ org.bukkit.event.entity.EntityPortalEnterEvent event = new org.bukkit.event.entity.EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(level.getWorld(), pos.getX(), pos.getY(), pos.getZ()), org.bukkit.PortalType.NETHER); // Paper - add portal type ++ level.getCraftServer().getPluginManager().callEvent(event); ++ if (event.isCancelled()) return; // Paper - make cancellable ++ // CraftBukkit end + entity.setAsInsidePortal(this, pos); + } + } +@@ -134,22 +_,46 @@ + @Nullable + @Override + public TeleportTransition getPortalDestination(ServerLevel level, Entity entity, BlockPos pos) { +- ResourceKey resourceKey = level.dimension() == Level.NETHER ? Level.OVERWORLD : Level.NETHER; ++ // CraftBukkit start ++ ResourceKey resourceKey = level.getTypeKey() == net.minecraft.world.level.dimension.LevelStem.NETHER ? Level.OVERWORLD : Level.NETHER; + ServerLevel level1 = level.getServer().getLevel(resourceKey); ++ // Paper start - Add EntityPortalReadyEvent ++ io.papermc.paper.event.entity.EntityPortalReadyEvent portalReadyEvent = new io.papermc.paper.event.entity.EntityPortalReadyEvent(entity.getBukkitEntity(), level1 == null ? null : level1.getWorld(), org.bukkit.PortalType.NETHER); ++ if (!portalReadyEvent.callEvent()) { ++ entity.portalProcess = null; ++ return null; ++ } ++ level1 = portalReadyEvent.getTargetWorld() == null ? null : ((org.bukkit.craftbukkit.CraftWorld) portalReadyEvent.getTargetWorld()).getHandle(); ++ // Paper end - Add EntityPortalReadyEvent + if (level1 == null) { + return null; + } else { +- boolean flag = level1.dimension() == Level.NETHER; ++ boolean flag = level1.getTypeKey() == net.minecraft.world.level.dimension.LevelStem.NETHER; // CraftBukkit + WorldBorder worldBorder = level1.getWorldBorder(); + double teleportationScale = DimensionType.getTeleportationScale(level.dimensionType(), level1.dimensionType()); + BlockPos blockPos = worldBorder.clampToBounds(entity.getX() * teleportationScale, entity.getY(), entity.getZ() * teleportationScale); ++ // Paper start - Configurable portal search radius ++ int portalSearchRadius = level1.paperConfig().environment.portalSearchRadius; ++ if (entity.level().paperConfig().environment.portalSearchVanillaDimensionScaling && flag) { // flag = is going to nether ++ portalSearchRadius = (int) (portalSearchRadius / level1.dimensionType().coordinateScale()); ++ } ++ // Paper end - Configurable portal search radius ++ // CraftBukkit start ++ org.bukkit.craftbukkit.event.CraftPortalEvent event = entity.callPortalEvent(entity, org.bukkit.craftbukkit.util.CraftLocation.toBukkit(blockPos, level1.getWorld()), org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.NETHER_PORTAL, portalSearchRadius, level1.paperConfig().environment.portalCreateRadius); // Paper - use custom portal search radius ++ if (event == null) { ++ return null; ++ } ++ level1 = ((org.bukkit.craftbukkit.CraftWorld) event.getTo().getWorld()).getHandle(); ++ worldBorder = level1.getWorldBorder(); ++ blockPos = worldBorder.clampToBounds(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ()); ++ // CraftBukkit end + return this.getExitPortal(level1, entity, pos, blockPos, flag, worldBorder); + } + } + + @Nullable +- private TeleportTransition getExitPortal(ServerLevel level, Entity entity, BlockPos pos, BlockPos exitPos, boolean isNether, WorldBorder worldBorder) { +- Optional optional = level.getPortalForcer().findClosestPortalPosition(exitPos, isNether, worldBorder); ++ private TeleportTransition getExitPortal(ServerLevel level, Entity entity, BlockPos pos, BlockPos exitPos, boolean isNether, WorldBorder worldBorder, int searchRadius, boolean canCreatePortal, int createRadius) { // CraftBukkit ++ Optional optional = level.getPortalForcer().findClosestPortalPosition(exitPos, worldBorder, searchRadius); // Craftbukkit + BlockUtil.FoundRectangle largestRectangleAround; + TeleportTransition.PostTeleportTransition postTeleportTransition; + if (optional.isPresent()) { +@@ -164,17 +_,22 @@ + blockPos1 -> level.getBlockState(blockPos1) == blockState + ); + postTeleportTransition = TeleportTransition.PLAY_PORTAL_SOUND.then(entity1 -> entity1.placePortalTicket(blockPos)); +- } else { ++ } else if (canCreatePortal) { // CraftBukkit + Direction.Axis axis = entity.level().getBlockState(pos).getOptionalValue(AXIS).orElse(Direction.Axis.X); +- Optional optional1 = level.getPortalForcer().createPortal(exitPos, axis); ++ Optional optional1 = level.getPortalForcer().createPortal(exitPos, axis, entity, createRadius); // CraftBukkit + if (optional1.isEmpty()) { +- LOGGER.error("Unable to create a portal, likely target out of worldborder"); ++ // LOGGER.error("Unable to create a portal, likely target out of worldborder"); // CraftBukkit + return null; + } + + largestRectangleAround = optional1.get(); + postTeleportTransition = TeleportTransition.PLAY_PORTAL_SOUND.then(TeleportTransition.PLACE_PORTAL_TICKET); + } ++ // CraftBukkit start ++ else { ++ return null; ++ } ++ // CraftBukkit end + + return getDimensionTransitionFromExit(entity, pos, largestRectangleAround, level, postTeleportTransition); + } +@@ -220,7 +_,7 @@ + boolean flag = axis1 == Direction.Axis.X; + Vec3 vec3 = new Vec3(blockPos.getX() + (flag ? d2 : d4), blockPos.getY() + d3, blockPos.getZ() + (flag ? d4 : d2)); + Vec3 vec31 = PortalShape.findCollisionFreePosition(vec3, level, entity, dimensions); +- return new TeleportTransition(level, vec31, Vec3.ZERO, i, 0.0F, Relative.union(Relative.DELTA, Relative.ROTATION), postTeleportTransition); ++ return new TeleportTransition(level, vec31, Vec3.ZERO, i, 0.0F, Relative.union(Relative.DELTA, Relative.ROTATION), postTeleportTransition, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.NETHER_PORTAL); // CraftBukkit + } + + @Override diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/NetherWartBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/NetherWartBlock.java.patch new file mode 100644 index 0000000000..d55e5647cf --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/NetherWartBlock.java.patch @@ -0,0 +1,14 @@ +--- a/net/minecraft/world/level/block/NetherWartBlock.java ++++ b/net/minecraft/world/level/block/NetherWartBlock.java +@@ -55,9 +_,9 @@ + @Override + protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { + int ageValue = state.getValue(AGE); +- if (ageValue < 3 && random.nextInt(10) == 0) { ++ if (ageValue < 3 && random.nextFloat() < (level.spigotConfig.wartModifier / (100.0f * 10))) { // Spigot - SPIGOT-7159: Better modifier resolution + state = state.setValue(AGE, Integer.valueOf(ageValue + 1)); +- level.setBlock(pos, state, 2); ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, pos, state, 2); // CraftBukkit + } + } + diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/NoteBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/NoteBlock.java.patch new file mode 100644 index 0000000000..0ff72778c3 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/NoteBlock.java.patch @@ -0,0 +1,78 @@ +--- a/net/minecraft/world/level/block/NoteBlock.java ++++ b/net/minecraft/world/level/block/NoteBlock.java +@@ -70,6 +_,7 @@ + + @Override + public BlockState getStateForPlacement(BlockPlaceContext context) { ++ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableNoteblockUpdates) return this.defaultBlockState(); // Paper - place without considering instrument + return this.setInstrument(context.getLevel(), context.getClickedPos(), this.defaultBlockState()); + } + +@@ -84,6 +_,7 @@ + BlockState neighborState, + RandomSource random + ) { ++ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableNoteblockUpdates) return state; // Paper - prevent noteblock instrument from updating + boolean flag = direction.getAxis() == Direction.Axis.Y; + return flag + ? this.setInstrument(level, pos, state) +@@ -92,10 +_,12 @@ + + @Override + protected void neighborChanged(BlockState state, Level level, BlockPos pos, Block neighborBlock, @Nullable Orientation orientation, boolean movedByPiston) { ++ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableNoteblockUpdates) return; // Paper - prevent noteblock powered-state from updating + boolean hasNeighborSignal = level.hasNeighborSignal(pos); + if (hasNeighborSignal != state.getValue(POWERED)) { + if (hasNeighborSignal) { + this.playNote(null, state, level, pos); ++ state = level.getBlockState(pos); // CraftBukkit - SPIGOT-5617: update in case changed in event + } + + level.setBlock(pos, state.setValue(POWERED, Boolean.valueOf(hasNeighborSignal)), 3); +@@ -104,6 +_,13 @@ + + private void playNote(@Nullable Entity entity, BlockState state, Level level, BlockPos pos) { + if (state.getValue(INSTRUMENT).worksAboveNoteBlock() || level.getBlockState(pos.above()).isAir()) { ++ // CraftBukkit start ++ // org.bukkit.event.block.NotePlayEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callNotePlayEvent(world, pos, state.getValue(NoteBlock.INSTRUMENT), state.getValue(NoteBlock.NOTE)); ++ // if (event.isCancelled()) { ++ // return; ++ // } ++ // CraftBukkit end ++ // Paper - move NotePlayEvent call to fix instrument/note changes; TODO any way to cancel the game event? + level.blockEvent(pos, this, 0, 0); + level.gameEvent(entity, GameEvent.NOTE_BLOCK_PLAY, pos); + } +@@ -121,7 +_,7 @@ + @Override + protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) { + if (!level.isClientSide) { +- state = state.cycle(NOTE); ++ if (!io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableNoteblockUpdates) state = state.cycle(NoteBlock.NOTE); // Paper - prevent noteblock note from updating + level.setBlock(pos, state, 3); + this.playNote(player, state, level, pos); + player.awardStat(Stats.TUNE_NOTEBLOCK); +@@ -145,9 +_,13 @@ + @Override + protected boolean triggerEvent(BlockState state, Level level, BlockPos pos, int id, int param) { + NoteBlockInstrument noteBlockInstrument = state.getValue(INSTRUMENT); ++ // Paper start - move NotePlayEvent call to fix instrument/note changes ++ org.bukkit.event.block.NotePlayEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callNotePlayEvent(level, pos, noteBlockInstrument, state.getValue(NOTE)); ++ if (event.isCancelled()) return false; ++ // Paper end - move NotePlayEvent call to fix instrument/note changes + float pitchFromNote; + if (noteBlockInstrument.isTunable()) { +- int noteValue = state.getValue(NOTE); ++ int noteValue = event.getNote().getId(); // Paper - move NotePlayEvent call to fix instrument/note changes + pitchFromNote = getPitchFromNote(noteValue); + level.addParticle(ParticleTypes.NOTE, pos.getX() + 0.5, pos.getY() + 1.2, pos.getZ() + 0.5, noteValue / 24.0, 0.0, 0.0); + } else { +@@ -163,7 +_,7 @@ + + holder = Holder.direct(SoundEvent.createVariableRangeEvent(customSoundId)); + } else { +- holder = noteBlockInstrument.getSoundEvent(); ++ holder = org.bukkit.craftbukkit.block.data.CraftBlockData.toNMS(event.getInstrument(), NoteBlockInstrument.class).getSoundEvent(); // Paper - move NotePlayEvent call to fix instrument/note changes + } + + level.playSeededSound( diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/NyliumBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/NyliumBlock.java.patch similarity index 52% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/NyliumBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/NyliumBlock.java.patch index cc4aae4d48..c447936cca 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/NyliumBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/NyliumBlock.java.patch @@ -1,14 +1,14 @@ --- a/net/minecraft/world/level/block/NyliumBlock.java +++ b/net/minecraft/world/level/block/NyliumBlock.java -@@ -41,6 +41,11 @@ +@@ -39,6 +_,11 @@ @Override - protected void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { - if (!NyliumBlock.canBeNylium(state, world, pos)) { + protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { + if (!canBeNylium(state, level, pos)) { + // CraftBukkit start -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, pos, Blocks.NETHERRACK.defaultBlockState()).isCancelled()) { ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(level, pos, Blocks.NETHERRACK.defaultBlockState()).isCancelled()) { + return; + } + // CraftBukkit end - world.setBlockAndUpdate(pos, Blocks.NETHERRACK.defaultBlockState()); + level.setBlockAndUpdate(pos, Blocks.NETHERRACK.defaultBlockState()); } - + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/ObserverBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/ObserverBlock.java.patch new file mode 100644 index 0000000000..12eb553307 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/ObserverBlock.java.patch @@ -0,0 +1,21 @@ +--- a/net/minecraft/world/level/block/ObserverBlock.java ++++ b/net/minecraft/world/level/block/ObserverBlock.java +@@ -50,8 +_,18 @@ + @Override + protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { + if (state.getValue(POWERED)) { ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, 15, 0).getNewCurrent() != 0) { ++ return; ++ } ++ // CraftBukkit end + level.setBlock(pos, state.setValue(POWERED, Boolean.valueOf(false)), 2); + } else { ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, 0, 15).getNewCurrent() != 15) { ++ return; ++ } ++ // CraftBukkit end + level.setBlock(pos, state.setValue(POWERED, Boolean.valueOf(true)), 2); + level.scheduleTick(pos, this, 2); + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/PitcherCropBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/PitcherCropBlock.java.patch new file mode 100644 index 0000000000..174bccf67d --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/PitcherCropBlock.java.patch @@ -0,0 +1,20 @@ +--- a/net/minecraft/world/level/block/PitcherCropBlock.java ++++ b/net/minecraft/world/level/block/PitcherCropBlock.java +@@ -131,7 +_,7 @@ + @Override + public void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { + float growthSpeed = CropBlock.getGrowthSpeed(this, level, pos); +- boolean flag = random.nextInt((int)(25.0F / growthSpeed) + 1) == 0; ++ boolean flag = random.nextFloat() < (level.spigotConfig.pitcherPlantModifier / (100.0F * (Math.floor(25.0F / growthSpeed) + 1))); // Paper - Fix Spigot growth modifiers + if (flag) { + this.grow(level, state, pos, 1); + } +@@ -141,7 +_,7 @@ + int min = Math.min(state.getValue(AGE) + ageIncrement, 4); + if (this.canGrow(level, pos, state, min)) { + BlockState blockState = state.setValue(AGE, Integer.valueOf(min)); +- level.setBlock(pos, blockState, 2); ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, pos, blockState, 2)) return; // Paper + if (isDouble(min)) { + level.setBlock(pos.above(), blockState.setValue(HALF, DoubleBlockHalf.UPPER), 3); + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/PointedDripstoneBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/PointedDripstoneBlock.java.patch new file mode 100644 index 0000000000..b998179c3b --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/PointedDripstoneBlock.java.patch @@ -0,0 +1,68 @@ +--- a/net/minecraft/world/level/block/PointedDripstoneBlock.java ++++ b/net/minecraft/world/level/block/PointedDripstoneBlock.java +@@ -147,6 +_,11 @@ + && projectile.mayBreak(serverLevel) + && projectile instanceof ThrownTrident + && projectile.getDeltaMovement().length() > 0.6) { ++ // CraftBukkit start ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(projectile, blockPos, state.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state ++ return; ++ } ++ // CraftBukkit end + level.destroyBlock(blockPos, true); + } + } +@@ -155,7 +_,7 @@ + @Override + public void fallOn(Level level, BlockState state, BlockPos pos, Entity entity, float fallDistance) { + if (state.getValue(TIP_DIRECTION) == Direction.UP && state.getValue(THICKNESS) == DripstoneThickness.TIP) { +- entity.causeFallDamage(fallDistance + 2.0F, 2.0F, level.damageSources().stalagmite()); ++ entity.causeFallDamage(fallDistance + 2.0F, 2.0F, level.damageSources().stalagmite().directBlock(level, pos)); // CraftBukkit + } else { + super.fallOn(level, state, pos, entity, fallDistance); + } +@@ -213,10 +_,12 @@ + if (blockPos != null) { + if (fluidAboveStalactite.get().sourceState.is(Blocks.MUD) && fluid == Fluids.WATER) { + BlockState blockState = Blocks.CLAY.defaultBlockState(); ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(level, fluidAboveStalactite.get().pos, blockState)) { // Paper - Call BlockFormEvent + level.setBlockAndUpdate(fluidAboveStalactite.get().pos, blockState); + Block.pushEntitiesUp(fluidAboveStalactite.get().sourceState, blockState, level, fluidAboveStalactite.get().pos); + level.gameEvent(GameEvent.BLOCK_CHANGE, fluidAboveStalactite.get().pos, GameEvent.Context.of(blockState)); + level.levelEvent(1504, blockPos, 0); ++ } // Paper - Call BlockFormEvent + } else { + BlockPos blockPos1 = findFillableCauldronBelowStalactiteTip(level, blockPos, fluid); + if (blockPos1 != null) { +@@ -380,17 +_,17 @@ + if (isUnmergedTipWithDirection(blockState, direction.getOpposite())) { + createMergedTips(blockState, server, blockPos); + } else if (blockState.isAir() || blockState.is(Blocks.WATER)) { +- createDripstone(server, blockPos, direction, DripstoneThickness.TIP); ++ createDripstone(server, blockPos, direction, DripstoneThickness.TIP, pos); // CraftBukkit; + } + } + +- private static void createDripstone(LevelAccessor level, BlockPos pos, Direction direction, DripstoneThickness thickness) { ++ private static void createDripstone(LevelAccessor level, BlockPos pos, Direction direction, DripstoneThickness thickness, BlockPos source) { // CraftBukkit + BlockState blockState = Blocks.POINTED_DRIPSTONE + .defaultBlockState() + .setValue(TIP_DIRECTION, direction) + .setValue(THICKNESS, thickness) + .setValue(WATERLOGGED, Boolean.valueOf(level.getFluidState(pos).getType() == Fluids.WATER)); +- level.setBlock(pos, blockState, 3); ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, source, pos, blockState, 3); // CraftBukkit + } + + private static void createMergedTips(BlockState state, LevelAccessor level, BlockPos pos) { +@@ -404,8 +_,8 @@ + blockPos = pos.below(); + } + +- createDripstone(level, blockPos1, Direction.DOWN, DripstoneThickness.TIP_MERGE); +- createDripstone(level, blockPos, Direction.UP, DripstoneThickness.TIP_MERGE); ++ createDripstone(level, blockPos1, Direction.DOWN, DripstoneThickness.TIP_MERGE, pos); // CraftBukkit ++ createDripstone(level, blockPos, Direction.UP, DripstoneThickness.TIP_MERGE, pos); // CraftBukkit + } + + public static void spawnDripParticle(Level level, BlockPos pos, BlockState state) { diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/PowderSnowBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/PowderSnowBlock.java.patch new file mode 100644 index 0000000000..1254939fc6 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/PowderSnowBlock.java.patch @@ -0,0 +1,25 @@ +--- a/net/minecraft/world/level/block/PowderSnowBlock.java ++++ b/net/minecraft/world/level/block/PowderSnowBlock.java +@@ -58,6 +_,7 @@ + + @Override + protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity) { ++ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent + if (!(entity instanceof LivingEntity) || entity.getInBlockState().is(this)) { + entity.makeStuckInBlock(state, new Vec3(0.9F, 1.5, 0.9F)); + if (level.isClientSide) { +@@ -80,8 +_,13 @@ + entity.setIsInPowderSnow(true); + if (level instanceof ServerLevel serverLevel) { + if (entity.isOnFire() +- && (serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) || entity instanceof Player) ++ // CraftBukkit - move down + && entity.mayInteract(serverLevel, pos)) { ++ // CraftBukkit start ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState(), !(serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) || entity instanceof Player))) { ++ return; ++ } ++ // CraftBukkit end + level.destroyBlock(pos, false); + } + diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/PoweredRailBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/PoweredRailBlock.java.patch new file mode 100644 index 0000000000..04777f56ac --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/PoweredRailBlock.java.patch @@ -0,0 +1,16 @@ +--- a/net/minecraft/world/level/block/PoweredRailBlock.java ++++ b/net/minecraft/world/level/block/PoweredRailBlock.java +@@ -133,6 +_,13 @@ + || this.findPoweredRailSignal(level, pos, state, true, 0) + || this.findPoweredRailSignal(level, pos, state, false, 0); + if (flag != poweredValue) { ++ // CraftBukkit start ++ int power = flag ? 15 : 0; ++ int newPower = org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, power, 15 - power).getNewCurrent(); ++ if (newPower == power) { ++ return; ++ } ++ // CraftBukkit end + level.setBlock(pos, state.setValue(POWERED, Boolean.valueOf(flag)), 3); + level.updateNeighborsAt(pos.below(), this); + if (state.getValue(SHAPE).isSlope()) { diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/PressurePlateBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/PressurePlateBlock.java.patch new file mode 100644 index 0000000000..235e99adff --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/PressurePlateBlock.java.patch @@ -0,0 +1,43 @@ +--- a/net/minecraft/world/level/block/PressurePlateBlock.java ++++ b/net/minecraft/world/level/block/PressurePlateBlock.java +@@ -5,6 +_,7 @@ + import net.minecraft.core.BlockPos; + import net.minecraft.world.entity.Entity; + import net.minecraft.world.entity.LivingEntity; ++import net.minecraft.world.entity.player.Player; + import net.minecraft.world.level.Level; + import net.minecraft.world.level.block.state.BlockBehaviour; + import net.minecraft.world.level.block.state.BlockState; +@@ -46,7 +_,31 @@ + case EVERYTHING -> Entity.class; + case MOBS -> LivingEntity.class; + }; +- return getEntityCount(level, TOUCH_AABB.move(pos), clazz) > 0 ? 15 : 0; ++ // CraftBukkit start - Call interact event when turning on a pressure plate ++ for (Entity entity : getEntities(level, PressurePlateBlock.TOUCH_AABB.move(pos), clazz)) { ++ if (this.getSignalForState(level.getBlockState(pos)) == 0) { ++ org.bukkit.World bworld = level.getWorld(); ++ org.bukkit.plugin.PluginManager manager = level.getCraftServer().getPluginManager(); ++ org.bukkit.event.Cancellable cancellable; ++ ++ if (entity instanceof Player) { ++ cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((Player) entity, org.bukkit.event.block.Action.PHYSICAL, pos, null, null, null); ++ } else { ++ cancellable = new org.bukkit.event.entity.EntityInteractEvent(entity.getBukkitEntity(), bworld.getBlockAt(pos.getX(), pos.getY(), pos.getZ())); ++ manager.callEvent((org.bukkit.event.entity.EntityInteractEvent) cancellable); ++ } ++ ++ // We only want to block turning the plate on if all events are cancelled ++ if (cancellable.isCancelled()) { ++ continue; ++ } ++ } ++ ++ return 15; ++ } ++ ++ return 0; ++ // CraftBukkit end + } + + @Override diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/PumpkinBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/PumpkinBlock.java.patch similarity index 64% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/PumpkinBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/PumpkinBlock.java.patch index d3d384ea46..20e12e9b1d 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/PumpkinBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/PumpkinBlock.java.patch @@ -1,7 +1,7 @@ --- a/net/minecraft/world/level/block/PumpkinBlock.java +++ b/net/minecraft/world/level/block/PumpkinBlock.java -@@ -38,16 +38,24 @@ - } else if (world.isClientSide) { +@@ -40,21 +_,30 @@ + } else if (level.isClientSide) { return InteractionResult.SUCCESS; } else { + // Paper start - Add PlayerShearBlockEvent @@ -11,26 +11,24 @@ + return InteractionResult.PASS; + } + // Paper end - Add PlayerShearBlockEvent - Direction direction = hit.getDirection(); - Direction direction2 = direction.getAxis() == Direction.Axis.Y ? player.getDirection().getOpposite() : direction; - world.playSound(null, pos, SoundEvents.PUMPKIN_CARVE, SoundSource.BLOCKS, 1.0F, 1.0F); - world.setBlock(pos, Blocks.CARVED_PUMPKIN.defaultBlockState().setValue(CarvedPumpkinBlock.FACING, direction2), 11); + Direction direction = hitResult.getDirection(); + Direction direction1 = direction.getAxis() == Direction.Axis.Y ? player.getDirection().getOpposite() : direction; + level.playSound(null, pos, SoundEvents.PUMPKIN_CARVE, SoundSource.BLOCKS, 1.0F, 1.0F); + level.setBlock(pos, Blocks.CARVED_PUMPKIN.defaultBlockState().setValue(CarvedPumpkinBlock.FACING, direction1), 11); + for (org.bukkit.inventory.ItemStack item : event.getDrops()) { // Paper - Add PlayerShearBlockEvent ItemEntity itemEntity = new ItemEntity( - world, - (double)pos.getX() + 0.5 + (double)direction2.getStepX() * 0.65, - (double)pos.getY() + 0.1, - (double)pos.getZ() + 0.5 + (double)direction2.getStepZ() * 0.65, + level, + pos.getX() + 0.5 + direction1.getStepX() * 0.65, + pos.getY() + 0.1, + pos.getZ() + 0.5 + direction1.getStepZ() * 0.65, - new ItemStack(Items.PUMPKIN_SEEDS, 4) + org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(item) // Paper - Add PlayerShearBlockEvent ); itemEntity.setDeltaMovement( - 0.05 * (double)direction2.getStepX() + world.random.nextDouble() * 0.02, -@@ -55,6 +63,7 @@ - 0.05 * (double)direction2.getStepZ() + world.random.nextDouble() * 0.02 + 0.05 * direction1.getStepX() + level.random.nextDouble() * 0.02, 0.05, 0.05 * direction1.getStepZ() + level.random.nextDouble() * 0.02 ); - world.addFreshEntity(itemEntity); + level.addFreshEntity(itemEntity); + } // Paper - Add PlayerShearBlockEvent stack.hurtAndBreak(1, player, LivingEntity.getSlotForHand(hand)); - world.gameEvent(player, GameEvent.SHEAR, pos); + level.gameEvent(player, GameEvent.SHEAR, pos); player.awardStat(Stats.ITEM_USED.get(Items.SHEARS)); diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/RailState.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/RailState.java.patch similarity index 59% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/RailState.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/RailState.java.patch index b79bfb5efd..1a9dbf420d 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/RailState.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/RailState.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/RailState.java +++ b/net/minecraft/world/level/block/RailState.java -@@ -17,6 +17,12 @@ +@@ -17,6 +_,12 @@ private final boolean isStraight; private final List connections = Lists.newArrayList(); @@ -10,24 +10,24 @@ + } + // Paper end - Fix some rails connecting improperly + - public RailState(Level world, BlockPos pos, BlockState state) { - this.level = world; + public RailState(Level level, BlockPos pos, BlockState state) { + this.level = level; this.pos = pos; -@@ -141,6 +147,11 @@ +@@ -141,6 +_,11 @@ } - private void connectTo(RailState placementHelper) { + private void connectTo(RailState state) { + // Paper start - Fix some rails connecting improperly -+ if (!this.isValid() || !placementHelper.isValid()) { ++ if (!this.isValid() || !state.isValid()) { + return; + } + // Paper end - Fix some rails connecting improperly - this.connections.add(placementHelper.pos); + this.connections.add(state.pos); BlockPos blockPos = this.pos.north(); - BlockPos blockPos2 = this.pos.south(); -@@ -331,10 +342,15 @@ - this.state = this.state.setValue(this.block.getShapeProperty(), railShape2); - if (forceUpdate || this.level.getBlockState(this.pos) != this.state) { + BlockPos blockPos1 = this.pos.south(); +@@ -331,10 +_,15 @@ + this.state = this.state.setValue(this.block.getShapeProperty(), railShape); + if (alwaysPlace || this.level.getBlockState(this.pos) != this.state) { this.level.setBlock(this.pos, this.state, 3); + // Paper start - Fix some rails connecting improperly + if (!this.isValid()) { @@ -36,13 +36,13 @@ + // Paper end - Fix some rails connecting improperly for (int i = 0; i < this.connections.size(); i++) { - RailState railState = this.getRail(this.connections.get(i)); -- if (railState != null) { -+ if (railState != null && railState.isValid()) { // Paper - Fix some rails connecting improperly - railState.removeSoftConnections(); - if (railState.canConnectTo(this)) { - railState.connectTo(this); -@@ -347,6 +363,6 @@ + RailState rail = this.getRail(this.connections.get(i)); +- if (rail != null) { ++ if (rail != null && rail.isValid()) { // Paper - Fix some rails connecting improperly + rail.removeSoftConnections(); + if (rail.canConnectTo(this)) { + rail.connectTo(this); +@@ -347,6 +_,6 @@ } public BlockState getState() { diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/RedStoneOreBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/RedStoneOreBlock.java.patch new file mode 100644 index 0000000000..6f93bcddd4 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/RedStoneOreBlock.java.patch @@ -0,0 +1,89 @@ +--- a/net/minecraft/world/level/block/RedStoneOreBlock.java ++++ b/net/minecraft/world/level/block/RedStoneOreBlock.java +@@ -37,14 +_,27 @@ + + @Override + protected void attack(BlockState state, Level level, BlockPos pos, Player player) { +- interact(state, level, pos); ++ interact(state, level, pos, player); // CraftBukkit - add entityhuman + super.attack(state, level, pos, player); + } + + @Override + public void stepOn(Level level, BlockPos pos, BlockState state, Entity entity) { + if (!entity.isSteppingCarefully()) { +- interact(state, level, pos); ++ // CraftBukkit start ++ if (entity instanceof Player) { ++ org.bukkit.event.player.PlayerInteractEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((Player) entity, org.bukkit.event.block.Action.PHYSICAL, pos, null, null, null); ++ if (!event.isCancelled()) { ++ RedStoneOreBlock.interact(level.getBlockState(pos), level, pos, entity); // add entity ++ } ++ } else { ++ org.bukkit.event.entity.EntityInteractEvent event = new org.bukkit.event.entity.EntityInteractEvent(entity.getBukkitEntity(), level.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ())); ++ level.getCraftServer().getPluginManager().callEvent(event); ++ if (!event.isCancelled()) { ++ RedStoneOreBlock.interact(level.getBlockState(pos), level, pos, entity); // add entity ++ } ++ } ++ // CraftBukkit end + } + + super.stepOn(level, pos, state, entity); +@@ -57,7 +_,7 @@ + if (level.isClientSide) { + spawnParticles(level, pos); + } else { +- interact(state, level, pos); ++ interact(state, level, pos, player); // CraftBukkit - add entityhuman + } + + return (InteractionResult)(stack.getItem() instanceof BlockItem && new BlockPlaceContext(player, hand, stack, hitResult).canPlace() +@@ -65,9 +_,14 @@ + : InteractionResult.SUCCESS); + } + +- private static void interact(BlockState state, Level level, BlockPos pos) { ++ private static void interact(BlockState state, Level level, BlockPos pos, Entity entity) { // CraftBukkit - add Entity + spawnParticles(level, pos); + if (!state.getValue(LIT)) { ++ // CraftBukkit start ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, state.setValue(RedStoneOreBlock.LIT, true))) { ++ return; ++ } ++ // CraftBukkit end + level.setBlock(pos, state.setValue(LIT, Boolean.valueOf(true)), 3); + } + } +@@ -80,6 +_,11 @@ + @Override + protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { + if (state.getValue(LIT)) { ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(level, pos, state.setValue(RedStoneOreBlock.LIT, false)).isCancelled()) { ++ return; ++ } ++ // CraftBukkit end + level.setBlock(pos, state.setValue(LIT, Boolean.valueOf(false)), 3); + } + } +@@ -87,9 +_,17 @@ + @Override + protected void spawnAfterBreak(BlockState state, ServerLevel level, BlockPos pos, ItemStack stack, boolean dropExperience) { + super.spawnAfterBreak(state, level, pos, stack, dropExperience); +- if (dropExperience) { +- this.tryDropExperience(level, pos, stack, UniformInt.of(1, 5)); ++ // CraftBukkit start - Delegated to getExpDrop ++ } ++ ++ @Override ++ public int getExpDrop(BlockState iblockdata, ServerLevel worldserver, BlockPos blockposition, ItemStack itemstack, boolean flag) { ++ if (flag) { ++ return this.tryDropExperience(worldserver, blockposition, itemstack, UniformInt.of(1, 5)); + } ++ ++ return 0; ++ // CraftBukkit end + } + + @Override diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/RedstoneLampBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/RedstoneLampBlock.java.patch new file mode 100644 index 0000000000..32b4488b6d --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/RedstoneLampBlock.java.patch @@ -0,0 +1,26 @@ +--- a/net/minecraft/world/level/block/RedstoneLampBlock.java ++++ b/net/minecraft/world/level/block/RedstoneLampBlock.java +@@ -41,6 +_,11 @@ + if (litValue) { + level.scheduleTick(pos, this, 4); + } else { ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, 0, 15).getNewCurrent() != 15) { ++ return; ++ } ++ // CraftBukkit end + level.setBlock(pos, state.cycle(LIT), 2); + } + } +@@ -50,6 +_,11 @@ + @Override + protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { + if (state.getValue(LIT) && !level.hasNeighborSignal(pos)) { ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(level, pos, 15, 0).getNewCurrent() != 0) { ++ return; ++ } ++ // CraftBukkit end + level.setBlock(pos, state.cycle(LIT), 2); + } + } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/RedstoneTorchBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/RedstoneTorchBlock.java.patch similarity index 55% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/RedstoneTorchBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/RedstoneTorchBlock.java.patch index 69d1dcb6e7..d8efa215bb 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/RedstoneTorchBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/RedstoneTorchBlock.java.patch @@ -1,47 +1,42 @@ --- a/net/minecraft/world/level/block/RedstoneTorchBlock.java +++ b/net/minecraft/world/level/block/RedstoneTorchBlock.java -@@ -22,11 +22,13 @@ - import net.minecraft.world.level.redstone.ExperimentalRedstoneUtils; - import net.minecraft.world.level.redstone.Orientation; - -+import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit -+ +@@ -24,7 +_,7 @@ public class RedstoneTorchBlock extends BaseTorchBlock { - public static final MapCodec CODEC = simpleCodec(RedstoneTorchBlock::new); public static final BooleanProperty LIT = BlockStateProperties.LIT; -- private static final Map> RECENT_TOGGLES = new WeakHashMap(); +- private static final Map> RECENT_TOGGLES = new WeakHashMap<>(); + // Paper - Faster redstone torch rapid clock removal; Move the mapped list to World public static final int RECENT_TOGGLE_TIMER = 60; public static final int MAX_RECENT_TOGGLES = 8; public static final int RESTART_DELAY = 160; -@@ -79,14 +81,34 @@ +@@ -72,14 +_,34 @@ @Override - protected void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { - boolean flag = this.hasNeighborSignal(world, pos, state); -- List list = (List) RedstoneTorchBlock.RECENT_TOGGLES.get(world); + protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { + boolean hasNeighborSignal = this.hasNeighborSignal(level, pos, state); +- List list = RECENT_TOGGLES.get(level); - -- while (list != null && !list.isEmpty() && world.getGameTime() - ((RedstoneTorchBlock.Toggle) list.get(0)).when > 60L) { +- while (list != null && !list.isEmpty() && level.getGameTime() - list.get(0).when > 60L) { - list.remove(0); + // Paper start - Faster redstone torch rapid clock removal -+ java.util.ArrayDeque redstoneUpdateInfos = world.redstoneUpdateInfos; ++ java.util.ArrayDeque redstoneUpdateInfos = level.redstoneUpdateInfos; + if (redstoneUpdateInfos != null) { + RedstoneTorchBlock.Toggle curr; -+ while ((curr = redstoneUpdateInfos.peek()) != null && world.getGameTime() - curr.when > 60L) { ++ while ((curr = redstoneUpdateInfos.peek()) != null && level.getGameTime() - curr.when > 60L) { + redstoneUpdateInfos.poll(); + } } +- + // Paper end - Faster redstone torch rapid clock removal - ++ + // CraftBukkit start -+ org.bukkit.plugin.PluginManager manager = world.getCraftServer().getPluginManager(); -+ org.bukkit.block.Block block = world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); ++ org.bukkit.plugin.PluginManager manager = level.getCraftServer().getPluginManager(); ++ org.bukkit.block.Block block = level.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); + int oldCurrent = ((Boolean) state.getValue(RedstoneTorchBlock.LIT)).booleanValue() ? 15 : 0; + -+ BlockRedstoneEvent event = new BlockRedstoneEvent(block, oldCurrent, oldCurrent); ++ org.bukkit.event.block.BlockRedstoneEvent event = new org.bukkit.event.block.BlockRedstoneEvent(block, oldCurrent, oldCurrent); + // CraftBukkit end - if ((Boolean) state.getValue(RedstoneTorchBlock.LIT)) { - if (flag) { + if (state.getValue(LIT)) { + if (hasNeighborSignal) { + // CraftBukkit start + if (oldCurrent != 0) { + event.setNewCurrent(0); @@ -51,13 +46,13 @@ + } + } + // CraftBukkit end - world.setBlock(pos, (BlockState) state.setValue(RedstoneTorchBlock.LIT, false), 3); - if (RedstoneTorchBlock.isToggledTooFrequently(world, pos, true)) { - world.levelEvent(1502, pos, 0); -@@ -94,6 +116,15 @@ + level.setBlock(pos, state.setValue(LIT, Boolean.valueOf(false)), 3); + if (isToggledTooFrequently(level, pos, true)) { + level.levelEvent(1502, pos, 0); +@@ -87,6 +_,15 @@ } } - } else if (!flag && !RedstoneTorchBlock.isToggledTooFrequently(world, pos, false)) { + } else if (!hasNeighborSignal && !isToggledTooFrequently(level, pos, false)) { + // CraftBukkit start + if (oldCurrent != 15) { + event.setNewCurrent(15); @@ -67,22 +62,20 @@ + } + } + // CraftBukkit end - world.setBlock(pos, (BlockState) state.setValue(RedstoneTorchBlock.LIT, true), 3); + level.setBlock(pos, state.setValue(LIT, Boolean.valueOf(true)), 3); } - -@@ -134,9 +165,12 @@ + } +@@ -124,7 +_,12 @@ } - private static boolean isToggledTooFrequently(Level world, BlockPos pos, boolean addNew) { -- List list = (List) RedstoneTorchBlock.RECENT_TOGGLES.computeIfAbsent(world, (iblockaccess) -> { -- return Lists.newArrayList(); -- }); + private static boolean isToggledTooFrequently(Level level, BlockPos pos, boolean logToggle) { +- List list = RECENT_TOGGLES.computeIfAbsent(level, toggles -> Lists.newArrayList()); + // Paper start - Faster redstone torch rapid clock removal -+ java.util.ArrayDeque list = world.redstoneUpdateInfos; ++ java.util.ArrayDeque list = level.redstoneUpdateInfos; + if (list == null) { -+ list = world.redstoneUpdateInfos = new java.util.ArrayDeque<>(); ++ list = level.redstoneUpdateInfos = new java.util.ArrayDeque<>(); + } + // Paper end - Faster redstone torch rapid clock removal - - if (addNew) { - list.add(new RedstoneTorchBlock.Toggle(pos.immutable(), world.getGameTime())); + if (logToggle) { + list.add(new RedstoneTorchBlock.Toggle(pos.immutable(), level.getGameTime())); + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/RespawnAnchorBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/RespawnAnchorBlock.java.patch new file mode 100644 index 0000000000..17ec642eda --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/block/RespawnAnchorBlock.java.patch @@ -0,0 +1,37 @@ +--- a/net/minecraft/world/level/block/RespawnAnchorBlock.java ++++ b/net/minecraft/world/level/block/RespawnAnchorBlock.java +@@ -102,11 +_,16 @@ + if (!level.isClientSide) { + ServerPlayer serverPlayer = (ServerPlayer)player; + if (serverPlayer.getRespawnDimension() != level.dimension() || !pos.equals(serverPlayer.getRespawnPosition())) { +- serverPlayer.setRespawnPosition(level.dimension(), pos, 0.0F, false, true); ++ if (serverPlayer.setRespawnPosition(level.dimension(), pos, 0.0F, false, true, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.RESPAWN_ANCHOR)) { // Paper - Add PlayerSetSpawnEvent + level.playSound( + null, pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5, SoundEvents.RESPAWN_ANCHOR_SET_SPAWN, SoundSource.BLOCKS, 1.0F, 1.0F + ); + return InteractionResult.SUCCESS_SERVER; ++ // Paper start - Add PlayerSetSpawnEvent ++ } else { ++ return InteractionResult.FAIL; ++ } ++ // Paper end - Add PlayerSetSpawnEvent + } + } + +@@ -140,6 +_,7 @@ + } + + private void explode(BlockState state, Level level, final BlockPos pos2) { ++ org.bukkit.block.BlockState blockState = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos2).getState(); // CraftBukkit - capture BlockState before remove block + level.removeBlock(pos2, false); + boolean flag = Direction.Plane.HORIZONTAL.stream().map(pos2::relative).anyMatch(pos -> isWaterThatWouldFlow(pos, level)); + final boolean flag1 = flag || level.getFluidState(pos2.above()).is(FluidTags.WATER); +@@ -153,7 +_,7 @@ + }; + Vec3 center = pos2.getCenter(); + level.explode( +- null, level.damageSources().badRespawnPointExplosion(center), explosionDamageCalculator, center, 5.0F, true, Level.ExplosionInteraction.BLOCK ++ null, level.damageSources().badRespawnPointExplosion(center, blockState), explosionDamageCalculator, center, 5.0F, true, Level.ExplosionInteraction.BLOCK // CraftBukkit - add state + ); + } + diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/RootedDirtBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/RootedDirtBlock.java.patch similarity index 60% rename from paper-server/patches/unapplied/net/minecraft/world/level/block/RootedDirtBlock.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/RootedDirtBlock.java.patch index de8d7301e4..6a3b2066a8 100644 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/RootedDirtBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/RootedDirtBlock.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/world/level/block/RootedDirtBlock.java +++ b/net/minecraft/world/level/block/RootedDirtBlock.java -@@ -34,7 +34,7 @@ +@@ -33,7 +_,7 @@ @Override - public void performBonemeal(ServerLevel world, RandomSource random, BlockPos pos, BlockState state) { -- world.setBlockAndUpdate(pos.below(), Blocks.HANGING_ROOTS.defaultBlockState()); -+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(world, pos, pos.below(), Blocks.HANGING_ROOTS.defaultBlockState()); // CraftBukkit + public void performBonemeal(ServerLevel level, RandomSource random, BlockPos pos, BlockState state) { +- level.setBlockAndUpdate(pos.below(), Blocks.HANGING_ROOTS.defaultBlockState()); ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(level, pos, pos.below(), Blocks.HANGING_ROOTS.defaultBlockState()); // CraftBukkit } @Override diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/AbstractCandleBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/AbstractCandleBlock.java.patch deleted file mode 100644 index 2c42f4cb51..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/AbstractCandleBlock.java.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- a/net/minecraft/world/level/block/AbstractCandleBlock.java -+++ b/net/minecraft/world/level/block/AbstractCandleBlock.java -@@ -47,6 +47,11 @@ - @Override - protected void onProjectileHit(Level world, BlockState state, BlockHitResult hit, Projectile projectile) { - if (!world.isClientSide && projectile.isOnFire() && this.canBeLit(state)) { -+ // CraftBukkit start -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(world, hit.getBlockPos(), projectile).isCancelled()) { -+ return; -+ } -+ // CraftBukkit end - AbstractCandleBlock.setLit(world, state, hit.getBlockPos(), true); - } - diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/AbstractCauldronBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/AbstractCauldronBlock.java.patch deleted file mode 100644 index e2c8cb7f03..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/AbstractCauldronBlock.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/net/minecraft/world/level/block/AbstractCauldronBlock.java -+++ b/net/minecraft/world/level/block/AbstractCauldronBlock.java -@@ -56,7 +56,7 @@ - @Override - protected InteractionResult useItemOn(ItemStack stack, BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { - CauldronInteraction cauldronInteraction = this.interactions.map().get(stack.getItem()); -- return cauldronInteraction.interact(state, world, pos, player, hand, stack); -+ return cauldronInteraction.interact(state, world, pos, player, hand, stack, hit.getDirection()); // Paper - pass hit direction - } - - @Override diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/BambooSaplingBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/BambooSaplingBlock.java.patch deleted file mode 100644 index 88344a70cd..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/BambooSaplingBlock.java.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- a/net/minecraft/world/level/block/BambooSaplingBlock.java -+++ b/net/minecraft/world/level/block/BambooSaplingBlock.java -@@ -45,7 +45,7 @@ - - @Override - protected void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { -- if (random.nextInt(3) == 0 && world.isEmptyBlock(pos.above()) && world.getRawBrightness(pos.above(), 0) >= 9) { -+ if (random.nextFloat() < (world.spigotConfig.bambooModifier / (100.0f * 3)) && world.isEmptyBlock(pos.above()) && world.getRawBrightness(pos.above(), 0) >= 9) { // Spigot - SPIGOT-7159: Better modifier resolution - this.growBamboo(world, pos); - } - -@@ -87,6 +87,6 @@ - } - - protected void growBamboo(Level world, BlockPos pos) { -- world.setBlock(pos.above(), (BlockState) Blocks.BAMBOO.defaultBlockState().setValue(BambooStalkBlock.LEAVES, BambooLeaves.SMALL), 3); -+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(world, pos, pos.above(), (BlockState) Blocks.BAMBOO.defaultBlockState().setValue(BambooStalkBlock.LEAVES, BambooLeaves.SMALL), 3); // CraftBukkit - BlockSpreadEvent - } - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/BambooStalkBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/BambooStalkBlock.java.patch deleted file mode 100644 index eb12b201ec..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/BambooStalkBlock.java.patch +++ /dev/null @@ -1,89 +0,0 @@ ---- a/net/minecraft/world/level/block/BambooStalkBlock.java -+++ b/net/minecraft/world/level/block/BambooStalkBlock.java -@@ -134,10 +134,10 @@ - @Override - protected void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { - if ((Integer) state.getValue(BambooStalkBlock.STAGE) == 0) { -- if (random.nextInt(3) == 0 && world.isEmptyBlock(pos.above()) && world.getRawBrightness(pos.above(), 0) >= 9) { -+ if (random.nextFloat() < (world.spigotConfig.bambooModifier / (100.0f * 3)) && world.isEmptyBlock(pos.above()) && world.getRawBrightness(pos.above(), 0) >= 9) { // Spigot - SPIGOT-7159: Better modifier resolution - int i = this.getHeightBelowUpToMax(world, pos) + 1; - -- if (i < 16) { -+ if (i < world.paperConfig().maxGrowthHeight.bamboo.max) { // Paper - Configurable cactus/bamboo/reed growth height - this.growBamboo(state, world, pos, random, i); - } - } -@@ -164,7 +164,7 @@ - int i = this.getHeightAboveUpToMax(world, pos); - int j = this.getHeightBelowUpToMax(world, pos); - -- return i + j + 1 < 16 && (Integer) world.getBlockState(pos.above(i)).getValue(BambooStalkBlock.STAGE) != 1; -+ return i + j + 1 < ((Level) world).paperConfig().maxGrowthHeight.bamboo.max && (Integer) world.getBlockState(pos.above(i)).getValue(BambooStalkBlock.STAGE) != 1; // Paper - Configurable cactus/bamboo/reed growth height - } - - @Override -@@ -183,7 +183,7 @@ - BlockPos blockposition1 = pos.above(i); - BlockState iblockdata1 = world.getBlockState(blockposition1); - -- if (k >= 16 || (Integer) iblockdata1.getValue(BambooStalkBlock.STAGE) == 1 || !world.isEmptyBlock(blockposition1.above())) { -+ if (k >= world.paperConfig().maxGrowthHeight.bamboo.max || !iblockdata1.is(Blocks.BAMBOO) || (Integer) iblockdata1.getValue(BambooStalkBlock.STAGE) == 1 || !world.isEmptyBlock(blockposition1.above())) { // CraftBukkit - If the BlockSpreadEvent was cancelled, we have no bamboo here // Paper - Configurable cactus/bamboo/reed growth height - return; - } - -@@ -204,14 +204,18 @@ - BlockPos blockposition1 = pos.below(2); - BlockState iblockdata2 = world.getBlockState(blockposition1); - BambooLeaves blockpropertybamboosize = BambooLeaves.NONE; -+ boolean shouldUpdateOthers = false; // CraftBukkit - - if (height >= 1) { - if (iblockdata1.is(Blocks.BAMBOO) && iblockdata1.getValue(BambooStalkBlock.LEAVES) != BambooLeaves.NONE) { - if (iblockdata1.is(Blocks.BAMBOO) && iblockdata1.getValue(BambooStalkBlock.LEAVES) != BambooLeaves.NONE) { - blockpropertybamboosize = BambooLeaves.LARGE; - if (iblockdata2.is(Blocks.BAMBOO)) { -- world.setBlock(pos.below(), (BlockState) iblockdata1.setValue(BambooStalkBlock.LEAVES, BambooLeaves.SMALL), 3); -- world.setBlock(blockposition1, (BlockState) iblockdata2.setValue(BambooStalkBlock.LEAVES, BambooLeaves.NONE), 3); -+ // CraftBukkit start - moved down -+ // world.setBlock(blockposition.below(), (IBlockData) iblockdata1.setValue(BlockBamboo.LEAVES, BlockPropertyBambooSize.SMALL), 3); -+ // world.setBlock(blockposition1, (IBlockData) iblockdata2.setValue(BlockBamboo.LEAVES, BlockPropertyBambooSize.NONE), 3); -+ shouldUpdateOthers = true; -+ // CraftBukkit end - } - } - } else { -@@ -220,15 +224,22 @@ - } - - int j = (Integer) state.getValue(BambooStalkBlock.AGE) != 1 && !iblockdata2.is(Blocks.BAMBOO) ? 0 : 1; -- int k = (height < 11 || random.nextFloat() >= 0.25F) && height != 15 ? 0 : 1; -+ int k = (height < world.paperConfig().maxGrowthHeight.bamboo.min || random.nextFloat() >= 0.25F) && height != (world.paperConfig().maxGrowthHeight.bamboo.max - 1) ? 0 : 1; // Paper - Configurable cactus/bamboo/reed growth height - -- world.setBlock(pos.above(), (BlockState) ((BlockState) ((BlockState) this.defaultBlockState().setValue(BambooStalkBlock.AGE, j)).setValue(BambooStalkBlock.LEAVES, blockpropertybamboosize)).setValue(BambooStalkBlock.STAGE, k), 3); -+ // CraftBukkit start -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(world, pos, pos.above(), (BlockState) ((BlockState) ((BlockState) this.defaultBlockState().setValue(BambooStalkBlock.AGE, j)).setValue(BambooStalkBlock.LEAVES, blockpropertybamboosize)).setValue(BambooStalkBlock.STAGE, k), 3)) { -+ if (shouldUpdateOthers) { -+ world.setBlock(pos.below(), (BlockState) iblockdata1.setValue(BambooStalkBlock.LEAVES, BambooLeaves.SMALL), 3); -+ world.setBlock(blockposition1, (BlockState) iblockdata2.setValue(BambooStalkBlock.LEAVES, BambooLeaves.NONE), 3); -+ } -+ } -+ // CraftBukkit end - } - - protected int getHeightAboveUpToMax(BlockGetter world, BlockPos pos) { - int i; - -- for (i = 0; i < 16 && world.getBlockState(pos.above(i + 1)).is(Blocks.BAMBOO); ++i) { -+ for (i = 0; i < ((Level) world).paperConfig().maxGrowthHeight.bamboo.max && world.getBlockState(pos.above(i + 1)).is(Blocks.BAMBOO); ++i) { // Paper - Configurable cactus/bamboo/reed growth height - ; - } - -@@ -238,7 +249,7 @@ - protected int getHeightBelowUpToMax(BlockGetter world, BlockPos pos) { - int i; - -- for (i = 0; i < 16 && world.getBlockState(pos.below(i + 1)).is(Blocks.BAMBOO); ++i) { -+ for (i = 0; i < ((Level) world).paperConfig().maxGrowthHeight.bamboo.max && world.getBlockState(pos.below(i + 1)).is(Blocks.BAMBOO); ++i) { // Paper - Configurable cactus/bamboo/reed growth height - ; - } - diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/BasePressurePlateBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/BasePressurePlateBlock.java.patch deleted file mode 100644 index 65470ccca0..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/BasePressurePlateBlock.java.patch +++ /dev/null @@ -1,56 +0,0 @@ ---- a/net/minecraft/world/level/block/BasePressurePlateBlock.java -+++ b/net/minecraft/world/level/block/BasePressurePlateBlock.java -@@ -22,6 +22,7 @@ - import net.minecraft.world.phys.AABB; - import net.minecraft.world.phys.shapes.CollisionContext; - import net.minecraft.world.phys.shapes.VoxelShape; -+import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit - - public abstract class BasePressurePlateBlock extends Block { - -@@ -76,6 +77,7 @@ - - @Override - protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { -+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent - if (!world.isClientSide) { - int i = this.getSignalForState(state); - -@@ -91,6 +93,19 @@ - boolean flag = output > 0; - boolean flag1 = j > 0; - -+ // CraftBukkit start - Interact Pressure Plate -+ org.bukkit.World bworld = world.getWorld(); -+ org.bukkit.plugin.PluginManager manager = world.getCraftServer().getPluginManager(); -+ -+ if (flag != flag1) { -+ BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(bworld.getBlockAt(pos.getX(), pos.getY(), pos.getZ()), output, j); -+ manager.callEvent(eventRedstone); -+ -+ flag1 = eventRedstone.getNewCurrent() > 0; -+ j = eventRedstone.getNewCurrent(); -+ } -+ // CraftBukkit end -+ - if (output != j) { - BlockState iblockdata1 = this.setSignalForState(state, j); - -@@ -145,9 +160,15 @@ - } - - protected static int getEntityCount(Level world, AABB box, Class entityClass) { -- return world.getEntitiesOfClass(entityClass, box, EntitySelector.NO_SPECTATORS.and((entity) -> { -+ // CraftBukkit start -+ return BasePressurePlateBlock.getEntities(world, box, entityClass).size(); -+ } -+ -+ protected static java.util.List getEntities(Level world, AABB axisalignedbb, Class oclass) { -+ // CraftBukkit end -+ return world.getEntitiesOfClass(oclass, axisalignedbb, EntitySelector.NO_SPECTATORS.and((entity) -> { - return !entity.isIgnoringBlockTriggers(); -- })).size(); -+ })); // CraftBukkit - } - - protected abstract int getSignalStrength(Level world, BlockPos pos); diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/BaseRailBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/BaseRailBlock.java.patch deleted file mode 100644 index 9e6c76abd9..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/BaseRailBlock.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/net/minecraft/world/level/block/BaseRailBlock.java -+++ b/net/minecraft/world/level/block/BaseRailBlock.java -@@ -71,6 +71,7 @@ - state = this.updateDir(world, pos, state, true); - if (this.isStraight) { - world.neighborChanged(state, pos, this, null, notify); -+ state = world.getBlockState(pos); // Paper - Fix some rails connecting improperly - } - - return state; diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/BeehiveBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/BeehiveBlock.java.patch deleted file mode 100644 index 73f015dbe6..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/BeehiveBlock.java.patch +++ /dev/null @@ -1,79 +0,0 @@ ---- a/net/minecraft/world/level/block/BeehiveBlock.java -+++ b/net/minecraft/world/level/block/BeehiveBlock.java -@@ -94,8 +94,8 @@ - } - - @Override -- public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool) { -- super.playerDestroy(world, player, pos, state, blockEntity, tool); -+ public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool, boolean includeDrops, boolean dropExp) { // Paper - fix drops not preventing stats/food exhaustion -+ super.playerDestroy(world, player, pos, state, blockEntity, tool, includeDrops, dropExp); // Paper - fix drops not preventing stats/food exhaustion - if (!world.isClientSide && blockEntity instanceof BeehiveBlockEntity tileentitybeehive) { - if (!EnchantmentHelper.hasTag(tool, EnchantmentTags.PREVENTS_BEE_SPAWNS_WHEN_MINING)) { - tileentitybeehive.emptyAllLivingFromHive(player, state, BeehiveBlockEntity.BeeReleaseStatus.EMERGENCY); -@@ -103,7 +103,7 @@ - this.angerNearbyBees(world, pos); - } - -- CriteriaTriggers.BEE_NEST_DESTROYED.trigger((ServerPlayer) player, state, tool, tileentitybeehive.getOccupantCount()); -+ // CriteriaTriggers.BEE_NEST_DESTROYED.trigger((ServerPlayer) player, state, tool, tileentitybeehive.getOccupantCount()); // Paper - Trigger bee_nest_destroyed trigger in the correct place; moved until after items are dropped - } - - } -@@ -133,7 +133,7 @@ - if (entitybee.getTarget() == null) { - Player entityhuman = (Player) Util.getRandom(list1, world.random); - -- entitybee.setTarget(entityhuman); -+ entitybee.setTarget(entityhuman, org.bukkit.event.entity.EntityTargetEvent.TargetReason.CLOSEST_PLAYER, true); // CraftBukkit - } - } - } -@@ -141,7 +141,7 @@ - } - - public static void dropHoneycomb(Level world, BlockPos pos) { -- popResource(world, pos, new ItemStack(Items.HONEYCOMB, 3)); -+ popResource(world, pos, new ItemStack(Items.HONEYCOMB, 3)); // Paper - Add PlayerShearBlockEvent; conflict on change, item needs to be set below - } - - @Override -@@ -153,8 +153,19 @@ - Item item = stack.getItem(); - - if (stack.is(Items.SHEARS)) { -+ // Paper start - Add PlayerShearBlockEvent -+ io.papermc.paper.event.block.PlayerShearBlockEvent event = new io.papermc.paper.event.block.PlayerShearBlockEvent((org.bukkit.entity.Player) player.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(stack), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand), new java.util.ArrayList<>()); -+ event.getDrops().add(org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(new ItemStack(Items.HONEYCOMB, 3))); -+ if (!event.callEvent()) { -+ return InteractionResult.PASS; -+ } -+ // Paper end - world.playSound(player, player.getX(), player.getY(), player.getZ(), SoundEvents.BEEHIVE_SHEAR, SoundSource.BLOCKS, 1.0F, 1.0F); -- BeehiveBlock.dropHoneycomb(world, pos); -+ // Paper start - Add PlayerShearBlockEvent -+ for (org.bukkit.inventory.ItemStack itemDrop : event.getDrops()) { -+ popResource(world, pos, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(itemDrop)); -+ } -+ // Paper end - Add PlayerShearBlockEvent - stack.hurtAndBreak(1, player, LivingEntity.getSlotForHand(hand)); - flag = true; - world.gameEvent((Entity) player, (Holder) GameEvent.SHEAR, pos); -@@ -297,7 +308,7 @@ - ItemStack itemstack = new ItemStack(this); - - itemstack.applyComponents(tileentitybeehive.collectComponents()); -- itemstack.set(DataComponents.BLOCK_STATE, BlockItemStateProperties.EMPTY.with(BeehiveBlock.HONEY_LEVEL, (Comparable) i)); -+ itemstack.set(DataComponents.BLOCK_STATE, BlockItemStateProperties.EMPTY.with(BeehiveBlock.HONEY_LEVEL, i)); // CraftBukkit - decompile error - ItemEntity entityitem = new ItemEntity(world, (double) pos.getX(), (double) pos.getY(), (double) pos.getZ(), itemstack); - - entityitem.setDefaultPickUpDelay(); -@@ -332,7 +343,7 @@ - ItemStack itemstack = super.getCloneItemStack(world, pos, state, includeData); - - if (includeData) { -- itemstack.set(DataComponents.BLOCK_STATE, BlockItemStateProperties.EMPTY.with(BeehiveBlock.HONEY_LEVEL, (Comparable) ((Integer) state.getValue(BeehiveBlock.HONEY_LEVEL)))); -+ itemstack.set(DataComponents.BLOCK_STATE, BlockItemStateProperties.EMPTY.with(BeehiveBlock.HONEY_LEVEL, ((Integer) state.getValue(BeehiveBlock.HONEY_LEVEL)))); // CraftBukkit - decompile error - } - - return itemstack; diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/BellBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/BellBlock.java.patch deleted file mode 100644 index d677bbedab..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/BellBlock.java.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- a/net/minecraft/world/level/block/BellBlock.java -+++ b/net/minecraft/world/level/block/BellBlock.java -@@ -148,6 +148,11 @@ - if (direction == null) { - direction = (Direction) world.getBlockState(pos).getValue(BellBlock.FACING); - } -+ // CraftBukkit start -+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBellRingEvent(world, pos, direction, entity)) { -+ return false; -+ } -+ // CraftBukkit end - - ((BellBlockEntity) tileentity).onHit(direction); - world.playSound((Player) null, pos, SoundEvents.BELL_BLOCK, SoundSource.BLOCKS, 2.0F, 1.0F); diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/BigDripleafBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/BigDripleafBlock.java.patch deleted file mode 100644 index c0eab8e717..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/BigDripleafBlock.java.patch +++ /dev/null @@ -1,116 +0,0 @@ ---- a/net/minecraft/world/level/block/BigDripleafBlock.java -+++ b/net/minecraft/world/level/block/BigDripleafBlock.java -@@ -44,6 +44,10 @@ - import net.minecraft.world.phys.shapes.CollisionContext; - import net.minecraft.world.phys.shapes.Shapes; - import net.minecraft.world.phys.shapes.VoxelShape; -+// CraftBukkit start -+import org.bukkit.craftbukkit.event.CraftEventFactory; -+import org.bukkit.event.entity.EntityInteractEvent; -+// CraftBukkit end - - public class BigDripleafBlock extends HorizontalDirectionalBlock implements BonemealableBlock, SimpleWaterloggedBlock { - -@@ -119,7 +123,7 @@ - - @Override - protected void onProjectileHit(Level world, BlockState state, BlockHitResult hit, Projectile projectile) { -- this.setTiltAndScheduleTick(state, world, hit.getBlockPos(), Tilt.FULL, SoundEvents.BIG_DRIPLEAF_TILT_DOWN); -+ this.setTiltAndScheduleTick(state, world, hit.getBlockPos(), Tilt.FULL, SoundEvents.BIG_DRIPLEAF_TILT_DOWN, projectile); // CraftBukkit - } - - @Override -@@ -176,9 +180,23 @@ - - @Override - protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { -+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent - if (!world.isClientSide) { - if (state.getValue(BigDripleafBlock.TILT) == Tilt.NONE && BigDripleafBlock.canEntityTilt(pos, entity) && !world.hasNeighborSignal(pos)) { -- this.setTiltAndScheduleTick(state, world, pos, Tilt.UNSTABLE, (SoundEvent) null); -+ // CraftBukkit start - tilt dripleaf -+ org.bukkit.event.Cancellable cancellable; -+ if (entity instanceof Player) { -+ cancellable = CraftEventFactory.callPlayerInteractEvent((Player) entity, org.bukkit.event.block.Action.PHYSICAL, pos, null, null, null); -+ } else { -+ cancellable = new EntityInteractEvent(entity.getBukkitEntity(), world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ())); -+ world.getCraftServer().getPluginManager().callEvent((EntityInteractEvent) cancellable); -+ } -+ -+ if (cancellable.isCancelled()) { -+ return; -+ } -+ this.setTiltAndScheduleTick(state, world, pos, Tilt.UNSTABLE, (SoundEvent) null, entity); -+ // CraftBukkit end - } - - } -@@ -192,9 +210,9 @@ - Tilt tilt = (Tilt) state.getValue(BigDripleafBlock.TILT); - - if (tilt == Tilt.UNSTABLE) { -- this.setTiltAndScheduleTick(state, world, pos, Tilt.PARTIAL, SoundEvents.BIG_DRIPLEAF_TILT_DOWN); -+ this.setTiltAndScheduleTick(state, world, pos, Tilt.PARTIAL, SoundEvents.BIG_DRIPLEAF_TILT_DOWN, null); // CraftBukkit - } else if (tilt == Tilt.PARTIAL) { -- this.setTiltAndScheduleTick(state, world, pos, Tilt.FULL, SoundEvents.BIG_DRIPLEAF_TILT_DOWN); -+ this.setTiltAndScheduleTick(state, world, pos, Tilt.FULL, SoundEvents.BIG_DRIPLEAF_TILT_DOWN, null); // CraftBukkit - } else if (tilt == Tilt.FULL) { - BigDripleafBlock.resetTilt(state, world, pos); - } -@@ -220,36 +238,46 @@ - return entity.onGround() && entity.position().y > (double) ((float) pos.getY() + 0.6875F); - } - -- private void setTiltAndScheduleTick(BlockState state, Level world, BlockPos pos, Tilt tilt, @Nullable SoundEvent sound) { -- BigDripleafBlock.setTilt(state, world, pos, tilt); -- if (sound != null) { -- BigDripleafBlock.playTiltSound(world, pos, sound); -+ // CraftBukkit start -+ private void setTiltAndScheduleTick(BlockState iblockdata, Level world, BlockPos blockposition, Tilt tilt, @Nullable SoundEvent soundeffect, @Nullable Entity entity) { -+ if (!BigDripleafBlock.setTilt(iblockdata, world, blockposition, tilt, entity)) return; -+ // CraftBukkit end -+ if (soundeffect != null) { -+ BigDripleafBlock.playTiltSound(world, blockposition, soundeffect); - } - - int i = BigDripleafBlock.DELAY_UNTIL_NEXT_TILT_STATE.getInt(tilt); - - if (i != -1) { -- world.scheduleTick(pos, (Block) this, i); -+ world.scheduleTick(blockposition, (Block) this, i); - } - - } - - private static void resetTilt(BlockState state, Level world, BlockPos pos) { -- BigDripleafBlock.setTilt(state, world, pos, Tilt.NONE); -+ BigDripleafBlock.setTilt(state, world, pos, Tilt.NONE, null); // CraftBukkit - if (state.getValue(BigDripleafBlock.TILT) != Tilt.NONE) { - BigDripleafBlock.playTiltSound(world, pos, SoundEvents.BIG_DRIPLEAF_TILT_UP); - } - - } - -- private static void setTilt(BlockState state, Level world, BlockPos pos, Tilt tilt) { -- Tilt tilt1 = (Tilt) state.getValue(BigDripleafBlock.TILT); -+ // CraftBukkit start -+ private static boolean setTilt(BlockState iblockdata, Level world, BlockPos blockposition, Tilt tilt, @Nullable Entity entity) { -+ if (entity != null) { -+ if (!CraftEventFactory.callEntityChangeBlockEvent(entity, blockposition, iblockdata.setValue(BigDripleafBlock.TILT, tilt))) { -+ return false; -+ } -+ } -+ // CraftBukkit end -+ Tilt tilt1 = (Tilt) iblockdata.getValue(BigDripleafBlock.TILT); - -- world.setBlock(pos, (BlockState) state.setValue(BigDripleafBlock.TILT, tilt), 2); -+ world.setBlock(blockposition, (BlockState) iblockdata.setValue(BigDripleafBlock.TILT, tilt), 2); - if (tilt.causesVibration() && tilt != tilt1) { -- world.gameEvent((Entity) null, (Holder) GameEvent.BLOCK_CHANGE, pos); -+ world.gameEvent((Entity) null, (Holder) GameEvent.BLOCK_CHANGE, blockposition); - } - -+ return true; // CraftBukkit - } - - @Override diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/BushBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/BushBlock.java.patch deleted file mode 100644 index d8fb08b681..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/BushBlock.java.patch +++ /dev/null @@ -1,27 +0,0 @@ ---- a/net/minecraft/world/level/block/BushBlock.java -+++ b/net/minecraft/world/level/block/BushBlock.java -@@ -6,6 +6,7 @@ - import net.minecraft.tags.BlockTags; - import net.minecraft.util.RandomSource; - import net.minecraft.world.level.BlockGetter; -+import net.minecraft.world.level.Level; - import net.minecraft.world.level.LevelReader; - import net.minecraft.world.level.ScheduledTickAccess; - import net.minecraft.world.level.block.state.BlockBehaviour; -@@ -27,7 +28,15 @@ - - @Override - protected BlockState updateShape(BlockState state, LevelReader world, ScheduledTickAccess tickView, BlockPos pos, Direction direction, BlockPos neighborPos, BlockState neighborState, RandomSource random) { -- return !state.canSurvive(world, pos) ? Blocks.AIR.defaultBlockState() : super.updateShape(state, world, tickView, pos, direction, neighborPos, neighborState, random); -+ // CraftBukkit start -+ if (!state.canSurvive(world, pos)) { -+ // Suppress during worldgen -+ if (!(world instanceof net.minecraft.server.level.ServerLevel world1 && world1.hasPhysicsEvent) || !org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPhysicsEvent(world1, pos).isCancelled()) { // Paper -+ return Blocks.AIR.defaultBlockState(); -+ } -+ } -+ return super.updateShape(state, world, tickView, pos, direction, neighborPos, neighborState, random); -+ // CraftBukkit end - } - - @Override diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/ButtonBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/ButtonBlock.java.patch deleted file mode 100644 index 8311b29036..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/ButtonBlock.java.patch +++ /dev/null @@ -1,78 +0,0 @@ ---- a/net/minecraft/world/level/block/ButtonBlock.java -+++ b/net/minecraft/world/level/block/ButtonBlock.java -@@ -34,6 +34,10 @@ - import net.minecraft.world.phys.BlockHitResult; - import net.minecraft.world.phys.shapes.CollisionContext; - import net.minecraft.world.phys.shapes.VoxelShape; -+// CraftBukkit start -+import org.bukkit.event.block.BlockRedstoneEvent; -+import org.bukkit.event.entity.EntityInteractEvent; -+// CraftBukkit end - - public class ButtonBlock extends FaceAttachedHorizontalDirectionalBlock { - -@@ -126,6 +130,19 @@ - if ((Boolean) state.getValue(ButtonBlock.POWERED)) { - return InteractionResult.CONSUME; - } else { -+ // CraftBukkit start -+ boolean powered = ((Boolean) state.getValue(ButtonBlock.POWERED)); -+ org.bukkit.block.Block block = world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); -+ int old = (powered) ? 15 : 0; -+ int current = (!powered) ? 15 : 0; -+ -+ BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, old, current); -+ world.getCraftServer().getPluginManager().callEvent(eventRedstone); -+ -+ if ((eventRedstone.getNewCurrent() > 0) != (!powered)) { -+ return InteractionResult.SUCCESS; -+ } -+ // CraftBukkit end - this.press(state, world, pos, player); - return InteractionResult.SUCCESS; - } -@@ -191,17 +208,43 @@ - - @Override - protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { -+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent - if (!world.isClientSide && this.type.canButtonBeActivatedByArrows() && !(Boolean) state.getValue(ButtonBlock.POWERED)) { - this.checkPressed(state, world, pos); - } - } - - protected void checkPressed(BlockState state, Level world, BlockPos pos) { -- AbstractArrow entityarrow = this.type.canButtonBeActivatedByArrows() ? (AbstractArrow) world.getEntitiesOfClass(AbstractArrow.class, state.getShape(world, pos).bounds().move(pos)).stream().findFirst().orElse((Object) null) : null; -+ AbstractArrow entityarrow = this.type.canButtonBeActivatedByArrows() ? (AbstractArrow) world.getEntitiesOfClass(AbstractArrow.class, state.getShape(world, pos).bounds().move(pos)).stream().findFirst().orElse(null) : null; // CraftBukkit - decompile error - boolean flag = entityarrow != null; - boolean flag1 = (Boolean) state.getValue(ButtonBlock.POWERED); - -+ // CraftBukkit start - Call interact event when arrows turn on wooden buttons -+ if (flag1 != flag && flag) { -+ org.bukkit.block.Block block = world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); -+ EntityInteractEvent event = new EntityInteractEvent(entityarrow.getBukkitEntity(), block); -+ world.getCraftServer().getPluginManager().callEvent(event); -+ -+ if (event.isCancelled()) { -+ return; -+ } -+ } -+ // CraftBukkit end -+ - if (flag != flag1) { -+ // CraftBukkit start -+ boolean powered = flag1; -+ org.bukkit.block.Block block = world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); -+ int old = (powered) ? 15 : 0; -+ int current = (!powered) ? 15 : 0; -+ -+ BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, old, current); -+ world.getCraftServer().getPluginManager().callEvent(eventRedstone); -+ -+ if ((flag && eventRedstone.getNewCurrent() <= 0) || (!flag && eventRedstone.getNewCurrent() > 0)) { -+ return; -+ } -+ // CraftBukkit end - world.setBlock(pos, (BlockState) state.setValue(ButtonBlock.POWERED, flag), 3); - this.updateNeighbours(state, world, pos); - this.playSound((Player) null, world, pos, flag); diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/CactusBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/CactusBlock.java.patch deleted file mode 100644 index c7084f8b41..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/CactusBlock.java.patch +++ /dev/null @@ -1,42 +0,0 @@ ---- a/net/minecraft/world/level/block/CactusBlock.java -+++ b/net/minecraft/world/level/block/CactusBlock.java -@@ -22,6 +22,7 @@ - import net.minecraft.world.level.redstone.Orientation; - import net.minecraft.world.phys.shapes.CollisionContext; - import net.minecraft.world.phys.shapes.VoxelShape; -+import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit - - public class CactusBlock extends Block { - -@@ -61,16 +62,17 @@ - ; - } - -- if (i < 3) { -+ if (i < world.paperConfig().maxGrowthHeight.cactus) { // Paper - Configurable cactus/bamboo/reed growth height - int j = (Integer) state.getValue(CactusBlock.AGE); - -- if (j == 15) { -- world.setBlockAndUpdate(blockposition1, this.defaultBlockState()); -+ int modifier = world.spigotConfig.cactusModifier; // Spigot - SPIGOT-7159: Better modifier resolution -+ if (j >= 15 || (modifier != 100 && random.nextFloat() < (modifier / (100.0f * 16)))) { // Spigot - SPIGOT-7159: Better modifier resolution -+ CraftEventFactory.handleBlockGrowEvent(world, blockposition1, this.defaultBlockState()); // CraftBukkit - BlockState iblockdata1 = (BlockState) state.setValue(CactusBlock.AGE, 0); - - world.setBlock(pos, iblockdata1, 4); - world.neighborChanged(iblockdata1, blockposition1, this, (Orientation) null, false); -- } else { -+ } else if (modifier == 100 || random.nextFloat() < (modifier / (100.0f * 16))) { // Spigot - SPIGOT-7159: Better modifier resolution - world.setBlock(pos, (BlockState) state.setValue(CactusBlock.AGE, j + 1), 4); - } - -@@ -120,7 +122,8 @@ - - @Override - protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { -- entity.hurt(world.damageSources().cactus(), 1.0F); -+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent -+ entity.hurt(world.damageSources().cactus().directBlock(world, pos), 1.0F); // CraftBukkit - } - - @Override diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/CampfireBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/CampfireBlock.java.patch deleted file mode 100644 index 133764e05b..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/CampfireBlock.java.patch +++ /dev/null @@ -1,25 +0,0 @@ ---- a/net/minecraft/world/level/block/CampfireBlock.java -+++ b/net/minecraft/world/level/block/CampfireBlock.java -@@ -112,8 +112,9 @@ - - @Override - protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { -+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent - if ((Boolean) state.getValue(CampfireBlock.LIT) && entity instanceof LivingEntity) { -- entity.hurt(world.damageSources().campfire(), (float) this.fireDamage); -+ entity.hurt(world.damageSources().campfire().directBlock(world, pos), (float) this.fireDamage); // CraftBukkit - } - - super.entityInside(state, world, pos, entity); -@@ -219,6 +220,11 @@ - - if (world instanceof ServerLevel worldserver) { - if (projectile.isOnFire() && projectile.mayInteract(worldserver, blockposition) && !(Boolean) state.getValue(CampfireBlock.LIT) && !(Boolean) state.getValue(CampfireBlock.WATERLOGGED)) { -+ // CraftBukkit start -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(world, blockposition, projectile).isCancelled()) { -+ return; -+ } -+ // CraftBukkit end - world.setBlock(blockposition, (BlockState) state.setValue(BlockStateProperties.LIT, true), 11); - } - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/CarvedPumpkinBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/CarvedPumpkinBlock.java.patch deleted file mode 100644 index 8b9fd76990..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/CarvedPumpkinBlock.java.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- a/net/minecraft/world/level/block/CarvedPumpkinBlock.java -+++ b/net/minecraft/world/level/block/CarvedPumpkinBlock.java -@@ -24,6 +24,9 @@ - import net.minecraft.world.level.block.state.pattern.BlockPatternBuilder; - import net.minecraft.world.level.block.state.predicate.BlockStatePredicate; - import net.minecraft.world.level.block.state.properties.EnumProperty; -+// CraftBukkit start -+import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; -+// CraftBukkit end - - public class CarvedPumpkinBlock extends HorizontalDirectionalBlock { - -@@ -87,9 +90,14 @@ - } - - private static void spawnGolemInWorld(Level world, BlockPattern.BlockPatternMatch patternResult, Entity entity, BlockPos pos) { -- CarvedPumpkinBlock.clearPatternBlocks(world, patternResult); -+ // clearPatternBlocks(world, shapedetector_shapedetectorcollection); // CraftBukkit - moved down - entity.moveTo((double) pos.getX() + 0.5D, (double) pos.getY() + 0.05D, (double) pos.getZ() + 0.5D, 0.0F, 0.0F); -- world.addFreshEntity(entity); -+ // CraftBukkit start -+ if (!world.addFreshEntity(entity, (entity.getType() == EntityType.SNOW_GOLEM) ? SpawnReason.BUILD_SNOWMAN : SpawnReason.BUILD_IRONGOLEM)) { -+ return; -+ } -+ CarvedPumpkinBlock.clearPatternBlocks(world, patternResult); // CraftBukkit - from above -+ // CraftBukkit end - Iterator iterator = world.getEntitiesOfClass(ServerPlayer.class, entity.getBoundingBox().inflate(5.0D)).iterator(); - - while (iterator.hasNext()) { diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/CauldronBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/CauldronBlock.java.patch deleted file mode 100644 index 0d9def53a1..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/CauldronBlock.java.patch +++ /dev/null @@ -1,56 +0,0 @@ ---- a/net/minecraft/world/level/block/CauldronBlock.java -+++ b/net/minecraft/world/level/block/CauldronBlock.java -@@ -12,6 +12,9 @@ - import net.minecraft.world.level.gameevent.GameEvent; - import net.minecraft.world.level.material.Fluid; - import net.minecraft.world.level.material.Fluids; -+// CraftBukkit start -+import org.bukkit.event.block.CauldronLevelChangeEvent; -+// CraftBukkit end - - public class CauldronBlock extends AbstractCauldronBlock { - -@@ -41,9 +44,19 @@ - public void handlePrecipitation(BlockState state, Level world, BlockPos pos, Biome.Precipitation precipitation) { - if (CauldronBlock.shouldHandlePrecipitation(world, precipitation)) { - if (precipitation == Biome.Precipitation.RAIN) { -+ // Paper start - Call CauldronLevelChangeEvent -+ if (!LayeredCauldronBlock.changeLevel(state, world, pos, Blocks.WATER_CAULDRON.defaultBlockState(), null, CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL, false)) { // avoid duplicate game event -+ return; -+ } -+ // Paper end - Call CauldronLevelChangeEvent - world.setBlockAndUpdate(pos, Blocks.WATER_CAULDRON.defaultBlockState()); - world.gameEvent((Entity) null, (Holder) GameEvent.BLOCK_CHANGE, pos); - } else if (precipitation == Biome.Precipitation.SNOW) { -+ // Paper start - Call CauldronLevelChangeEvent -+ if (!LayeredCauldronBlock.changeLevel(state, world, pos, Blocks.POWDER_SNOW_CAULDRON.defaultBlockState(), null, CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL, false)) { // avoid duplicate game event -+ return; -+ } -+ // Paper end - Call CauldronLevelChangeEvent - world.setBlockAndUpdate(pos, Blocks.POWDER_SNOW_CAULDRON.defaultBlockState()); - world.gameEvent((Entity) null, (Holder) GameEvent.BLOCK_CHANGE, pos); - } -@@ -62,13 +75,19 @@ - - if (fluid == Fluids.WATER) { - iblockdata1 = Blocks.WATER_CAULDRON.defaultBlockState(); -- world.setBlockAndUpdate(pos, iblockdata1); -- world.gameEvent((Holder) GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(iblockdata1)); -+ // Paper start - Call CauldronLevelChangeEvent; don't send level event or game event if cancelled -+ if (!LayeredCauldronBlock.changeLevel(state, world, pos, iblockdata1, null, CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL)) { // CraftBukkit -+ return; -+ } -+ // Paper end - Call CauldronLevelChangeEvent - world.levelEvent(1047, pos, 0); - } else if (fluid == Fluids.LAVA) { - iblockdata1 = Blocks.LAVA_CAULDRON.defaultBlockState(); -- world.setBlockAndUpdate(pos, iblockdata1); -- world.gameEvent((Holder) GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(iblockdata1)); -+ // Paper start - Call CauldronLevelChangeEvent; don't send level event or game event if cancelled -+ if (!LayeredCauldronBlock.changeLevel(state, world, pos, iblockdata1, null, CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL)) { // CraftBukkit -+ return; -+ } -+ // Paper end - Call CauldronLevelChangeEvent - world.levelEvent(1046, pos, 0); - } - diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/CaveVines.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/CaveVines.java.patch deleted file mode 100644 index b340d9c9cb..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/CaveVines.java.patch +++ /dev/null @@ -1,42 +0,0 @@ ---- a/net/minecraft/world/level/block/CaveVines.java -+++ b/net/minecraft/world/level/block/CaveVines.java -@@ -19,6 +19,13 @@ - import net.minecraft.world.level.gameevent.GameEvent; - import net.minecraft.world.phys.shapes.VoxelShape; - -+// CraftBukkit start -+import java.util.Collections; -+import org.bukkit.craftbukkit.event.CraftEventFactory; -+import org.bukkit.craftbukkit.inventory.CraftItemStack; -+import org.bukkit.event.player.PlayerHarvestBlockEvent; -+// CraftBukkit end -+ - public interface CaveVines { - - VoxelShape SHAPE = Block.box(1.0D, 0.0D, 1.0D, 15.0D, 16.0D, 15.0D); -@@ -26,7 +33,24 @@ - - static InteractionResult use(@Nullable Entity picker, BlockState state, Level world, BlockPos pos) { - if ((Boolean) state.getValue(CaveVines.BERRIES)) { -- Block.popResource(world, pos, new ItemStack(Items.GLOW_BERRIES, 1)); -+ // CraftBukkit start -+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(picker, pos, (BlockState) state.setValue(CaveVines.BERRIES, false))) { -+ return InteractionResult.SUCCESS; -+ } -+ -+ if (picker instanceof Player) { -+ PlayerHarvestBlockEvent event = CraftEventFactory.callPlayerHarvestBlockEvent(world, pos, (Player) picker, net.minecraft.world.InteractionHand.MAIN_HAND, Collections.singletonList(new ItemStack(Items.GLOW_BERRIES, 1))); -+ if (event.isCancelled()) { -+ return InteractionResult.SUCCESS; // We need to return a success either way, because making it PASS or FAIL will result in a bug where cancelling while harvesting w/ block in hand places block -+ } -+ for (org.bukkit.inventory.ItemStack itemStack : event.getItemsHarvested()) { -+ Block.popResource(world, pos, CraftItemStack.asNMSCopy(itemStack)); -+ } -+ } else { -+ Block.popResource(world, pos, new ItemStack(Items.GLOW_BERRIES, 1)); -+ } -+ // CraftBukkit end -+ - float f = Mth.randomBetween(world.random, 0.8F, 1.2F); - - world.playSound((Player) null, pos, SoundEvents.CAVE_VINES_PICK_BERRIES, SoundSource.BLOCKS, 1.0F, f); diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/ChangeOverTimeBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/ChangeOverTimeBlock.java.patch deleted file mode 100644 index 94b24017e5..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/ChangeOverTimeBlock.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/net/minecraft/world/level/block/ChangeOverTimeBlock.java -+++ b/net/minecraft/world/level/block/ChangeOverTimeBlock.java -@@ -20,7 +20,7 @@ - - if (random.nextFloat() < 0.05688889F) { - this.getNextState(state, world, pos, random).ifPresent((iblockdata1) -> { -- world.setBlockAndUpdate(pos, iblockdata1); -+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(world, pos, iblockdata1); // CraftBukkit - }); - } - diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/ChestBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/ChestBlock.java.patch deleted file mode 100644 index 4b025cb2e4..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/ChestBlock.java.patch +++ /dev/null @@ -1,118 +0,0 @@ ---- a/net/minecraft/world/level/block/ChestBlock.java -+++ b/net/minecraft/world/level/block/ChestBlock.java -@@ -91,24 +91,7 @@ - public Optional acceptDouble(final ChestBlockEntity first, final ChestBlockEntity second) { - final CompoundContainer inventorylargechest = new CompoundContainer(first, second); - -- return Optional.of(new MenuProvider(this) { -- @Nullable -- @Override -- public AbstractContainerMenu createMenu(int syncId, Inventory playerInventory, Player player) { -- if (first.canOpen(player) && second.canOpen(player)) { -- first.unpackLootTable(playerInventory.player); -- second.unpackLootTable(playerInventory.player); -- return ChestMenu.sixRows(syncId, playerInventory, inventorylargechest); -- } else { -- return null; -- } -- } -- -- @Override -- public Component getDisplayName() { -- return (Component) (first.hasCustomName() ? first.getDisplayName() : (second.hasCustomName() ? second.getDisplayName() : Component.translatable("container.chestDouble"))); -- } -- }); -+ return Optional.of(new DoubleInventory(first, second, inventorylargechest)); // CraftBukkit // CraftBukkit - decompile error - } - - public Optional acceptSingle(ChestBlockEntity single) { -@@ -118,8 +101,40 @@ - @Override - public Optional acceptNone() { - return Optional.empty(); -+ } -+ }; -+ -+ // CraftBukkit start -+ public static class DoubleInventory implements MenuProvider { -+ -+ private final ChestBlockEntity tileentitychest; -+ private final ChestBlockEntity tileentitychest1; -+ public final CompoundContainer inventorylargechest; -+ -+ public DoubleInventory(ChestBlockEntity tileentitychest, ChestBlockEntity tileentitychest1, CompoundContainer inventorylargechest) { -+ this.tileentitychest = tileentitychest; -+ this.tileentitychest1 = tileentitychest1; -+ this.inventorylargechest = inventorylargechest; -+ } -+ -+ @Nullable -+ @Override -+ public AbstractContainerMenu createMenu(int syncId, Inventory playerInventory, Player player) { -+ if (this.tileentitychest.canOpen(player) && this.tileentitychest1.canOpen(player)) { -+ this.tileentitychest.unpackLootTable(playerInventory.player); -+ this.tileentitychest1.unpackLootTable(playerInventory.player); -+ return ChestMenu.sixRows(syncId, playerInventory, this.inventorylargechest); -+ } else { -+ return null; -+ } - } -+ -+ @Override -+ public Component getDisplayName() { -+ return (Component) (this.tileentitychest.hasCustomName() ? this.tileentitychest.getDisplayName() : (this.tileentitychest1.hasCustomName() ? this.tileentitychest1.getDisplayName() : Component.translatable("container.chestDouble"))); -+ } - }; -+ // CraftBukkit end - - @Override - public MapCodec codec() { -@@ -232,8 +247,7 @@ - if (world instanceof ServerLevel worldserver) { - MenuProvider itileinventory = this.getMenuProvider(state, world, pos); - -- if (itileinventory != null) { -- player.openMenu(itileinventory); -+ if (itileinventory != null && player.openMenu(itileinventory).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation - player.awardStat(this.getOpenChestStat()); - PiglinAi.angerNearbyPiglins(worldserver, player, true); - } -@@ -257,7 +271,7 @@ - - @Override - public DoubleBlockCombiner.NeighborCombineResult combine(BlockState state, Level world, BlockPos pos, boolean ignoreBlocked) { -- BiPredicate bipredicate; -+ BiPredicate bipredicate; // CraftBukkit - decompile error - - if (ignoreBlocked) { - bipredicate = (generatoraccess, blockposition1) -> { -@@ -273,9 +287,16 @@ - @Nullable - @Override - public MenuProvider getMenuProvider(BlockState state, Level world, BlockPos pos) { -- return (MenuProvider) ((Optional) this.combine(state, world, pos, false).apply(ChestBlock.MENU_PROVIDER_COMBINER)).orElse((Object) null); -+ // CraftBukkit start -+ return this.getMenuProvider(state, world, pos, false); - } - -+ @Nullable -+ public MenuProvider getMenuProvider(BlockState iblockdata, Level world, BlockPos blockposition, boolean ignoreObstructions) { -+ return (MenuProvider) ((Optional) this.combine(iblockdata, world, blockposition, ignoreObstructions).apply(ChestBlock.MENU_PROVIDER_COMBINER)).orElse((Object) null); -+ // CraftBukkit end -+ } -+ - public static DoubleBlockCombiner.Combiner opennessCombiner(final LidBlockEntity progress) { - return new DoubleBlockCombiner.Combiner() { - public Float2FloatFunction acceptDouble(ChestBlockEntity first, ChestBlockEntity second) { -@@ -321,6 +342,11 @@ - } - - private static boolean isCatSittingOnChest(LevelAccessor world, BlockPos pos) { -+ // Paper start - Option to disable chest cat detection -+ if (world.getMinecraftWorld().paperConfig().entities.behavior.disableChestCatDetection) { -+ return false; -+ } -+ // Paper end - Option to disable chest cat detection - List list = world.getEntitiesOfClass(Cat.class, new AABB((double) pos.getX(), (double) (pos.getY() + 1), (double) pos.getZ(), (double) (pos.getX() + 1), (double) (pos.getY() + 2), (double) (pos.getZ() + 1))); - - if (!list.isEmpty()) { diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/ChorusFlowerBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/ChorusFlowerBlock.java.patch deleted file mode 100644 index 88160b2d20..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/ChorusFlowerBlock.java.patch +++ /dev/null @@ -1,73 +0,0 @@ ---- a/net/minecraft/world/level/block/ChorusFlowerBlock.java -+++ b/net/minecraft/world/level/block/ChorusFlowerBlock.java -@@ -23,6 +23,8 @@ - import net.minecraft.world.phys.BlockHitResult; - import net.minecraft.world.phys.shapes.VoxelShape; - -+import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit -+ - public class ChorusFlowerBlock extends Block { - - public static final MapCodec CODEC = RecordCodecBuilder.mapCodec((instance) -> { -@@ -103,8 +105,12 @@ - } - - if (flag && ChorusFlowerBlock.allNeighborsEmpty(world, blockposition1, (Direction) null) && world.isEmptyBlock(pos.above(2))) { -- world.setBlock(pos, ChorusPlantBlock.getStateWithConnections(world, pos, this.plant.defaultBlockState()), 2); -- this.placeGrownFlower(world, blockposition1, i); -+ // CraftBukkit start - add event -+ if (CraftEventFactory.handleBlockSpreadEvent(world, pos, blockposition1, this.defaultBlockState().setValue(ChorusFlowerBlock.AGE, Integer.valueOf(i)), 2)) { -+ world.setBlock(pos, ChorusPlantBlock.getStateWithConnections(world, pos, this.plant.defaultBlockState()), 2); -+ this.placeGrownFlower(world, blockposition1, i); -+ } -+ // CraftBukkit end - } else if (i < 4) { - j = random.nextInt(4); - if (flag1) { -@@ -118,18 +124,30 @@ - BlockPos blockposition2 = pos.relative(enumdirection); - - if (world.isEmptyBlock(blockposition2) && world.isEmptyBlock(blockposition2.below()) && ChorusFlowerBlock.allNeighborsEmpty(world, blockposition2, enumdirection.getOpposite())) { -- this.placeGrownFlower(world, blockposition2, i + 1); -- flag2 = true; -+ // CraftBukkit start - add event -+ if (CraftEventFactory.handleBlockSpreadEvent(world, pos, blockposition2, this.defaultBlockState().setValue(ChorusFlowerBlock.AGE, Integer.valueOf(i + 1)), 2)) { -+ this.placeGrownFlower(world, blockposition2, i + 1); -+ flag2 = true; -+ } -+ // CraftBukkit end - } - } - - if (flag2) { - world.setBlock(pos, ChorusPlantBlock.getStateWithConnections(world, pos, this.plant.defaultBlockState()), 2); - } else { -- this.placeDeadFlower(world, pos); -+ // CraftBukkit start - add event -+ if (CraftEventFactory.handleBlockGrowEvent(world, pos, this.defaultBlockState().setValue(ChorusFlowerBlock.AGE, Integer.valueOf(5)), 2)) { -+ this.placeDeadFlower(world, pos); -+ } -+ // CraftBukkit end - } - } else { -- this.placeDeadFlower(world, pos); -+ // CraftBukkit start - add event -+ if (CraftEventFactory.handleBlockGrowEvent(world, pos, this.defaultBlockState().setValue(ChorusFlowerBlock.AGE, Integer.valueOf(5)), 2)) { -+ this.placeDeadFlower(world, pos); -+ } -+ // CraftBukkit end - } - - } -@@ -267,6 +285,11 @@ - - if (world instanceof ServerLevel worldserver) { - if (projectile.mayInteract(worldserver, blockposition) && projectile.mayBreak(worldserver)) { -+ // CraftBukkit -+ if (!CraftEventFactory.callEntityChangeBlockEvent(projectile, blockposition, state.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state -+ return; -+ } -+ // CraftBukkit end - world.destroyBlock(blockposition, true, projectile); - } - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/CocoaBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/CocoaBlock.java.patch deleted file mode 100644 index 963cb2ef7b..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/CocoaBlock.java.patch +++ /dev/null @@ -1,33 +0,0 @@ ---- a/net/minecraft/world/level/block/CocoaBlock.java -+++ b/net/minecraft/world/level/block/CocoaBlock.java -@@ -20,6 +20,7 @@ - import net.minecraft.world.level.pathfinder.PathComputationType; - import net.minecraft.world.phys.shapes.CollisionContext; - import net.minecraft.world.phys.shapes.VoxelShape; -+import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit - - public class CocoaBlock extends HorizontalDirectionalBlock implements BonemealableBlock { - -@@ -57,11 +58,11 @@ - - @Override - protected void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { -- if (world.random.nextInt(5) == 0) { -+ if (world.random.nextFloat() < (world.spigotConfig.cocoaModifier / (100.0f * 5))) { // Spigot - SPIGOT-7159: Better modifier resolution - int i = (Integer) state.getValue(CocoaBlock.AGE); - - if (i < 2) { -- world.setBlock(pos, (BlockState) state.setValue(CocoaBlock.AGE, i + 1), 2); -+ CraftEventFactory.handleBlockGrowEvent(world, pos, (BlockState) state.setValue(CocoaBlock.AGE, i + 1), 2); // CraftBukkkit - } - } - -@@ -131,7 +132,7 @@ - - @Override - public void performBonemeal(ServerLevel world, RandomSource random, BlockPos pos, BlockState state) { -- world.setBlock(pos, (BlockState) state.setValue(CocoaBlock.AGE, (Integer) state.getValue(CocoaBlock.AGE) + 1), 2); -+ CraftEventFactory.handleBlockGrowEvent(world, pos, (BlockState) state.setValue(CocoaBlock.AGE, (Integer) state.getValue(CocoaBlock.AGE) + 1), 2); // CraftBukkit - } - - @Override diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/CommandBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/CommandBlock.java.patch deleted file mode 100644 index 6c6c7fbbd8..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/CommandBlock.java.patch +++ /dev/null @@ -1,37 +0,0 @@ ---- a/net/minecraft/world/level/block/CommandBlock.java -+++ b/net/minecraft/world/level/block/CommandBlock.java -@@ -31,6 +31,8 @@ - import net.minecraft.world.phys.BlockHitResult; - import org.slf4j.Logger; - -+import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit -+ - public class CommandBlock extends BaseEntityBlock implements GameMasterBlock { - - public static final MapCodec CODEC = RecordCodecBuilder.mapCodec((instance) -> { -@@ -78,7 +80,16 @@ - - private void setPoweredAndUpdate(Level world, BlockPos pos, CommandBlockEntity blockEntity, boolean powered) { - boolean flag1 = blockEntity.isPowered(); -+ // CraftBukkit start -+ org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); -+ int old = flag1 ? 15 : 0; -+ int current = powered ? 15 : 0; - -+ BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(bukkitBlock, old, current); -+ world.getCraftServer().getPluginManager().callEvent(eventRedstone); -+ powered = eventRedstone.getNewCurrent() > 0; -+ // CraftBukkit end -+ - if (powered != flag1) { - blockEntity.setPowered(powered); - if (powered) { -@@ -141,7 +152,7 @@ - protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { - BlockEntity tileentity = world.getBlockEntity(pos); - -- if (tileentity instanceof CommandBlockEntity && player.canUseGameMasterBlocks()) { -+ if (tileentity instanceof CommandBlockEntity && (player.canUseGameMasterBlocks() || (player.isCreative() && player.getBukkitEntity().hasPermission("minecraft.commandblock")))) { // Paper - command block permission - player.openCommandBlock((CommandBlockEntity) tileentity); - return InteractionResult.SUCCESS; - } else { diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/ComparatorBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/ComparatorBlock.java.patch deleted file mode 100644 index a59662f5c7..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/ComparatorBlock.java.patch +++ /dev/null @@ -1,39 +0,0 @@ ---- a/net/minecraft/world/level/block/ComparatorBlock.java -+++ b/net/minecraft/world/level/block/ComparatorBlock.java -@@ -27,6 +27,7 @@ - import net.minecraft.world.phys.AABB; - import net.minecraft.world.phys.BlockHitResult; - import net.minecraft.world.ticks.TickPriority; -+import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit - - public class ComparatorBlock extends DiodeBlock implements EntityBlock { - -@@ -110,7 +111,8 @@ - - @Nullable - private ItemFrame getItemFrame(Level world, Direction facing, BlockPos pos) { -- List list = world.getEntitiesOfClass(ItemFrame.class, new AABB((double) pos.getX(), (double) pos.getY(), (double) pos.getZ(), (double) (pos.getX() + 1), (double) (pos.getY() + 1), (double) (pos.getZ() + 1)), (entityitemframe) -> { -+ // CraftBukkit - decompile error -+ List list = world.getEntitiesOfClass(ItemFrame.class, new AABB((double) pos.getX(), (double) pos.getY(), (double) pos.getZ(), (double) (pos.getX() + 1), (double) (pos.getY() + 1), (double) (pos.getZ() + 1)), (java.util.function.Predicate) (entityitemframe) -> { - return entityitemframe != null && entityitemframe.getDirection() == facing; - }); - -@@ -163,8 +165,18 @@ - boolean flag1 = (Boolean) state.getValue(ComparatorBlock.POWERED); - - if (flag1 && !flag) { -+ // CraftBukkit start -+ if (CraftEventFactory.callRedstoneChange(world, pos, 15, 0).getNewCurrent() != 0) { -+ return; -+ } -+ // CraftBukkit end - world.setBlock(pos, (BlockState) state.setValue(ComparatorBlock.POWERED, false), 2); - } else if (!flag1 && flag) { -+ // CraftBukkit start -+ if (CraftEventFactory.callRedstoneChange(world, pos, 0, 15).getNewCurrent() != 15) { -+ return; -+ } -+ // CraftBukkit end - world.setBlock(pos, (BlockState) state.setValue(ComparatorBlock.POWERED, true), 2); - } - diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/ComposterBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/ComposterBlock.java.patch deleted file mode 100644 index 919fb7f0cb..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/ComposterBlock.java.patch +++ /dev/null @@ -1,184 +0,0 @@ ---- a/net/minecraft/world/level/block/ComposterBlock.java -+++ b/net/minecraft/world/level/block/ComposterBlock.java -@@ -41,6 +41,10 @@ - import net.minecraft.world.phys.shapes.CollisionContext; - import net.minecraft.world.phys.shapes.Shapes; - import net.minecraft.world.phys.shapes.VoxelShape; -+// CraftBukkit start -+import org.bukkit.craftbukkit.inventory.CraftBlockInventoryHolder; -+import org.bukkit.craftbukkit.util.DummyGeneratorAccess; -+// CraftBukkit end - - public class ComposterBlock extends Block implements WorldlyContainerHolder { - -@@ -241,6 +245,11 @@ - if (i < 8 && ComposterBlock.COMPOSTABLES.containsKey(stack.getItem())) { - if (i < 7 && !world.isClientSide) { - BlockState iblockdata1 = ComposterBlock.addItem(player, state, world, pos, stack); -+ // Paper start - handle cancelled events -+ if (iblockdata1 == null) { -+ return InteractionResult.PASS; -+ } -+ // Paper end - - world.levelEvent(1500, pos, state != iblockdata1 ? 1 : 0); - player.awardStat(Stats.ITEM_USED.get(stack.getItem())); -@@ -269,7 +278,19 @@ - int i = (Integer) state.getValue(ComposterBlock.LEVEL); - - if (i < 7 && ComposterBlock.COMPOSTABLES.containsKey(stack.getItem())) { -- BlockState iblockdata1 = ComposterBlock.addItem(user, state, world, pos, stack); -+ // CraftBukkit start -+ double rand = world.getRandom().nextDouble(); -+ BlockState iblockdata1 = null; // Paper -+ if (false && (state == iblockdata1 || !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(user, pos, iblockdata1))) { // Paper - move event call into addItem -+ return state; -+ } -+ iblockdata1 = ComposterBlock.addItem(user, state, world, pos, stack, rand); -+ // Paper start - handle cancelled events -+ if (iblockdata1 == null) { -+ return state; -+ } -+ // Paper end -+ // CraftBukkit end - - stack.shrink(1); - return iblockdata1; -@@ -279,6 +300,14 @@ - } - - public static BlockState extractProduce(Entity user, BlockState state, Level world, BlockPos pos) { -+ // CraftBukkit start -+ if (user != null && !(user instanceof Player)) { -+ BlockState iblockdata1 = ComposterBlock.empty(user, state, DummyGeneratorAccess.INSTANCE, pos); -+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(user, pos, iblockdata1)) { -+ return state; -+ } -+ } -+ // CraftBukkit end - if (!world.isClientSide) { - Vec3 vec3d = Vec3.atLowerCornerWithOffset(pos, 0.5D, 1.01D, 0.5D).offsetRandom(world.random, 0.7F); - ItemEntity entityitem = new ItemEntity(world, vec3d.x(), vec3d.y(), vec3d.z(), new ItemStack(Items.BONE_MEAL)); -@@ -301,20 +330,47 @@ - return iblockdata1; - } - -+ @Nullable // Paper - static BlockState addItem(@Nullable Entity user, BlockState state, LevelAccessor world, BlockPos pos, ItemStack stack) { -- int i = (Integer) state.getValue(ComposterBlock.LEVEL); -- float f = ComposterBlock.COMPOSTABLES.getFloat(stack.getItem()); -+ // CraftBukkit start -+ return ComposterBlock.addItem(user, state, world, pos, stack, world.getRandom().nextDouble()); -+ } - -- if ((i != 0 || f <= 0.0F) && world.getRandom().nextDouble() >= (double) f) { -- return state; -- } else { -- int j = i + 1; -- BlockState iblockdata1 = (BlockState) state.setValue(ComposterBlock.LEVEL, j); -+ @Nullable // Paper - make it nullable -+ static BlockState addItem(@Nullable Entity entity, BlockState iblockdata, LevelAccessor generatoraccess, BlockPos blockposition, ItemStack itemstack, double rand) { -+ // CraftBukkit end -+ int i = (Integer) iblockdata.getValue(ComposterBlock.LEVEL); -+ float f = ComposterBlock.COMPOSTABLES.getFloat(itemstack.getItem()); - -- world.setBlock(pos, iblockdata1, 3); -- world.gameEvent((Holder) GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(user, iblockdata1)); -+ // Paper start - Add CompostItemEvent and EntityCompostItemEvent -+ boolean willRaiseLevel = !((i != 0 || f <= 0.0F) && rand >= (double) f); -+ final io.papermc.paper.event.block.CompostItemEvent event; -+ if (entity == null) { -+ event = new io.papermc.paper.event.block.CompostItemEvent(org.bukkit.craftbukkit.block.CraftBlock.at(generatoraccess, blockposition), itemstack.getBukkitStack(), willRaiseLevel); -+ } else { -+ event = new io.papermc.paper.event.entity.EntityCompostItemEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(generatoraccess, blockposition), itemstack.getBukkitStack(), willRaiseLevel); -+ } -+ if (!event.callEvent()) { // check for cancellation of entity event (non entity event can't be cancelled cause of hoppers) -+ return null; -+ } -+ willRaiseLevel = event.willRaiseLevel(); -+ -+ if (!willRaiseLevel) { -+ // Paper end - Add CompostItemEvent and EntityCompostItemEvent -+ return iblockdata; -+ } else { -+ int j = i + 1; -+ BlockState iblockdata1 = (BlockState) iblockdata.setValue(ComposterBlock.LEVEL, j); -+ // Paper start - move the EntityChangeBlockEvent here to avoid conflict later for the compost events -+ if (entity != null && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, blockposition, iblockdata1)) { -+ return null; -+ } -+ // Paper end -+ -+ generatoraccess.setBlock(blockposition, iblockdata1, 3); -+ generatoraccess.gameEvent((Holder) GameEvent.BLOCK_CHANGE, blockposition, GameEvent.Context.of(entity, iblockdata1)); - if (j == 7) { -- world.scheduleTick(pos, state.getBlock(), 20); -+ generatoraccess.scheduleTick(blockposition, iblockdata.getBlock(), 20); - } - - return iblockdata1; -@@ -354,7 +410,8 @@ - public WorldlyContainer getContainer(BlockState state, LevelAccessor world, BlockPos pos) { - int i = (Integer) state.getValue(ComposterBlock.LEVEL); - -- return (WorldlyContainer) (i == 8 ? new ComposterBlock.OutputContainer(state, world, pos, new ItemStack(Items.BONE_MEAL)) : (i < 7 ? new ComposterBlock.InputContainer(state, world, pos) : new ComposterBlock.EmptyContainer())); -+ // CraftBukkit - empty generatoraccess, blockposition -+ return (WorldlyContainer) (i == 8 ? new ComposterBlock.OutputContainer(state, world, pos, new ItemStack(Items.BONE_MEAL)) : (i < 7 ? new ComposterBlock.InputContainer(state, world, pos) : new ComposterBlock.EmptyContainer(world, pos))); - } - - public static class OutputContainer extends SimpleContainer implements WorldlyContainer { -@@ -369,6 +426,7 @@ - this.state = state; - this.level = world; - this.pos = pos; -+ this.bukkitOwner = new CraftBlockInventoryHolder(world, pos, this); // CraftBukkit - } - - @Override -@@ -393,8 +451,15 @@ - - @Override - public void setChanged() { -+ // CraftBukkit start - allow putting items back (eg cancelled InventoryMoveItemEvent) -+ if (this.isEmpty()) { - ComposterBlock.empty((Entity) null, this.state, this.level, this.pos); - this.changed = true; -+ } else { -+ this.level.setBlock(this.pos, this.state, 3); -+ this.changed = false; -+ } -+ // CraftBukkit end - } - } - -@@ -407,6 +472,7 @@ - - public InputContainer(BlockState state, LevelAccessor world, BlockPos pos) { - super(1); -+ this.bukkitOwner = new CraftBlockInventoryHolder(world, pos, this); // CraftBukkit - this.state = state; - this.level = world; - this.pos = pos; -@@ -439,6 +505,11 @@ - if (!itemstack.isEmpty()) { - this.changed = true; - BlockState iblockdata = ComposterBlock.addItem((Entity) null, this.state, this.level, this.pos, itemstack); -+ // Paper start - Add CompostItemEvent and EntityCompostItemEvent -+ if (iblockdata == null) { -+ return; -+ } -+ // Paper end - Add CompostItemEvent and EntityCompostItemEvent - - this.level.levelEvent(1500, this.pos, iblockdata != this.state ? 1 : 0); - this.removeItemNoUpdate(0); -@@ -449,8 +520,9 @@ - - public static class EmptyContainer extends SimpleContainer implements WorldlyContainer { - -- public EmptyContainer() { -+ public EmptyContainer(LevelAccessor generatoraccess, BlockPos blockposition) { // CraftBukkit - super(0); -+ this.bukkitOwner = new CraftBlockInventoryHolder(generatoraccess, blockposition, this); // CraftBukkit - } - - @Override diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/ConcretePowderBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/ConcretePowderBlock.java.patch deleted file mode 100644 index 5778abe978..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/ConcretePowderBlock.java.patch +++ /dev/null @@ -1,76 +0,0 @@ ---- a/net/minecraft/world/level/block/ConcretePowderBlock.java -+++ b/net/minecraft/world/level/block/ConcretePowderBlock.java -@@ -15,6 +15,11 @@ - import net.minecraft.world.level.ScheduledTickAccess; - import net.minecraft.world.level.block.state.BlockBehaviour; - import net.minecraft.world.level.block.state.BlockState; -+// CraftBukkit start -+import org.bukkit.craftbukkit.block.CraftBlockState; -+import org.bukkit.craftbukkit.block.CraftBlockStates; -+import org.bukkit.event.block.BlockFormEvent; -+// CraftBukkit end - - public class ConcretePowderBlock extends FallingBlock { - -@@ -38,7 +43,7 @@ - @Override - public void onLand(Level world, BlockPos pos, BlockState fallingBlockState, BlockState currentStateInPos, FallingBlockEntity fallingBlockEntity) { - if (ConcretePowderBlock.shouldSolidify(world, pos, currentStateInPos)) { -- world.setBlock(pos, this.concrete.defaultBlockState(), 3); -+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(world, pos, this.concrete.defaultBlockState(), 3); // CraftBukkit - } - - } -@@ -49,7 +54,24 @@ - BlockPos blockposition = ctx.getClickedPos(); - BlockState iblockdata = world.getBlockState(blockposition); - -- return ConcretePowderBlock.shouldSolidify(world, blockposition, iblockdata) ? this.concrete.defaultBlockState() : super.getStateForPlacement(ctx); -+ // CraftBukkit start -+ if (!ConcretePowderBlock.shouldSolidify(world, blockposition, iblockdata)) { -+ return super.getStateForPlacement(ctx); -+ } -+ -+ // TODO: An event factory call for methods like this -+ CraftBlockState blockState = CraftBlockStates.getBlockState(world, blockposition); -+ blockState.setData(this.concrete.defaultBlockState()); -+ -+ BlockFormEvent event = new BlockFormEvent(blockState.getBlock(), blockState); -+ world.getServer().server.getPluginManager().callEvent(event); -+ -+ if (!event.isCancelled()) { -+ return blockState.getHandle(); -+ } -+ -+ return super.getStateForPlacement(ctx); -+ // CraftBukkit end - } - - private static boolean shouldSolidify(BlockGetter world, BlockPos pos, BlockState state) { -@@ -85,7 +107,25 @@ - - @Override - protected BlockState updateShape(BlockState state, LevelReader world, ScheduledTickAccess tickView, BlockPos pos, Direction direction, BlockPos neighborPos, BlockState neighborState, RandomSource random) { -- return ConcretePowderBlock.touchesLiquid(world, pos) ? this.concrete.defaultBlockState() : super.updateShape(state, world, tickView, pos, direction, neighborPos, neighborState, random); -+ // CraftBukkit start -+ if (ConcretePowderBlock.touchesLiquid(world, pos)) { -+ // Suppress during worldgen -+ if (!(world instanceof Level world1)) { -+ return this.concrete.defaultBlockState(); -+ } -+ CraftBlockState blockState = CraftBlockStates.getBlockState(world1, pos); -+ blockState.setData(this.concrete.defaultBlockState()); -+ -+ BlockFormEvent event = new BlockFormEvent(blockState.getBlock(), blockState); -+ world1.getCraftServer().getPluginManager().callEvent(event); -+ -+ if (!event.isCancelled()) { -+ return blockState.getHandle(); -+ } -+ } -+ -+ return super.updateShape(state, world, tickView, pos, direction, neighborPos, neighborState, random); -+ // CraftBukkit end - } - - @Override diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/CrafterBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/CrafterBlock.java.patch deleted file mode 100644 index b3f1ac312a..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/CrafterBlock.java.patch +++ /dev/null @@ -1,89 +0,0 @@ ---- a/net/minecraft/world/level/block/CrafterBlock.java -+++ b/net/minecraft/world/level/block/CrafterBlock.java -@@ -12,6 +12,7 @@ - import net.minecraft.server.level.ServerLevel; - import net.minecraft.server.level.ServerPlayer; - import net.minecraft.util.RandomSource; -+import net.minecraft.world.CompoundContainer; - import net.minecraft.world.Container; - import net.minecraft.world.Containers; - import net.minecraft.world.InteractionResult; -@@ -39,6 +40,12 @@ - import net.minecraft.world.phys.AABB; - import net.minecraft.world.phys.BlockHitResult; - import net.minecraft.world.phys.Vec3; -+import org.bukkit.craftbukkit.event.CraftEventFactory; -+import org.bukkit.craftbukkit.inventory.CraftItemStack; -+import org.bukkit.event.block.CrafterCraftEvent; -+import org.bukkit.event.inventory.InventoryMoveItemEvent; -+import org.bukkit.inventory.Inventory; -+// CraftBukkit end - - public class CrafterBlock extends BaseEntityBlock { - -@@ -189,6 +196,13 @@ - RecipeHolder recipeholder = (RecipeHolder) optional.get(); - ItemStack itemstack = ((CraftingRecipe) recipeholder.value()).assemble(craftinginput, world.registryAccess()); - -+ // CraftBukkit start -+ CrafterCraftEvent event = CraftEventFactory.callCrafterCraftEvent(pos, world, crafterblockentity, itemstack, recipeholder); -+ if (event.isCancelled()) { -+ return; -+ } -+ itemstack = CraftItemStack.asNMSCopy(event.getResult()); -+ // CraftBukkit end - if (itemstack.isEmpty()) { - world.levelEvent(1050, pos, 0); - } else { -@@ -227,7 +241,25 @@ - ItemStack itemstack1 = stack.copy(); - - if (iinventory != null && (iinventory instanceof CrafterBlockEntity || stack.getCount() > iinventory.getMaxStackSize(stack))) { -+ // CraftBukkit start - InventoryMoveItemEvent -+ CraftItemStack oitemstack = CraftItemStack.asCraftMirror(itemstack1); -+ -+ Inventory destinationInventory; -+ // Have to special case large chests as they work oddly -+ if (iinventory instanceof CompoundContainer) { -+ destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((CompoundContainer) iinventory); -+ } else { -+ destinationInventory = iinventory.getOwner().getInventory(); -+ } -+ -+ InventoryMoveItemEvent event = new InventoryMoveItemEvent(blockEntity.getOwner().getInventory(), oitemstack, destinationInventory, true); -+ world.getCraftServer().getPluginManager().callEvent(event); -+ itemstack1 = CraftItemStack.asNMSCopy(event.getItem()); - while (!itemstack1.isEmpty()) { -+ if (event.isCancelled()) { -+ break; -+ } -+ // CraftBukkit end - ItemStack itemstack2 = itemstack1.copyWithCount(1); - ItemStack itemstack3 = HopperBlockEntity.addItem(blockEntity, iinventory, itemstack2, enumdirection.getOpposite()); - -@@ -238,7 +270,25 @@ - itemstack1.shrink(1); - } - } else if (iinventory != null) { -+ // CraftBukkit start - InventoryMoveItemEvent -+ CraftItemStack oitemstack = CraftItemStack.asCraftMirror(itemstack1); -+ -+ Inventory destinationInventory; -+ // Have to special case large chests as they work oddly -+ if (iinventory instanceof CompoundContainer) { -+ destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((CompoundContainer) iinventory); -+ } else { -+ destinationInventory = iinventory.getOwner().getInventory(); -+ } -+ -+ InventoryMoveItemEvent event = new InventoryMoveItemEvent(blockEntity.getOwner().getInventory(), oitemstack, destinationInventory, true); -+ world.getCraftServer().getPluginManager().callEvent(event); -+ itemstack1 = CraftItemStack.asNMSCopy(event.getItem()); - while (!itemstack1.isEmpty()) { -+ if (event.isCancelled()) { -+ break; -+ } -+ // CraftBukkit end - int i = itemstack1.getCount(); - - itemstack1 = HopperBlockEntity.addItem(blockEntity, iinventory, itemstack1, enumdirection.getOpposite()); diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/CropBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/CropBlock.java.patch deleted file mode 100644 index 4883d93884..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/CropBlock.java.patch +++ /dev/null @@ -1,59 +0,0 @@ ---- a/net/minecraft/world/level/block/CropBlock.java -+++ b/net/minecraft/world/level/block/CropBlock.java -@@ -21,6 +21,7 @@ - import net.minecraft.world.level.block.state.properties.IntegerProperty; - import net.minecraft.world.phys.shapes.CollisionContext; - import net.minecraft.world.phys.shapes.VoxelShape; -+import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit - - public class CropBlock extends BushBlock implements BonemealableBlock { - -@@ -82,9 +83,26 @@ - if (i < this.getMaxAge()) { - float f = CropBlock.getGrowthSpeed(this, world, pos); - -- if (random.nextInt((int) (25.0F / f) + 1) == 0) { -- world.setBlock(pos, this.getStateForAge(i + 1), 2); -+ // Spigot start -+ int modifier; -+ if (this == Blocks.BEETROOTS) { -+ modifier = world.spigotConfig.beetrootModifier; -+ } else if (this == Blocks.CARROTS) { -+ modifier = world.spigotConfig.carrotModifier; -+ } else if (this == Blocks.POTATOES) { -+ modifier = world.spigotConfig.potatoModifier; -+ // Paper start - Fix Spigot growth modifiers -+ } else if (this == Blocks.TORCHFLOWER_CROP) { -+ modifier = world.spigotConfig.torchFlowerModifier; -+ // Paper end - Fix Spigot growth modifiers -+ } else { -+ modifier = world.spigotConfig.wheatModifier; - } -+ -+ if (random.nextFloat() < (modifier / (100.0f * (Math.floor((25.0F / f) + 1))))) { // Spigot - SPIGOT-7159: Better modifier resolution -+ // Spigot end -+ CraftEventFactory.handleBlockGrowEvent(world, pos, this.getStateForAge(i + 1), 2); // CraftBukkit -+ } - } - } - -@@ -98,7 +116,7 @@ - i = j; - } - -- world.setBlock(pos, this.getStateForAge(i), 2); -+ CraftEventFactory.handleBlockGrowEvent(world, pos, this.getStateForAge(i), 2); // CraftBukkit - } - - protected int getBonemealAgeIncrease(Level world) { -@@ -160,8 +178,9 @@ - - @Override - protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { -+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent - if (world instanceof ServerLevel worldserver) { -- if (entity instanceof Ravager && worldserver.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { -+ if (entity instanceof Ravager && CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState(), !worldserver.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING))) { // CraftBukkit - worldserver.destroyBlock(pos, true, entity); - } - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/DaylightDetectorBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/DaylightDetectorBlock.java.patch deleted file mode 100644 index 4631339b55..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/DaylightDetectorBlock.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/net/minecraft/world/level/block/DaylightDetectorBlock.java -+++ b/net/minecraft/world/level/block/DaylightDetectorBlock.java -@@ -74,6 +74,7 @@ - - i = Mth.clamp(i, 0, 15); - if ((Integer) state.getValue(DaylightDetectorBlock.POWER) != i) { -+ i = org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(world, pos, ((Integer) state.getValue(DaylightDetectorBlock.POWER)), i).getNewCurrent(); // CraftBukkit - Call BlockRedstoneEvent - world.setBlock(pos, (BlockState) state.setValue(DaylightDetectorBlock.POWER, i), 3); - } - diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/DecoratedPotBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/DecoratedPotBlock.java.patch deleted file mode 100644 index 6b148eba67..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/DecoratedPotBlock.java.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- a/net/minecraft/world/level/block/DecoratedPotBlock.java -+++ b/net/minecraft/world/level/block/DecoratedPotBlock.java -@@ -240,6 +240,11 @@ - - if (world instanceof ServerLevel worldserver) { - if (projectile.mayInteract(worldserver, blockposition) && projectile.mayBreak(worldserver)) { -+ // CraftBukkit start - call EntityChangeBlockEvent -+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(projectile, blockposition, this.getFluidState(state).createLegacyBlock())) { -+ return; -+ } -+ // CraftBukkit end - world.setBlock(blockposition, (BlockState) state.setValue(DecoratedPotBlock.CRACKED, true), 4); - world.destroyBlock(blockposition, true, projectile); - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/DetectorRailBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/DetectorRailBlock.java.patch deleted file mode 100644 index de7bae1c90..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/DetectorRailBlock.java.patch +++ /dev/null @@ -1,44 +0,0 @@ ---- a/net/minecraft/world/level/block/DetectorRailBlock.java -+++ b/net/minecraft/world/level/block/DetectorRailBlock.java -@@ -26,6 +26,7 @@ - import net.minecraft.world.level.block.state.properties.RailShape; - import net.minecraft.world.level.redstone.Orientation; - import net.minecraft.world.phys.AABB; -+import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit - - public class DetectorRailBlock extends BaseRailBlock { - -@@ -51,6 +52,7 @@ - - @Override - protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { -+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent - if (!world.isClientSide) { - if (!(Boolean) state.getValue(DetectorRailBlock.POWERED)) { - this.checkPressed(world, pos, state); -@@ -77,6 +79,7 @@ - - private void checkPressed(Level world, BlockPos pos, BlockState state) { - if (this.canSurvive(state, world, pos)) { -+ if (state.getBlock() != this) { return; } // Paper - Fix some rails connecting improperly - boolean flag = (Boolean) state.getValue(DetectorRailBlock.POWERED); - boolean flag1 = false; - List list = this.getInteractingMinecartOfType(world, pos, AbstractMinecart.class, (entity) -> { -@@ -88,7 +91,17 @@ - } - - BlockState iblockdata1; -+ // CraftBukkit start -+ if (flag != flag1) { -+ org.bukkit.block.Block block = world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); - -+ BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, flag ? 15 : 0, flag1 ? 15 : 0); -+ world.getCraftServer().getPluginManager().callEvent(eventRedstone); -+ -+ flag1 = eventRedstone.getNewCurrent() > 0; -+ } -+ // CraftBukkit end -+ - if (flag1 && !flag) { - iblockdata1 = (BlockState) state.setValue(DetectorRailBlock.POWERED, true); - world.setBlock(pos, iblockdata1, 3); diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/DiodeBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/DiodeBlock.java.patch deleted file mode 100644 index 91c2eb8ada..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/DiodeBlock.java.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- a/net/minecraft/world/level/block/DiodeBlock.java -+++ b/net/minecraft/world/level/block/DiodeBlock.java -@@ -23,6 +23,7 @@ - import net.minecraft.world.phys.shapes.CollisionContext; - import net.minecraft.world.phys.shapes.VoxelShape; - import net.minecraft.world.ticks.TickPriority; -+import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit - - public abstract class DiodeBlock extends HorizontalDirectionalBlock { - -@@ -59,8 +60,18 @@ - boolean flag1 = this.shouldTurnOn(world, pos, state); - - if (flag && !flag1) { -+ // CraftBukkit start -+ if (CraftEventFactory.callRedstoneChange(world, pos, 15, 0).getNewCurrent() != 0) { -+ return; -+ } -+ // CraftBukkit end - world.setBlock(pos, (BlockState) state.setValue(DiodeBlock.POWERED, false), 2); - } else if (!flag) { -+ // CraftBukkit start -+ if (CraftEventFactory.callRedstoneChange(world, pos, 0, 15).getNewCurrent() != 15) { -+ return; -+ } -+ // CraftBukkit end - world.setBlock(pos, (BlockState) state.setValue(DiodeBlock.POWERED, true), 2); - if (!flag1) { - world.scheduleTick(pos, (Block) this, this.getDelay(state), TickPriority.VERY_HIGH); diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/DispenserBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/DispenserBlock.java.patch deleted file mode 100644 index 71019ffd00..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/DispenserBlock.java.patch +++ /dev/null @@ -1,61 +0,0 @@ ---- a/net/minecraft/world/level/block/DispenserBlock.java -+++ b/net/minecraft/world/level/block/DispenserBlock.java -@@ -52,6 +52,7 @@ - private static final DefaultDispenseItemBehavior DEFAULT_BEHAVIOR = new DefaultDispenseItemBehavior(); - public static final Map DISPENSER_REGISTRY = new IdentityHashMap(); - private static final int TRIGGER_DURATION = 4; -+ public static boolean eventFired = false; // CraftBukkit - - @Override - public MapCodec codec() { -@@ -79,8 +80,9 @@ - if (tileentity instanceof DispenserBlockEntity) { - DispenserBlockEntity tileentitydispenser = (DispenserBlockEntity) tileentity; - -- player.openMenu(tileentitydispenser); -+ if (player.openMenu(tileentitydispenser).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation - player.awardStat(tileentitydispenser instanceof DropperBlockEntity ? Stats.INSPECT_DROPPER : Stats.INSPECT_DISPENSER); -+ } // Paper - Fix InventoryOpenEvent cancellation - } - } - -@@ -88,7 +90,7 @@ - } - - public void dispenseFrom(ServerLevel world, BlockState state, BlockPos pos) { -- DispenserBlockEntity tileentitydispenser = (DispenserBlockEntity) world.getBlockEntity(pos, BlockEntityType.DISPENSER).orElse((Object) null); -+ DispenserBlockEntity tileentitydispenser = (DispenserBlockEntity) world.getBlockEntity(pos, BlockEntityType.DISPENSER).orElse(null); // CraftBukkit - decompile error - - if (tileentitydispenser == null) { - DispenserBlock.LOGGER.warn("Ignoring dispensing attempt for Dispenser without matching block entity at {}", pos); -@@ -97,13 +99,17 @@ - int i = tileentitydispenser.getRandomSlot(world.random); - - if (i < 0) { -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFailedDispenseEvent(world, pos)) { // Paper - Add BlockFailedDispenseEvent - world.levelEvent(1001, pos, 0); - world.gameEvent((Holder) GameEvent.BLOCK_ACTIVATE, pos, GameEvent.Context.of(tileentitydispenser.getBlockState())); -+ } // Paper - Add BlockFailedDispenseEvent - } else { - ItemStack itemstack = tileentitydispenser.getItem(i); - DispenseItemBehavior idispensebehavior = this.getDispenseMethod(world, itemstack); - - if (idispensebehavior != DispenseItemBehavior.NOOP) { -+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockPreDispenseEvent(world, pos, itemstack, i)) return; // Paper - Add BlockPreDispenseEvent -+ DispenserBlock.eventFired = false; // CraftBukkit - reset event status - tileentitydispenser.setItem(i, idispensebehavior.dispense(sourceblock, itemstack)); - } - -@@ -111,6 +117,12 @@ - } - } - -+ // Paper start - Fix NPE with equippable and items without behavior -+ public static DispenseItemBehavior getDispenseBehavior(BlockSource pointer, ItemStack stack) { -+ return ((DispenserBlock) pointer.state().getBlock()).getDispenseMethod(pointer.level(), stack); -+ } -+ // Paper end - Fix NPE with equippable and items without behavior -+ - protected DispenseItemBehavior getDispenseMethod(Level world, ItemStack stack) { - if (!stack.isItemEnabled(world.enabledFeatures())) { - return DispenserBlock.DEFAULT_BEHAVIOR; diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/DoorBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/DoorBlock.java.patch deleted file mode 100644 index ea278f700f..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/DoorBlock.java.patch +++ /dev/null @@ -1,37 +0,0 @@ ---- a/net/minecraft/world/level/block/DoorBlock.java -+++ b/net/minecraft/world/level/block/DoorBlock.java -@@ -38,6 +38,7 @@ - import net.minecraft.world.phys.Vec3; - import net.minecraft.world.phys.shapes.CollisionContext; - import net.minecraft.world.phys.shapes.VoxelShape; -+import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit - - public class DoorBlock extends Block { - -@@ -222,9 +223,24 @@ - - @Override - protected void neighborChanged(BlockState state, Level world, BlockPos pos, Block sourceBlock, @Nullable Orientation wireOrientation, boolean notify) { -- boolean flag1 = world.hasNeighborSignal(pos) || world.hasNeighborSignal(pos.relative(state.getValue(DoorBlock.HALF) == DoubleBlockHalf.LOWER ? Direction.UP : Direction.DOWN)); -+ // CraftBukkit start -+ BlockPos otherHalf = pos.relative(state.getValue(DoorBlock.HALF) == DoubleBlockHalf.LOWER ? Direction.UP : Direction.DOWN); - -- if (!this.defaultBlockState().is(sourceBlock) && flag1 != (Boolean) state.getValue(DoorBlock.POWERED)) { -+ org.bukkit.World bworld = world.getWorld(); -+ org.bukkit.block.Block bukkitBlock = bworld.getBlockAt(pos.getX(), pos.getY(), pos.getZ()); -+ org.bukkit.block.Block blockTop = bworld.getBlockAt(otherHalf.getX(), otherHalf.getY(), otherHalf.getZ()); -+ -+ int power = bukkitBlock.getBlockPower(); -+ int powerTop = blockTop.getBlockPower(); -+ if (powerTop > power) power = powerTop; -+ int oldPower = (Boolean) state.getValue(DoorBlock.POWERED) ? 15 : 0; -+ -+ if (oldPower == 0 ^ power == 0) { -+ BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(bukkitBlock, oldPower, power); -+ world.getCraftServer().getPluginManager().callEvent(eventRedstone); -+ -+ boolean flag1 = eventRedstone.getNewCurrent() > 0; -+ // CraftBukkit end - if (flag1 != (Boolean) state.getValue(DoorBlock.OPEN)) { - this.playSound((Entity) null, world, pos, flag1); - world.gameEvent((Entity) null, (Holder) (flag1 ? GameEvent.BLOCK_OPEN : GameEvent.BLOCK_CLOSE), pos); diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/DoublePlantBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/DoublePlantBlock.java.patch deleted file mode 100644 index a59d6fc4f3..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/DoublePlantBlock.java.patch +++ /dev/null @@ -1,21 +0,0 @@ ---- a/net/minecraft/world/level/block/DoublePlantBlock.java -+++ b/net/minecraft/world/level/block/DoublePlantBlock.java -@@ -98,11 +98,16 @@ - } - - @Override -- public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool) { -- super.playerDestroy(world, player, pos, Blocks.AIR.defaultBlockState(), blockEntity, tool); -+ public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool, boolean includeDrops, boolean dropExp) { // Paper - fix drops not preventing stats/food exhaustion -+ super.playerDestroy(world, player, pos, Blocks.AIR.defaultBlockState(), blockEntity, tool, includeDrops, dropExp); // Paper - fix drops not preventing stats/food exhaustion - } - - protected static void preventDropFromBottomPart(Level world, BlockPos pos, BlockState state, Player player) { -+ // CraftBukkit start -+ if (((net.minecraft.server.level.ServerLevel)world).hasPhysicsEvent && org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPhysicsEvent(world, pos).isCancelled()) { // Paper -+ return; -+ } -+ // CraftBukkit end - DoubleBlockHalf blockpropertydoubleblockhalf = (DoubleBlockHalf) state.getValue(DoublePlantBlock.HALF); - - if (blockpropertydoubleblockhalf == DoubleBlockHalf.UPPER) { diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/DragonEggBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/DragonEggBlock.java.patch deleted file mode 100644 index b73b669baf..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/DragonEggBlock.java.patch +++ /dev/null @@ -1,29 +0,0 @@ ---- a/net/minecraft/world/level/block/DragonEggBlock.java -+++ b/net/minecraft/world/level/block/DragonEggBlock.java -@@ -15,6 +15,7 @@ - import net.minecraft.world.phys.BlockHitResult; - import net.minecraft.world.phys.shapes.CollisionContext; - import net.minecraft.world.phys.shapes.VoxelShape; -+import org.bukkit.event.block.BlockFromToEvent; // CraftBukkit - - public class DragonEggBlock extends FallingBlock { - -@@ -53,6 +54,18 @@ - BlockPos blockposition1 = pos.offset(world.random.nextInt(16) - world.random.nextInt(16), world.random.nextInt(8) - world.random.nextInt(8), world.random.nextInt(16) - world.random.nextInt(16)); - - if (world.getBlockState(blockposition1).isAir() && worldborder.isWithinBounds(blockposition1)) { -+ // CraftBukkit start -+ org.bukkit.block.Block from = world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); -+ org.bukkit.block.Block to = world.getWorld().getBlockAt(blockposition1.getX(), blockposition1.getY(), blockposition1.getZ()); -+ BlockFromToEvent event = new BlockFromToEvent(from, to); -+ org.bukkit.Bukkit.getPluginManager().callEvent(event); -+ -+ if (event.isCancelled()) { -+ return; -+ } -+ -+ blockposition1 = new BlockPos(event.getToBlock().getX(), event.getToBlock().getY(), event.getToBlock().getZ()); -+ // CraftBukkit end - if (world.isClientSide) { - for (int j = 0; j < 128; ++j) { - double d0 = world.random.nextDouble(); diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/DropperBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/DropperBlock.java.patch deleted file mode 100644 index 0a8d6b5e2e..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/DropperBlock.java.patch +++ /dev/null @@ -1,75 +0,0 @@ ---- a/net/minecraft/world/level/block/DropperBlock.java -+++ b/net/minecraft/world/level/block/DropperBlock.java -@@ -8,6 +8,7 @@ - import net.minecraft.core.dispenser.DefaultDispenseItemBehavior; - import net.minecraft.core.dispenser.DispenseItemBehavior; - import net.minecraft.server.level.ServerLevel; -+import net.minecraft.world.CompoundContainer; - import net.minecraft.world.Container; - import net.minecraft.world.item.ItemStack; - import net.minecraft.world.level.Level; -@@ -19,12 +20,15 @@ - import net.minecraft.world.level.block.state.BlockBehaviour; - import net.minecraft.world.level.block.state.BlockState; - import org.slf4j.Logger; -+import org.bukkit.craftbukkit.inventory.CraftItemStack; -+import org.bukkit.event.inventory.InventoryMoveItemEvent; -+// CraftBukkit end - - public class DropperBlock extends DispenserBlock { - - private static final Logger LOGGER = LogUtils.getLogger(); - public static final MapCodec CODEC = simpleCodec(DropperBlock::new); -- private static final DispenseItemBehavior DISPENSE_BEHAVIOUR = new DefaultDispenseItemBehavior(); -+ private static final DispenseItemBehavior DISPENSE_BEHAVIOUR = new DefaultDispenseItemBehavior(true); // CraftBukkit - - @Override - public MapCodec codec() { -@@ -47,7 +51,7 @@ - - @Override - public void dispenseFrom(ServerLevel world, BlockState state, BlockPos pos) { -- DispenserBlockEntity tileentitydispenser = (DispenserBlockEntity) world.getBlockEntity(pos, BlockEntityType.DROPPER).orElse((Object) null); -+ DispenserBlockEntity tileentitydispenser = (DispenserBlockEntity) world.getBlockEntity(pos, BlockEntityType.DROPPER).orElse(null); // CraftBukkit - decompile error - - if (tileentitydispenser == null) { - DropperBlock.LOGGER.warn("Ignoring dispensing attempt for Dropper without matching block entity at {}", pos); -@@ -56,6 +60,7 @@ - int i = tileentitydispenser.getRandomSlot(world.random); - - if (i < 0) { -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFailedDispenseEvent(world, pos)) // Paper - Add BlockFailedDispenseEvent - world.levelEvent(1001, pos, 0); - } else { - ItemStack itemstack = tileentitydispenser.getItem(i); -@@ -66,10 +71,28 @@ - ItemStack itemstack1; - - if (iinventory == null) { -+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockPreDispenseEvent(world, pos, itemstack, i)) return; // Paper - Add BlockPreDispenseEvent - itemstack1 = DropperBlock.DISPENSE_BEHAVIOUR.dispense(sourceblock, itemstack); - } else { -- itemstack1 = HopperBlockEntity.addItem(tileentitydispenser, iinventory, itemstack.copyWithCount(1), enumdirection.getOpposite()); -- if (itemstack1.isEmpty()) { -+ // CraftBukkit start - Fire event when pushing items into other inventories -+ CraftItemStack oitemstack = CraftItemStack.asCraftMirror(itemstack.copyWithCount(1)); -+ -+ org.bukkit.inventory.Inventory destinationInventory; -+ // Have to special case large chests as they work oddly -+ if (iinventory instanceof CompoundContainer) { -+ destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((CompoundContainer) iinventory); -+ } else { -+ destinationInventory = iinventory.getOwner().getInventory(); -+ } -+ -+ InventoryMoveItemEvent event = new InventoryMoveItemEvent(tileentitydispenser.getOwner().getInventory(), oitemstack, destinationInventory, true); -+ world.getCraftServer().getPluginManager().callEvent(event); -+ if (event.isCancelled()) { -+ return; -+ } -+ itemstack1 = HopperBlockEntity.addItem(tileentitydispenser, iinventory, CraftItemStack.asNMSCopy(event.getItem()), enumdirection.getOpposite()); -+ if (event.getItem().equals(oitemstack) && itemstack1.isEmpty()) { -+ // CraftBukkit end - itemstack1 = itemstack.copy(); - itemstack1.shrink(1); - } else { diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/EndGatewayBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/EndGatewayBlock.java.patch deleted file mode 100644 index 2e2055c634..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/EndGatewayBlock.java.patch +++ /dev/null @@ -1,34 +0,0 @@ ---- a/net/minecraft/world/level/block/EndGatewayBlock.java -+++ b/net/minecraft/world/level/block/EndGatewayBlock.java -@@ -22,6 +22,9 @@ - import net.minecraft.world.level.material.Fluid; - import net.minecraft.world.level.portal.TeleportTransition; - import net.minecraft.world.phys.Vec3; -+// CraftBukkit start -+import org.bukkit.event.player.PlayerTeleportEvent; -+// CraftBukkit end - - public class EndGatewayBlock extends BaseEntityBlock implements Portal { - -@@ -89,7 +92,12 @@ - - @Override - protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { -+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent - if (entity.canUsePortal(false)) { -+ // Paper start - call EntityPortalEnterEvent -+ org.bukkit.event.entity.EntityPortalEnterEvent event = new org.bukkit.event.entity.EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ()), org.bukkit.PortalType.END_GATEWAY); // Paper - add portal type -+ if (!event.callEvent()) return; -+ // Paper end - call EntityPortalEnterEvent - BlockEntity tileentity = world.getBlockEntity(pos); - - if (!world.isClientSide && tileentity instanceof TheEndGatewayBlockEntity) { -@@ -112,7 +120,7 @@ - if (tileentity instanceof TheEndGatewayBlockEntity tileentityendgateway) { - Vec3 vec3d = tileentityendgateway.getPortalPosition(world, pos); - -- return vec3d == null ? null : (entity instanceof ThrownEnderpearl ? new TeleportTransition(world, vec3d, Vec3.ZERO, 0.0F, 0.0F, Set.of(), TeleportTransition.PLACE_PORTAL_TICKET) : new TeleportTransition(world, vec3d, Vec3.ZERO, 0.0F, 0.0F, Relative.union(Relative.DELTA, Relative.ROTATION), TeleportTransition.PLACE_PORTAL_TICKET)); -+ return vec3d == null ? null : (entity instanceof ThrownEnderpearl ? new TeleportTransition(world, vec3d, Vec3.ZERO, 0.0F, 0.0F, Set.of(), TeleportTransition.PLACE_PORTAL_TICKET, PlayerTeleportEvent.TeleportCause.END_GATEWAY) : new TeleportTransition(world, vec3d, Vec3.ZERO, 0.0F, 0.0F, Relative.union(Relative.DELTA, Relative.ROTATION), TeleportTransition.PLACE_PORTAL_TICKET, PlayerTeleportEvent.TeleportCause.END_GATEWAY)); // CraftBukkit - } else { - return null; - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/EndPortalBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/EndPortalBlock.java.patch deleted file mode 100644 index c075ce1cd8..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/EndPortalBlock.java.patch +++ /dev/null @@ -1,91 +0,0 @@ ---- a/net/minecraft/world/level/block/EndPortalBlock.java -+++ b/net/minecraft/world/level/block/EndPortalBlock.java -@@ -19,12 +19,23 @@ - import net.minecraft.world.level.block.entity.TheEndPortalBlockEntity; - import net.minecraft.world.level.block.state.BlockBehaviour; - import net.minecraft.world.level.block.state.BlockState; -+import net.minecraft.world.level.dimension.LevelStem; - import net.minecraft.world.level.levelgen.feature.EndPlatformFeature; - import net.minecraft.world.level.material.Fluid; - import net.minecraft.world.level.portal.TeleportTransition; - import net.minecraft.world.phys.Vec3; - import net.minecraft.world.phys.shapes.CollisionContext; - import net.minecraft.world.phys.shapes.VoxelShape; -+// CraftBukkit start -+import java.util.List; -+import org.bukkit.Location; -+import org.bukkit.craftbukkit.CraftWorld; -+import org.bukkit.craftbukkit.event.CraftPortalEvent; -+import org.bukkit.craftbukkit.util.CraftLocation; -+import org.bukkit.event.entity.EntityPortalEnterEvent; -+import org.bukkit.event.player.PlayerRespawnEvent; -+import org.bukkit.event.player.PlayerTeleportEvent; -+// CraftBukkit end - - public class EndPortalBlock extends BaseEntityBlock implements Portal { - -@@ -57,10 +68,17 @@ - - @Override - protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { -+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent - if (entity.canUsePortal(false)) { -+ // CraftBukkit start - Entity in portal -+ EntityPortalEnterEvent event = new EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ()), org.bukkit.PortalType.ENDER); // Paper - add portal type -+ world.getCraftServer().getPluginManager().callEvent(event); -+ if (event.isCancelled()) return; // Paper - make cancellable -+ // CraftBukkit end - if (!world.isClientSide && world.dimension() == Level.END && entity instanceof ServerPlayer) { - ServerPlayer entityplayer = (ServerPlayer) entity; - -+ if (world.paperConfig().misc.disableEndCredits) entityplayer.seenCredits = true; // Paper - Option to disable end credits - if (!entityplayer.seenCredits) { - entityplayer.showEndCredits(); - return; -@@ -74,11 +92,11 @@ - - @Override - public TeleportTransition getPortalDestination(ServerLevel world, Entity entity, BlockPos pos) { -- ResourceKey resourcekey = world.dimension() == Level.END ? Level.OVERWORLD : Level.END; -+ ResourceKey resourcekey = world.getTypeKey() == LevelStem.END ? Level.OVERWORLD : Level.END; // CraftBukkit - SPIGOT-6152: send back to main overworld in custom ends - ServerLevel worldserver1 = world.getServer().getLevel(resourcekey); - - if (worldserver1 == null) { -- return null; -+ return null; // Paper - keep previous behavior of not firing PlayerTeleportEvent if the target world doesn't exist - } else { - boolean flag = resourcekey == Level.END; - BlockPos blockposition1 = flag ? ServerLevel.END_SPAWN_POINT : worldserver1.getSharedSpawnPos(); -@@ -87,7 +105,7 @@ - Set set; - - if (flag) { -- EndPlatformFeature.createEndPlatform(worldserver1, BlockPos.containing(vec3d).below(), true); -+ EndPlatformFeature.createEndPlatform(worldserver1, BlockPos.containing(vec3d).below(), true, entity); // CraftBukkit - f = Direction.WEST.toYRot(); - set = Relative.union(Relative.DELTA, Set.of(Relative.X_ROT)); - if (entity instanceof ServerPlayer) { -@@ -99,13 +117,21 @@ - if (entity instanceof ServerPlayer) { - ServerPlayer entityplayer = (ServerPlayer) entity; - -- return entityplayer.findRespawnPositionAndUseSpawnBlock(false, TeleportTransition.DO_NOTHING); -+ return entityplayer.findRespawnPositionAndUseSpawnBlock(false, TeleportTransition.DO_NOTHING, PlayerRespawnEvent.RespawnReason.END_PORTAL); // CraftBukkit - } - - vec3d = entity.adjustSpawnLocation(worldserver1, blockposition1).getBottomCenter(); - } - -- return new TeleportTransition(worldserver1, vec3d, Vec3.ZERO, f, 0.0F, set, TeleportTransition.PLAY_PORTAL_SOUND.then(TeleportTransition.PLACE_PORTAL_TICKET)); -+ // CraftBukkit start -+ CraftPortalEvent event = entity.callPortalEvent(entity, CraftLocation.toBukkit(vec3d, worldserver1.getWorld(), f, entity.getXRot()), PlayerTeleportEvent.TeleportCause.END_PORTAL, 0, 0); -+ if (event == null) { -+ return null; -+ } -+ Location to = event.getTo(); -+ -+ return new TeleportTransition(((CraftWorld) to.getWorld()).getHandle(), CraftLocation.toVec3D(to), entity.getDeltaMovement(), to.getYaw(), to.getPitch(), set, TeleportTransition.PLAY_PORTAL_SOUND.then(TeleportTransition.PLACE_PORTAL_TICKET), PlayerTeleportEvent.TeleportCause.END_PORTAL); -+ // CraftBukkit end - } - } - diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/EnderChestBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/EnderChestBlock.java.patch deleted file mode 100644 index 0b1e52d838..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/EnderChestBlock.java.patch +++ /dev/null @@ -1,25 +0,0 @@ ---- a/net/minecraft/world/level/block/EnderChestBlock.java -+++ b/net/minecraft/world/level/block/EnderChestBlock.java -@@ -78,14 +78,16 @@ - PlayerEnderChestContainer playerEnderChestContainer = player.getEnderChestInventory(); - if (playerEnderChestContainer != null && world.getBlockEntity(pos) instanceof EnderChestBlockEntity enderChestBlockEntity) { - BlockPos blockPos = pos.above(); -- if (world.getBlockState(blockPos).isRedstoneConductor(world, blockPos)) { -+ if (world.getBlockState(blockPos).isRedstoneConductor(world, blockPos)) { // Paper - diff on change; make sure that EnderChest#isBlocked uses the same logic - return InteractionResult.SUCCESS; - } else { -- if (world instanceof ServerLevel serverLevel) { -- playerEnderChestContainer.setActiveChest(enderChestBlockEntity); -- player.openMenu( -- new SimpleMenuProvider((i, inventory, playerx) -> ChestMenu.threeRows(i, inventory, playerEnderChestContainer), CONTAINER_TITLE) -- ); -+ // Paper start - Fix InventoryOpenEvent cancellation - moved up; -+ playerEnderChestContainer.setActiveChest(enderChestBlockEntity); // Needs to happen before ChestMenu.threeRows as it is required for opening animations -+ if (world instanceof ServerLevel serverLevel && player.openMenu( -+ new SimpleMenuProvider((i, inventory, playerx) -> ChestMenu.threeRows(i, inventory, playerEnderChestContainer), CONTAINER_TITLE) -+ ).isPresent()) { -+ // Paper end - Fix InventoryOpenEvent cancellation - moved up; -+ // Paper - Fix InventoryOpenEvent cancellation - moved up; - player.awardStat(Stats.OPEN_ENDERCHEST); - PiglinAi.angerNearbyPiglins(serverLevel, player, true); - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/FarmBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/FarmBlock.java.patch deleted file mode 100644 index d862f84ba3..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/FarmBlock.java.patch +++ /dev/null @@ -1,112 +0,0 @@ ---- a/net/minecraft/world/level/block/FarmBlock.java -+++ b/net/minecraft/world/level/block/FarmBlock.java -@@ -29,6 +29,10 @@ - import net.minecraft.world.level.pathfinder.PathComputationType; - import net.minecraft.world.phys.shapes.CollisionContext; - import net.minecraft.world.phys.shapes.VoxelShape; -+// CraftBukkit start -+import org.bukkit.event.entity.EntityInteractEvent; -+import org.bukkit.craftbukkit.event.CraftEventFactory; -+// CraftBukkit end - - public class FarmBlock extends Block { - -@@ -89,31 +93,56 @@ - @Override - protected void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { - int i = (Integer) state.getValue(FarmBlock.MOISTURE); -+ if (i > 0 && world.paperConfig().tickRates.wetFarmland != 1 && (world.paperConfig().tickRates.wetFarmland < 1 || (net.minecraft.server.MinecraftServer.currentTick + pos.hashCode()) % world.paperConfig().tickRates.wetFarmland != 0)) { return; } // Paper - Configurable random tick rates for blocks -+ if (i == 0 && world.paperConfig().tickRates.dryFarmland != 1 && (world.paperConfig().tickRates.dryFarmland < 1 || (net.minecraft.server.MinecraftServer.currentTick + pos.hashCode()) % world.paperConfig().tickRates.dryFarmland != 0)) { return; } // Paper - Configurable random tick rates for blocks - - if (!FarmBlock.isNearWater(world, pos) && !world.isRainingAt(pos.above())) { - if (i > 0) { -- world.setBlock(pos, (BlockState) state.setValue(FarmBlock.MOISTURE, i - 1), 2); -+ org.bukkit.craftbukkit.event.CraftEventFactory.handleMoistureChangeEvent(world, pos, (BlockState) state.setValue(FarmBlock.MOISTURE, i - 1), 2); // CraftBukkit - } else if (!FarmBlock.shouldMaintainFarmland(world, pos)) { - FarmBlock.turnToDirt((Entity) null, state, world, pos); - } - } else if (i < 7) { -- world.setBlock(pos, (BlockState) state.setValue(FarmBlock.MOISTURE, 7), 2); -+ org.bukkit.craftbukkit.event.CraftEventFactory.handleMoistureChangeEvent(world, pos, (BlockState) state.setValue(FarmBlock.MOISTURE, 7), 2); // CraftBukkit - } - - } - - @Override - public void fallOn(Level world, BlockState state, BlockPos pos, Entity entity, float fallDistance) { -+ super.fallOn(world, state, pos, entity, fallDistance); // CraftBukkit - moved here as game rules / events shouldn't affect fall damage. - if (world instanceof ServerLevel worldserver) { - if (world.random.nextFloat() < fallDistance - 0.5F && entity instanceof LivingEntity && (entity instanceof Player || worldserver.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) && entity.getBbWidth() * entity.getBbWidth() * entity.getBbHeight() > 0.512F) { -+ // CraftBukkit start - Interact soil -+ org.bukkit.event.Cancellable cancellable; -+ if (entity instanceof Player) { -+ cancellable = CraftEventFactory.callPlayerInteractEvent((Player) entity, org.bukkit.event.block.Action.PHYSICAL, pos, null, null, null); -+ } else { -+ cancellable = new EntityInteractEvent(entity.getBukkitEntity(), world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ())); -+ world.getCraftServer().getPluginManager().callEvent((EntityInteractEvent) cancellable); -+ } -+ -+ if (cancellable.isCancelled()) { -+ return; -+ } -+ -+ if (!CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.DIRT.defaultBlockState())) { -+ return; -+ } -+ // CraftBukkit end - FarmBlock.turnToDirt(entity, state, world, pos); - } - } - -- super.fallOn(world, state, pos, entity, fallDistance); -+ // super.fallOn(world, iblockdata, blockposition, entity, f); // CraftBukkit - moved up - } - - public static void turnToDirt(@Nullable Entity entity, BlockState state, Level world, BlockPos pos) { -+ // CraftBukkit start -+ if (CraftEventFactory.callBlockFadeEvent(world, pos, Blocks.DIRT.defaultBlockState()).isCancelled()) { -+ return; -+ } -+ // CraftBukkit end - BlockState iblockdata1 = pushEntitiesUp(state, Blocks.DIRT.defaultBlockState(), world, pos); - - world.setBlockAndUpdate(pos, iblockdata1); -@@ -125,19 +154,28 @@ - } - - private static boolean isNearWater(LevelReader world, BlockPos pos) { -- Iterator iterator = BlockPos.betweenClosed(pos.offset(-4, 0, -4), pos.offset(4, 1, 4)).iterator(); -+ // Paper start - Perf: remove abstract block iteration -+ int xOff = pos.getX(); -+ int yOff = pos.getY(); -+ int zOff = pos.getZ(); - -- BlockPos blockposition1; -- -- do { -- if (!iterator.hasNext()) { -- return false; -+ for (int dz = -4; dz <= 4; ++dz) { -+ int z = dz + zOff; -+ for (int dx = -4; dx <= 4; ++dx) { -+ int x = xOff + dx; -+ for (int dy = 0; dy <= 1; ++dy) { -+ int y = dy + yOff; -+ net.minecraft.world.level.chunk.LevelChunk chunk = (net.minecraft.world.level.chunk.LevelChunk)world.getChunk(x >> 4, z >> 4); -+ net.minecraft.world.level.material.FluidState fluid = chunk.getBlockStateFinal(x, y, z).getFluidState(); -+ if (fluid.is(FluidTags.WATER)) { -+ return true; -+ } -+ } - } -+ } - -- blockposition1 = (BlockPos) iterator.next(); -- } while (!world.getFluidState(blockposition1).is(FluidTags.WATER)); -- -- return true; -+ return false; -+ // Paper end - Perf: remove abstract block iteration - } - - @Override diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/FenceGateBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/FenceGateBlock.java.patch deleted file mode 100644 index 78872a0616..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/FenceGateBlock.java.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- a/net/minecraft/world/level/block/FenceGateBlock.java -+++ b/net/minecraft/world/level/block/FenceGateBlock.java -@@ -173,6 +173,17 @@ - protected void neighborChanged(BlockState state, Level world, BlockPos pos, Block sourceBlock, @Nullable Orientation wireOrientation, boolean notify) { - if (!world.isClientSide) { - boolean flag1 = world.hasNeighborSignal(pos); -+ // CraftBukkit start -+ boolean oldPowered = state.getValue(FenceGateBlock.POWERED); -+ if (oldPowered != flag1) { -+ int newPower = flag1 ? 15 : 0; -+ int oldPower = oldPowered ? 15 : 0; -+ org.bukkit.block.Block bukkitBlock = org.bukkit.craftbukkit.block.CraftBlock.at(world, pos); -+ org.bukkit.event.block.BlockRedstoneEvent eventRedstone = new org.bukkit.event.block.BlockRedstoneEvent(bukkitBlock, oldPower, newPower); -+ world.getCraftServer().getPluginManager().callEvent(eventRedstone); -+ flag1 = eventRedstone.getNewCurrent() > 0; -+ } -+ // CraftBukkit end - - if ((Boolean) state.getValue(FenceGateBlock.POWERED) != flag1) { - world.setBlock(pos, (BlockState) ((BlockState) state.setValue(FenceGateBlock.POWERED, flag1)).setValue(FenceGateBlock.OPEN, flag1), 2); diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/FireBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/FireBlock.java.patch deleted file mode 100644 index 5d840efc2e..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/FireBlock.java.patch +++ /dev/null @@ -1,205 +0,0 @@ ---- a/net/minecraft/world/level/block/FireBlock.java -+++ b/net/minecraft/world/level/block/FireBlock.java -@@ -14,6 +14,7 @@ - import net.minecraft.tags.BiomeTags; - import net.minecraft.util.RandomSource; - import net.minecraft.world.item.context.BlockPlaceContext; -+import net.minecraft.world.item.context.UseOnContext; - import net.minecraft.world.level.BlockGetter; - import net.minecraft.world.level.GameRules; - import net.minecraft.world.level.Level; -@@ -28,6 +29,12 @@ - import net.minecraft.world.phys.shapes.CollisionContext; - import net.minecraft.world.phys.shapes.Shapes; - import net.minecraft.world.phys.shapes.VoxelShape; -+import org.bukkit.craftbukkit.block.CraftBlockState; -+import org.bukkit.craftbukkit.block.CraftBlockStates; -+import org.bukkit.craftbukkit.event.CraftEventFactory; -+import org.bukkit.event.block.BlockBurnEvent; -+import org.bukkit.event.block.BlockFadeEvent; -+// CraftBukkit end - - public class FireBlock extends BaseFireBlock { - -@@ -100,7 +107,25 @@ - - @Override - protected BlockState updateShape(BlockState state, LevelReader world, ScheduledTickAccess tickView, BlockPos pos, Direction direction, BlockPos neighborPos, BlockState neighborState, RandomSource random) { -- return this.canSurvive(state, world, pos) ? this.getStateWithAge(world, pos, (Integer) state.getValue(FireBlock.AGE)) : Blocks.AIR.defaultBlockState(); -+ // CraftBukkit start -+ if (!(world instanceof ServerLevel)) return this.canSurvive(state, world, pos) ? (BlockState) this.getStateWithAge(world, pos, (Integer) state.getValue(FireBlock.AGE)) : Blocks.AIR.defaultBlockState(); // Paper - don't fire events in world generation -+ if (!this.canSurvive(state, world, pos)) { -+ // Suppress during worldgen -+ if (!(world instanceof Level world1)) { -+ return Blocks.AIR.defaultBlockState(); -+ } -+ CraftBlockState blockState = CraftBlockStates.getBlockState(world1, pos); -+ blockState.setData(Blocks.AIR.defaultBlockState()); -+ -+ BlockFadeEvent event = new BlockFadeEvent(blockState.getBlock(), blockState); -+ world1.getCraftServer().getPluginManager().callEvent(event); -+ -+ if (!event.isCancelled()) { -+ return blockState.getHandle(); -+ } -+ } -+ return this.getStateWithAge(world, pos, (Integer) state.getValue(FireBlock.AGE)); // Paper - don't fire events in world generation; diff on change, see "don't fire events in world generation" -+ // CraftBukkit end - } - - @Override -@@ -146,10 +171,10 @@ - - @Override - protected void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { -- world.scheduleTick(pos, (Block) this, FireBlock.getFireTickDelay(world.random)); -+ world.scheduleTick(pos, (Block) this, FireBlock.getFireTickDelay(world)); // Paper - Add fire-tick-delay option - if (world.getGameRules().getBoolean(GameRules.RULE_DOFIRETICK)) { - if (!state.canSurvive(world, pos)) { -- world.removeBlock(pos, false); -+ this.fireExtinguished(world, pos); // CraftBukkit - invalid place location - } - - BlockState iblockdata1 = world.getBlockState(pos.below()); -@@ -157,7 +182,7 @@ - int i = (Integer) state.getValue(FireBlock.AGE); - - if (!flag && world.isRaining() && this.isNearRain(world, pos) && random.nextFloat() < 0.2F + (float) i * 0.03F) { -- world.removeBlock(pos, false); -+ this.fireExtinguished(world, pos); // CraftBukkit - extinguished by rain - } else { - int j = Math.min(15, i + random.nextInt(3) / 2); - -@@ -171,14 +196,14 @@ - BlockPos blockposition1 = pos.below(); - - if (!world.getBlockState(blockposition1).isFaceSturdy(world, blockposition1, Direction.UP) || i > 3) { -- world.removeBlock(pos, false); -+ this.fireExtinguished(world, pos); // CraftBukkit - } - - return; - } - - if (i == 15 && random.nextInt(4) == 0 && !this.canBurn(world.getBlockState(pos.below()))) { -- world.removeBlock(pos, false); -+ this.fireExtinguished(world, pos); // CraftBukkit - return; - } - } -@@ -186,12 +211,14 @@ - boolean flag1 = world.getBiome(pos).is(BiomeTags.INCREASED_FIRE_BURNOUT); - int k = flag1 ? -50 : 0; - -- this.checkBurnOut(world, pos.east(), 300 + k, random, i); -- this.checkBurnOut(world, pos.west(), 300 + k, random, i); -- this.checkBurnOut(world, pos.below(), 250 + k, random, i); -- this.checkBurnOut(world, pos.above(), 250 + k, random, i); -- this.checkBurnOut(world, pos.north(), 300 + k, random, i); -- this.checkBurnOut(world, pos.south(), 300 + k, random, i); -+ // CraftBukkit start - add source blockposition to burn calls -+ this.trySpread(world, pos.east(), 300 + k, random, i, pos); -+ this.trySpread(world, pos.west(), 300 + k, random, i, pos); -+ this.trySpread(world, pos.below(), 250 + k, random, i, pos); -+ this.trySpread(world, pos.above(), 250 + k, random, i, pos); -+ this.trySpread(world, pos.north(), 300 + k, random, i, pos); -+ this.trySpread(world, pos.south(), 300 + k, random, i, pos); -+ // CraftBukkit end - BlockPos.MutableBlockPos blockposition_mutableblockposition = new BlockPos.MutableBlockPos(); - - for (int l = -1; l <= 1; ++l) { -@@ -217,7 +244,15 @@ - if (i2 > 0 && random.nextInt(k1) <= i2 && (!world.isRaining() || !this.isNearRain(world, blockposition_mutableblockposition))) { - int j2 = Math.min(15, i + random.nextInt(5) / 4); - -- world.setBlock(blockposition_mutableblockposition, this.getStateWithAge(world, blockposition_mutableblockposition, j2), 3); -+ // CraftBukkit start - Call to stop spread of fire -+ if (world.getBlockState(blockposition_mutableblockposition).getBlock() != Blocks.FIRE) { -+ if (CraftEventFactory.callBlockIgniteEvent(world, blockposition_mutableblockposition, pos).isCancelled()) { -+ continue; -+ } -+ -+ CraftEventFactory.handleBlockSpreadEvent(world, pos, blockposition_mutableblockposition, this.getStateWithAge(world, blockposition_mutableblockposition, j2), 3); // CraftBukkit -+ } -+ // CraftBukkit end - } - } - } -@@ -241,24 +276,47 @@ - return state.hasProperty(BlockStateProperties.WATERLOGGED) && (Boolean) state.getValue(BlockStateProperties.WATERLOGGED) ? 0 : this.igniteOdds.getInt(state.getBlock()); - } - -- private void checkBurnOut(Level world, BlockPos pos, int spreadFactor, RandomSource random, int currentAge) { -- int k = this.getBurnOdds(world.getBlockState(pos)); -+ private void trySpread(Level world, BlockPos blockposition, int i, RandomSource randomsource, int j, BlockPos sourceposition) { // CraftBukkit add sourceposition -+ int k = this.getBurnOdds(world.getBlockState(blockposition)); - -- if (random.nextInt(spreadFactor) < k) { -- BlockState iblockdata = world.getBlockState(pos); -+ if (randomsource.nextInt(i) < k) { -+ BlockState iblockdata = world.getBlockState(blockposition); - -- if (random.nextInt(currentAge + 10) < 5 && !world.isRainingAt(pos)) { -- int l = Math.min(currentAge + random.nextInt(5) / 4, 15); -+ // CraftBukkit start -+ org.bukkit.block.Block theBlock = world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()); -+ org.bukkit.block.Block sourceBlock = world.getWorld().getBlockAt(sourceposition.getX(), sourceposition.getY(), sourceposition.getZ()); - -- world.setBlock(pos, this.getStateWithAge(world, pos, l), 3); -+ BlockBurnEvent event = new BlockBurnEvent(theBlock, sourceBlock); -+ world.getCraftServer().getPluginManager().callEvent(event); -+ -+ if (event.isCancelled()) { -+ return; -+ } -+ -+ if (iblockdata.getBlock() instanceof TntBlock && !CraftEventFactory.callTNTPrimeEvent(world, blockposition, org.bukkit.event.block.TNTPrimeEvent.PrimeCause.FIRE, null, sourceposition)) { -+ return; -+ } -+ // CraftBukkit end -+ -+ if (randomsource.nextInt(j + 10) < 5 && !world.isRainingAt(blockposition)) { -+ int l = Math.min(j + randomsource.nextInt(5) / 4, 15); -+ -+ world.setBlock(blockposition, this.getStateWithAge(world, blockposition, l), 3); - } else { -- world.removeBlock(pos, false); -+ if(iblockdata.getBlock() != Blocks.TNT) world.removeBlock(blockposition, false); // Paper - TNTPrimeEvent; We might be cancelling it below, move the setAir down - } - - Block block = iblockdata.getBlock(); - - if (block instanceof TntBlock) { -- TntBlock.explode(world, pos); -+ // Paper start - TNTPrimeEvent -+ org.bukkit.block.Block tntBlock = org.bukkit.craftbukkit.block.CraftBlock.at(world, blockposition); -+ if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.FIRE, null).callEvent()) { -+ return; -+ } -+ world.removeBlock(blockposition, false); -+ // Paper end - TNTPrimeEvent -+ TntBlock.explode(world, blockposition); - } - } - -@@ -310,13 +368,15 @@ - } - - @Override -- protected void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) { -- super.onPlace(state, world, pos, oldState, notify); -- world.scheduleTick(pos, (Block) this, FireBlock.getFireTickDelay(world.random)); -+ // CraftBukkit start - context -+ protected void onPlace(BlockState iblockdata, Level world, BlockPos blockposition, BlockState iblockdata1, boolean flag, UseOnContext context) { -+ super.onPlace(iblockdata, world, blockposition, iblockdata1, flag, context); -+ // CraftBukkit end -+ world.scheduleTick(blockposition, (Block) this, FireBlock.getFireTickDelay(world)); // Paper - Add fire-tick-delay option - } - -- private static int getFireTickDelay(RandomSource random) { -- return 30 + random.nextInt(10); -+ private static int getFireTickDelay(Level world) { // Paper - Add fire-tick-delay option -+ return world.paperConfig().environment.fireTickDelay + world.random.nextInt(10); // Paper - Add fire-tick-delay option - } - - @Override diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/FrogspawnBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/FrogspawnBlock.java.patch deleted file mode 100644 index c5fefd2f6b..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/FrogspawnBlock.java.patch +++ /dev/null @@ -1,31 +0,0 @@ ---- a/net/minecraft/world/level/block/FrogspawnBlock.java -+++ b/net/minecraft/world/level/block/FrogspawnBlock.java -@@ -89,6 +89,7 @@ - - @Override - protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { -+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent - if (entity.getType().equals(EntityType.FALLING_BLOCK)) { - this.destroyBlock(world, pos); - } -@@ -101,6 +102,11 @@ - } - - private void hatchFrogspawn(ServerLevel world, BlockPos pos, RandomSource random) { -+ // Paper start - Call BlockFadeEvent -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, pos, Blocks.AIR.defaultBlockState()).isCancelled()) { -+ return; -+ } -+ // Paper end - Call BlockFadeEvent - this.destroyBlock(world, pos); - world.playSound(null, pos, SoundEvents.FROGSPAWN_HATCH, SoundSource.BLOCKS, 1.0F, 1.0F); - this.spawnTadpoles(world, pos, random); -@@ -121,7 +127,7 @@ - int k = random.nextInt(1, 361); - tadpole.moveTo(d, (double)pos.getY() - 0.5, e, (float)k, 0.0F); - tadpole.setPersistenceRequired(); -- world.addFreshEntity(tadpole); -+ world.addFreshEntity(tadpole, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.EGG); // Paper - use correct spawn reason - } - } - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/FrostedIceBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/FrostedIceBlock.java.patch deleted file mode 100644 index 9d1efc3454..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/FrostedIceBlock.java.patch +++ /dev/null @@ -1,24 +0,0 @@ ---- a/net/minecraft/world/level/block/FrostedIceBlock.java -+++ b/net/minecraft/world/level/block/FrostedIceBlock.java -@@ -42,6 +42,7 @@ - - @Override - protected void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { -+ if (!world.paperConfig().environment.frostedIce.enabled) return; // Paper - Frosted ice options - if ((random.nextInt(3) == 0 || this.fewerNeigboursThan(world, pos, 4)) - && world.getMaxLocalRawBrightness(pos) > 11 - state.getValue(AGE) - state.getLightBlock() - && this.slightlyMelt(state, world, pos)) { -@@ -51,11 +52,11 @@ - mutableBlockPos.setWithOffset(pos, direction); - BlockState blockState = world.getBlockState(mutableBlockPos); - if (blockState.is(this) && !this.slightlyMelt(blockState, world, mutableBlockPos)) { -- world.scheduleTick(mutableBlockPos, this, Mth.nextInt(random, 20, 40)); -+ world.scheduleTick(mutableBlockPos, this, Mth.nextInt(random, world.paperConfig().environment.frostedIce.delay.min, world.paperConfig().environment.frostedIce.delay.max)); // Paper - Frosted ice options - } - } - } else { -- world.scheduleTick(pos, this, Mth.nextInt(random, 20, 40)); -+ world.scheduleTick(pos, this, Mth.nextInt(random, world.paperConfig().environment.frostedIce.delay.min, world.paperConfig().environment.frostedIce.delay.max)); // Paper - Frosted ice options - } - } - diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/FungusBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/FungusBlock.java.patch deleted file mode 100644 index 6508c8df14..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/FungusBlock.java.patch +++ /dev/null @@ -1,16 +0,0 @@ ---- a/net/minecraft/world/level/block/FungusBlock.java -+++ b/net/minecraft/world/level/block/FungusBlock.java -@@ -74,6 +74,13 @@ - @Override - public void performBonemeal(ServerLevel world, RandomSource random, BlockPos pos, BlockState state) { - this.getFeature(world).ifPresent((holder) -> { -+ // CraftBukkit start -+ if (this == Blocks.WARPED_FUNGUS) { -+ SaplingBlock.treeType = org.bukkit.TreeType.WARPED_FUNGUS; -+ } else if (this == Blocks.CRIMSON_FUNGUS) { -+ SaplingBlock.treeType = org.bukkit.TreeType.CRIMSON_FUNGUS; -+ } -+ // CraftBukkit end - ((ConfiguredFeature) holder.value()).place(world, world.getChunkSource().getGenerator(), random, pos); - }); - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/GrindstoneBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/GrindstoneBlock.java.patch deleted file mode 100644 index 860a309048..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/GrindstoneBlock.java.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- a/net/minecraft/world/level/block/GrindstoneBlock.java -+++ b/net/minecraft/world/level/block/GrindstoneBlock.java -@@ -152,8 +152,9 @@ - @Override - protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { - if (!world.isClientSide) { -- player.openMenu(state.getMenuProvider(world, pos)); -+ if (player.openMenu(state.getMenuProvider(world, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation - player.awardStat(Stats.INTERACT_WITH_GRINDSTONE); -+ } // Paper - Fix InventoryOpenEvent cancellation - } - - return InteractionResult.SUCCESS; diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/GrowingPlantHeadBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/GrowingPlantHeadBlock.java.patch deleted file mode 100644 index b55ee5aef9..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/GrowingPlantHeadBlock.java.patch +++ /dev/null @@ -1,39 +0,0 @@ ---- a/net/minecraft/world/level/block/GrowingPlantHeadBlock.java -+++ b/net/minecraft/world/level/block/GrowingPlantHeadBlock.java -@@ -44,16 +44,34 @@ - - @Override - protected void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { -- if ((Integer) state.getValue(GrowingPlantHeadBlock.AGE) < 25 && random.nextDouble() < this.growPerTickProbability) { -+ // Spigot start -+ int modifier; -+ if (this == Blocks.KELP) { -+ modifier = world.spigotConfig.kelpModifier; -+ } else if (this == Blocks.TWISTING_VINES) { -+ modifier = world.spigotConfig.twistingVinesModifier; -+ } else if (this == Blocks.WEEPING_VINES) { -+ modifier = world.spigotConfig.weepingVinesModifier; -+ } else { -+ modifier = world.spigotConfig.caveVinesModifier; -+ } -+ if ((Integer) state.getValue(GrowingPlantHeadBlock.AGE) < 25 && random.nextDouble() < ((modifier / 100.0D) * this.growPerTickProbability)) { // Spigot - SPIGOT-7159: Better modifier resolution -+ // Spigot end - BlockPos blockposition1 = pos.relative(this.growthDirection); - - if (this.canGrowInto(world.getBlockState(blockposition1))) { -- world.setBlockAndUpdate(blockposition1, this.getGrowIntoState(state, world.random)); -+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(world, pos, blockposition1, this.getGrowIntoState(state, world.random, world)); // CraftBukkit // Paper - Fix Spigot growth modifiers - } - } - - } - -+ // Paper start - Fix Spigot growth modifiers -+ protected BlockState getGrowIntoState(BlockState state, RandomSource random, @javax.annotation.Nullable Level level) { -+ return this.getGrowIntoState(state, random); -+ } -+ // Paper end - Fix Spigot growth modifiers -+ - protected BlockState getGrowIntoState(BlockState state, RandomSource random) { - return (BlockState) state.cycle(GrowingPlantHeadBlock.AGE); - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/IceBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/IceBlock.java.patch deleted file mode 100644 index 003b651052..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/IceBlock.java.patch +++ /dev/null @@ -1,30 +0,0 @@ ---- a/net/minecraft/world/level/block/IceBlock.java -+++ b/net/minecraft/world/level/block/IceBlock.java -@@ -34,8 +34,13 @@ - } - - @Override -- public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool) { -- super.playerDestroy(world, player, pos, state, blockEntity, tool); -+ public void playerDestroy(Level world, Player player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack tool, boolean includeDrops, boolean dropExp) { // Paper - fix drops not preventing stats/food exhaustion -+ super.playerDestroy(world, player, pos, state, blockEntity, tool, includeDrops, dropExp); // Paper - fix drops not preventing stats/food exhaustion -+ // Paper start - Improve Block#breakNaturally API -+ this.afterDestroy(world, pos, tool); -+ } -+ public void afterDestroy(Level world, BlockPos pos, ItemStack tool) { -+ // Paper end - Improve Block#breakNaturally API - if (!EnchantmentHelper.hasTag(tool, EnchantmentTags.PREVENTS_ICE_MELTING)) { - if (world.dimensionType().ultraWarm()) { - world.removeBlock(pos, false); -@@ -60,6 +65,11 @@ - } - - protected void melt(BlockState state, Level world, BlockPos pos) { -+ // CraftBukkit start -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(world, pos, world.dimensionType().ultraWarm() ? Blocks.AIR.defaultBlockState() : Blocks.WATER.defaultBlockState()).isCancelled()) { -+ return; -+ } -+ // CraftBukkit end - if (world.dimensionType().ultraWarm()) { - world.removeBlock(pos, false); - } else { diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/InfestedBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/InfestedBlock.java.patch deleted file mode 100644 index 49d54e7dd2..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/InfestedBlock.java.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- a/net/minecraft/world/level/block/InfestedBlock.java -+++ b/net/minecraft/world/level/block/InfestedBlock.java -@@ -19,6 +19,7 @@ - import net.minecraft.world.level.block.state.BlockBehaviour; - import net.minecraft.world.level.block.state.BlockState; - import net.minecraft.world.level.block.state.properties.Property; -+import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; // CraftBukkit - - public class InfestedBlock extends Block { - -@@ -54,7 +55,7 @@ - - if (entitysilverfish != null) { - entitysilverfish.moveTo((double) pos.getX() + 0.5D, (double) pos.getY(), (double) pos.getZ() + 0.5D, 0.0F, 0.0F); -- world.addFreshEntity(entitysilverfish); -+ world.addFreshEntity(entitysilverfish, SpawnReason.SILVERFISH_BLOCK); // CraftBukkit - add SpawnReason - entitysilverfish.spawnAnim(); - } - diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/LayeredCauldronBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/LayeredCauldronBlock.java.patch deleted file mode 100644 index 67743248ac..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/LayeredCauldronBlock.java.patch +++ /dev/null @@ -1,127 +0,0 @@ ---- a/net/minecraft/world/level/block/LayeredCauldronBlock.java -+++ b/net/minecraft/world/level/block/LayeredCauldronBlock.java -@@ -17,6 +17,11 @@ - import net.minecraft.world.level.gameevent.GameEvent; - import net.minecraft.world.level.material.Fluid; - import net.minecraft.world.level.material.Fluids; -+// CraftBukkit start -+import org.bukkit.craftbukkit.block.CraftBlockState; -+import org.bukkit.craftbukkit.block.CraftBlockStates; -+import org.bukkit.event.block.CauldronLevelChangeEvent; -+// CraftBukkit end - - public class LayeredCauldronBlock extends AbstractCauldronBlock { - -@@ -62,41 +67,86 @@ - - @Override - protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { -+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent - if (world instanceof ServerLevel worldserver) { - if (entity.isOnFire() && this.isEntityInsideContent(state, pos, entity)) { -- entity.clearFire(); -- if (entity.mayInteract(worldserver, pos)) { -- this.handleEntityOnFireInside(state, world, pos); -+ // CraftBukkit start - moved down -+ // entity.clearFire(); -+ if ((entity instanceof net.minecraft.world.entity.player.Player || worldserver.getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_MOBGRIEFING)) && entity.mayInteract(worldserver, pos)) { // Paper - Fixes MC-248588 -+ if (this.handleEntityOnFireInsideWithEvent(state, world, pos, entity)) { // Paper - fix powdered snow cauldron extinguishing entities -+ entity.clearFire(); -+ } -+ // CraftBukkit end - } - } - } - - } - -- private void handleEntityOnFireInside(BlockState state, Level world, BlockPos pos) { -+ // CraftBukkit start -+ @io.papermc.paper.annotation.DoNotUse @Deprecated // Paper - fix powdered snow cauldron extinguishing entities; use #handleEntityOnFireInsideWithEvent -+ private boolean handleEntityOnFireInside(BlockState iblockdata, Level world, BlockPos blockposition, Entity entity) { - if (this.precipitationType == Biome.Precipitation.SNOW) { -- LayeredCauldronBlock.lowerFillLevel((BlockState) Blocks.WATER_CAULDRON.defaultBlockState().setValue(LayeredCauldronBlock.LEVEL, (Integer) state.getValue(LayeredCauldronBlock.LEVEL)), world, pos); -+ return LayeredCauldronBlock.lowerFillLevel((BlockState) Blocks.WATER_CAULDRON.defaultBlockState().setValue(LayeredCauldronBlock.LEVEL, (Integer) iblockdata.getValue(LayeredCauldronBlock.LEVEL)), world, blockposition, entity, CauldronLevelChangeEvent.ChangeReason.EXTINGUISH); - } else { -- LayeredCauldronBlock.lowerFillLevel(state, world, pos); -+ return LayeredCauldronBlock.lowerFillLevel(iblockdata, world, blockposition, entity, CauldronLevelChangeEvent.ChangeReason.EXTINGUISH); -+ // CraftBukkit end - } - - } -+ // Paper start - fix powdered snow cauldron extinguishing entities -+ protected boolean handleEntityOnFireInsideWithEvent(BlockState state, Level world, BlockPos pos, Entity entity) { -+ if (this.precipitationType == Biome.Precipitation.SNOW) { -+ return LayeredCauldronBlock.lowerFillLevel((BlockState) Blocks.WATER_CAULDRON.defaultBlockState().setValue(LayeredCauldronBlock.LEVEL, (Integer) state.getValue(LayeredCauldronBlock.LEVEL)), world, pos, entity, CauldronLevelChangeEvent.ChangeReason.EXTINGUISH); -+ } else { -+ return LayeredCauldronBlock.lowerFillLevel(state, world, pos, entity, CauldronLevelChangeEvent.ChangeReason.EXTINGUISH); -+ } -+ } -+ // Paper end - fix powdered snow cauldron extinguishing entities - - public static void lowerFillLevel(BlockState state, Level world, BlockPos pos) { -- int i = (Integer) state.getValue(LayeredCauldronBlock.LEVEL) - 1; -- BlockState iblockdata1 = i == 0 ? Blocks.CAULDRON.defaultBlockState() : (BlockState) state.setValue(LayeredCauldronBlock.LEVEL, i); -+ // CraftBukkit start -+ LayeredCauldronBlock.lowerFillLevel(state, world, pos, null, CauldronLevelChangeEvent.ChangeReason.UNKNOWN); -+ } - -- world.setBlockAndUpdate(pos, iblockdata1); -- world.gameEvent((Holder) GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(iblockdata1)); -+ public static boolean lowerFillLevel(BlockState iblockdata, Level world, BlockPos blockposition, Entity entity, CauldronLevelChangeEvent.ChangeReason reason) { -+ int i = (Integer) iblockdata.getValue(LayeredCauldronBlock.LEVEL) - 1; -+ BlockState iblockdata1 = i == 0 ? Blocks.CAULDRON.defaultBlockState() : (BlockState) iblockdata.setValue(LayeredCauldronBlock.LEVEL, i); -+ -+ return LayeredCauldronBlock.changeLevel(iblockdata, world, blockposition, iblockdata1, entity, reason); - } - -+ // CraftBukkit start -+ // Paper start - Call CauldronLevelChangeEvent -+ public static boolean changeLevel(BlockState iblockdata, Level world, BlockPos blockposition, BlockState newBlock, @javax.annotation.Nullable Entity entity, CauldronLevelChangeEvent.ChangeReason reason) { // Paper - entity is nullable -+ return changeLevel(iblockdata, world, blockposition, newBlock, entity, reason, true); -+ } -+ -+ public static boolean changeLevel(BlockState iblockdata, Level world, BlockPos blockposition, BlockState newBlock, @javax.annotation.Nullable Entity entity, CauldronLevelChangeEvent.ChangeReason reason, boolean sendGameEvent) { // Paper - entity is nullable -+ // Paper end - Call CauldronLevelChangeEvent -+ CraftBlockState newState = CraftBlockStates.getBlockState(world, blockposition); -+ newState.setData(newBlock); -+ -+ CauldronLevelChangeEvent event = new CauldronLevelChangeEvent( -+ world.getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ()), -+ (entity == null) ? null : entity.getBukkitEntity(), reason, newState -+ ); -+ world.getCraftServer().getPluginManager().callEvent(event); -+ if (event.isCancelled()) { -+ return false; -+ } -+ newState.update(true); -+ if (sendGameEvent) world.gameEvent((Holder) GameEvent.BLOCK_CHANGE, blockposition, GameEvent.Context.of(newBlock)); // Paper - Call CauldronLevelChangeEvent -+ return true; -+ } -+ // CraftBukkit end -+ - @Override - public void handlePrecipitation(BlockState state, Level world, BlockPos pos, Biome.Precipitation precipitation) { - if (CauldronBlock.shouldHandlePrecipitation(world, precipitation) && (Integer) state.getValue(LayeredCauldronBlock.LEVEL) != 3 && precipitation == this.precipitationType) { - BlockState iblockdata1 = (BlockState) state.cycle(LayeredCauldronBlock.LEVEL); - -- world.setBlockAndUpdate(pos, iblockdata1); -- world.gameEvent((Holder) GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(iblockdata1)); -+ LayeredCauldronBlock.changeLevel(state, world, pos, iblockdata1, null, CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL); // CraftBukkit - } - } - -@@ -115,8 +165,11 @@ - if (!this.isFull(state)) { - BlockState iblockdata1 = (BlockState) state.setValue(LayeredCauldronBlock.LEVEL, (Integer) state.getValue(LayeredCauldronBlock.LEVEL) + 1); - -- world.setBlockAndUpdate(pos, iblockdata1); -- world.gameEvent((Holder) GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(iblockdata1)); -+ // CraftBukkit start -+ if (!LayeredCauldronBlock.changeLevel(state, world, pos, iblockdata1, null, CauldronLevelChangeEvent.ChangeReason.NATURAL_FILL)) { -+ return; -+ } -+ // CraftBukkit end - world.levelEvent(1047, pos, 0); - } - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/LeavesBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/LeavesBlock.java.patch deleted file mode 100644 index 4e3cc600f3..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/LeavesBlock.java.patch +++ /dev/null @@ -1,25 +0,0 @@ ---- a/net/minecraft/world/level/block/LeavesBlock.java -+++ b/net/minecraft/world/level/block/LeavesBlock.java -@@ -26,6 +26,7 @@ - import net.minecraft.world.level.material.Fluids; - import net.minecraft.world.phys.shapes.Shapes; - import net.minecraft.world.phys.shapes.VoxelShape; -+import org.bukkit.event.block.LeavesDecayEvent; // CraftBukkit - - public class LeavesBlock extends Block implements SimpleWaterloggedBlock { - -@@ -59,6 +60,14 @@ - @Override - protected void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { - if (this.decaying(state)) { -+ // CraftBukkit start -+ LeavesDecayEvent event = new LeavesDecayEvent(world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ())); -+ world.getCraftServer().getPluginManager().callEvent(event); -+ -+ if (event.isCancelled() || world.getBlockState(pos).getBlock() != this) { -+ return; -+ } -+ // CraftBukkit end - dropResources(state, world, pos); - world.removeBlock(pos, false); - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/LecternBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/LecternBlock.java.patch deleted file mode 100644 index a928fea703..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/LecternBlock.java.patch +++ /dev/null @@ -1,69 +0,0 @@ ---- a/net/minecraft/world/level/block/LecternBlock.java -+++ b/net/minecraft/world/level/block/LecternBlock.java -@@ -153,7 +153,24 @@ - BlockEntity tileentity = world.getBlockEntity(pos); - - if (tileentity instanceof LecternBlockEntity tileentitylectern) { -- tileentitylectern.setBook(stack.consumeAndReturn(1, user)); -+ // Paper start - Add PlayerInsertLecternBookEvent -+ ItemStack eventSourcedBookStack = null; -+ if (user instanceof final net.minecraft.server.level.ServerPlayer serverPlayer) { -+ final io.papermc.paper.event.player.PlayerInsertLecternBookEvent event = new io.papermc.paper.event.player.PlayerInsertLecternBookEvent( -+ serverPlayer.getBukkitEntity(), -+ org.bukkit.craftbukkit.block.CraftBlock.at(world, pos), -+ org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(stack.copyWithCount(1)) -+ ); -+ if (!event.callEvent()) return; -+ eventSourcedBookStack = org.bukkit.craftbukkit.inventory.CraftItemStack.unwrap(event.getBook()); -+ } -+ if (eventSourcedBookStack == null) { -+ eventSourcedBookStack = stack.consumeAndReturn(1, user); -+ } else { -+ stack.consume(1, user); -+ } -+ tileentitylectern.setBook(eventSourcedBookStack); -+ // Paper end - Add PlayerInsertLecternBookEvent - LecternBlock.resetBookState(user, world, pos, state, true); - world.playSound((Player) null, pos, SoundEvents.BOOK_PUT, SoundSource.BLOCKS, 1.0F, 1.0F); - } -@@ -175,6 +192,16 @@ - } - - private static void changePowered(Level world, BlockPos pos, BlockState state, boolean powered) { -+ // Paper start - Call BlockRedstoneEvent properly -+ final int currentRedstoneLevel = state.getValue(LecternBlock.POWERED) ? 15 : 0, targetRedstoneLevel = powered ? 15 : 0; -+ if (currentRedstoneLevel != targetRedstoneLevel) { -+ final org.bukkit.event.block.BlockRedstoneEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(world, pos, currentRedstoneLevel, targetRedstoneLevel); -+ -+ if (event.getNewCurrent() != targetRedstoneLevel) { -+ return; -+ } -+ } -+ // Paper end - Call BlockRedstoneEvent properly - world.setBlock(pos, (BlockState) state.setValue(LecternBlock.POWERED, powered), 3); - LecternBlock.updateBelow(world, pos, state); - } -@@ -206,11 +233,12 @@ - } - - private void popBook(BlockState state, Level world, BlockPos pos) { -- BlockEntity tileentity = world.getBlockEntity(pos); -+ BlockEntity tileentity = world.getBlockEntity(pos, false); // CraftBukkit - don't validate, type may be changed already - - if (tileentity instanceof LecternBlockEntity tileentitylectern) { - Direction enumdirection = (Direction) state.getValue(LecternBlock.FACING); - ItemStack itemstack = tileentitylectern.getBook().copy(); -+ if (itemstack.isEmpty()) return; // CraftBukkit - SPIGOT-5500 - float f = 0.25F * (float) enumdirection.getStepX(); - float f1 = 0.25F * (float) enumdirection.getStepZ(); - ItemEntity entityitem = new ItemEntity(world, (double) pos.getX() + 0.5D + (double) f, (double) (pos.getY() + 1), (double) pos.getZ() + 0.5D + (double) f1, itemstack); -@@ -282,8 +310,7 @@ - private void openScreen(Level world, BlockPos pos, Player player) { - BlockEntity tileentity = world.getBlockEntity(pos); - -- if (tileentity instanceof LecternBlockEntity) { -- player.openMenu((LecternBlockEntity) tileentity); -+ if (tileentity instanceof LecternBlockEntity && player.openMenu((LecternBlockEntity) tileentity).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation - player.awardStat(Stats.INTERACT_WITH_LECTERN); - } - diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/LeverBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/LeverBlock.java.patch deleted file mode 100644 index 325443e6f3..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/LeverBlock.java.patch +++ /dev/null @@ -1,31 +0,0 @@ ---- a/net/minecraft/world/level/block/LeverBlock.java -+++ b/net/minecraft/world/level/block/LeverBlock.java -@@ -31,6 +31,7 @@ - import net.minecraft.world.phys.BlockHitResult; - import net.minecraft.world.phys.shapes.CollisionContext; - import net.minecraft.world.phys.shapes.VoxelShape; -+import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit - - public class LeverBlock extends FaceAttachedHorizontalDirectionalBlock { - -@@ -102,6 +103,20 @@ - LeverBlock.makeParticle(iblockdata1, world, pos, 1.0F); - } - } else { -+ // CraftBukkit start - Interact Lever -+ boolean powered = state.getValue(LeverBlock.POWERED); // Old powered state -+ org.bukkit.block.Block block = world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); -+ int old = (powered) ? 15 : 0; -+ int current = (!powered) ? 15 : 0; -+ -+ BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, old, current); -+ world.getCraftServer().getPluginManager().callEvent(eventRedstone); -+ -+ if ((eventRedstone.getNewCurrent() > 0) != (!powered)) { -+ return InteractionResult.SUCCESS; -+ } -+ // CraftBukkit end -+ - this.pull(state, world, pos, (Player) null); - } - diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/LightningRodBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/LightningRodBlock.java.patch deleted file mode 100644 index c97ad7d96c..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/LightningRodBlock.java.patch +++ /dev/null @@ -1,33 +0,0 @@ ---- a/net/minecraft/world/level/block/LightningRodBlock.java -+++ b/net/minecraft/world/level/block/LightningRodBlock.java -@@ -24,6 +24,11 @@ - import net.minecraft.world.level.material.Fluids; - import net.minecraft.world.level.redstone.ExperimentalRedstoneUtils; - -+// CraftBukkit start -+import org.bukkit.craftbukkit.block.CraftBlock; -+import org.bukkit.event.block.BlockRedstoneEvent; -+// CraftBukkit end -+ - public class LightningRodBlock extends RodBlock implements SimpleWaterloggedBlock { - - public static final MapCodec CODEC = simpleCodec(LightningRodBlock::new); -@@ -76,6 +81,18 @@ - } - - public void onLightningStrike(BlockState state, Level world, BlockPos pos) { -+ // CraftBukkit start -+ boolean powered = state.getValue(LightningRodBlock.POWERED); -+ int old = (powered) ? 15 : 0; -+ int current = (!powered) ? 15 : 0; -+ -+ BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(CraftBlock.at(world, pos), old, current); -+ world.getCraftServer().getPluginManager().callEvent(eventRedstone); -+ -+ if (eventRedstone.getNewCurrent() <= 0) { -+ return; -+ } -+ // CraftBukkit end - world.setBlock(pos, (BlockState) state.setValue(LightningRodBlock.POWERED, true), 3); - this.updateNeighbours(state, world, pos); - world.scheduleTick(pos, (Block) this, 8); diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/LiquidBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/LiquidBlock.java.patch deleted file mode 100644 index 42df446a82..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/LiquidBlock.java.patch +++ /dev/null @@ -1,78 +0,0 @@ ---- a/net/minecraft/world/level/block/LiquidBlock.java -+++ b/net/minecraft/world/level/block/LiquidBlock.java -@@ -42,7 +42,7 @@ - public class LiquidBlock extends Block implements BucketPickup { - - private static final Codec FLOWING_FLUID = BuiltInRegistries.FLUID.byNameCodec().comapFlatMap((fluidtype) -> { -- DataResult dataresult; -+ DataResult dataresult; // CraftBukkit - decompile error - - if (fluidtype instanceof FlowingFluid fluidtypeflowing) { - dataresult = DataResult.success(fluidtypeflowing); -@@ -141,11 +141,31 @@ - @Override - protected void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) { - if (this.shouldSpreadLiquid(world, pos, state)) { -- world.scheduleTick(pos, state.getFluidState().getType(), this.fluid.getTickDelay(world)); -+ world.scheduleTick(pos, state.getFluidState().getType(), this.getFlowSpeed(world, pos)); // Paper - Configurable speed for water flowing over lava - } - - } - -+ // Paper start - Configurable speed for water flowing over lava -+ public int getFlowSpeed(Level world, BlockPos blockposition) { -+ if (net.minecraft.core.registries.BuiltInRegistries.FLUID.wrapAsHolder(this.fluid).is(FluidTags.WATER)) { -+ if ( -+ isLava(world, blockposition.north(1)) || -+ isLava(world, blockposition.south(1)) || -+ isLava(world, blockposition.west(1)) || -+ isLava(world, blockposition.east(1)) -+ ) { -+ return world.paperConfig().environment.waterOverLavaFlowSpeed; -+ } -+ } -+ return this.fluid.getTickDelay(world); -+ } -+ private static boolean isLava(Level world, BlockPos blockPos) { -+ final FluidState fluidState = world.getFluidIfLoaded(blockPos); -+ return fluidState != null && fluidState.is(FluidTags.LAVA); -+ } -+ // Paper end - Configurable speed for water flowing over lava -+ - @Override - protected BlockState updateShape(BlockState state, LevelReader world, ScheduledTickAccess tickView, BlockPos pos, Direction direction, BlockPos neighborPos, BlockState neighborState, RandomSource random) { - if (state.getFluidState().isSource() || neighborState.getFluidState().isSource()) { -@@ -158,7 +178,7 @@ - @Override - protected void neighborChanged(BlockState state, Level world, BlockPos pos, Block sourceBlock, @Nullable Orientation wireOrientation, boolean notify) { - if (this.shouldSpreadLiquid(world, pos, state)) { -- world.scheduleTick(pos, state.getFluidState().getType(), this.fluid.getTickDelay(world)); -+ world.scheduleTick(pos, state.getFluidState().getType(), this.getFlowSpeed(world, pos)); // Paper - Configurable speed for water flowing over lava - } - - } -@@ -175,14 +195,20 @@ - if (world.getFluidState(blockposition1).is(FluidTags.WATER)) { - Block block = world.getFluidState(pos).isSource() ? Blocks.OBSIDIAN : Blocks.COBBLESTONE; - -- world.setBlockAndUpdate(pos, block.defaultBlockState()); -- this.fizz(world, pos); -+ // CraftBukkit start -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(world, pos, block.defaultBlockState())) { -+ this.fizz(world, pos); -+ } -+ // CraftBukkit end - return false; - } - - if (flag && world.getBlockState(blockposition1).is(Blocks.BLUE_ICE)) { -- world.setBlockAndUpdate(pos, Blocks.BASALT.defaultBlockState()); -- this.fizz(world, pos); -+ // CraftBukkit start -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(world, pos, Blocks.BASALT.defaultBlockState())) { -+ this.fizz(world, pos); -+ } -+ // CraftBukkit end - return false; - } - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/LoomBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/LoomBlock.java.patch deleted file mode 100644 index 9fc3631803..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/LoomBlock.java.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- a/net/minecraft/world/level/block/LoomBlock.java -+++ b/net/minecraft/world/level/block/LoomBlock.java -@@ -33,8 +33,9 @@ - @Override - protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { - if (!world.isClientSide) { -- player.openMenu(state.getMenuProvider(world, pos)); -+ if (player.openMenu(state.getMenuProvider(world, pos)).isPresent()) { // Paper - Fix InventoryOpenEvent cancellation - player.awardStat(Stats.INTERACT_WITH_LOOM); -+ } // Paper - Fix InventoryOpenEvent cancellation - } - - return InteractionResult.SUCCESS; diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/MagmaBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/MagmaBlock.java.patch deleted file mode 100644 index 6febd2458e..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/MagmaBlock.java.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- a/net/minecraft/world/level/block/MagmaBlock.java -+++ b/net/minecraft/world/level/block/MagmaBlock.java -@@ -30,7 +30,7 @@ - @Override - public void stepOn(Level world, BlockPos pos, BlockState state, Entity entity) { - if (!entity.isSteppingCarefully() && entity instanceof LivingEntity) { -- entity.hurt(world.damageSources().hotFloor(), 1.0F); -+ entity.hurt(world.damageSources().hotFloor().directBlock(world, pos), 1.0F); // CraftBukkit - } - - super.stepOn(world, pos, state, entity); diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/MultifaceSpreader.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/MultifaceSpreader.java.patch deleted file mode 100644 index 31dd40a615..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/MultifaceSpreader.java.patch +++ /dev/null @@ -1,43 +0,0 @@ ---- a/net/minecraft/world/level/block/MultifaceSpreader.java -+++ b/net/minecraft/world/level/block/MultifaceSpreader.java -@@ -156,7 +156,7 @@ - world.getChunk(growPos.pos()).markPosForPostprocessing(growPos.pos()); - } - -- return world.setBlock(growPos.pos(), iblockdata1, 2); -+ return org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(world, growPos.source(), growPos.pos(), iblockdata1, 2); // CraftBukkit - } else { - return false; - } -@@ -174,19 +174,19 @@ - SAME_POSITION { - @Override - public MultifaceSpreader.SpreadPos getSpreadPos(BlockPos pos, Direction newDirection, Direction oldDirection) { -- return new MultifaceSpreader.SpreadPos(pos, newDirection); -+ return new MultifaceSpreader.SpreadPos(pos, newDirection, pos); // CraftBukkit - } - }, - SAME_PLANE { - @Override - public MultifaceSpreader.SpreadPos getSpreadPos(BlockPos pos, Direction newDirection, Direction oldDirection) { -- return new MultifaceSpreader.SpreadPos(pos.relative(newDirection), oldDirection); -+ return new MultifaceSpreader.SpreadPos(pos.relative(newDirection), oldDirection, pos); // CraftBukkit - } - }, - WRAP_AROUND { - @Override - public MultifaceSpreader.SpreadPos getSpreadPos(BlockPos pos, Direction newDirection, Direction oldDirection) { -- return new MultifaceSpreader.SpreadPos(pos.relative(newDirection).relative(oldDirection), newDirection.getOpposite()); -+ return new MultifaceSpreader.SpreadPos(pos.relative(newDirection).relative(oldDirection), newDirection.getOpposite(), pos); // CraftBukkit - } - }; - -@@ -195,7 +195,7 @@ - public abstract MultifaceSpreader.SpreadPos getSpreadPos(BlockPos pos, Direction newDirection, Direction oldDirection); - } - -- public static record SpreadPos(BlockPos pos, Direction face) { -+ public static record SpreadPos(BlockPos pos, Direction face, BlockPos source) { // CraftBukkit - - } - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/MushroomBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/MushroomBlock.java.patch deleted file mode 100644 index 7fa4b44f28..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/MushroomBlock.java.patch +++ /dev/null @@ -1,46 +0,0 @@ ---- a/net/minecraft/world/level/block/MushroomBlock.java -+++ b/net/minecraft/world/level/block/MushroomBlock.java -@@ -19,6 +19,9 @@ - import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; - import net.minecraft.world.phys.shapes.CollisionContext; - import net.minecraft.world.phys.shapes.VoxelShape; -+// CraftBukkit start -+import org.bukkit.TreeType; -+// CraftBukkit end - - public class MushroomBlock extends BushBlock implements BonemealableBlock { - -@@ -48,7 +51,7 @@ - - @Override - protected void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { -- if (random.nextInt(25) == 0) { -+ if (random.nextFloat() < (world.spigotConfig.mushroomModifier / (100.0f * 25))) { // Spigot - SPIGOT-7159: Better modifier resolution - int i = 5; - boolean flag = true; - Iterator iterator = BlockPos.betweenClosed(pos.offset(-4, -1, -4), pos.offset(4, 1, 4)).iterator(); -@@ -65,6 +68,7 @@ - } - - BlockPos blockposition2 = pos.offset(random.nextInt(3) - 1, random.nextInt(2) - random.nextInt(2), random.nextInt(3) - 1); -+ final BlockPos sourcePos = pos; // Paper - Use correct source for mushroom block spread event - - for (int j = 0; j < 4; ++j) { - if (world.isEmptyBlock(blockposition2) && state.canSurvive(world, blockposition2)) { -@@ -75,7 +79,7 @@ - } - - if (world.isEmptyBlock(blockposition2) && state.canSurvive(world, blockposition2)) { -- world.setBlock(blockposition2, state, 2); -+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(world, sourcePos, blockposition2, state, 2); // CraftBukkit // Paper - Use correct source for mushroom block spread event - } - } - -@@ -101,6 +105,7 @@ - return false; - } else { - world.removeBlock(pos, false); -+ SaplingBlock.treeType = (this == Blocks.BROWN_MUSHROOM) ? TreeType.BROWN_MUSHROOM : TreeType.RED_MUSHROOM; // CraftBukkit - if (((ConfiguredFeature) ((Holder) optional.get()).value()).place(world, world.getChunkSource().getGenerator(), random, pos)) { - return true; - } else { diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/NetherPortalBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/NetherPortalBlock.java.patch deleted file mode 100644 index 5b83537d76..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/NetherPortalBlock.java.patch +++ /dev/null @@ -1,163 +0,0 @@ ---- a/net/minecraft/world/level/block/NetherPortalBlock.java -+++ b/net/minecraft/world/level/block/NetherPortalBlock.java -@@ -32,12 +32,19 @@ - import net.minecraft.world.level.block.state.properties.EnumProperty; - import net.minecraft.world.level.border.WorldBorder; - import net.minecraft.world.level.dimension.DimensionType; -+import net.minecraft.world.level.dimension.LevelStem; - import net.minecraft.world.level.portal.PortalShape; - import net.minecraft.world.level.portal.TeleportTransition; - import net.minecraft.world.phys.Vec3; - import net.minecraft.world.phys.shapes.CollisionContext; - import net.minecraft.world.phys.shapes.VoxelShape; - import org.slf4j.Logger; -+import org.bukkit.craftbukkit.CraftWorld; -+import org.bukkit.craftbukkit.event.CraftPortalEvent; -+import org.bukkit.craftbukkit.util.CraftLocation; -+import org.bukkit.event.entity.EntityPortalEnterEvent; -+import org.bukkit.event.player.PlayerTeleportEvent; -+// CraftBukkit end - - public class NetherPortalBlock extends Block implements Portal { - -@@ -71,16 +78,21 @@ - - @Override - protected void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { -- if (world.dimensionType().natural() && world.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && random.nextInt(2000) < world.getDifficulty().getId()) { -+ if (world.spigotConfig.enableZombiePigmenPortalSpawns && world.dimensionType().natural() && world.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && random.nextInt(2000) < world.getDifficulty().getId()) { // Spigot - while (world.getBlockState(pos).is((Block) this)) { - pos = pos.below(); - } - - if (world.getBlockState(pos).isValidSpawn(world, pos, EntityType.ZOMBIFIED_PIGLIN)) { -- Entity entity = EntityType.ZOMBIFIED_PIGLIN.spawn(world, pos.above(), EntitySpawnReason.STRUCTURE); -+ // CraftBukkit - set spawn reason to NETHER_PORTAL -+ Entity entity = EntityType.ZOMBIFIED_PIGLIN.spawn(world, pos.above(), EntitySpawnReason.STRUCTURE, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NETHER_PORTAL); - - if (entity != null) { - entity.setPortalCooldown(); -+ // Paper start - Add option to nerf pigmen from nether portals -+ entity.fromNetherPortal = true; -+ if (world.paperConfig().entities.behavior.nerfPigmenFromNetherPortals) ((net.minecraft.world.entity.Mob) entity).aware = false; -+ // Paper end - Add option to nerf pigmen from nether portals - Entity entity1 = entity.getVehicle(); - - if (entity1 != null) { -@@ -103,7 +115,13 @@ - - @Override - protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { -+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent - if (entity.canUsePortal(false)) { -+ // CraftBukkit start - Entity in portal -+ EntityPortalEnterEvent event = new EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ()), org.bukkit.PortalType.NETHER); // Paper - add portal type -+ world.getCraftServer().getPluginManager().callEvent(event); -+ if (event.isCancelled()) return; // Paper - make cancellable -+ // CraftBukkit end - entity.setAsInsidePortal(this, pos); - } - -@@ -121,51 +139,80 @@ - @Nullable - @Override - public TeleportTransition getPortalDestination(ServerLevel world, Entity entity, BlockPos pos) { -- ResourceKey resourcekey = world.dimension() == Level.NETHER ? Level.OVERWORLD : Level.NETHER; -+ // CraftBukkit start -+ ResourceKey resourcekey = world.getTypeKey() == LevelStem.NETHER ? Level.OVERWORLD : Level.NETHER; - ServerLevel worldserver1 = world.getServer().getLevel(resourcekey); -+ // Paper start - Add EntityPortalReadyEvent -+ io.papermc.paper.event.entity.EntityPortalReadyEvent portalReadyEvent = new io.papermc.paper.event.entity.EntityPortalReadyEvent(entity.getBukkitEntity(), worldserver1 == null ? null : worldserver1.getWorld(), org.bukkit.PortalType.NETHER); -+ if (!portalReadyEvent.callEvent()) { -+ entity.portalProcess = null; -+ return null; -+ } -+ worldserver1 = portalReadyEvent.getTargetWorld() == null ? null : ((org.bukkit.craftbukkit.CraftWorld) portalReadyEvent.getTargetWorld()).getHandle(); -+ // Paper end - Add EntityPortalReadyEvent - - if (worldserver1 == null) { -- return null; -+ return null; // Paper - keep previous behavior of not firing PlayerTeleportEvent if the target world doesn't exist - } else { -- boolean flag = worldserver1.dimension() == Level.NETHER; -+ boolean flag = worldserver1.getTypeKey() == LevelStem.NETHER; -+ // CraftBukkit end - WorldBorder worldborder = worldserver1.getWorldBorder(); - double d0 = DimensionType.getTeleportationScale(world.dimensionType(), worldserver1.dimensionType()); - BlockPos blockposition1 = worldborder.clampToBounds(entity.getX() * d0, entity.getY(), entity.getZ() * d0); -+ // Paper start - Configurable portal search radius -+ int portalSearchRadius = worldserver1.paperConfig().environment.portalSearchRadius; -+ if (entity.level().paperConfig().environment.portalSearchVanillaDimensionScaling && flag) { // flag = is going to nether -+ portalSearchRadius = (int) (portalSearchRadius / worldserver1.dimensionType().coordinateScale()); -+ } -+ // Paper end - Configurable portal search radius -+ // CraftBukkit start -+ CraftPortalEvent event = entity.callPortalEvent(entity, CraftLocation.toBukkit(blockposition1, worldserver1.getWorld()), PlayerTeleportEvent.TeleportCause.NETHER_PORTAL, portalSearchRadius, worldserver1.paperConfig().environment.portalCreateRadius); // Paper - use custom portal search radius -+ if (event == null) { -+ return null; -+ } -+ worldserver1 = ((CraftWorld) event.getTo().getWorld()).getHandle(); -+ worldborder = worldserver1.getWorldBorder(); -+ blockposition1 = worldborder.clampToBounds(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ()); - -- return this.getExitPortal(worldserver1, entity, pos, blockposition1, flag, worldborder); -+ return this.getExitPortal(worldserver1, entity, pos, blockposition1, flag, worldborder, event.getSearchRadius(), event.getCanCreatePortal(), event.getCreationRadius()); - } - } - - @Nullable -- private TeleportTransition getExitPortal(ServerLevel world, Entity entity, BlockPos pos, BlockPos scaledPos, boolean inNether, WorldBorder worldBorder) { -- Optional optional = world.getPortalForcer().findClosestPortalPosition(scaledPos, inNether, worldBorder); -+ private TeleportTransition getExitPortal(ServerLevel worldserver, Entity entity, BlockPos blockposition, BlockPos blockposition1, boolean flag, WorldBorder worldborder, int searchRadius, boolean canCreatePortal, int createRadius) { -+ Optional optional = worldserver.getPortalForcer().findClosestPortalPosition(blockposition1, worldborder, searchRadius); - BlockUtil.FoundRectangle blockutil_rectangle; - TeleportTransition.PostTeleportTransition teleporttransition_a; - - if (optional.isPresent()) { - BlockPos blockposition2 = (BlockPos) optional.get(); -- BlockState iblockdata = world.getBlockState(blockposition2); -+ BlockState iblockdata = worldserver.getBlockState(blockposition2); - - blockutil_rectangle = BlockUtil.getLargestRectangleAround(blockposition2, (Direction.Axis) iblockdata.getValue(BlockStateProperties.HORIZONTAL_AXIS), 21, Direction.Axis.Y, 21, (blockposition3) -> { -- return world.getBlockState(blockposition3) == iblockdata; -+ return worldserver.getBlockState(blockposition3) == iblockdata; - }); - teleporttransition_a = TeleportTransition.PLAY_PORTAL_SOUND.then((entity1) -> { - entity1.placePortalTicket(blockposition2); - }); -- } else { -- Direction.Axis enumdirection_enumaxis = (Direction.Axis) entity.level().getBlockState(pos).getOptionalValue(NetherPortalBlock.AXIS).orElse(Direction.Axis.X); -- Optional optional1 = world.getPortalForcer().createPortal(scaledPos, enumdirection_enumaxis); -+ } else if (canCreatePortal) { -+ Direction.Axis enumdirection_enumaxis = (Direction.Axis) entity.level().getBlockState(blockposition).getOptionalValue(NetherPortalBlock.AXIS).orElse(Direction.Axis.X); -+ Optional optional1 = worldserver.getPortalForcer().createPortal(blockposition1, enumdirection_enumaxis, entity, createRadius); -+ // CraftBukkit end - - if (optional1.isEmpty()) { -- NetherPortalBlock.LOGGER.error("Unable to create a portal, likely target out of worldborder"); -+ // BlockPortal.LOGGER.error("Unable to create a portal, likely target out of worldborder"); // CraftBukkit - return null; - } - - blockutil_rectangle = (BlockUtil.FoundRectangle) optional1.get(); - teleporttransition_a = TeleportTransition.PLAY_PORTAL_SOUND.then(TeleportTransition.PLACE_PORTAL_TICKET); -+ // CraftBukkit start -+ } else { -+ return null; -+ // CraftBukkit end - } - -- return NetherPortalBlock.getDimensionTransitionFromExit(entity, pos, blockutil_rectangle, world, teleporttransition_a); -+ return NetherPortalBlock.getDimensionTransitionFromExit(entity, blockposition, blockutil_rectangle, worldserver, teleporttransition_a); - } - - private static TeleportTransition getDimensionTransitionFromExit(Entity entity, BlockPos pos, BlockUtil.FoundRectangle exitPortalRectangle, ServerLevel world, TeleportTransition.PostTeleportTransition postDimensionTransition) { -@@ -203,7 +250,7 @@ - Vec3 vec3d1 = new Vec3((double) blockposition.getX() + (flag ? d2 : d4), (double) blockposition.getY() + d3, (double) blockposition.getZ() + (flag ? d4 : d2)); - Vec3 vec3d2 = PortalShape.findCollisionFreePosition(vec3d1, world, entity, entitysize); - -- return new TeleportTransition(world, vec3d2, Vec3.ZERO, (float) i, 0.0F, Relative.union(Relative.DELTA, Relative.ROTATION), postDimensionTransition); -+ return new TeleportTransition(world, vec3d2, Vec3.ZERO, (float) i, 0.0F, Relative.union(Relative.DELTA, Relative.ROTATION), postDimensionTransition, PlayerTeleportEvent.TeleportCause.NETHER_PORTAL); // CraftBukkit - } - - @Override diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/NetherWartBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/NetherWartBlock.java.patch deleted file mode 100644 index 849dc04024..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/NetherWartBlock.java.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- a/net/minecraft/world/level/block/NetherWartBlock.java -+++ b/net/minecraft/world/level/block/NetherWartBlock.java -@@ -52,9 +52,9 @@ - protected void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { - int i = (Integer) state.getValue(NetherWartBlock.AGE); - -- if (i < 3 && random.nextInt(10) == 0) { -+ if (i < 3 && random.nextFloat() < (world.spigotConfig.wartModifier / (100.0f * 10))) { // Spigot - SPIGOT-7159: Better modifier resolution - state = (BlockState) state.setValue(NetherWartBlock.AGE, i + 1); -- world.setBlock(pos, state, 2); -+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(world, pos, state, 2); // CraftBukkit - } - - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/NoteBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/NoteBlock.java.patch deleted file mode 100644 index b1d5c77400..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/NoteBlock.java.patch +++ /dev/null @@ -1,78 +0,0 @@ ---- a/net/minecraft/world/level/block/NoteBlock.java -+++ b/net/minecraft/world/level/block/NoteBlock.java -@@ -68,11 +68,13 @@ - - @Override - public BlockState getStateForPlacement(BlockPlaceContext ctx) { -+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableNoteblockUpdates) return this.defaultBlockState(); // Paper - place without considering instrument - return this.setInstrument(ctx.getLevel(), ctx.getClickedPos(), this.defaultBlockState()); - } - - @Override - protected BlockState updateShape(BlockState state, LevelReader world, ScheduledTickAccess tickView, BlockPos pos, Direction direction, BlockPos neighborPos, BlockState neighborState, RandomSource random) { -+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableNoteblockUpdates) return state; // Paper - prevent noteblock instrument from updating - boolean flag = direction.getAxis() == Direction.Axis.Y; - - return flag ? this.setInstrument(world, pos, state) : super.updateShape(state, world, tickView, pos, direction, neighborPos, neighborState, random); -@@ -80,11 +82,13 @@ - - @Override - protected void neighborChanged(BlockState state, Level world, BlockPos pos, Block sourceBlock, @Nullable Orientation wireOrientation, boolean notify) { -+ if (io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableNoteblockUpdates) return; // Paper - prevent noteblock powered-state from updating - boolean flag1 = world.hasNeighborSignal(pos); - - if (flag1 != (Boolean) state.getValue(NoteBlock.POWERED)) { - if (flag1) { - this.playNote((Entity) null, state, world, pos); -+ state = world.getBlockState(pos); // CraftBukkit - SPIGOT-5617: update in case changed in event - } - - world.setBlock(pos, (BlockState) state.setValue(NoteBlock.POWERED, flag1), 3); -@@ -94,6 +98,13 @@ - - private void playNote(@Nullable Entity entity, BlockState state, Level world, BlockPos pos) { - if (((NoteBlockInstrument) state.getValue(NoteBlock.INSTRUMENT)).worksAboveNoteBlock() || world.getBlockState(pos.above()).isAir()) { -+ // CraftBukkit start -+ // org.bukkit.event.block.NotePlayEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callNotePlayEvent(world, pos, state.getValue(NoteBlock.INSTRUMENT), state.getValue(NoteBlock.NOTE)); -+ // if (event.isCancelled()) { -+ // return; -+ // } -+ // CraftBukkit end -+ // Paper - move NotePlayEvent call to fix instrument/note changes; TODO any way to cancel the game event? - world.blockEvent(pos, this, 0, 0); - world.gameEvent(entity, (Holder) GameEvent.NOTE_BLOCK_PLAY, pos); - } -@@ -108,7 +119,7 @@ - @Override - protected InteractionResult useWithoutItem(BlockState state, Level world, BlockPos pos, Player player, BlockHitResult hit) { - if (!world.isClientSide) { -- state = (BlockState) state.cycle(NoteBlock.NOTE); -+ if (!io.papermc.paper.configuration.GlobalConfiguration.get().blockUpdates.disableNoteblockUpdates) state = (BlockState) state.cycle(NoteBlock.NOTE); // Paper - prevent noteblock note from updating - world.setBlock(pos, state, 3); - this.playNote(player, state, world, pos); - player.awardStat(Stats.TUNE_NOTEBLOCK); -@@ -132,10 +143,14 @@ - @Override - protected boolean triggerEvent(BlockState state, Level world, BlockPos pos, int type, int data) { - NoteBlockInstrument blockpropertyinstrument = (NoteBlockInstrument) state.getValue(NoteBlock.INSTRUMENT); -+ // Paper start - move NotePlayEvent call to fix instrument/note changes -+ org.bukkit.event.block.NotePlayEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callNotePlayEvent(world, pos, blockpropertyinstrument, state.getValue(NOTE)); -+ if (event.isCancelled()) return false; -+ // Paper end - move NotePlayEvent call to fix instrument/note changes - float f; - - if (blockpropertyinstrument.isTunable()) { -- int k = (Integer) state.getValue(NoteBlock.NOTE); -+ int k = event.getNote().getId(); // Paper - move NotePlayEvent call to fix instrument/note changes - - f = NoteBlock.getPitchFromNote(k); - world.addParticle(ParticleTypes.NOTE, (double) pos.getX() + 0.5D, (double) pos.getY() + 1.2D, (double) pos.getZ() + 0.5D, (double) k / 24.0D, 0.0D, 0.0D); -@@ -154,7 +169,7 @@ - - holder = Holder.direct(SoundEvent.createVariableRangeEvent(minecraftkey)); - } else { -- holder = blockpropertyinstrument.getSoundEvent(); -+ holder = org.bukkit.craftbukkit.block.data.CraftBlockData.toNMS(event.getInstrument(), NoteBlockInstrument.class).getSoundEvent(); // Paper - move NotePlayEvent call to fix instrument/note changes - } - - world.playSeededSound((Player) null, (double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, holder, SoundSource.RECORDS, 3.0F, f, world.random.nextLong()); diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/ObserverBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/ObserverBlock.java.patch deleted file mode 100644 index 0718f3ab29..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/ObserverBlock.java.patch +++ /dev/null @@ -1,30 +0,0 @@ ---- a/net/minecraft/world/level/block/ObserverBlock.java -+++ b/net/minecraft/world/level/block/ObserverBlock.java -@@ -18,6 +18,8 @@ - import net.minecraft.world.level.redstone.ExperimentalRedstoneUtils; - import net.minecraft.world.level.redstone.Orientation; - -+import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit -+ - public class ObserverBlock extends DirectionalBlock { - - public static final MapCodec CODEC = simpleCodec(ObserverBlock::new); -@@ -51,8 +53,18 @@ - @Override - protected void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { - if ((Boolean) state.getValue(ObserverBlock.POWERED)) { -+ // CraftBukkit start -+ if (CraftEventFactory.callRedstoneChange(world, pos, 15, 0).getNewCurrent() != 0) { -+ return; -+ } -+ // CraftBukkit end - world.setBlock(pos, (BlockState) state.setValue(ObserverBlock.POWERED, false), 2); - } else { -+ // CraftBukkit start -+ if (CraftEventFactory.callRedstoneChange(world, pos, 0, 15).getNewCurrent() != 15) { -+ return; -+ } -+ // CraftBukkit end - world.setBlock(pos, (BlockState) state.setValue(ObserverBlock.POWERED, true), 2); - world.scheduleTick(pos, (Block) this, 2); - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/PitcherCropBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/PitcherCropBlock.java.patch deleted file mode 100644 index bdd3b319d7..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/PitcherCropBlock.java.patch +++ /dev/null @@ -1,28 +0,0 @@ ---- a/net/minecraft/world/level/block/PitcherCropBlock.java -+++ b/net/minecraft/world/level/block/PitcherCropBlock.java -@@ -107,6 +107,7 @@ - - @Override - public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { -+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent - if (world instanceof ServerLevel serverLevel && entity instanceof Ravager && serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { - serverLevel.destroyBlock(pos, true, entity); - } -@@ -131,7 +132,7 @@ - @Override - public void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { - float f = CropBlock.getGrowthSpeed(this, world, pos); -- boolean bl = random.nextInt((int)(25.0F / f) + 1) == 0; -+ boolean bl = random.nextFloat() < (world.spigotConfig.pitcherPlantModifier / (100.0F * (Math.floor(25.0F / f) + 1))); // Paper - Fix Spigot growth modifiers - if (bl) { - this.grow(world, state, pos, 1); - } -@@ -141,7 +142,7 @@ - int i = Math.min(state.getValue(AGE) + amount, 4); - if (this.canGrow(world, pos, state, i)) { - BlockState blockState = state.setValue(AGE, Integer.valueOf(i)); -- world.setBlock(pos, blockState, 2); -+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(world, pos, blockState, 2)) return; // Paper - if (isDouble(i)) { - world.setBlock(pos.above(), blockState.setValue(HALF, DoubleBlockHalf.UPPER), 3); - } diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/PointedDripstoneBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/PointedDripstoneBlock.java.patch deleted file mode 100644 index 3536598553..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/PointedDripstoneBlock.java.patch +++ /dev/null @@ -1,96 +0,0 @@ ---- a/net/minecraft/world/level/block/PointedDripstoneBlock.java -+++ b/net/minecraft/world/level/block/PointedDripstoneBlock.java -@@ -136,6 +136,11 @@ - ServerLevel worldserver = (ServerLevel) world; - - if (projectile.mayInteract(worldserver, blockposition) && projectile.mayBreak(worldserver) && projectile instanceof ThrownTrident && projectile.getDeltaMovement().length() > 0.6D) { -+ // CraftBukkit start -+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(projectile, blockposition, state.getFluidState().createLegacyBlock())) { // Paper - fix wrong block state -+ return; -+ } -+ // CraftBukkit end - world.destroyBlock(blockposition, true); - } - } -@@ -146,7 +151,7 @@ - @Override - public void fallOn(Level world, BlockState state, BlockPos pos, Entity entity, float fallDistance) { - if (state.getValue(PointedDripstoneBlock.TIP_DIRECTION) == Direction.UP && state.getValue(PointedDripstoneBlock.THICKNESS) == DripstoneThickness.TIP) { -- entity.causeFallDamage(fallDistance + 2.0F, 2.0F, world.damageSources().stalagmite()); -+ entity.causeFallDamage(fallDistance + 2.0F, 2.0F, world.damageSources().stalagmite().directBlock(world, pos)); // CraftBukkit - } else { - super.fallOn(world, state, pos, entity, fallDistance); - } -@@ -214,10 +219,13 @@ - if (((PointedDripstoneBlock.FluidInfo) optional.get()).sourceState.is(Blocks.MUD) && fluidtype == Fluids.WATER) { - BlockState iblockdata1 = Blocks.CLAY.defaultBlockState(); - -- world.setBlockAndUpdate(((PointedDripstoneBlock.FluidInfo) optional.get()).pos, iblockdata1); -+ // Paper start - Call BlockFormEvent -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockFormEvent(world, ((PointedDripstoneBlock.FluidInfo) optional.get()).pos, iblockdata1)) { - Block.pushEntitiesUp(((PointedDripstoneBlock.FluidInfo) optional.get()).sourceState, iblockdata1, world, ((PointedDripstoneBlock.FluidInfo) optional.get()).pos); - world.gameEvent((Holder) GameEvent.BLOCK_CHANGE, ((PointedDripstoneBlock.FluidInfo) optional.get()).pos, GameEvent.Context.of(iblockdata1)); - world.levelEvent(1504, blockposition1, 0); -+ } -+ // Paper end - Call BlockFormEvent - } else { - BlockPos blockposition2 = PointedDripstoneBlock.findFillableCauldronBelowStalactiteTip(world, blockposition1, fluidtype); - -@@ -391,15 +399,15 @@ - if (PointedDripstoneBlock.isUnmergedTipWithDirection(iblockdata, direction.getOpposite())) { - PointedDripstoneBlock.createMergedTips(iblockdata, world, blockposition1); - } else if (iblockdata.isAir() || iblockdata.is(Blocks.WATER)) { -- PointedDripstoneBlock.createDripstone(world, blockposition1, direction, DripstoneThickness.TIP); -+ PointedDripstoneBlock.createDripstone(world, blockposition1, direction, DripstoneThickness.TIP, pos); // CraftBukkit - } - - } - -- private static void createDripstone(LevelAccessor world, BlockPos pos, Direction direction, DripstoneThickness thickness) { -- BlockState iblockdata = (BlockState) ((BlockState) ((BlockState) Blocks.POINTED_DRIPSTONE.defaultBlockState().setValue(PointedDripstoneBlock.TIP_DIRECTION, direction)).setValue(PointedDripstoneBlock.THICKNESS, thickness)).setValue(PointedDripstoneBlock.WATERLOGGED, world.getFluidState(pos).getType() == Fluids.WATER); -+ private static void createDripstone(LevelAccessor generatoraccess, BlockPos blockposition, Direction enumdirection, DripstoneThickness dripstonethickness, BlockPos source) { // CraftBukkit -+ BlockState iblockdata = (BlockState) ((BlockState) ((BlockState) Blocks.POINTED_DRIPSTONE.defaultBlockState().setValue(PointedDripstoneBlock.TIP_DIRECTION, enumdirection)).setValue(PointedDripstoneBlock.THICKNESS, dripstonethickness)).setValue(PointedDripstoneBlock.WATERLOGGED, generatoraccess.getFluidState(blockposition).getType() == Fluids.WATER); - -- world.setBlock(pos, iblockdata, 3); -+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockSpreadEvent(generatoraccess, source, blockposition, iblockdata, 3); // CraftBukkit - } - - private static void createMergedTips(BlockState state, LevelAccessor world, BlockPos pos) { -@@ -414,8 +422,8 @@ - blockposition1 = pos.below(); - } - -- PointedDripstoneBlock.createDripstone(world, blockposition2, Direction.DOWN, DripstoneThickness.TIP_MERGE); -- PointedDripstoneBlock.createDripstone(world, blockposition1, Direction.UP, DripstoneThickness.TIP_MERGE); -+ PointedDripstoneBlock.createDripstone(world, blockposition2, Direction.DOWN, DripstoneThickness.TIP_MERGE, pos); // CraftBukkit -+ PointedDripstoneBlock.createDripstone(world, blockposition1, Direction.UP, DripstoneThickness.TIP_MERGE, pos); // CraftBukkit - } - - public static void spawnDripParticle(Level world, BlockPos pos, BlockState state) { -@@ -448,7 +456,7 @@ - - return (BlockPos) PointedDripstoneBlock.findBlockVertical(world, pos, enumdirection.getAxisDirection(), bipredicate, (iblockdata1) -> { - return PointedDripstoneBlock.isTip(iblockdata1, allowMerged); -- }, range).orElse((Object) null); -+ }, range).orElse(null); // CraftBukkit - decompile error - } - } - -@@ -564,7 +572,7 @@ - return PointedDripstoneBlock.canDripThrough(world, blockposition1, iblockdata); - }; - -- return (BlockPos) PointedDripstoneBlock.findBlockVertical(world, pos, Direction.DOWN.getAxisDirection(), bipredicate, predicate, 11).orElse((Object) null); -+ return (BlockPos) PointedDripstoneBlock.findBlockVertical(world, pos, Direction.DOWN.getAxisDirection(), bipredicate, predicate, 11).orElse(null); // CraftBukkit - decompile error - } - - @Nullable -@@ -573,7 +581,7 @@ - return PointedDripstoneBlock.canDripThrough(world, blockposition1, iblockdata); - }; - -- return (BlockPos) PointedDripstoneBlock.findBlockVertical(world, pos, Direction.UP.getAxisDirection(), bipredicate, PointedDripstoneBlock::canDrip, 11).orElse((Object) null); -+ return (BlockPos) PointedDripstoneBlock.findBlockVertical(world, pos, Direction.UP.getAxisDirection(), bipredicate, PointedDripstoneBlock::canDrip, 11).orElse(null); // CraftBukkit - decompile error - } - - public static Fluid getCauldronFillFluidType(ServerLevel world, BlockPos pos) { diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/PowderSnowBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/PowderSnowBlock.java.patch deleted file mode 100644 index 0f012c2b02..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/PowderSnowBlock.java.patch +++ /dev/null @@ -1,24 +0,0 @@ ---- a/net/minecraft/world/level/block/PowderSnowBlock.java -+++ b/net/minecraft/world/level/block/PowderSnowBlock.java -@@ -59,6 +59,7 @@ - - @Override - protected void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) { -+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent - if (!(entity instanceof LivingEntity) || entity.getInBlockState().is((Block) this)) { - entity.makeStuckInBlock(state, new Vec3(0.8999999761581421D, 1.5D, 0.8999999761581421D)); - if (world.isClientSide) { -@@ -73,7 +74,12 @@ - - entity.setIsInPowderSnow(true); - if (world instanceof ServerLevel worldserver) { -- if (entity.isOnFire() && (worldserver.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) || entity instanceof Player) && entity.mayInteract(worldserver, pos)) { -+ // CraftBukkit start -+ if (entity.isOnFire() && entity.mayInteract(worldserver, pos)) { -+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState(), !(worldserver.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) || entity instanceof Player))) { -+ return; -+ } -+ // CraftBukkit end - world.destroyBlock(pos, false); - } - diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/PoweredRailBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/PoweredRailBlock.java.patch deleted file mode 100644 index e0443a21f6..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/PoweredRailBlock.java.patch +++ /dev/null @@ -1,24 +0,0 @@ ---- a/net/minecraft/world/level/block/PoweredRailBlock.java -+++ b/net/minecraft/world/level/block/PoweredRailBlock.java -@@ -11,6 +11,7 @@ - import net.minecraft.world.level.block.state.properties.EnumProperty; - import net.minecraft.world.level.block.state.properties.Property; - import net.minecraft.world.level.block.state.properties.RailShape; -+import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit - - public class PoweredRailBlock extends BaseRailBlock { - -@@ -120,6 +121,13 @@ - boolean flag1 = world.hasNeighborSignal(pos) || this.findPoweredRailSignal(world, pos, state, true, 0) || this.findPoweredRailSignal(world, pos, state, false, 0); - - if (flag1 != flag) { -+ // CraftBukkit start -+ int power = flag ? 15 : 0; -+ int newPower = CraftEventFactory.callRedstoneChange(world, pos, power, 15 - power).getNewCurrent(); -+ if (newPower == power) { -+ return; -+ } -+ // CraftBukkit end - world.setBlock(pos, (BlockState) state.setValue(PoweredRailBlock.POWERED, flag1), 3); - world.updateNeighborsAt(pos.below(), this); - if (((RailShape) state.getValue(PoweredRailBlock.SHAPE)).isSlope()) { diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/PressurePlateBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/PressurePlateBlock.java.patch deleted file mode 100644 index 4b6ba046eb..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/PressurePlateBlock.java.patch +++ /dev/null @@ -1,61 +0,0 @@ ---- a/net/minecraft/world/level/block/PressurePlateBlock.java -+++ b/net/minecraft/world/level/block/PressurePlateBlock.java -@@ -5,6 +5,7 @@ - import net.minecraft.core.BlockPos; - import net.minecraft.world.entity.Entity; - import net.minecraft.world.entity.LivingEntity; -+import net.minecraft.world.entity.player.Player; - import net.minecraft.world.level.Level; - import net.minecraft.world.level.block.state.BlockBehaviour; - import net.minecraft.world.level.block.state.BlockState; -@@ -12,6 +13,8 @@ - import net.minecraft.world.level.block.state.properties.BlockSetType; - import net.minecraft.world.level.block.state.properties.BlockStateProperties; - import net.minecraft.world.level.block.state.properties.BooleanProperty; -+import org.bukkit.event.entity.EntityInteractEvent; -+// CraftBukkit end - - public class PressurePlateBlock extends BasePressurePlateBlock { - -@@ -44,7 +47,7 @@ - - @Override - protected int getSignalStrength(Level world, BlockPos pos) { -- Class oclass; -+ Class oclass; // CraftBukkit - - switch (this.type.pressurePlateSensitivity()) { - case EVERYTHING: -@@ -59,7 +62,31 @@ - - Class oclass1 = oclass; - -- return getEntityCount(world, PressurePlateBlock.TOUCH_AABB.move(pos), oclass1) > 0 ? 15 : 0; -+ // CraftBukkit start - Call interact event when turning on a pressure plate -+ for (Entity entity : getEntities(world, PressurePlateBlock.TOUCH_AABB.move(pos), oclass)) { -+ if (this.getSignalForState(world.getBlockState(pos)) == 0) { -+ org.bukkit.World bworld = world.getWorld(); -+ org.bukkit.plugin.PluginManager manager = world.getCraftServer().getPluginManager(); -+ org.bukkit.event.Cancellable cancellable; -+ -+ if (entity instanceof Player) { -+ cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((Player) entity, org.bukkit.event.block.Action.PHYSICAL, pos, null, null, null); -+ } else { -+ cancellable = new EntityInteractEvent(entity.getBukkitEntity(), bworld.getBlockAt(pos.getX(), pos.getY(), pos.getZ())); -+ manager.callEvent((EntityInteractEvent) cancellable); -+ } -+ -+ // We only want to block turning the plate on if all events are cancelled -+ if (cancellable.isCancelled()) { -+ continue; -+ } -+ } -+ -+ return 15; -+ } -+ -+ return 0; -+ // CraftBukkit end - } - - @Override diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/RedStoneOreBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/RedStoneOreBlock.java.patch deleted file mode 100644 index 29e5229732..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/RedStoneOreBlock.java.patch +++ /dev/null @@ -1,102 +0,0 @@ ---- a/net/minecraft/world/level/block/RedStoneOreBlock.java -+++ b/net/minecraft/world/level/block/RedStoneOreBlock.java -@@ -20,6 +20,10 @@ - import net.minecraft.world.level.block.state.StateDefinition; - import net.minecraft.world.level.block.state.properties.BooleanProperty; - import net.minecraft.world.phys.BlockHitResult; -+// CraftBukkit start -+import org.bukkit.craftbukkit.event.CraftEventFactory; -+import org.bukkit.event.entity.EntityInteractEvent; -+// CraftBukkit end - - public class RedStoneOreBlock extends Block { - -@@ -38,14 +42,27 @@ - - @Override - protected void attack(BlockState state, Level world, BlockPos pos, Player player) { -- RedStoneOreBlock.interact(state, world, pos); -+ RedStoneOreBlock.interact(state, world, pos, player); // CraftBukkit - add entityhuman - super.attack(state, world, pos, player); - } - - @Override - public void stepOn(Level world, BlockPos pos, BlockState state, Entity entity) { - if (!entity.isSteppingCarefully()) { -- RedStoneOreBlock.interact(state, world, pos); -+ // CraftBukkit start -+ if (entity instanceof Player) { -+ org.bukkit.event.player.PlayerInteractEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((Player) entity, org.bukkit.event.block.Action.PHYSICAL, pos, null, null, null); -+ if (!event.isCancelled()) { -+ RedStoneOreBlock.interact(world.getBlockState(pos), world, pos, entity); // add entity -+ } -+ } else { -+ EntityInteractEvent event = new EntityInteractEvent(entity.getBukkitEntity(), world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ())); -+ world.getCraftServer().getPluginManager().callEvent(event); -+ if (!event.isCancelled()) { -+ RedStoneOreBlock.interact(world.getBlockState(pos), world, pos, entity); // add entity -+ } -+ } -+ // CraftBukkit end - } - - super.stepOn(world, pos, state, entity); -@@ -56,16 +73,21 @@ - if (world.isClientSide) { - RedStoneOreBlock.spawnParticles(world, pos); - } else { -- RedStoneOreBlock.interact(state, world, pos); -+ RedStoneOreBlock.interact(state, world, pos, player); // CraftBukkit - add entityhuman - } - - return (InteractionResult) (stack.getItem() instanceof BlockItem && (new BlockPlaceContext(player, hand, stack, hit)).canPlace() ? InteractionResult.PASS : InteractionResult.SUCCESS); - } - -- private static void interact(BlockState state, Level world, BlockPos pos) { -- RedStoneOreBlock.spawnParticles(world, pos); -- if (!(Boolean) state.getValue(RedStoneOreBlock.LIT)) { -- world.setBlock(pos, (BlockState) state.setValue(RedStoneOreBlock.LIT, true), 3); -+ private static void interact(BlockState iblockdata, Level world, BlockPos blockposition, Entity entity) { // CraftBukkit - add Entity -+ RedStoneOreBlock.spawnParticles(world, blockposition); -+ if (!(Boolean) iblockdata.getValue(RedStoneOreBlock.LIT)) { -+ // CraftBukkit start -+ if (!CraftEventFactory.callEntityChangeBlockEvent(entity, blockposition, iblockdata.setValue(RedStoneOreBlock.LIT, true))) { -+ return; -+ } -+ // CraftBukkit end -+ world.setBlock(blockposition, (BlockState) iblockdata.setValue(RedStoneOreBlock.LIT, true), 3); - } - - } -@@ -78,6 +100,11 @@ - @Override - protected void randomTick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { - if ((Boolean) state.getValue(RedStoneOreBlock.LIT)) { -+ // CraftBukkit start -+ if (CraftEventFactory.callBlockFadeEvent(world, pos, state.setValue(RedStoneOreBlock.LIT, false)).isCancelled()) { -+ return; -+ } -+ // CraftBukkit end - world.setBlock(pos, (BlockState) state.setValue(RedStoneOreBlock.LIT, false), 3); - } - -@@ -86,10 +113,17 @@ - @Override - protected void spawnAfterBreak(BlockState state, ServerLevel world, BlockPos pos, ItemStack tool, boolean dropExperience) { - super.spawnAfterBreak(state, world, pos, tool, dropExperience); -- if (dropExperience) { -- this.tryDropExperience(world, pos, tool, UniformInt.of(1, 5)); -+ // CraftBukkit start - Delegated to getExpDrop -+ } -+ -+ @Override -+ public int getExpDrop(BlockState iblockdata, ServerLevel worldserver, BlockPos blockposition, ItemStack itemstack, boolean flag) { -+ if (flag) { -+ return this.tryDropExperience(worldserver, blockposition, itemstack, UniformInt.of(1, 5)); - } - -+ return 0; -+ // CraftBukkit end - } - - @Override diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/RedstoneLampBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/RedstoneLampBlock.java.patch deleted file mode 100644 index dc1b67c34c..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/RedstoneLampBlock.java.patch +++ /dev/null @@ -1,35 +0,0 @@ ---- a/net/minecraft/world/level/block/RedstoneLampBlock.java -+++ b/net/minecraft/world/level/block/RedstoneLampBlock.java -@@ -13,6 +13,8 @@ - import net.minecraft.world.level.block.state.properties.BooleanProperty; - import net.minecraft.world.level.redstone.Orientation; - -+import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit -+ - public class RedstoneLampBlock extends Block { - - public static final MapCodec CODEC = simpleCodec(RedstoneLampBlock::new); -@@ -43,6 +45,11 @@ - if (flag1) { - world.scheduleTick(pos, (Block) this, 4); - } else { -+ // CraftBukkit start -+ if (CraftEventFactory.callRedstoneChange(world, pos, 0, 15).getNewCurrent() != 15) { -+ return; -+ } -+ // CraftBukkit end - world.setBlock(pos, (BlockState) state.cycle(RedstoneLampBlock.LIT), 2); - } - } -@@ -53,6 +60,11 @@ - @Override - protected void tick(BlockState state, ServerLevel world, BlockPos pos, RandomSource random) { - if ((Boolean) state.getValue(RedstoneLampBlock.LIT) && !world.hasNeighborSignal(pos)) { -+ // CraftBukkit start -+ if (CraftEventFactory.callRedstoneChange(world, pos, 15, 0).getNewCurrent() != 0) { -+ return; -+ } -+ // CraftBukkit end - world.setBlock(pos, (BlockState) state.cycle(RedstoneLampBlock.LIT), 2); - } - diff --git a/paper-server/patches/unapplied/net/minecraft/world/level/block/RespawnAnchorBlock.java.patch b/paper-server/patches/unapplied/net/minecraft/world/level/block/RespawnAnchorBlock.java.patch deleted file mode 100644 index 86e3e80aca..0000000000 --- a/paper-server/patches/unapplied/net/minecraft/world/level/block/RespawnAnchorBlock.java.patch +++ /dev/null @@ -1,46 +0,0 @@ ---- a/net/minecraft/world/level/block/RespawnAnchorBlock.java -+++ b/net/minecraft/world/level/block/RespawnAnchorBlock.java -@@ -88,9 +88,14 @@ - ServerPlayer entityplayer = (ServerPlayer) player; - - if (entityplayer.getRespawnDimension() != world.dimension() || !pos.equals(entityplayer.getRespawnPosition())) { -- entityplayer.setRespawnPosition(world.dimension(), pos, 0.0F, false, true); -+ if (entityplayer.setRespawnPosition(world.dimension(), pos, 0.0F, false, true, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.RESPAWN_ANCHOR)) { // Paper - Add PlayerSetSpawnEvent - world.playSound((Player) null, (double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, SoundEvents.RESPAWN_ANCHOR_SET_SPAWN, SoundSource.BLOCKS, 1.0F, 1.0F); - return InteractionResult.SUCCESS_SERVER; -+ // Paper start - Add PlayerSetSpawnEvent -+ } else { -+ return InteractionResult.FAIL; -+ } -+ // Paper end - Add PlayerSetSpawnEvent - } - } - -@@ -127,15 +132,16 @@ - } - - private void explode(BlockState state, Level world, final BlockPos explodedPos) { -+ org.bukkit.block.BlockState blockState = org.bukkit.craftbukkit.block.CraftBlock.at(world, explodedPos).getState(); // CraftBukkit - capture BlockState before remove block - world.removeBlock(explodedPos, false); -- Stream stream = Direction.Plane.HORIZONTAL.stream(); -+ Stream stream = Direction.Plane.HORIZONTAL.stream(); // CraftBukkit - decompile error - - Objects.requireNonNull(explodedPos); - boolean flag = stream.map(explodedPos::relative).anyMatch((blockposition1) -> { - return RespawnAnchorBlock.isWaterThatWouldFlow(blockposition1, world); - }); - final boolean flag1 = flag || world.getFluidState(explodedPos.above()).is(FluidTags.WATER); -- ExplosionDamageCalculator explosiondamagecalculator = new ExplosionDamageCalculator(this) { -+ ExplosionDamageCalculator explosiondamagecalculator = new ExplosionDamageCalculator() { // CraftBukkit - decompile error - @Override - public Optional getBlockExplosionResistance(Explosion explosion, BlockGetter world, BlockPos pos, BlockState blockState, FluidState fluidState) { - return pos.equals(explodedPos) && flag1 ? Optional.of(Blocks.WATER.getExplosionResistance()) : super.getBlockExplosionResistance(explosion, world, pos, blockState, fluidState); -@@ -143,7 +149,7 @@ - }; - Vec3 vec3d = explodedPos.getCenter(); - -- world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d), explosiondamagecalculator, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); -+ world.explode((Entity) null, world.damageSources().badRespawnPointExplosion(vec3d, blockState), explosiondamagecalculator, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); // CraftBukkit - add state - } - - public static boolean canSetSpawn(Level world) {