94 lines
6.1 KiB
Diff
94 lines
6.1 KiB
Diff
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||
|
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||
|
Date: Thu, 11 Jun 2020 17:29:42 -0700
|
||
|
Subject: [PATCH] Fix piston physics inconsistency - MC-188840
|
||
|
|
||
|
Pistons invoke physics when they move blocks. The physics can cause
|
||
|
tnt blocks to ignite. However, pistons (when storing the blocks they "moved")
|
||
|
don't actually go back to the world state sometimes to check if something
|
||
|
like that happened. As a result they end up moving the tnt like it was
|
||
|
never ignited. This resulted in the ability to create machines
|
||
|
that can duplicate tnt, called "world eaters".
|
||
|
This patch makes the piston logic retrieve the block state from the world
|
||
|
prevent this from occuring.
|
||
|
|
||
|
This patch also sets the moved pos to air immediately after creating
|
||
|
the moving piston TE. This prevents the block from being updated from
|
||
|
other physics calls by the piston.
|
||
|
|
||
|
Tested against the following tnt duper design:
|
||
|
https://www.youtube.com/watch?v=mS7xxNGhjxs
|
||
|
|
||
|
This patch also affects every type of machine that utilises
|
||
|
this mechanic. For example, dead coral is removed by a physics
|
||
|
update when being moved while it is attached to slimeblocks.
|
||
|
|
||
|
Standard piston machines that don't destroy or modify the
|
||
|
blocks they move by physics updates should be entirely
|
||
|
unaffected.
|
||
|
|
||
|
This patch fixes https://bugs.mojang.com/browse/MC-188840
|
||
|
|
||
|
This patch also fixes rail duping and carpet duping.
|
||
|
|
||
|
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||
|
index 7f140333c2e62012fa572c1a061d84432426997f..b67ba8f75e4a3358d7c2462918b85b0bf9b5a922 100644
|
||
|
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||
|
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||
|
@@ -434,4 +434,10 @@ public class PaperConfig {
|
||
|
consoleHasAllPermissions = getBoolean("settings.console-has-all-permissions", consoleHasAllPermissions);
|
||
|
}
|
||
|
|
||
|
+ public static boolean allowPistonDuplication;
|
||
|
+ private static void allowPistonDuplication() {
|
||
|
+ config.set("settings.unsupported-settings.allow-piston-duplication-readme", "This setting controls if player should be able to use TNT duplication, but this also allows duplicating carpet, rails and potentially other items");
|
||
|
+ allowPistonDuplication = getBoolean("settings.unsupported-settings.allow-piston-duplication", config.getBoolean("settings.unsupported-settings.allow-tnt-duplication", false));
|
||
|
+ set("settings.unsupported-settings.allow-tnt-duplication", 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 40a18302dd682e5ade4ec77ac7f316b6c0f8c112..44876557515eaa6bbe33344b3d3ba03aee58409f 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
|
||
|
@@ -398,12 +398,24 @@ public class PistonBaseBlock extends DirectionalBlock {
|
||
|
}
|
||
|
|
||
|
for (k = list.size() - 1; k >= 0; --k) {
|
||
|
- blockposition3 = (BlockPos) list.get(k);
|
||
|
- iblockdata1 = world.getBlockState(blockposition3);
|
||
|
+ // Paper start - fix a variety of piston desync dupes
|
||
|
+ boolean allowDesync = com.destroystokyo.paper.PaperConfig.allowPistonDuplication;
|
||
|
+ BlockPos oldPos = blockposition3 = (BlockPos) list.get(k);
|
||
|
+ iblockdata1 = allowDesync ? world.getBlockState(oldPos) : null;
|
||
|
+ // Paper end - fix a variety of piston desync dupes
|
||
|
blockposition3 = blockposition3.relative(enumdirection1);
|
||
|
map.remove(blockposition3);
|
||
|
world.setBlock(blockposition3, (BlockState) Blocks.MOVING_PISTON.defaultBlockState().setValue(PistonBaseBlock.FACING, dir), 68);
|
||
|
- world.setBlockEntity(blockposition3, MovingPistonBlock.newMovingBlockEntity((BlockState) list1.get(k), dir, retract, false));
|
||
|
+ // Paper start - fix a variety of piston desync dupes
|
||
|
+ if (!allowDesync) {
|
||
|
+ iblockdata1 = world.getBlockState(oldPos);
|
||
|
+ map.replace(oldPos, iblockdata1);
|
||
|
+ }
|
||
|
+ world.setBlockEntity(blockposition3, MovingPistonBlock.newMovingBlockEntity(allowDesync ? list1.get(k) : iblockdata1, dir, retract, false));
|
||
|
+ if (!allowDesync) {
|
||
|
+ world.setBlock(oldPos, Blocks.AIR.defaultBlockState(), 2 | 4 | 16 | 1024); // set air to prevent later physics updates from seeing this block
|
||
|
+ }
|
||
|
+ // Paper end - fix a variety of piston desync dupes
|
||
|
aiblockdata[j++] = iblockdata1;
|
||
|
}
|
||
|
|
||
|
diff --git a/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java b/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
|
||
|
index 73888713746e7ddd72ba9ac9d33d8e616eb3bd25..001e90da8b09e16b6df4849a5bac4f4821000c94 100644
|
||
|
--- a/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
|
||
|
+++ b/src/main/java/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java
|
||
|
@@ -279,7 +279,7 @@ public class PistonMovingBlockEntity extends BlockEntity implements TickableBloc
|
||
|
BlockState iblockdata = Block.updateFromNeighbourShapes(this.movedState, (LevelAccessor) this.level, this.worldPosition);
|
||
|
|
||
|
if (iblockdata.isAir()) {
|
||
|
- this.level.setBlock(this.worldPosition, this.movedState, 84);
|
||
|
+ this.level.setBlock(this.worldPosition, this.movedState, com.destroystokyo.paper.PaperConfig.allowPistonDuplication ? 84 : (84 | 2)); // Paper - force notify (flag 2), it's possible the set type by the piston block (which doesn't notify) set this block to air
|
||
|
Block.updateOrDestroy(this.movedState, iblockdata, this.level, this.worldPosition, 3);
|
||
|
} else {
|
||
|
if (iblockdata.hasProperty(BlockStateProperties.WATERLOGGED) && (Boolean) iblockdata.getValue(BlockStateProperties.WATERLOGGED)) {
|