mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-22 08:57:35 +01:00
dc684c60d1
The new behavior of disconnect to block the current thread until the disconnect succeeded is better than throwing it off to happen at some point
170 lines
11 KiB
Diff
170 lines
11 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Aikar <aikar@aikar.co>
|
|
Date: Wed, 13 May 2020 23:01:26 -0400
|
|
Subject: [PATCH] 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.
|
|
|
|
diff --git a/src/main/java/net/minecraft/world/level/Explosion.java b/src/main/java/net/minecraft/world/level/Explosion.java
|
|
index 69914a048987c21ee2ed2c489aab269862fda8f2..bff83fe413c7baef4ba56a3270ea4463a58c792f 100644
|
|
--- a/src/main/java/net/minecraft/world/level/Explosion.java
|
|
+++ b/src/main/java/net/minecraft/world/level/Explosion.java
|
|
@@ -193,6 +193,7 @@ public class Explosion {
|
|
for (float f1 = 0.3F; f > 0.0F; f -= 0.22500001F) {
|
|
BlockPos blockposition = BlockPos.containing(d4, d5, d6);
|
|
BlockState iblockdata = this.level.getBlockState(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)) {
|
|
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
|
index 4d6409875771413de7ae20def2aaad4049709c30..dd519eacd6d4bea5447bea471f0ac6540d9bb49c 100644
|
|
--- a/src/main/java/net/minecraft/world/level/Level.java
|
|
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
|
@@ -449,6 +449,10 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
|
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);
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java
|
|
index bf52c36f31992a01a7403d8c85151327c9e944c4..45704653310efe9cb755a644674b54b8722c2c84 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/Block.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/Block.java
|
|
@@ -89,6 +89,19 @@ public class Block extends BlockBehaviour implements ItemLike {
|
|
protected final StateDefinition<Block, BlockState> stateDefinition;
|
|
private BlockState defaultBlockState;
|
|
// Paper start
|
|
+ public final boolean isDestroyable() {
|
|
+ return io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.allowPermanentBlockBreakExploits ||
|
|
+ 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.BARRIER &&
|
|
+ this != Blocks.STRUCTURE_BLOCK &&
|
|
+ this != Blocks.JIGSAW;
|
|
+ }
|
|
public co.aikar.timings.Timing timing;
|
|
public co.aikar.timings.Timing getTiming() {
|
|
if (timing == null) {
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java
|
|
index e6bfbe2588e0c2a1be14e38d654e889d392ad4db..e0c62227b279a5fe0f3868fbf9ce8c78c515a09c 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java
|
|
@@ -213,6 +213,12 @@ public class PistonBaseBlock extends DirectionalBlock {
|
|
@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) {
|
|
@@ -253,7 +259,7 @@ public class PistonBaseBlock extends DirectionalBlock {
|
|
}
|
|
// 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) {
|
|
@@ -289,7 +295,14 @@ public class PistonBaseBlock extends DirectionalBlock {
|
|
}
|
|
}
|
|
} 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);
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
|
|
index 936b56c116de63b38a416d5bab4223a88d0469d0..6c4a339be29bb9c07b741a1ca12de2217c8687ba 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
|
|
@@ -173,7 +173,7 @@ public abstract class BlockBehaviour implements FeatureElement {
|
|
}
|
|
|
|
protected void onExplosionHit(BlockState state, Level 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;
|
|
|
|
@@ -253,7 +253,7 @@ public abstract class BlockBehaviour implements FeatureElement {
|
|
}
|
|
|
|
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) {
|
|
@@ -888,6 +888,12 @@ public abstract class BlockBehaviour implements FeatureElement {
|
|
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);
|
|
}
|
|
@@ -991,7 +997,7 @@ public abstract class BlockBehaviour implements FeatureElement {
|
|
}
|
|
|
|
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(BlockGetter world, BlockPos pos) {
|
|
diff --git a/src/main/java/net/minecraft/world/level/portal/PortalForcer.java b/src/main/java/net/minecraft/world/level/portal/PortalForcer.java
|
|
index 5c4b2a33d4007c36aef68604bca40a4eba510b4e..fd04a50183ccb1f21fc6efa70256e1bb4db2d6d4 100644
|
|
--- a/src/main/java/net/minecraft/world/level/portal/PortalForcer.java
|
|
+++ b/src/main/java/net/minecraft/world/level/portal/PortalForcer.java
|
|
@@ -207,6 +207,13 @@ public class PortalForcer {
|
|
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;
|
|
}
|