From 91459fe514dd56e31cf8a166a8f689f5a20ce130 Mon Sep 17 00:00:00 2001
From: Spottedleaf <spottedleaf@spottedleaf.dev>
Date: Fri, 12 Jun 2020 00:30:30 -0700
Subject: [PATCH] Fix piston physics inconsistency (fix tnt dupers) (#3544)

Co-authored-by: Spottedleaf <Spottedleaf@users.noreply.github.com>
---
 Spigot-Server-Patches/0003-MC-Dev-fixes.patch | 13 +++++
 ...ston-physics-inconsistency-MC-188840.patch | 58 +++++++++++++++++++
 2 files changed, 71 insertions(+)
 create mode 100644 Spigot-Server-Patches/0541-Fix-piston-physics-inconsistency-MC-188840.patch

diff --git a/Spigot-Server-Patches/0003-MC-Dev-fixes.patch b/Spigot-Server-Patches/0003-MC-Dev-fixes.patch
index 34bd17b8b7..fe2e403337 100644
--- a/Spigot-Server-Patches/0003-MC-Dev-fixes.patch
+++ b/Spigot-Server-Patches/0003-MC-Dev-fixes.patch
@@ -640,6 +640,19 @@ index ee2059cf8ef0a0372e02b91a4bf6fa8a0ab31bca..77bb6b092a0763ff27f90f0401a8a81b
          }
      }
  
+diff --git a/src/main/java/net/minecraft/server/TileEntityPiston.java b/src/main/java/net/minecraft/server/TileEntityPiston.java
+index 79df42f5e53464f07e76d22cd1317637145e2056..489175abd8e582a3c082364fec357c4f061a22d7 100644
+--- a/src/main/java/net/minecraft/server/TileEntityPiston.java
++++ b/src/main/java/net/minecraft/server/TileEntityPiston.java
+@@ -137,7 +137,7 @@ public class TileEntityPiston extends TileEntity implements ITickable {
+     private static void a(EnumDirection enumdirection, Entity entity, double d0, EnumDirection enumdirection1) {
+         TileEntityPiston.h.set(enumdirection);
+         entity.move(EnumMoveType.PISTON, new Vec3D(d0 * (double) enumdirection1.getAdjacentX(), d0 * (double) enumdirection1.getAdjacentY(), d0 * (double) enumdirection1.getAdjacentZ()));
+-        TileEntityPiston.h.set((Object) null);
++        TileEntityPiston.h.set(null); // Paper - decompile fix
+     }
+ 
+     private void g(float f) {
 diff --git a/src/main/java/net/minecraft/server/VillagePlace.java b/src/main/java/net/minecraft/server/VillagePlace.java
 index c137484f66a022f7f4581d0657210d60c619c5fa..c999f8c9bf8a59e19b3d6d1b7ad8b5fb6e48b928 100644
 --- a/src/main/java/net/minecraft/server/VillagePlace.java
diff --git a/Spigot-Server-Patches/0541-Fix-piston-physics-inconsistency-MC-188840.patch b/Spigot-Server-Patches/0541-Fix-piston-physics-inconsistency-MC-188840.patch
new file mode 100644
index 0000000000..689fd216f7
--- /dev/null
+++ b/Spigot-Server-Patches/0541-Fix-piston-physics-inconsistency-MC-188840.patch
@@ -0,0 +1,58 @@
+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.
+
+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
+
+diff --git a/src/main/java/net/minecraft/server/BlockPiston.java b/src/main/java/net/minecraft/server/BlockPiston.java
+index b29525c40dc8e3ae747b8ddf5a3bd79b7cc0b792..880aa8c86d1724cd9ef68e0abfff8bb38f389462 100644
+--- a/src/main/java/net/minecraft/server/BlockPiston.java
++++ b/src/main/java/net/minecraft/server/BlockPiston.java
+@@ -364,11 +364,11 @@ public class BlockPiston extends BlockDirectional {
+ 
+             for (k = list.size() - 1; k >= 0; --k) {
+                 blockposition3 = (BlockPosition) list.get(k);
+-                iblockdata1 = world.getType(blockposition3);
++                iblockdata1 = world.getType(blockposition3); map.replace(blockposition3, iblockdata1); // Paper - fix piston physics inconsistency
+                 blockposition3 = blockposition3.shift(enumdirection1);
+                 map.remove(blockposition3);
+                 world.setTypeAndData(blockposition3, (IBlockData) Blocks.MOVING_PISTON.getBlockData().set(BlockPiston.FACING, enumdirection), 68);
+-                world.setTileEntity(blockposition3, BlockPistonMoving.a((IBlockData) list1.get(k), enumdirection, flag, false));
++                world.setTileEntity(blockposition3, BlockPistonMoving.a(iblockdata1, enumdirection, flag, false)); // Paper - fix piston physics inconsistency
+                 --j;
+                 aiblockdata[j] = iblockdata1;
+             }
+diff --git a/src/main/java/net/minecraft/server/TileEntityPiston.java b/src/main/java/net/minecraft/server/TileEntityPiston.java
+index 489175abd8e582a3c082364fec357c4f061a22d7..946522f6362638f518fba15172fb7f676d46b67c 100644
+--- a/src/main/java/net/minecraft/server/TileEntityPiston.java
++++ b/src/main/java/net/minecraft/server/TileEntityPiston.java
+@@ -275,7 +275,7 @@ public class TileEntityPiston extends TileEntity implements ITickable {
+                 IBlockData iblockdata = Block.b(this.a, (GeneratorAccess) this.world, this.position);
+ 
+                 if (iblockdata.isAir()) {
+-                    this.world.setTypeAndData(this.position, this.a, 84);
++                    this.world.setTypeAndData(this.position, this.a, 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.a(this.a, iblockdata, this.world, this.position, 3);
+                 } else {
+                     if (iblockdata.b((IBlockState) BlockProperties.C) && (Boolean) iblockdata.get(BlockProperties.C)) {