mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-27 15:00:13 +01:00
Protect Bedrock and End Portal/Frames from being destroyed
This fixes exploits that let players destroy bedrock by Pistons, explosions and Mushrooom/Tree generation. These blocks are designed to not be broken except by creative players/commands. So protect them from a multitude of methods of destroying them. A config is provided if you rather let players use these exploits, and let them destroy the worlds End Portals and get on top of the nether easy.
This commit is contained in:
parent
27979040fd
commit
eb626e1176
6 changed files with 156 additions and 52 deletions
|
@ -344,7 +344,7 @@
|
|||
+ return chunk == null ? null : chunk.getFluidState(blockposition);
|
||||
+ }
|
||||
+
|
||||
@Override
|
||||
+ @Override
|
||||
+ public final boolean hasChunkAt(BlockPos pos) {
|
||||
+ return getChunkIfLoaded(pos.getX() >> 4, pos.getZ() >> 4) != null; // Paper - Perf: Optimize Level.hasChunkAt(BlockPosition)Z
|
||||
+ }
|
||||
|
@ -365,18 +365,22 @@
|
|||
+ return getWorldBorder().isWithinBounds(blockposition) ? getBlockStateIfLoaded(blockposition) : null;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
@Override
|
||||
public ChunkAccess getChunk(int chunkX, int chunkZ, ChunkStatus leastStatus, boolean create) {
|
||||
+ // Paper end
|
||||
ChunkAccess ichunkaccess = this.getChunkSource().getChunk(chunkX, chunkZ, leastStatus, create);
|
||||
|
||||
if (ichunkaccess == null && create) {
|
||||
@@ -207,6 +444,18 @@
|
||||
@@ -207,6 +444,22 @@
|
||||
|
||||
@Override
|
||||
public boolean setBlock(BlockPos pos, BlockState state, int flags, int maxUpdateDepth) {
|
||||
+ // CraftBukkit start - tree generation
|
||||
+ if (this.captureTreeGeneration) {
|
||||
+ // Paper start - Protect Bedrock and End Portal/Frames from being destroyed
|
||||
+ BlockState type = getBlockState(pos);
|
||||
+ if (!type.isDestroyable()) return false;
|
||||
+ // Paper end - Protect Bedrock and End Portal/Frames from being destroyed
|
||||
+ CraftBlockState blockstate = this.capturedBlockStates.get(pos);
|
||||
+ if (blockstate == null) {
|
||||
+ blockstate = CapturedBlockState.getTreeBlockState(this, pos, flags);
|
||||
|
@ -390,7 +394,7 @@
|
|||
if (this.isOutsideBuildHeight(pos)) {
|
||||
return false;
|
||||
} else if (!this.isClientSide && this.isDebug()) {
|
||||
@@ -214,45 +463,126 @@
|
||||
@@ -214,45 +467,126 @@
|
||||
} else {
|
||||
LevelChunk chunk = this.getChunkAt(pos);
|
||||
Block block = state.getBlock();
|
||||
|
@ -532,7 +536,7 @@
|
|||
public void onBlockStateChange(BlockPos pos, BlockState oldBlock, BlockState newBlock) {}
|
||||
|
||||
@Override
|
||||
@@ -270,15 +600,33 @@
|
||||
@@ -270,15 +604,33 @@
|
||||
return false;
|
||||
} else {
|
||||
FluidState fluid = this.getFluidState(pos);
|
||||
|
@ -569,7 +573,7 @@
|
|||
}
|
||||
|
||||
boolean flag1 = this.setBlock(pos, fluid.createLegacyBlock(), 3, maxUpdateDepth);
|
||||
@@ -340,10 +688,18 @@
|
||||
@@ -340,10 +692,18 @@
|
||||
|
||||
@Override
|
||||
public BlockState getBlockState(BlockPos pos) {
|
||||
|
@ -589,7 +593,7 @@
|
|||
|
||||
return chunk.getBlockState(pos);
|
||||
}
|
||||
@@ -446,34 +802,53 @@
|
||||
@@ -446,34 +806,53 @@
|
||||
this.pendingBlockEntityTickers.clear();
|
||||
}
|
||||
|
||||
|
@ -641,18 +645,18 @@
|
|||
+ entity.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DISCARD);
|
||||
+ // Paper end - Prevent block entity and entity crashes
|
||||
}
|
||||
}
|
||||
+ }
|
||||
+ // Paper start - Option to prevent armor stands from doing entity lookups
|
||||
+ @Override
|
||||
+ public boolean noCollision(@Nullable Entity entity, AABB box) {
|
||||
+ if (entity instanceof net.minecraft.world.entity.decoration.ArmorStand && !entity.level().paperConfig().entities.armorStands.doCollisionEntityLookups) return false;
|
||||
+ return LevelAccessor.super.noCollision(entity, box);
|
||||
+ }
|
||||
}
|
||||
+ // Paper end - Option to prevent armor stands from doing entity lookups
|
||||
|
||||
public boolean shouldTickDeath(Entity entity) {
|
||||
return true;
|
||||
@@ -510,13 +885,32 @@
|
||||
@@ -510,13 +889,32 @@
|
||||
@Nullable
|
||||
@Override
|
||||
public BlockEntity getBlockEntity(BlockPos pos) {
|
||||
|
@ -686,7 +690,7 @@
|
|||
this.getChunkAt(blockposition).addAndRegisterBlockEntity(blockEntity);
|
||||
}
|
||||
}
|
||||
@@ -643,7 +1037,7 @@
|
||||
@@ -643,7 +1041,7 @@
|
||||
|
||||
for (int k = 0; k < j; ++k) {
|
||||
EnderDragonPart entitycomplexpart = aentitycomplexpart[k];
|
||||
|
@ -695,7 +699,7 @@
|
|||
|
||||
if (t0 != null && predicate.test(t0)) {
|
||||
result.add(t0);
|
||||
@@ -912,7 +1306,7 @@
|
||||
@@ -912,7 +1310,7 @@
|
||||
|
||||
public static enum ExplosionInteraction implements StringRepresentable {
|
||||
|
||||
|
|
|
@ -53,16 +53,17 @@
|
|||
}
|
||||
|
||||
private ExplosionDamageCalculator makeDamageCalculator(@Nullable Entity entity) {
|
||||
@@ -135,7 +150,7 @@
|
||||
@@ -135,7 +150,8 @@
|
||||
for (float f1 = 0.3F; f > 0.0F; f -= 0.22500001F) {
|
||||
BlockPos blockposition = BlockPos.containing(d4, d5, d6);
|
||||
BlockState iblockdata = this.level.getBlockState(blockposition);
|
||||
- FluidState fluid = this.level.getFluidState(blockposition);
|
||||
+ if (!iblockdata.isDestroyable()) continue; // Paper - Protect Bedrock and End Portal/Frames from being destroyed
|
||||
+ FluidState fluid = iblockdata.getFluidState(); // Paper - Perf: Optimize call to getFluid for explosions
|
||||
|
||||
if (!this.level.isInWorldBounds(blockposition)) {
|
||||
break;
|
||||
@@ -149,6 +164,15 @@
|
||||
@@ -149,6 +165,15 @@
|
||||
|
||||
if (f > 0.0F && this.damageCalculator.shouldBlockExplode(this, this.level, blockposition, iblockdata, f)) {
|
||||
set.add(blockposition);
|
||||
|
@ -78,7 +79,7 @@
|
|||
}
|
||||
|
||||
d4 += d0 * 0.30000001192092896D;
|
||||
@@ -171,7 +195,7 @@
|
||||
@@ -171,7 +196,7 @@
|
||||
int l = Mth.floor(this.center.y + (double) f + 1.0D);
|
||||
int i1 = Mth.floor(this.center.z - (double) f - 1.0D);
|
||||
int j1 = Mth.floor(this.center.z + (double) f + 1.0D);
|
||||
|
@ -87,7 +88,7 @@
|
|||
Iterator iterator = list.iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
@@ -192,10 +216,38 @@
|
||||
@@ -192,10 +217,38 @@
|
||||
d3 /= d4;
|
||||
boolean flag = this.damageCalculator.shouldDamageEntity(this, entity);
|
||||
float f1 = this.damageCalculator.getKnockbackMultiplier(entity);
|
||||
|
@ -128,7 +129,7 @@
|
|||
}
|
||||
|
||||
double d5 = (1.0D - d0) * (double) f2 * (double) f1;
|
||||
@@ -204,7 +256,7 @@
|
||||
@@ -204,7 +257,7 @@
|
||||
if (entity instanceof LivingEntity) {
|
||||
LivingEntity entityliving = (LivingEntity) entity;
|
||||
|
||||
|
@ -137,7 +138,7 @@
|
|||
} else {
|
||||
d6 = d5;
|
||||
}
|
||||
@@ -214,11 +266,19 @@
|
||||
@@ -214,11 +267,19 @@
|
||||
d3 *= d6;
|
||||
Vec3 vec3d = new Vec3(d1, d2, d3);
|
||||
|
||||
|
@ -158,7 +159,7 @@
|
|||
this.hitPlayers.put(entityhuman, vec3d);
|
||||
}
|
||||
}
|
||||
@@ -235,10 +295,62 @@
|
||||
@@ -235,10 +296,62 @@
|
||||
List<ServerExplosion.StackCollector> list1 = new ArrayList();
|
||||
|
||||
Util.shuffle(positions, this.level.random);
|
||||
|
@ -221,7 +222,7 @@
|
|||
|
||||
this.level.getBlockState(blockposition).onExplosionHit(this.level, blockposition, this, (itemstack, blockposition1) -> {
|
||||
ServerExplosion.addOrAppendStack(list1, itemstack, blockposition1);
|
||||
@@ -262,13 +374,22 @@
|
||||
@@ -262,13 +375,22 @@
|
||||
BlockPos blockposition = (BlockPos) iterator.next();
|
||||
|
||||
if (this.level.random.nextInt(3) == 0 && this.level.getBlockState(blockposition).isAir() && this.level.getBlockState(blockposition.below()).isSolidRender()) {
|
||||
|
@ -245,7 +246,7 @@
|
|||
this.level.gameEvent(this.source, (Holder) GameEvent.EXPLODE, this.center);
|
||||
List<BlockPos> list = this.calculateExplodedPositions();
|
||||
|
||||
@@ -288,6 +409,7 @@
|
||||
@@ -288,6 +410,7 @@
|
||||
}
|
||||
|
||||
private static void addOrAppendStack(List<ServerExplosion.StackCollector> droppedItemsOut, ItemStack item, BlockPos pos) {
|
||||
|
@ -253,7 +254,7 @@
|
|||
Iterator iterator = droppedItemsOut.iterator();
|
||||
|
||||
do {
|
||||
@@ -372,4 +494,85 @@
|
||||
@@ -372,4 +495,85 @@
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,30 @@
|
|||
--- a/net/minecraft/world/level/block/Block.java
|
||||
+++ b/net/minecraft/world/level/block/Block.java
|
||||
@@ -292,15 +292,41 @@
|
||||
});
|
||||
state.spawnAfterBreak((ServerLevel) world, pos, ItemStack.EMPTY, true);
|
||||
}
|
||||
+
|
||||
@@ -88,6 +88,21 @@
|
||||
public static final int UPDATE_LIMIT = 512;
|
||||
protected final StateDefinition<Block, BlockState> stateDefinition;
|
||||
private BlockState defaultBlockState;
|
||||
+ // Paper start - Protect Bedrock and End Portal/Frames from being destroyed
|
||||
+ public final boolean isDestroyable() {
|
||||
+ return io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowPermanentBlockBreakExploits ||
|
||||
+ this != Blocks.BARRIER &&
|
||||
+ this != Blocks.BEDROCK &&
|
||||
+ this != Blocks.END_PORTAL_FRAME &&
|
||||
+ this != Blocks.END_PORTAL &&
|
||||
+ this != Blocks.END_GATEWAY &&
|
||||
+ this != Blocks.COMMAND_BLOCK &&
|
||||
+ this != Blocks.REPEATING_COMMAND_BLOCK &&
|
||||
+ this != Blocks.CHAIN_COMMAND_BLOCK &&
|
||||
+ this != Blocks.STRUCTURE_BLOCK &&
|
||||
+ this != Blocks.JIGSAW;
|
||||
+ }
|
||||
+ // Paper end - Protect Bedrock and End Portal/Frames from being destroyed
|
||||
@Nullable
|
||||
private Item item;
|
||||
private static final int CACHE_SIZE = 256;
|
||||
@@ -295,12 +310,38 @@
|
||||
|
||||
}
|
||||
|
||||
+ // Paper start - Add BlockBreakBlockEvent
|
||||
+ public static boolean dropResources(BlockState state, LevelAccessor levelAccessor, BlockPos pos, @Nullable BlockEntity blockEntity, BlockPos source) {
|
||||
|
@ -25,9 +44,9 @@
|
|||
+ block.popExperience(serverLevel, pos, event.getExpToDrop()); // Paper - Properly handle xp dropping
|
||||
+ }
|
||||
+ return true;
|
||||
}
|
||||
+ }
|
||||
+ // Paper end - Add BlockBreakBlockEvent
|
||||
|
||||
+
|
||||
public static void dropResources(BlockState state, Level world, BlockPos pos, @Nullable BlockEntity blockEntity, @Nullable Entity entity, ItemStack tool) {
|
||||
+ // Paper start - Properly handle xp dropping
|
||||
+ dropResources(state, world, pos, blockEntity, entity, tool, true);
|
||||
|
@ -43,7 +62,7 @@
|
|||
}
|
||||
|
||||
}
|
||||
@@ -340,7 +366,13 @@
|
||||
@@ -340,7 +381,13 @@
|
||||
ItemEntity entityitem = (ItemEntity) itemEntitySupplier.get();
|
||||
|
||||
entityitem.setDefaultPickUpDelay();
|
||||
|
@ -58,7 +77,7 @@
|
|||
return;
|
||||
}
|
||||
}
|
||||
@@ -348,8 +380,13 @@
|
||||
@@ -348,8 +395,13 @@
|
||||
}
|
||||
|
||||
public void popExperience(ServerLevel world, BlockPos pos, int size) {
|
||||
|
@ -73,7 +92,7 @@
|
|||
}
|
||||
|
||||
}
|
||||
@@ -367,10 +404,18 @@
|
||||
@@ -367,10 +419,18 @@
|
||||
return this.defaultBlockState();
|
||||
}
|
||||
|
||||
|
@ -94,7 +113,7 @@
|
|||
}
|
||||
|
||||
public void setPlacedBy(Level world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack itemStack) {}
|
||||
@@ -490,15 +535,35 @@
|
||||
@@ -490,15 +550,35 @@
|
||||
return this.builtInRegistryHolder;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,20 @@
|
|||
world.blockEvent(pos, this, b0, enumdirection.get3DDataValue());
|
||||
}
|
||||
|
||||
@@ -229,6 +248,13 @@
|
||||
@@ -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);
|
||||
|
||||
|
@ -45,9 +58,12 @@
|
|||
+ }
|
||||
+ // 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));
|
||||
+ 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());
|
||||
@@ -255,6 +281,13 @@
|
||||
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 {
|
||||
|
@ -61,18 +77,31 @@
|
|||
world.removeBlock(pos.relative(enumdirection), false);
|
||||
}
|
||||
}
|
||||
@@ -335,7 +368,49 @@
|
||||
} 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();
|
||||
|
@ -111,7 +140,7 @@
|
|||
BlockPos blockposition3;
|
||||
int j;
|
||||
BlockState iblockdata1;
|
||||
@@ -345,7 +420,7 @@
|
||||
@@ -345,7 +433,7 @@
|
||||
iblockdata1 = world.getBlockState(blockposition3);
|
||||
BlockEntity tileentity = iblockdata1.hasBlockEntity() ? world.getBlockEntity(blockposition3) : null;
|
||||
|
||||
|
@ -120,7 +149,7 @@
|
|||
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 +433,25 @@
|
||||
@@ -358,13 +446,25 @@
|
||||
BlockState iblockdata2;
|
||||
|
||||
for (j = list.size() - 1; j >= 0; --j) {
|
||||
|
|
|
@ -37,6 +37,15 @@
|
|||
if (state.hasBlockEntity() && !state.is(newState.getBlock())) {
|
||||
world.removeBlockEntity(pos);
|
||||
}
|
||||
@@ -166,7 +178,7 @@
|
||||
}
|
||||
|
||||
protected void onExplosionHit(BlockState state, ServerLevel world, BlockPos pos, Explosion explosion, BiConsumer<ItemStack, BlockPos> stackMerger) {
|
||||
- if (!state.isAir() && explosion.getBlockInteraction() != Explosion.BlockInteraction.TRIGGER_BLOCK) {
|
||||
+ if (!state.isAir() && explosion.getBlockInteraction() != Explosion.BlockInteraction.TRIGGER_BLOCK && state.isDestroyable()) { // Paper - Protect Bedrock and End Portal/Frames from being destroyed
|
||||
Block block = state.getBlock();
|
||||
boolean flag = explosion.getIndirectSourceEntity() instanceof Player;
|
||||
|
||||
@@ -174,8 +186,10 @@
|
||||
BlockEntity tileentity = state.hasBlockEntity() ? world.getBlockEntity(pos) : null;
|
||||
LootParams.Builder lootparams_a = (new LootParams.Builder(world)).withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(pos)).withParameter(LootContextParams.TOOL, ItemStack.EMPTY).withOptionalParameter(LootContextParams.BLOCK_ENTITY, tileentity).withOptionalParameter(LootContextParams.THIS_ENTITY, explosion.getDirectSourceEntity());
|
||||
|
@ -50,6 +59,15 @@
|
|||
}
|
||||
|
||||
state.spawnAfterBreak(world, pos, ItemStack.EMPTY, flag);
|
||||
@@ -243,7 +257,7 @@
|
||||
}
|
||||
|
||||
protected boolean canBeReplaced(BlockState state, BlockPlaceContext context) {
|
||||
- return state.canBeReplaced() && (context.getItemInHand().isEmpty() || !context.getItemInHand().is(this.asItem()));
|
||||
+ return state.canBeReplaced() && (context.getItemInHand().isEmpty() || !context.getItemInHand().is(this.asItem())) && (state.isDestroyable() || (context.getPlayer() != null && context.getPlayer().getAbilities().instabuild)); // Paper - Protect Bedrock and End Portal/Frames from being destroyed
|
||||
}
|
||||
|
||||
protected boolean canBeReplaced(BlockState state, Fluid fluid) {
|
||||
@@ -851,7 +865,15 @@
|
||||
this.spawnTerrainParticles = blockbase_info.spawnTerrainParticles;
|
||||
this.instrument = blockbase_info.instrument;
|
||||
|
@ -81,7 +99,20 @@
|
|||
|
||||
this.legacySolid = this.calculateSolid();
|
||||
this.occlusionShape = this.canOcclude ? ((Block) this.owner).getOcclusionShape(this.asState()) : Shapes.empty();
|
||||
@@ -945,19 +969,19 @@
|
||||
@@ -925,6 +949,12 @@
|
||||
return this.legacySolid;
|
||||
}
|
||||
|
||||
+ // Paper start - Protect Bedrock and End Portal/Frames from being destroyed
|
||||
+ public final boolean isDestroyable() {
|
||||
+ return getBlock().isDestroyable();
|
||||
+ }
|
||||
+ // Paper end - Protect Bedrock and End Portal/Frames from being destroyed
|
||||
+
|
||||
public boolean isValidSpawn(BlockGetter world, BlockPos pos, EntityType<?> type) {
|
||||
return this.getBlock().properties.isValidSpawn.test(this.asState(), world, pos, type);
|
||||
}
|
||||
@@ -945,19 +975,19 @@
|
||||
return this.occlusionShape;
|
||||
}
|
||||
|
||||
|
@ -106,7 +137,15 @@
|
|||
return this.isAir;
|
||||
}
|
||||
|
||||
@@ -1035,7 +1059,7 @@
|
||||
@@ -1028,14 +1058,14 @@
|
||||
}
|
||||
|
||||
public PushReaction getPistonPushReaction() {
|
||||
- return this.pushReaction;
|
||||
+ return !this.isDestroyable() ? PushReaction.BLOCK : this.pushReaction; // Paper - Protect Bedrock and End Portal/Frames from being destroyed
|
||||
}
|
||||
|
||||
public boolean isSolidRender() {
|
||||
return this.solidRender;
|
||||
}
|
||||
|
||||
|
@ -115,24 +154,22 @@
|
|||
return this.canOcclude;
|
||||
}
|
||||
|
||||
@@ -1125,9 +1149,15 @@
|
||||
@@ -1125,7 +1155,13 @@
|
||||
}
|
||||
|
||||
public void onPlace(Level world, BlockPos pos, BlockState state, boolean notify) {
|
||||
- this.getBlock().onPlace(this.asState(), world, pos, state, notify);
|
||||
+ // CraftBukkit start
|
||||
+ this.onPlace(world, pos, state, notify, null);
|
||||
}
|
||||
|
||||
+ }
|
||||
+
|
||||
+ public void onPlace(Level world, BlockPos blockposition, BlockState iblockdata, boolean flag, @Nullable UseOnContext context) {
|
||||
+ this.getBlock().onPlace(this.asState(), world, blockposition, iblockdata, flag, context);
|
||||
+ // CraftBukkit end
|
||||
+ }
|
||||
+
|
||||
public void onRemove(Level world, BlockPos pos, BlockState state, boolean moved) {
|
||||
this.getBlock().onRemove(this.asState(), world, pos, state, moved);
|
||||
}
|
||||
@@ -1154,6 +1184,7 @@
|
||||
|
||||
public void onRemove(Level world, BlockPos pos, BlockState state, boolean moved) {
|
||||
@@ -1154,6 +1190,7 @@
|
||||
|
||||
public void spawnAfterBreak(ServerLevel world, BlockPos pos, ItemStack tool, boolean dropExperience) {
|
||||
this.getBlock().spawnAfterBreak(this.asState(), world, pos, tool, dropExperience);
|
||||
|
@ -140,7 +177,7 @@
|
|||
}
|
||||
|
||||
public List<ItemStack> getDrops(LootParams.Builder builder) {
|
||||
@@ -1250,11 +1281,11 @@
|
||||
@@ -1250,11 +1287,11 @@
|
||||
return this.getBlock().builtInRegistryHolder().is(key);
|
||||
}
|
||||
|
||||
|
|
|
@ -133,3 +133,17 @@
|
|||
return Optional.of(new BlockUtil.FoundRectangle(blockposition1.immutable(), 2, 3));
|
||||
}
|
||||
|
||||
@@ -178,6 +207,13 @@
|
||||
for (int j = -1; j < 3; ++j) {
|
||||
for (int k = -1; k < 4; ++k) {
|
||||
temp.setWithOffset(pos, portalDirection.getStepX() * j + enumdirection1.getStepX() * distanceOrthogonalToPortal, k, portalDirection.getStepZ() * j + enumdirection1.getStepZ() * distanceOrthogonalToPortal);
|
||||
+ // Paper start - Protect Bedrock and End Portal/Frames from being destroyed
|
||||
+ if (!io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowPermanentBlockBreakExploits) {
|
||||
+ if (!this.level.getBlockState(temp).isDestroyable()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - Protect Bedrock and End Portal/Frames from being destroyed
|
||||
if (k < 0 && !this.level.getBlockState(temp).isSolid()) {
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue