net/minecraft/world/level/block/piston/

This commit is contained in:
Owen1212055
2024-12-14 16:24:00 -05:00
parent 004ee8651c
commit 97043e3e5b
3 changed files with 174 additions and 186 deletions

View File

@@ -1,180 +0,0 @@
--- a/net/minecraft/world/level/block/piston/PistonBaseBlock.java
+++ b/net/minecraft/world/level/block/piston/PistonBaseBlock.java
@@ -44,6 +44,13 @@
import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
+// CraftBukkit start
+import com.google.common.collect.ImmutableList;
+import java.util.AbstractList;
+import org.bukkit.craftbukkit.block.CraftBlock;
+import org.bukkit.event.block.BlockPistonRetractEvent;
+import org.bukkit.event.block.BlockPistonExtendEvent;
+// CraftBukkit end
public class PistonBaseBlock extends DirectionalBlock {
@@ -155,6 +162,18 @@
}
}
+ // CraftBukkit start
+ // if (!this.isSticky) { // Paper - Fix sticky pistons and BlockPistonRetractEvent; Move further down
+ // org.bukkit.block.Block block = world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ());
+ // BlockPistonRetractEvent event = new BlockPistonRetractEvent(block, ImmutableList.<org.bukkit.block.Block>of(), CraftBlock.notchToBlockFace(enumdirection));
+ // world.getCraftServer().getPluginManager().callEvent(event);
+ //
+ // if (event.isCancelled()) {
+ // return;
+ // }
+ // }
+ // PAIL: checkME - what happened to setTypeAndData?
+ // CraftBukkit end
world.blockEvent(pos, this, b0, enumdirection.get3DDataValue());
}
@@ -197,6 +216,12 @@
@Override
protected boolean triggerEvent(BlockState state, Level world, BlockPos pos, int type, int data) {
Direction enumdirection = (Direction) state.getValue(PistonBaseBlock.FACING);
+ // Paper start - Protect Bedrock and End Portal/Frames from being destroyed; prevent retracting when we're facing the wrong way (we were replaced before retraction could occur)
+ Direction directionQueuedAs = Direction.from3DDataValue(data & 7); // Paper - copied from below
+ if (!io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowPermanentBlockBreakExploits && enumdirection != directionQueuedAs) {
+ return false;
+ }
+ // Paper end - Protect Bedrock and End Portal/Frames from being destroyed
BlockState iblockdata1 = (BlockState) state.setValue(PistonBaseBlock.EXTENDED, true);
if (!world.isClientSide) {
@@ -229,8 +254,15 @@
BlockState iblockdata2 = (BlockState) ((BlockState) Blocks.MOVING_PISTON.defaultBlockState().setValue(MovingPistonBlock.FACING, enumdirection)).setValue(MovingPistonBlock.TYPE, this.isSticky ? PistonType.STICKY : PistonType.DEFAULT);
+ // Paper start - Fix sticky pistons and BlockPistonRetractEvent; Move empty piston retract call to fix multiple event fires
+ if (!this.isSticky) {
+ if (!new BlockPistonRetractEvent(CraftBlock.at(world, pos), java.util.Collections.emptyList(), CraftBlock.notchToBlockFace(enumdirection)).callEvent()) {
+ return false;
+ }
+ }
+ // Paper end - Fix sticky pistons and BlockPistonRetractEvent
world.setBlock(pos, iblockdata2, 20);
- world.setBlockEntity(MovingPistonBlock.newMovingBlockEntity(pos, iblockdata2, (BlockState) this.defaultBlockState().setValue(PistonBaseBlock.FACING, Direction.from3DDataValue(data & 7)), enumdirection, false, true));
+ world.setBlockEntity(MovingPistonBlock.newMovingBlockEntity(pos, iblockdata2, (BlockState) this.defaultBlockState().setValue(PistonBaseBlock.FACING, Direction.from3DDataValue(data & 7)), enumdirection, false, true)); // Paper - Protect Bedrock and End Portal/Frames from being destroyed; diff on change
world.blockUpdated(pos, iblockdata2.getBlock());
iblockdata2.updateNeighbourShapes(world, pos, 2);
if (this.isSticky) {
@@ -255,11 +287,25 @@
if (type == 1 && !iblockdata3.isAir() && PistonBaseBlock.isPushable(iblockdata3, world, blockposition1, enumdirection.getOpposite(), false, enumdirection) && (iblockdata3.getPistonPushReaction() == PushReaction.NORMAL || iblockdata3.is(Blocks.PISTON) || iblockdata3.is(Blocks.STICKY_PISTON))) {
this.moveBlocks(world, pos, enumdirection, false);
} else {
+ // Paper start - Fix sticky pistons and BlockPistonRetractEvent; fire BlockPistonRetractEvent for sticky pistons retracting nothing (air)
+ if (type == TRIGGER_CONTRACT && iblockdata2.isAir()) {
+ if (!new BlockPistonRetractEvent(CraftBlock.at(world, pos), java.util.Collections.emptyList(), CraftBlock.notchToBlockFace(enumdirection)).callEvent()) {
+ return false;
+ }
+ }
+ // Paper end - Fix sticky pistons and BlockPistonRetractEvent
world.removeBlock(pos.relative(enumdirection), false);
}
}
} else {
- world.removeBlock(pos.relative(enumdirection), false);
+ // Paper start - Protect Bedrock and End Portal/Frames from being destroyed; fix headless pistons breaking blocks
+ BlockPos headPos = pos.relative(enumdirection);
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowPermanentBlockBreakExploits || world.getBlockState(headPos) == Blocks.PISTON_HEAD.defaultBlockState().setValue(FACING, enumdirection)) { // double check to make sure we're not a headless piston.
+ world.removeBlock(headPos, false);
+ } else {
+ ((ServerLevel) world).getChunkSource().blockChanged(headPos); // ... fix client desync
+ }
+ // Paper end - Protect Bedrock and End Portal/Frames from being destroyed
}
world.playSound((Player) null, pos, SoundEvents.PISTON_CONTRACT, SoundSource.BLOCKS, 0.5F, world.random.nextFloat() * 0.15F + 0.6F);
@@ -335,7 +381,49 @@
BlockState[] aiblockdata = new BlockState[list.size() + list2.size()];
Direction enumdirection1 = extend ? dir : dir.getOpposite();
int i = 0;
+ // CraftBukkit start
+ final org.bukkit.block.Block bblock = world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ());
+
+ final List<BlockPos> moved = pistonextendschecker.getToPush();
+ final List<BlockPos> broken = pistonextendschecker.getToDestroy();
+
+ List<org.bukkit.block.Block> blocks = new AbstractList<org.bukkit.block.Block>() {
+ @Override
+ public int size() {
+ return moved.size() + broken.size();
+ }
+
+ @Override
+ public org.bukkit.block.Block get(int index) {
+ if (index >= this.size() || index < 0) {
+ throw new ArrayIndexOutOfBoundsException(index);
+ }
+ BlockPos pos = (BlockPos) (index < moved.size() ? moved.get(index) : broken.get(index - moved.size()));
+ return bblock.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ());
+ }
+ };
+ org.bukkit.event.block.BlockPistonEvent event;
+ if (extend) {
+ event = new BlockPistonExtendEvent(bblock, blocks, CraftBlock.notchToBlockFace(enumdirection1));
+ } else {
+ event = new BlockPistonRetractEvent(bblock, blocks, CraftBlock.notchToBlockFace(enumdirection1));
+ }
+ world.getCraftServer().getPluginManager().callEvent(event);
+
+ if (event.isCancelled()) {
+ for (BlockPos b : broken) {
+ world.sendBlockUpdated(b, Blocks.AIR.defaultBlockState(), world.getBlockState(b), 3);
+ }
+ for (BlockPos b : moved) {
+ world.sendBlockUpdated(b, Blocks.AIR.defaultBlockState(), world.getBlockState(b), 3);
+ b = b.relative(enumdirection1);
+ world.sendBlockUpdated(b, Blocks.AIR.defaultBlockState(), world.getBlockState(b), 3);
+ }
+ return false;
+ }
+ // CraftBukkit end
+
BlockPos blockposition3;
int j;
BlockState iblockdata1;
@@ -345,7 +433,7 @@
iblockdata1 = world.getBlockState(blockposition3);
BlockEntity tileentity = iblockdata1.hasBlockEntity() ? world.getBlockEntity(blockposition3) : null;
- dropResources(iblockdata1, world, blockposition3, tileentity);
+ dropResources(iblockdata1, world, blockposition3, tileentity, pos); // Paper - Add BlockBreakBlockEvent
world.setBlock(blockposition3, Blocks.AIR.defaultBlockState(), 18);
world.gameEvent((Holder) GameEvent.BLOCK_DESTROY, blockposition3, GameEvent.Context.of(iblockdata1));
if (!iblockdata1.is(BlockTags.FIRE)) {
@@ -358,13 +446,25 @@
BlockState iblockdata2;
for (j = list.size() - 1; j >= 0; --j) {
- blockposition3 = (BlockPos) list.get(j);
- iblockdata1 = world.getBlockState(blockposition3);
+ // Paper start - fix a variety of piston desync dupes
+ boolean allowDesync = io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowPistonDuplication;
+ BlockPos oldPos = blockposition3 = (BlockPos) list.get(j);
+ iblockdata1 = allowDesync ? world.getBlockState(oldPos) : null;
+ // Paper end - fix a variety of piston desync dupes
blockposition3 = blockposition3.relative(enumdirection1);
map.remove(blockposition3);
iblockdata2 = (BlockState) Blocks.MOVING_PISTON.defaultBlockState().setValue(PistonBaseBlock.FACING, dir);
world.setBlock(blockposition3, iblockdata2, 68);
- world.setBlockEntity(MovingPistonBlock.newMovingBlockEntity(blockposition3, iblockdata2, (BlockState) list1.get(j), dir, extend, false));
+ // Paper start - fix a variety of piston desync dupes
+ if (!allowDesync) {
+ iblockdata1 = world.getBlockState(oldPos);
+ map.replace(oldPos, iblockdata1);
+ }
+ world.setBlockEntity(MovingPistonBlock.newMovingBlockEntity(blockposition3, iblockdata2, allowDesync ? (BlockState) list1.get(j) : iblockdata1, dir, extend, false));
+ if (!allowDesync) {
+ world.setBlock(oldPos, Blocks.AIR.defaultBlockState(), Block.UPDATE_CLIENTS | Block.UPDATE_KNOWN_SHAPE | Block.UPDATE_MOVE_BY_PISTON | 1024); // set air to prevent later physics updates from seeing this block
+ }
+ // Paper end - fix a variety of piston desync dupes
aiblockdata[i++] = iblockdata1;
}

View File

@@ -1,11 +0,0 @@
--- a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
+++ b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
@@ -306,7 +306,7 @@
if (world.getBlockState(pos).is(Blocks.MOVING_PISTON)) {
BlockState blockState = Block.updateFromNeighbourShapes(blockEntity.movedState, world, pos);
if (blockState.isAir()) {
- world.setBlock(pos, blockEntity.movedState, 84);
+ world.setBlock(pos, blockEntity.movedState, io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowPistonDuplication ? 84 : (84 | Block.UPDATE_CLIENTS)); // Paper - fix a variety of piston desync dupes; force notify (flag 2), it's possible the set type by the piston block (which doesn't notify) set this block to air
Block.updateOrDestroy(blockEntity.movedState, blockState, world, pos, 3);
} else {
if (blockState.hasProperty(BlockStateProperties.WATERLOGGED) && blockState.getValue(BlockStateProperties.WATERLOGGED)) {