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:
Aikar
2020-05-13 23:01:26 -04:00
parent 27979040fd
commit eb626e1176
6 changed files with 156 additions and 52 deletions

View File

@@ -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 {