d1a72eac31
Upstream has released updates that appear to apply and compile correctly. This update has not been tested by PaperMC and as with ANY update, please do your own testing Bukkit Changes: 1fc1020a PR-1049: Add MenuType API 8ae2e3be PR-1055: Expand riptiding API cac68bfb SPIGOT-7890: AttributeModifier#getUniqueId() doesn't match the UUID passed to its constructor 7004fcf2 SPIGOT-7886: Fix mistake in AttributeModifier UUID shim 1ac7f950 PR-1054: Add FireworkMeta#hasPower 4cfb565f SPIGOT-7873: Add powered state for skulls CraftBukkit Changes: bbb30e7a8 SPIGOT-7894: NPE when sending tile entity update ba21e9472 SPIGOT-7895: PlayerItemBreakEvent not firing 0fb24bbe0 SPIGOT-7875: Fix PlayerItemConsumeEvent cancellation causing client-side desync 815066449 SPIGOT-7891: Can't remove second ingredient of MerchantRecipe 45c206f2c PR-1458: Add MenuType API 19c8ef9ae SPIGOT-7867: Merchant instanceof AbstractVillager always returns false 4e006d28f PR-1468: Expand riptiding API bd8aded7d Ignore checks in CraftPlayerProfile for ResolvableProfile used in profile components 8679620b5 SPIGOT-7889: Fix tool component deserialisation without speed and/or correct-for-drops 8d5222691 SPIGOT-7882, PR-1467: Fix conversion of name in Profile Component to empty if it is missing 63f91669a SPIGOT-7887: Remove duplicate ProjectileHitEvent for fireballs 7070de8c8 SPIGOT-7878: Server#getLootTable does not return null on invalid loot table 060ee6cae SPIGOT-7876: Can't kick player or disconnect player in PlayerLoginEvent when checking for cookies 7ccb86cc0 PR-1465: Add FireworkMeta#hasPower 804ad6491 SPIGOT-7873: Add powered state for skulls f9610cdcb Improve minecart movement Spigot Changes: a759b629 Rebuild patches Co-authored-by: Jake Potrebic <jake.m.potrebic@gmail.com>
170 Zeilen
11 KiB
Diff
170 Zeilen
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 6a1e2614453bc3d6fe082c1fd43228c4a182442e..b70ac21d8dc70fb1513ea7ce5270fb381552c29a 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 b7bf7b3b91046c81467aeb483087e12b6d9191bf..a2877f3eb206ab9ccb93e3606f1c9b3401def5d6 100644
|
|
--- a/src/main/java/net/minecraft/world/level/Level.java
|
|
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
|
@@ -447,6 +447,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..3b06c080afebde1d649f05eca0af938ba32931c1 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.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;
|
|
+ }
|
|
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 240c250a93289776686d09d7eae17c07d7278da5..f2036917c5ba9f536087d7ee559704055469730e 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
|
|
@@ -174,7 +174,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;
|
|
|
|
@@ -254,7 +254,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) {
|
|
@@ -883,6 +883,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);
|
|
}
|
|
@@ -986,7 +992,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;
|
|
}
|