mirror of
https://github.com/PaperMC/Paper.git
synced 2024-09-12 06:58:11 +02:00
Upstream has released updates that appears to apply and compile correctly.
This update has not been tested by PaperMC and as with ANY update, please do your own testing
CraftBukkit Changes:
d5a72960
SPIGOT-6063: ConsoleSender sending extra lines in Java 13+
Spigot Changes:
2740d5ae Rebuild patches
174 lines
10 KiB
Diff
174 lines
10 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/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
|
index 093605fe8e079d9ec973702c55ea6caddf0369f1..3d63215a855c71d257b18a247eb7f0b2d7908bce 100644
|
|
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
|
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
|
@@ -411,4 +411,17 @@ public class PaperConfig {
|
|
private static void midTickChunkTasks() {
|
|
midTickChunkTasks = getInt("settings.chunk-tasks-per-tick", midTickChunkTasks);
|
|
}
|
|
+
|
|
+ public static boolean allowBlockPermanentBreakingExploits = false;
|
|
+ private static void allowBlockPermanentBreakingExploits() {
|
|
+ if (config.contains("allow-perm-block-break-exploits")) {
|
|
+ allowBlockPermanentBreakingExploits = config.getBoolean("allow-perm-block-break-exploits", false);
|
|
+ config.set("allow-perm-block-break-exploits", null);
|
|
+ }
|
|
+
|
|
+ config.set("settings.unsupported-settings.allow-permanent-block-break-exploits-readme", "This setting controls if players should be able to break bedrock, end portals and other intended to be permanent blocks.");
|
|
+ allowBlockPermanentBreakingExploits = getBoolean("settings.unsupported-settings.allow-permanent-block-break-exploits", allowBlockPermanentBreakingExploits);
|
|
+
|
|
+ }
|
|
+
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/server/Block.java b/src/main/java/net/minecraft/server/Block.java
|
|
index b364ceafb4c3412b0d11b3b2e8b4321ed96769bb..a45ceff9ff970b996b2767379a2ecd4693f52d3a 100644
|
|
--- a/src/main/java/net/minecraft/server/Block.java
|
|
+++ b/src/main/java/net/minecraft/server/Block.java
|
|
@@ -23,6 +23,19 @@ public class Block extends BlockBase implements IMaterial {
|
|
protected final BlockStateList<Block, IBlockData> blockStateList;
|
|
private IBlockData blockData;
|
|
// Paper start
|
|
+ public final boolean isDestroyable() {
|
|
+ return com.destroystokyo.paper.PaperConfig.allowBlockPermanentBreakingExploits ||
|
|
+ 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/server/BlockBase.java b/src/main/java/net/minecraft/server/BlockBase.java
|
|
index eeeffa989e7024dc345fafda822e0b29f928a759..b6081d259444f0d78736802b5d565faf776e825f 100644
|
|
--- a/src/main/java/net/minecraft/server/BlockBase.java
|
|
+++ b/src/main/java/net/minecraft/server/BlockBase.java
|
|
@@ -138,7 +138,7 @@ public abstract class BlockBase {
|
|
|
|
@Deprecated
|
|
public boolean a(IBlockData iblockdata, BlockActionContext blockactioncontext) {
|
|
- return this.material.isReplaceable() && (blockactioncontext.getItemStack().isEmpty() || blockactioncontext.getItemStack().getItem() != this.getItem());
|
|
+ return this.material.isReplaceable() && (blockactioncontext.getItemStack().isEmpty() || blockactioncontext.getItemStack().getItem() != this.getItem()) && (iblockdata.isDestroyable() || (blockactioncontext.getEntity() != null && blockactioncontext.getEntity().abilities.canInstantlyBuild)); // Paper
|
|
}
|
|
|
|
@Deprecated
|
|
@@ -342,7 +342,11 @@ public abstract class BlockBase {
|
|
public Block getBlock() {
|
|
return (Block) this.c;
|
|
}
|
|
-
|
|
+ // Paper start
|
|
+ public final boolean isDestroyable() {
|
|
+ return getBlock().isDestroyable();
|
|
+ }
|
|
+ // Paper end
|
|
public Material getMaterial() {
|
|
return this.g;
|
|
}
|
|
@@ -432,7 +436,7 @@ public abstract class BlockBase {
|
|
}
|
|
|
|
public EnumPistonReaction getPushReaction() {
|
|
- return this.getBlock().getPushReaction(this.p());
|
|
+ return !isDestroyable() ? EnumPistonReaction.BLOCK : this.getBlock().getPushReaction(this.p()); // Paper
|
|
}
|
|
|
|
public boolean i(IBlockAccess iblockaccess, BlockPosition blockposition) {
|
|
diff --git a/src/main/java/net/minecraft/server/BlockPiston.java b/src/main/java/net/minecraft/server/BlockPiston.java
|
|
index 417d1a6c3dbd23905672a847939d92a953bbc91c..0bab7dfb053c1aa92f5417c25fed5484e09bbec3 100644
|
|
--- a/src/main/java/net/minecraft/server/BlockPiston.java
|
|
+++ b/src/main/java/net/minecraft/server/BlockPiston.java
|
|
@@ -165,6 +165,12 @@ public class BlockPiston extends BlockDirectional {
|
|
@Override
|
|
public boolean a(IBlockData iblockdata, World world, BlockPosition blockposition, int i, int j) {
|
|
EnumDirection enumdirection = (EnumDirection) iblockdata.get(BlockPiston.FACING);
|
|
+ // Paper start - prevent retracting when we're facing the wrong way (we were replaced before retraction could occur)
|
|
+ EnumDirection directionQueuedAs = EnumDirection.fromType1(j & 7); // Paper - copied from below
|
|
+ if (!com.destroystokyo.paper.PaperConfig.allowBlockPermanentBreakingExploits && enumdirection != directionQueuedAs) {
|
|
+ return false;
|
|
+ }
|
|
+ // Paper end - prevent retracting when we're facing the wrong way
|
|
|
|
if (!world.isClientSide) {
|
|
boolean flag = this.a(world, blockposition, enumdirection);
|
|
@@ -196,7 +202,7 @@ public class BlockPiston extends BlockDirectional {
|
|
IBlockData iblockdata1 = (IBlockData) ((IBlockData) Blocks.MOVING_PISTON.getBlockData().set(BlockPistonMoving.a, enumdirection)).set(BlockPistonMoving.b, this.sticky ? BlockPropertyPistonType.STICKY : BlockPropertyPistonType.DEFAULT);
|
|
|
|
world.setTypeAndData(blockposition, iblockdata1, 20);
|
|
- world.setTileEntity(blockposition, BlockPistonMoving.a((IBlockData) this.getBlockData().set(BlockPiston.FACING, EnumDirection.fromType1(j & 7)), enumdirection, false, true));
|
|
+ world.setTileEntity(blockposition, BlockPistonMoving.a((IBlockData) this.getBlockData().set(BlockPiston.FACING, EnumDirection.fromType1(j & 7)), enumdirection, false, true)); // Paper - diff on change, j is facing direction - copy this above
|
|
world.update(blockposition, iblockdata1.getBlock());
|
|
iblockdata1.a(world, blockposition, 2);
|
|
if (this.sticky) {
|
|
@@ -225,7 +231,14 @@ public class BlockPiston extends BlockDirectional {
|
|
}
|
|
}
|
|
} else {
|
|
- world.a(blockposition.shift(enumdirection), false);
|
|
+ // Paper start - fix headless pistons breaking blocks
|
|
+ BlockPosition headPos = blockposition.shift(enumdirection);
|
|
+ if (com.destroystokyo.paper.PaperConfig.allowBlockPermanentBreakingExploits || world.getType(headPos) == Blocks.PISTON_HEAD.getBlockData().set(FACING, enumdirection)) { // double check to make sure we're not a headless piston.
|
|
+ world.setAir(headPos, false);
|
|
+ } else {
|
|
+ ((WorldServer)world).getChunkProvider().flagDirty(headPos); // ... fix client desync
|
|
+ }
|
|
+ // Paper end - fix headless pistons breaking blocks
|
|
}
|
|
|
|
world.playSound((EntityHuman) null, blockposition, SoundEffects.BLOCK_PISTON_CONTRACT, SoundCategory.BLOCKS, 0.5F, world.random.nextFloat() * 0.15F + 0.6F);
|
|
diff --git a/src/main/java/net/minecraft/server/Explosion.java b/src/main/java/net/minecraft/server/Explosion.java
|
|
index 9823fb5eebbfee026d3173c81368cf6e3e901f92..f263177e3d41fd5720c430be3dcb1b5e2adb0134 100644
|
|
--- a/src/main/java/net/minecraft/server/Explosion.java
|
|
+++ b/src/main/java/net/minecraft/server/Explosion.java
|
|
@@ -125,6 +125,7 @@ public class Explosion {
|
|
for (float f1 = 0.3F; f > 0.0F; f -= 0.22500001F) {
|
|
BlockPosition blockposition = new BlockPosition(d4, d5, d6);
|
|
IBlockData iblockdata = this.world.getType(blockposition);
|
|
+ if (!iblockdata.isDestroyable()) continue; // Paper
|
|
Fluid fluid = iblockdata.getFluid(); // Paper
|
|
Optional<Float> optional = this.l.a(this, this.world, blockposition, iblockdata, fluid);
|
|
|
|
@@ -278,7 +279,7 @@ public class Explosion {
|
|
IBlockData iblockdata = this.world.getType(blockposition);
|
|
Block block = iblockdata.getBlock();
|
|
|
|
- if (!iblockdata.isAir()) {
|
|
+ if (!iblockdata.isAir() && iblockdata.isDestroyable()) { // Paper
|
|
BlockPosition blockposition1 = blockposition.immutableCopy();
|
|
|
|
this.world.getMethodProfiler().enter("explosion_blocks");
|
|
diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java
|
|
index ce3a74d980e5551f4af5ae28f83f4c6e84bd96e7..17b6a4fb6c1893f000efaeaaf36e152e3da34893 100644
|
|
--- a/src/main/java/net/minecraft/server/World.java
|
|
+++ b/src/main/java/net/minecraft/server/World.java
|
|
@@ -371,6 +371,10 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
|
|
public boolean a(BlockPosition blockposition, IBlockData iblockdata, int i, int j) {
|
|
// CraftBukkit start - tree generation
|
|
if (this.captureTreeGeneration) {
|
|
+ // Paper start
|
|
+ IBlockData type = getType(blockposition);
|
|
+ if (!type.isDestroyable()) return false;
|
|
+ // Paper end
|
|
CraftBlockState blockstate = capturedBlockStates.get(blockposition);
|
|
if (blockstate == null) {
|
|
blockstate = CapturedBlockState.getTreeBlockState(this, blockposition, i);
|