From 8d2860c58f811b89214223a54e5c9a98eb79e545 Mon Sep 17 00:00:00 2001 From: William Blake Galbreath Date: Fri, 19 Jun 2020 00:04:28 -0500 Subject: [PATCH] Updated Upstream (Paper) Upstream has released updates that appears to apply and compile correctly Paper Changes: 9ffaa44a Also restrict height in the vanilla teleport command f8609691 Add unsupported-settings section to config (piston tnt dupe config option) (#3565) d7bb893c Document fixup commit way of modifing patches (#3423) --- Paper | 2 +- current-paper | 2 +- .../0125-PaperPR-3550-Fix-more-exploits.patch | 206 +++++ ...-exploits-carpet-dupe-rail-dupe-bedr.patch | 34 - ...otect-Bedrock-and-End-Portal-Frames-.patch | 70 -- ...le-to-execute-tasks-on-the-main-ser.patch} | 2 +- .../server/0127-PaperPR-Fix-sand-duping.patch | 43 -- ... 0127-YAPFA-Disable-mojang-profiler.patch} | 2 +- ...position-desync-in-playerconnection-.patch | 29 - ...129-PaperPR-Fix-enderdragon-exp-dupe.patch | 41 - ...Tuinity-Piston-pushable-TileEntities.patch | 714 ------------------ 11 files changed, 210 insertions(+), 935 deletions(-) create mode 100644 patches/server/0125-PaperPR-3550-Fix-more-exploits.patch delete mode 100644 patches/server/0125-PaperPR-Fix-more-exploits-carpet-dupe-rail-dupe-bedr.patch delete mode 100644 patches/server/0126-PaperPR-fixup-Protect-Bedrock-and-End-Portal-Frames-.patch rename patches/server/{0130-Tuinity-Always-able-to-execute-tasks-on-the-main-ser.patch => 0126-Tuinity-Always-able-to-execute-tasks-on-the-main-ser.patch} (94%) delete mode 100644 patches/server/0127-PaperPR-Fix-sand-duping.patch rename patches/server/{0132-YAPFA-Disable-mojang-profiler.patch => 0127-YAPFA-Disable-mojang-profiler.patch} (99%) delete mode 100644 patches/server/0128-PaperPR-Prevent-position-desync-in-playerconnection-.patch delete mode 100644 patches/server/0129-PaperPR-Fix-enderdragon-exp-dupe.patch delete mode 100644 patches/server/0131-Tuinity-Piston-pushable-TileEntities.patch diff --git a/Paper b/Paper index 83e832b44..9ffaa44ae 160000 --- a/Paper +++ b/Paper @@ -1 +1 @@ -Subproject commit 83e832b44c0837c6d9cca9d9e60afa851839487d +Subproject commit 9ffaa44ae1abc77f13d14804e718cb86012eac48 diff --git a/current-paper b/current-paper index d899e808a..e6f63eae4 100644 --- a/current-paper +++ b/current-paper @@ -1 +1 @@ -1.15.2--72e6dee61f700df6e67fc888ef11eb97202b7dd8 +1.15.2--bde4d33a1afce5fd1cbad2c640a028ab3ea7fd1c diff --git a/patches/server/0125-PaperPR-3550-Fix-more-exploits.patch b/patches/server/0125-PaperPR-3550-Fix-more-exploits.patch new file mode 100644 index 000000000..6aac53533 --- /dev/null +++ b/patches/server/0125-PaperPR-3550-Fix-more-exploits.patch @@ -0,0 +1,206 @@ +From c17ddd1bb257b49ab887fd8371c3ff0588cb7270 Mon Sep 17 00:00:00 2001 +From: Spottedleaf +Date: Thu, 11 Jun 2020 17:29:42 -0700 +Subject: [PATCH] PaperPR - 3550 - Fix more exploits + +--- + .../com/destroystokyo/paper/PaperConfig.java | 7 ++-- + src/main/java/net/minecraft/server/Block.java | 3 +- + .../net/minecraft/server/BlockPiston.java | 35 ++++++++++++++++--- + .../minecraft/server/EntityEnderDragon.java | 4 ++- + .../minecraft/server/EntityFallingBlock.java | 11 ++++++ + .../minecraft/server/PlayerConnection.java | 5 +++ + .../minecraft/server/TileEntityPiston.java | 2 +- + 7 files changed, 56 insertions(+), 11 deletions(-) + +diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java +index 863bec74a6..8444819f07 100644 +--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java ++++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java +@@ -442,8 +442,9 @@ public class PaperConfig { + consoleHasAllPermissions = getBoolean("settings.console-has-all-permissions", consoleHasAllPermissions); + } + +- public static boolean allowTntDuplication = false; +- private static void allowTntDuplication() { +- allowTntDuplication = getBoolean("settings.unsupported-settings.allow-tnt-duplication", allowTntDuplication); ++ public static boolean allowPistonDuplication; ++ private static void allowPistonDuplication() { ++ 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/server/Block.java b/src/main/java/net/minecraft/server/Block.java +index 8985d0ee9d..6db195e023 100644 +--- a/src/main/java/net/minecraft/server/Block.java ++++ b/src/main/java/net/minecraft/server/Block.java +@@ -37,7 +37,8 @@ public class Block implements IMaterial { + this != Blocks.BEDROCK && + this != Blocks.END_PORTAL_FRAME && + this != Blocks.END_PORTAL && +- this != Blocks.END_GATEWAY; ++ this != Blocks.END_GATEWAY && // Purpur ++ this != Blocks.MOVING_PISTON; // Purpur - try to prevent creation of headless pistons + } + public co.aikar.timings.Timing timing; + public co.aikar.timings.Timing getTiming() { +diff --git a/src/main/java/net/minecraft/server/BlockPiston.java b/src/main/java/net/minecraft/server/BlockPiston.java +index 2b15aa959f..1d4d0d3eb3 100644 +--- a/src/main/java/net/minecraft/server/BlockPiston.java ++++ b/src/main/java/net/minecraft/server/BlockPiston.java +@@ -175,6 +175,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); ++ // Purpur 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; ++ } ++ // Purpur end - prevent retracting when we're facing the wrong way + + if (!world.isClientSide) { + boolean flag = this.a(world, blockposition, enumdirection); +@@ -204,7 +210,7 @@ public class BlockPiston extends BlockDirectional { + } + + world.setTypeAndData(blockposition, (IBlockData) ((IBlockData) Blocks.MOVING_PISTON.getBlockData().set(BlockPistonMoving.a, enumdirection)).set(BlockPistonMoving.b, this.sticky ? BlockPropertyPistonType.STICKY : BlockPropertyPistonType.DEFAULT), 3); +- 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)); // Purpur - diff on change, j is facing direction + if (this.sticky) { + BlockPosition blockposition1 = blockposition.b(enumdirection.getAdjacentX() * 2, enumdirection.getAdjacentY() * 2, enumdirection.getAdjacentZ() * 2); + IBlockData iblockdata1 = world.getType(blockposition1); +@@ -232,7 +238,14 @@ public class BlockPiston extends BlockDirectional { + } + } + } else { +- world.a(blockposition.shift(enumdirection), false); ++ // Purpur 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 ++ } ++ // Purpur 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); +@@ -373,12 +386,24 @@ public class BlockPiston extends BlockDirectional { + } + + for (k = list.size() - 1; k >= 0; --k) { +- blockposition3 = (BlockPosition) list.get(k); +- iblockdata1 = world.getType(blockposition3); if (!com.destroystokyo.paper.PaperConfig.allowTntDuplication) map.replace(blockposition3, iblockdata1); // Paper start - fix piston physics inconsistency ++ // Purpur start - fix a variety of piston desync dupes ++ boolean allowDesync = com.destroystokyo.paper.PaperConfig.allowPistonDuplication; ++ BlockPosition oldPos = blockposition3 = (BlockPosition) list.get(k); ++ iblockdata1 = allowDesync ? world.getType(oldPos) : null; ++ // Purpur end - fix a variety of piston desync dupes + 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(com.destroystokyo.paper.PaperConfig.allowTntDuplication ? list1.get(k) : iblockdata1, enumdirection, flag, false)); // Paper - fix piston physics inconsistency ++ // Purpur start - fix a variety of piston desync dupes ++ if (!allowDesync) { ++ iblockdata1 = world.getType(oldPos); ++ map.replace(oldPos, iblockdata1); ++ } ++ world.setTileEntity(blockposition3, BlockPistonMoving.a(allowDesync ? list1.get(k) : iblockdata1, enumdirection, flag, false)); ++ if (!allowDesync) { ++ world.setTypeAndData(oldPos, Blocks.AIR.getBlockData(), 4 | 16 | 1024); // set air to prevent later physics updates from seeing this block ++ } ++ // Purpur end - fix a variety of piston desync dupes + --j; + aiblockdata[j] = iblockdata1; + } +diff --git a/src/main/java/net/minecraft/server/EntityEnderDragon.java b/src/main/java/net/minecraft/server/EntityEnderDragon.java +index f06fde3242..6abe47f776 100644 +--- a/src/main/java/net/minecraft/server/EntityEnderDragon.java ++++ b/src/main/java/net/minecraft/server/EntityEnderDragon.java +@@ -33,7 +33,7 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster { + public float bx; + public float by; + public boolean bz; +- public int bA; ++ public int bA; public final int getDeathTicks() { return this.bA; } public final void setDeathTicks(final int value) { this.bA = value; } // Purpur + public float bB; + @Nullable + public EntityEnderCrystal currentEnderCrystal; +@@ -908,6 +908,7 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster { + public void b(NBTTagCompound nbttagcompound) { + super.b(nbttagcompound); + nbttagcompound.setInt("DragonPhase", this.bO.a().getControllerPhase().b()); ++ nbttagcompound.setInt("Paper.DeathTick", this.getDeathTicks()); // Purpur + } + + @Override +@@ -916,6 +917,7 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster { + if (nbttagcompound.hasKey("DragonPhase")) { + this.bO.setControllerPhase(DragonControllerPhase.getById(nbttagcompound.getInt("DragonPhase"))); + } ++ this.setDeathTicks(nbttagcompound.getInt("Paper.DeathTick")); // Purpur + + } + +diff --git a/src/main/java/net/minecraft/server/EntityFallingBlock.java b/src/main/java/net/minecraft/server/EntityFallingBlock.java +index 6683f7c5f3..7969b1cd57 100644 +--- a/src/main/java/net/minecraft/server/EntityFallingBlock.java ++++ b/src/main/java/net/minecraft/server/EntityFallingBlock.java +@@ -64,6 +64,11 @@ public class EntityFallingBlock extends Entity { + + @Override + public void tick() { ++ // Purpur start - fix sand duping ++ if (this.dead) { ++ return; ++ } ++ // Purpur end - fix sand duping + if (this.block.isAir()) { + this.die(); + } else { +@@ -86,6 +91,12 @@ public class EntityFallingBlock extends Entity { + + this.move(EnumMoveType.SELF, this.getMot()); + ++ // Purpur start - fix sand duping ++ if (this.dead) { ++ return; ++ } ++ // Purpur end - fix sand duping ++ + // Paper start - Configurable EntityFallingBlock height nerf + if (this.world.paperConfig.fallingBlockHeightNerf != 0 && this.locY() > this.world.paperConfig.fallingBlockHeightNerf) { + if (this.dropItem && this.world.getGameRules().getBoolean(GameRules.DO_ENTITY_DROPS)) { +diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java +index 3a1aa1d4da..c13296935c 100644 +--- a/src/main/java/net/minecraft/server/PlayerConnection.java ++++ b/src/main/java/net/minecraft/server/PlayerConnection.java +@@ -1104,6 +1104,11 @@ public class PlayerConnection implements PacketListenerPlayIn { + } + + this.player.move(EnumMoveType.PLAYER, new Vec3D(d7, d8, d9)); ++ // Purpur start - prevent position desync ++ if (this.teleportPos != null) { ++ return; // ... thanks Mojang for letting move calls teleport across dimensions. ++ } ++ // Purpur end - prevent position desync + this.player.onGround = packetplayinflying.b(); + double d12 = d8; + +diff --git a/src/main/java/net/minecraft/server/TileEntityPiston.java b/src/main/java/net/minecraft/server/TileEntityPiston.java +index 634e378430..d700e8281f 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 | (com.destroystokyo.paper.PaperConfig.allowTntDuplication ? 0 : 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 ++ this.world.setTypeAndData(this.position, this.a, 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.a(this.a, iblockdata, this.world, this.position, 3); + } else { + if (iblockdata.b((IBlockState) BlockProperties.C) && (Boolean) iblockdata.get(BlockProperties.C)) { +-- +2.26.2 + diff --git a/patches/server/0125-PaperPR-Fix-more-exploits-carpet-dupe-rail-dupe-bedr.patch b/patches/server/0125-PaperPR-Fix-more-exploits-carpet-dupe-rail-dupe-bedr.patch deleted file mode 100644 index 18428b85c..000000000 --- a/patches/server/0125-PaperPR-Fix-more-exploits-carpet-dupe-rail-dupe-bedr.patch +++ /dev/null @@ -1,34 +0,0 @@ -From d5525ef160f81107273a8900513f869ae4f284d3 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Thu, 11 Jun 2020 17:29:42 -0700 -Subject: [PATCH] PaperPR - Fix more exploits (carpet dupe, rail dupe, bedrock - destroying, falling block (sand/dragon egg/etc) duping) - ---- - src/main/java/net/minecraft/server/BlockPiston.java | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/src/main/java/net/minecraft/server/BlockPiston.java b/src/main/java/net/minecraft/server/BlockPiston.java -index 9cca30a94f..80a4cf1641 100644 ---- a/src/main/java/net/minecraft/server/BlockPiston.java -+++ b/src/main/java/net/minecraft/server/BlockPiston.java -@@ -373,12 +373,14 @@ public class BlockPiston extends BlockDirectional { - } - - for (k = list.size() - 1; k >= 0; --k) { -- blockposition3 = (BlockPosition) list.get(k); -- iblockdata1 = world.getType(blockposition3); map.replace(blockposition3, iblockdata1); // Paper - fix piston physics inconsistency -+ BlockPosition oldPos = blockposition3 = (BlockPosition) list.get(k); // Purpur -+ iblockdata1 = null; // Purpur - explode if usage changes - blockposition3 = blockposition3.shift(enumdirection1); - map.remove(blockposition3); - world.setTypeAndData(blockposition3, (IBlockData) Blocks.MOVING_PISTON.getBlockData().set(BlockPiston.FACING, enumdirection), 68); -+ iblockdata1 = world.getType(oldPos); map.replace(oldPos, iblockdata1); // Purpur - fix piston physics inconsistency - move after the physics update - world.setTileEntity(blockposition3, BlockPistonMoving.a(iblockdata1, enumdirection, flag, false)); // Paper - fix piston physics inconsistency -+ world.setTypeAndData(oldPos, Blocks.AIR.getBlockData(), 68); // Purpur - set air to prevent later physics updates from seeing this block - --j; - aiblockdata[j] = iblockdata1; - } --- -2.26.2 - diff --git a/patches/server/0126-PaperPR-fixup-Protect-Bedrock-and-End-Portal-Frames-.patch b/patches/server/0126-PaperPR-fixup-Protect-Bedrock-and-End-Portal-Frames-.patch deleted file mode 100644 index 84a2987f4..000000000 --- a/patches/server/0126-PaperPR-fixup-Protect-Bedrock-and-End-Portal-Frames-.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 42e0355d159e2e4f8f931b2f0d9599a9ef541754 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Fri, 12 Jun 2020 11:45:41 -0700 -Subject: [PATCH] PaperPR - fixup! Protect Bedrock and End Portal/Frames from - being destroyed - ---- - src/main/java/net/minecraft/server/Block.java | 3 ++- - .../java/net/minecraft/server/BlockPiston.java | 17 +++++++++++++++-- - 2 files changed, 17 insertions(+), 3 deletions(-) - -diff --git a/src/main/java/net/minecraft/server/Block.java b/src/main/java/net/minecraft/server/Block.java -index 8985d0ee9d..97e553b38c 100644 ---- a/src/main/java/net/minecraft/server/Block.java -+++ b/src/main/java/net/minecraft/server/Block.java -@@ -37,7 +37,8 @@ public class Block implements IMaterial { - this != Blocks.BEDROCK && - this != Blocks.END_PORTAL_FRAME && - this != Blocks.END_PORTAL && -- this != Blocks.END_GATEWAY; -+ this != Blocks.END_GATEWAY && -+ this != Blocks.MOVING_PISTON; // try to prevent creation of headless pistons - } - public co.aikar.timings.Timing timing; - public co.aikar.timings.Timing getTiming() { -diff --git a/src/main/java/net/minecraft/server/BlockPiston.java b/src/main/java/net/minecraft/server/BlockPiston.java -index 80a4cf1641..0b7bed5e92 100644 ---- a/src/main/java/net/minecraft/server/BlockPiston.java -+++ b/src/main/java/net/minecraft/server/BlockPiston.java -@@ -175,6 +175,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); -+ // Purpur start - prevent retracting when we're facing the wrong way (we were replaced before retraction could occur) -+ EnumDirection directionQueuedAs = EnumDirection.fromType1(j & 7); // Purpur - copied from below -+ if (!com.destroystokyo.paper.PaperConfig.allowBlockPermanentBreakingExploits && enumdirection != directionQueuedAs) { -+ return false; -+ } -+ // Purpur end - prevent retracting when we're facing the wrong way - - if (!world.isClientSide) { - boolean flag = this.a(world, blockposition, enumdirection); -@@ -204,7 +210,7 @@ public class BlockPiston extends BlockDirectional { - } - - world.setTypeAndData(blockposition, (IBlockData) ((IBlockData) Blocks.MOVING_PISTON.getBlockData().set(BlockPistonMoving.a, enumdirection)).set(BlockPistonMoving.b, this.sticky ? BlockPropertyPistonType.STICKY : BlockPropertyPistonType.DEFAULT), 3); -- 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)); // Purpur - diff on change, j is facing direction - if (this.sticky) { - BlockPosition blockposition1 = blockposition.b(enumdirection.getAdjacentX() * 2, enumdirection.getAdjacentY() * 2, enumdirection.getAdjacentZ() * 2); - IBlockData iblockdata1 = world.getType(blockposition1); -@@ -232,7 +238,14 @@ public class BlockPiston extends BlockDirectional { - } - } - } else { -- world.a(blockposition.shift(enumdirection), false); -+ // Purpur 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 -+ } -+ // Purpur 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); --- -2.26.2 - diff --git a/patches/server/0130-Tuinity-Always-able-to-execute-tasks-on-the-main-ser.patch b/patches/server/0126-Tuinity-Always-able-to-execute-tasks-on-the-main-ser.patch similarity index 94% rename from patches/server/0130-Tuinity-Always-able-to-execute-tasks-on-the-main-ser.patch rename to patches/server/0126-Tuinity-Always-able-to-execute-tasks-on-the-main-ser.patch index c9522bb0d..900f774fb 100644 --- a/patches/server/0130-Tuinity-Always-able-to-execute-tasks-on-the-main-ser.patch +++ b/patches/server/0126-Tuinity-Always-able-to-execute-tasks-on-the-main-ser.patch @@ -1,4 +1,4 @@ -From 6b6fcb9d7ec44fbb629145a1a2d37770d5b60fb8 Mon Sep 17 00:00:00 2001 +From f3054cc2a7f88ef976d520a933e31ae19f7266b6 Mon Sep 17 00:00:00 2001 From: Spottedleaf Date: Fri, 3 Apr 2020 02:21:13 -0700 Subject: [PATCH] Tuinity - Always able to execute tasks on the main server diff --git a/patches/server/0127-PaperPR-Fix-sand-duping.patch b/patches/server/0127-PaperPR-Fix-sand-duping.patch deleted file mode 100644 index c48fb2c20..000000000 --- a/patches/server/0127-PaperPR-Fix-sand-duping.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 64b50bd6c8b3b0556d1813ce6be147d741628fcc Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Fri, 12 Jun 2020 13:33:19 -0700 -Subject: [PATCH] PaperPR - Fix sand duping - -If the falling block dies during teleportation (entity#move), then we need -to detect that by placing a check after the move. ---- - .../java/net/minecraft/server/EntityFallingBlock.java | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/src/main/java/net/minecraft/server/EntityFallingBlock.java b/src/main/java/net/minecraft/server/EntityFallingBlock.java -index 6683f7c5f3..7969b1cd57 100644 ---- a/src/main/java/net/minecraft/server/EntityFallingBlock.java -+++ b/src/main/java/net/minecraft/server/EntityFallingBlock.java -@@ -64,6 +64,11 @@ public class EntityFallingBlock extends Entity { - - @Override - public void tick() { -+ // Purpur start - fix sand duping -+ if (this.dead) { -+ return; -+ } -+ // Purpur end - fix sand duping - if (this.block.isAir()) { - this.die(); - } else { -@@ -86,6 +91,12 @@ public class EntityFallingBlock extends Entity { - - this.move(EnumMoveType.SELF, this.getMot()); - -+ // Purpur start - fix sand duping -+ if (this.dead) { -+ return; -+ } -+ // Purpur end - fix sand duping -+ - // Paper start - Configurable EntityFallingBlock height nerf - if (this.world.paperConfig.fallingBlockHeightNerf != 0 && this.locY() > this.world.paperConfig.fallingBlockHeightNerf) { - if (this.dropItem && this.world.getGameRules().getBoolean(GameRules.DO_ENTITY_DROPS)) { --- -2.26.2 - diff --git a/patches/server/0132-YAPFA-Disable-mojang-profiler.patch b/patches/server/0127-YAPFA-Disable-mojang-profiler.patch similarity index 99% rename from patches/server/0132-YAPFA-Disable-mojang-profiler.patch rename to patches/server/0127-YAPFA-Disable-mojang-profiler.patch index e9cc64718..0ff201877 100644 --- a/patches/server/0132-YAPFA-Disable-mojang-profiler.patch +++ b/patches/server/0127-YAPFA-Disable-mojang-profiler.patch @@ -1,4 +1,4 @@ -From d4eb2bae7ba3e08c51270950cb62e7019c5365ca Mon Sep 17 00:00:00 2001 +From afb1d97066c5a40f9613a6cf66e85d4e67e948c2 Mon Sep 17 00:00:00 2001 From: tr7zw Date: Thu, 5 Mar 2020 23:08:01 +0100 Subject: [PATCH] YAPFA - Disable mojang profiler diff --git a/patches/server/0128-PaperPR-Prevent-position-desync-in-playerconnection-.patch b/patches/server/0128-PaperPR-Prevent-position-desync-in-playerconnection-.patch deleted file mode 100644 index ceb380c67..000000000 --- a/patches/server/0128-PaperPR-Prevent-position-desync-in-playerconnection-.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 9ecbe216e237d1ec36d673217db1c26e514748be Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Fri, 12 Jun 2020 16:51:39 -0700 -Subject: [PATCH] PaperPR - Prevent position desync in playerconnection causing - tp exploit - ---- - src/main/java/net/minecraft/server/PlayerConnection.java | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java -index 3a1aa1d4da..c13296935c 100644 ---- a/src/main/java/net/minecraft/server/PlayerConnection.java -+++ b/src/main/java/net/minecraft/server/PlayerConnection.java -@@ -1104,6 +1104,11 @@ public class PlayerConnection implements PacketListenerPlayIn { - } - - this.player.move(EnumMoveType.PLAYER, new Vec3D(d7, d8, d9)); -+ // Purpur start - prevent position desync -+ if (this.teleportPos != null) { -+ return; // ... thanks Mojang for letting move calls teleport across dimensions. -+ } -+ // Purpur end - prevent position desync - this.player.onGround = packetplayinflying.b(); - double d12 = d8; - --- -2.26.2 - diff --git a/patches/server/0129-PaperPR-Fix-enderdragon-exp-dupe.patch b/patches/server/0129-PaperPR-Fix-enderdragon-exp-dupe.patch deleted file mode 100644 index 318aaa2a1..000000000 --- a/patches/server/0129-PaperPR-Fix-enderdragon-exp-dupe.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 4720840046eea35a58d5f4a60bc7337f5ca9bce9 Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Fri, 12 Jun 2020 22:25:11 -0700 -Subject: [PATCH] PaperPR - Fix enderdragon exp dupe - ---- - src/main/java/net/minecraft/server/EntityEnderDragon.java | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/src/main/java/net/minecraft/server/EntityEnderDragon.java b/src/main/java/net/minecraft/server/EntityEnderDragon.java -index f06fde3242..6abe47f776 100644 ---- a/src/main/java/net/minecraft/server/EntityEnderDragon.java -+++ b/src/main/java/net/minecraft/server/EntityEnderDragon.java -@@ -33,7 +33,7 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster { - public float bx; - public float by; - public boolean bz; -- public int bA; -+ public int bA; public final int getDeathTicks() { return this.bA; } public final void setDeathTicks(final int value) { this.bA = value; } // Purpur - public float bB; - @Nullable - public EntityEnderCrystal currentEnderCrystal; -@@ -908,6 +908,7 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster { - public void b(NBTTagCompound nbttagcompound) { - super.b(nbttagcompound); - nbttagcompound.setInt("DragonPhase", this.bO.a().getControllerPhase().b()); -+ nbttagcompound.setInt("Paper.DeathTick", this.getDeathTicks()); // Purpur - } - - @Override -@@ -916,6 +917,7 @@ public class EntityEnderDragon extends EntityInsentient implements IMonster { - if (nbttagcompound.hasKey("DragonPhase")) { - this.bO.setControllerPhase(DragonControllerPhase.getById(nbttagcompound.getInt("DragonPhase"))); - } -+ this.setDeathTicks(nbttagcompound.getInt("Paper.DeathTick")); // Purpur - - } - --- -2.26.2 - diff --git a/patches/server/0131-Tuinity-Piston-pushable-TileEntities.patch b/patches/server/0131-Tuinity-Piston-pushable-TileEntities.patch deleted file mode 100644 index cbcfe6f37..000000000 --- a/patches/server/0131-Tuinity-Piston-pushable-TileEntities.patch +++ /dev/null @@ -1,714 +0,0 @@ -From 5a033005a5db9a2fa0d3c1dbff281d56469988ae Mon Sep 17 00:00:00 2001 -From: Spottedleaf -Date: Sun, 14 Jun 2020 00:34:47 -0700 -Subject: [PATCH] Tuinity - Piston pushable TileEntities - ---- - .../java/net/minecraft/server/BlockChest.java | 2 +- - .../net/minecraft/server/BlockPiston.java | 30 ++++++++- - .../minecraft/server/BlockPistonMoving.java | 7 ++- - src/main/java/net/minecraft/server/Chunk.java | 11 ++++ - .../java/net/minecraft/server/MCUtil.java | 14 +++++ - .../java/net/minecraft/server/TileEntity.java | 49 ++++++++++++++- - .../minecraft/server/TileEntityBeacon.java | 20 +++++- - .../minecraft/server/TileEntityBeehive.java | 7 +++ - .../server/TileEntityBrewingStand.java | 21 ++++++- - .../net/minecraft/server/TileEntityChest.java | 16 +++++ - .../minecraft/server/TileEntityConduit.java | 21 ++++++- - .../minecraft/server/TileEntityFurnace.java | 26 ++++++-- - .../minecraft/server/TileEntityJukeBox.java | 7 +++ - .../minecraft/server/TileEntityLectern.java | 23 ++++++- - .../minecraft/server/TileEntityPiston.java | 63 +++++++++++++++++-- - src/main/java/net/minecraft/server/World.java | 13 +++- - .../java/net/pl3x/purpur/PurpurConfig.java | 5 ++ - 17 files changed, 308 insertions(+), 27 deletions(-) - -diff --git a/src/main/java/net/minecraft/server/BlockChest.java b/src/main/java/net/minecraft/server/BlockChest.java -index 72fb92f7c3..e9d1847fd5 100644 ---- a/src/main/java/net/minecraft/server/BlockChest.java -+++ b/src/main/java/net/minecraft/server/BlockChest.java -@@ -10,7 +10,7 @@ import javax.annotation.Nullable; - public class BlockChest extends BlockChestAbstract implements IBlockWaterlogged { - - public static final BlockStateDirection FACING = BlockFacingHorizontal.FACING; -- public static final BlockStateEnum c = BlockProperties.ay; -+ public static final BlockStateEnum c = BlockProperties.ay; public static final BlockStateEnum getChestTypeEnum() { return BlockChest.c; } // Purpur - OBFHELPER - public static final BlockStateBoolean d = BlockProperties.C; - protected static final VoxelShape e = Block.a(1.0D, 0.0D, 0.0D, 15.0D, 14.0D, 15.0D); - protected static final VoxelShape f = Block.a(1.0D, 0.0D, 1.0D, 15.0D, 14.0D, 16.0D); -diff --git a/src/main/java/net/minecraft/server/BlockPiston.java b/src/main/java/net/minecraft/server/BlockPiston.java -index 0b7bed5e92..33b25d599e 100644 ---- a/src/main/java/net/minecraft/server/BlockPiston.java -+++ b/src/main/java/net/minecraft/server/BlockPiston.java -@@ -280,7 +280,10 @@ public class BlockPiston extends BlockDirectional { - return false; - } - -- return !block.isTileEntity(); -+ // Purpur start - pushable TE's -+ TileEntity tileEntity = world.getTileEntity(blockposition); -+ return !block.isTileEntity() || (tileEntity != null && tileEntity.isPushable()); -+ // Purpur end - pushable TE's - } else { - return false; - } -@@ -392,8 +395,29 @@ public class BlockPiston extends BlockDirectional { - map.remove(blockposition3); - world.setTypeAndData(blockposition3, (IBlockData) Blocks.MOVING_PISTON.getBlockData().set(BlockPiston.FACING, enumdirection), 68); - iblockdata1 = world.getType(oldPos); map.replace(oldPos, iblockdata1); // Purpur - fix piston physics inconsistency - move after the physics update -- world.setTileEntity(blockposition3, BlockPistonMoving.a(iblockdata1, enumdirection, flag, false)); // Paper - fix piston physics inconsistency -- world.setTypeAndData(oldPos, Blocks.AIR.getBlockData(), 68); // Purpur - set air to prevent later physics updates from seeing this block -+ // Purpur start - pushable TE's -+ TileEntity tileEntity = world.getTileEntity(oldPos); -+ if (tileEntity != null) { -+ if (!tileEntity.isPushable()) { -+ tileEntity = null; -+ } else { -+ // ensure the death of world tied state -+ if (tileEntity instanceof IInventory) { -+ MCUtil.closeInventory((IInventory)tileEntity, org.bukkit.event.inventory.InventoryCloseEvent.Reason.CANT_USE); -+ } -+ if (tileEntity instanceof TileEntityLectern) { -+ MCUtil.closeInventory(((TileEntityLectern)tileEntity).inventory, org.bukkit.event.inventory.InventoryCloseEvent.Reason.CANT_USE); -+ } -+ // now copy -+ tileEntity = tileEntity.createCopyForPush((WorldServer)world, oldPos, blockposition3, iblockdata1); -+ } -+ } -+ // removing the old pos TE is an ugly hack to prevent containers from dropping items -+ // when they're moved. -+ world.removeTileEntity(oldPos); -+ world.setTileEntity(blockposition3, BlockPistonMoving.createPistonTile(iblockdata1, enumdirection, flag, false, tileEntity)); // Paper - fix piston physics inconsistency -+ world.setTypeAndData(oldPos, Blocks.AIR.getBlockData(), 2 | 16 | 1024); // Paper - set air to prevent later physics updates from seeing this block -+ // Purpur end - pushable TE's - --j; - aiblockdata[j] = iblockdata1; - } -diff --git a/src/main/java/net/minecraft/server/BlockPistonMoving.java b/src/main/java/net/minecraft/server/BlockPistonMoving.java -index 809ee9f9a6..93dfd0fa8d 100644 ---- a/src/main/java/net/minecraft/server/BlockPistonMoving.java -+++ b/src/main/java/net/minecraft/server/BlockPistonMoving.java -@@ -21,7 +21,12 @@ public class BlockPistonMoving extends BlockTileEntity { - } - - public static TileEntity a(IBlockData iblockdata, EnumDirection enumdirection, boolean flag, boolean flag1) { -- return new TileEntityPiston(iblockdata, enumdirection, flag, flag1); -+ // Purpur start - add tileEntity parameter -+ return createPistonTile(iblockdata, enumdirection, flag, flag1, null); -+ } -+ public static TileEntity createPistonTile(IBlockData iblockdata, EnumDirection enumdirection, boolean flag, boolean flag1, TileEntity tileEntity) { -+ return new TileEntityPiston(iblockdata, enumdirection, flag, flag1, tileEntity); -+ // Purpur end - add tileEntity parameter - } - - @Override -diff --git a/src/main/java/net/minecraft/server/Chunk.java b/src/main/java/net/minecraft/server/Chunk.java -index d7beb47d9e..c7bedee89e 100644 ---- a/src/main/java/net/minecraft/server/Chunk.java -+++ b/src/main/java/net/minecraft/server/Chunk.java -@@ -511,6 +511,12 @@ public class Chunk implements IChunkAccess { - - @Nullable - public IBlockData setType(BlockPosition blockposition, IBlockData iblockdata, boolean flag, boolean doPlace) { -+ // Purpur start - add tileEntity parameter -+ return this.setType(blockposition, iblockdata, flag, doPlace, null); -+ } -+ @Nullable -+ public IBlockData setType(BlockPosition blockposition, IBlockData iblockdata, boolean flag, boolean doPlace, TileEntity newTileEntity) { -+ // Purpur end - add tileEntity parameter - // CraftBukkit end - int i = blockposition.getX() & 15; - int j = blockposition.getY(); -@@ -569,6 +575,10 @@ public class Chunk implements IChunkAccess { - } - - if (block instanceof ITileEntity) { -+ // Purpur start - add tileEntity parameter -+ if (newTileEntity != null) { -+ this.world.setTileEntity(blockposition, newTileEntity); -+ } else { // Purpur end - add tileEntity parameter - tileentity = this.a(blockposition, Chunk.EnumTileEntityState.CHECK); - if (tileentity == null) { - tileentity = ((ITileEntity) block).createTile(this.world); -@@ -576,6 +586,7 @@ public class Chunk implements IChunkAccess { - } else { - tileentity.invalidateBlockCache(); - } -+ } // Purpur - add tileEntity parameter - } - - this.s = true; -diff --git a/src/main/java/net/minecraft/server/MCUtil.java b/src/main/java/net/minecraft/server/MCUtil.java -index 87d5800211..6b97484031 100644 ---- a/src/main/java/net/minecraft/server/MCUtil.java -+++ b/src/main/java/net/minecraft/server/MCUtil.java -@@ -48,6 +48,20 @@ public final class MCUtil { - new ThreadFactoryBuilder().setNameFormat("Paper Object Cleaner").build() - ); - -+ // Purpur start -+ private static org.bukkit.entity.HumanEntity[] EMPTY_HUMAN_ARRAY = new org.bukkit.entity.HumanEntity[0]; -+ public static void closeInventory(IInventory inventory, org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) { -+ List viewers = inventory.getViewers(); -+ if (viewers.isEmpty()) { -+ return; -+ } -+ -+ for (org.bukkit.entity.HumanEntity viewer : viewers.toArray(EMPTY_HUMAN_ARRAY)) { -+ viewer.closeInventory(reason); -+ } -+ } -+ // Purpur end -+ - public static final long INVALID_CHUNK_KEY = getCoordinateKey(Integer.MAX_VALUE, Integer.MAX_VALUE); - - -diff --git a/src/main/java/net/minecraft/server/TileEntity.java b/src/main/java/net/minecraft/server/TileEntity.java -index a8e64dfdab..3cd3ba1175 100644 ---- a/src/main/java/net/minecraft/server/TileEntity.java -+++ b/src/main/java/net/minecraft/server/TileEntity.java -@@ -12,7 +12,7 @@ import org.bukkit.inventory.InventoryHolder; - import co.aikar.timings.MinecraftTimings; // Paper - import co.aikar.timings.Timing; // Paper - --public abstract class TileEntity implements KeyedObject { // Paper -+public abstract class TileEntity implements KeyedObject, Cloneable { // Purpur // Paper - - public Timing tickTimer = MinecraftTimings.getTileEntityTimings(this); // Paper - // CraftBukkit start - data containers -@@ -27,7 +27,7 @@ public abstract class TileEntity implements KeyedObject { // Paper - protected BlockPosition position; - protected boolean f; - @Nullable -- private IBlockData c; -+ private IBlockData c;protected final IBlockData getBlockDataCache() { return this.c; } public final void setBlockDataCache(final IBlockData value) { this.c = value; } // Purpur - OBFHELPER - private boolean g; - - public TileEntity(TileEntityTypes tileentitytypes) { -@@ -35,6 +35,51 @@ public abstract class TileEntity implements KeyedObject { // Paper - this.tileType = tileentitytypes; - } - -+ // Purpur start - pushable TE's -+ public boolean isPushable() { -+ if (!net.pl3x.purpur.PurpurConfig.pistonsCanPushTileEntities) { -+ return false; -+ } -+ IBlockData block = this.getBlock(); -+ if (this.isRemoved() || !this.tileType.isValidBlock(block.getBlock())) { -+ return false; -+ } -+ EnumPistonReaction reaction = block.getPushReaction(); -+ return reaction == EnumPistonReaction.NORMAL || reaction == EnumPistonReaction.PUSH_ONLY; -+ } -+ -+ @Override -+ protected final TileEntity clone() { -+ try { -+ return (TileEntity)super.clone(); -+ } catch (final Throwable thr) { -+ if (thr instanceof ThreadDeath) { -+ throw (ThreadDeath)thr; -+ } -+ throw new InternalError(thr); -+ } -+ } -+ -+ // this method presumes the old TE has been completely dropped from worldstate and has no ties to it anymore (this -+ // includes players interacting with them) -+ public TileEntity createCopyForPush(WorldServer world, BlockPosition oldPos, BlockPosition newPos, IBlockData blockData) { -+ final TileEntity copy = this.clone(); -+ -+ copy.world = world; -+ copy.position = newPos; -+ -+ // removed is manually set to false after placing the entity into the world. -+ copy.setBlockDataCache(blockData); -+ -+ return copy; -+ } -+ -+ // updates TE state to its new position -+ public void onPostPush() { -+ this.update(); -+ } -+ // Purpur end - pushable TE's -+ - // Paper start - private String tileEntityKeyString = null; - private MinecraftKey tileEntityKey = null; -diff --git a/src/main/java/net/minecraft/server/TileEntityBeacon.java b/src/main/java/net/minecraft/server/TileEntityBeacon.java -index df2d6c3b07..333a40d4fa 100644 ---- a/src/main/java/net/minecraft/server/TileEntityBeacon.java -+++ b/src/main/java/net/minecraft/server/TileEntityBeacon.java -@@ -35,7 +35,7 @@ public class TileEntityBeacon extends TileEntity implements ITileInventory, ITic - @Nullable - public IChatBaseComponent customName; - public ChestLock chestLock; -- private final IContainerProperties containerProperties; -+ private IContainerProperties containerProperties; // Purpur - need non-final for `createCopyForPush` - // CraftBukkit start - add fields and methods - public PotionEffect getPrimaryEffect() { - return (this.primaryEffect != null) ? CraftPotionUtil.toBukkit(new MobEffect(this.primaryEffect, getLevel(), getAmplification(), true, true)) : null; -@@ -49,8 +49,12 @@ public class TileEntityBeacon extends TileEntity implements ITileInventory, ITic - public TileEntityBeacon() { - super(TileEntityTypes.BEACON); - this.chestLock = ChestLock.a; -- this.containerProperties = new IContainerProperties() { -- @Override -+ // Purpur start - pushable TE's -+ this.containerProperties = this.getNewContainerProperties(); -+ } -+ protected final IContainerProperties getNewContainerProperties() { -+ return new IContainerProperties() { -+ // Purpur end - pushable TE's - public int getProperty(int i) { - switch (i) { - case 0: -@@ -90,6 +94,16 @@ public class TileEntityBeacon extends TileEntity implements ITileInventory, ITic - }; - } - -+ // Purpur start - pushable TE's -+ @Override -+ public TileEntity createCopyForPush(WorldServer world, BlockPosition oldPos, BlockPosition newPos, IBlockData blockData) { -+ TileEntityBeacon copy = (TileEntityBeacon)super.createCopyForPush(world, oldPos, newPos, blockData); -+ copy.containerProperties = copy.getNewContainerProperties(); // old properties retains reference to old te -+ -+ return copy; -+ } -+ // Purpur end - pushable TE's -+ - @Override - public void tick() { - int i = this.position.getX(); -diff --git a/src/main/java/net/minecraft/server/TileEntityBeehive.java b/src/main/java/net/minecraft/server/TileEntityBeehive.java -index 417152d16c..b8e7e82ab3 100644 ---- a/src/main/java/net/minecraft/server/TileEntityBeehive.java -+++ b/src/main/java/net/minecraft/server/TileEntityBeehive.java -@@ -12,6 +12,13 @@ public class TileEntityBeehive extends TileEntity implements ITickable { - public BlockPosition flowerPos = null; - public int maxBees = 3; // CraftBukkit - allow setting max amount of bees a hive can hold - -+ // Purpur start - pushable TE's -+ @Override -+ public boolean isPushable() { -+ return false; // TODO until there is a good solution to making the already existing bees in the world re-acquire this position, this cannot be done. -+ } -+ // Purpur end - pushable TE's -+ - public TileEntityBeehive() { - super(TileEntityTypes.BEEHIVE); - } -diff --git a/src/main/java/net/minecraft/server/TileEntityBrewingStand.java b/src/main/java/net/minecraft/server/TileEntityBrewingStand.java -index 441157cf7f..3a5b7a7151 100644 ---- a/src/main/java/net/minecraft/server/TileEntityBrewingStand.java -+++ b/src/main/java/net/minecraft/server/TileEntityBrewingStand.java -@@ -24,7 +24,7 @@ public class TileEntityBrewingStand extends TileEntityContainer implements IWorl - private boolean[] j; - private Item k; - public int fuelLevel; -- protected final IContainerProperties a; -+ protected IContainerProperties a; protected final void setContainerProperties(IContainerProperties value) { this.a = value; } // Purpur - OBFHELPER // Purpur - need non-final for `createCopyForPush` - // CraftBukkit start - add fields and methods - private int lastTick = MinecraftServer.currentTick; - public List transaction = new java.util.ArrayList(); -@@ -59,7 +59,13 @@ public class TileEntityBrewingStand extends TileEntityContainer implements IWorl - public TileEntityBrewingStand() { - super(TileEntityTypes.BREWING_STAND); - this.items = NonNullList.a(5, ItemStack.a); -- this.a = new IContainerProperties() { -+ // Purpur start - pushable TE's -+ this.a = this.getNewContainerProperties(); -+ } -+ protected final IContainerProperties getNewContainerProperties() { -+ // moved from constructor - this should be re-copied if it changes -+ return new IContainerProperties() { -+ // Purpur end - pushable TE's - @Override - public int getProperty(int i) { - switch (i) { -@@ -91,6 +97,17 @@ public class TileEntityBrewingStand extends TileEntityContainer implements IWorl - }; - } - -+ // Purpur start - pushable TE's -+ @Override -+ public TileEntity createCopyForPush(WorldServer world, BlockPosition oldPos, BlockPosition newPos, IBlockData blockData) { -+ TileEntityBrewingStand copy = (TileEntityBrewingStand)super.createCopyForPush(world, oldPos, newPos, blockData); -+ -+ copy.setContainerProperties(copy.getNewContainerProperties()); // old properties retains reference to old te -+ -+ return copy; -+ } -+ // Purpur end - pushable TE's -+ - @Override - protected IChatBaseComponent getContainerName() { - return new ChatMessage("container.brewing", new Object[0]); -diff --git a/src/main/java/net/minecraft/server/TileEntityChest.java b/src/main/java/net/minecraft/server/TileEntityChest.java -index 9a5f2da8c0..f33f33bad9 100644 ---- a/src/main/java/net/minecraft/server/TileEntityChest.java -+++ b/src/main/java/net/minecraft/server/TileEntityChest.java -@@ -45,6 +45,22 @@ public class TileEntityChest extends TileEntityLootable { // Paper - Remove ITic - } - // CraftBukkit end - -+ // Purpur start -+ @Override -+ public boolean isPushable() { -+ if (!super.isPushable()) { -+ return false; -+ } -+ // what should happen when a double chest is moved is generally just a mess to deal with in the current -+ // codebase. TODO try and figure it out -+ IBlockData type = this.getBlock(); -+ if (type.getBlock() == Blocks.CHEST || type.getBlock() == Blocks.TRAPPED_CHEST) { -+ return type.get(BlockChest.getChestTypeEnum()) == BlockPropertyChestType.SINGLE; -+ } -+ return false; -+ } -+ // Purpur end -+ - protected TileEntityChest(TileEntityTypes tileentitytypes) { - super(tileentitytypes); - this.items = NonNullList.a(27, ItemStack.a); -diff --git a/src/main/java/net/minecraft/server/TileEntityConduit.java b/src/main/java/net/minecraft/server/TileEntityConduit.java -index 07f265b299..44ea73a7c6 100644 ---- a/src/main/java/net/minecraft/server/TileEntityConduit.java -+++ b/src/main/java/net/minecraft/server/TileEntityConduit.java -@@ -16,15 +16,32 @@ public class TileEntityConduit extends TileEntity implements ITickable { - private static final Block[] b = new Block[]{Blocks.PRISMARINE, Blocks.PRISMARINE_BRICKS, Blocks.SEA_LANTERN, Blocks.DARK_PRISMARINE}; - public int a; - private float c; -- private boolean g; -+ private boolean g; private final void setActive(boolean value) { this.g = value; } // Purpur - OBFHELPER - private boolean h; -- private final List i; -+ private final List i; private final List getPositionsActivating() { return this.i; } // Purpur - OBFHELPER - @Nullable - private EntityLiving target; - @Nullable - private UUID k; - private long l; - -+ // Purpur start - make TE's pushable -+ @Override -+ public TileEntity createCopyForPush(WorldServer world, BlockPosition oldPos, BlockPosition newPos, IBlockData blockData) { -+ final TileEntityConduit copy = (TileEntityConduit)super.createCopyForPush(world, oldPos, newPos, blockData); -+ -+ // the following states need to be re-calculated -+ copy.getPositionsActivating().clear(); -+ copy.setActive(false); -+ copy.target = null; -+ // also set our state because the copy and this share the same activating block list -+ this.setActive(false); -+ this.target = null; -+ -+ return copy; -+ } -+ // Purpur end - make TE's pushable -+ - public TileEntityConduit() { - this(TileEntityTypes.CONDUIT); - } -diff --git a/src/main/java/net/minecraft/server/TileEntityFurnace.java b/src/main/java/net/minecraft/server/TileEntityFurnace.java -index 91ef7ac60f..3ad5041cab 100644 ---- a/src/main/java/net/minecraft/server/TileEntityFurnace.java -+++ b/src/main/java/net/minecraft/server/TileEntityFurnace.java -@@ -30,14 +30,23 @@ public abstract class TileEntityFurnace extends TileEntityContainer implements I - public double cookSpeedMultiplier = 1.0; // Paper - cook speed multiplier API - public int cookTime; - public int cookTimeTotal; -- protected final IContainerProperties b; -+ protected IContainerProperties b; protected final void setContainerProperties(IContainerProperties value) { this.b = value; } // Purpur - OBFHELPER // Purpur - need non-final for `createCopyForPush` - private final Map n; - protected final Recipes c; - - protected TileEntityFurnace(TileEntityTypes tileentitytypes, Recipes recipes) { - super(tileentitytypes); - this.items = NonNullList.a(3, ItemStack.a); -- this.b = new IContainerProperties() { -+ this.b = this.getNewContainerProperties(); // Purpur - pushable TE's -+ this.n = Maps.newHashMap(); -+ this.c = recipes; -+ } -+ -+ // Purpur start - pushable TE's -+ protected final IContainerProperties getNewContainerProperties() { -+ // moved from constructor - this should be re-copied if it changes -+ return new IContainerProperties() { -+ // Purpur end - pushable TE's - @Override - public int getProperty(int i) { - switch (i) { -@@ -77,10 +86,19 @@ public abstract class TileEntityFurnace extends TileEntityContainer implements I - return 4; - } - }; -- this.n = Maps.newHashMap(); -- this.c = recipes; - } - -+ // Purpur start - pushable TE's -+ @Override -+ public TileEntity createCopyForPush(WorldServer world, BlockPosition oldPos, BlockPosition newPos, IBlockData blockData) { -+ TileEntityFurnace copy = (TileEntityFurnace)super.createCopyForPush(world, oldPos, newPos, blockData); -+ -+ copy.setContainerProperties(copy.getNewContainerProperties()); // old properties retains reference to old te -+ -+ return copy; -+ } -+ // Purpur end - pushable TE's -+ - public static Map f() { - Map map = Maps.newLinkedHashMap(); - -diff --git a/src/main/java/net/minecraft/server/TileEntityJukeBox.java b/src/main/java/net/minecraft/server/TileEntityJukeBox.java -index d66d9ff188..284eb8d000 100644 ---- a/src/main/java/net/minecraft/server/TileEntityJukeBox.java -+++ b/src/main/java/net/minecraft/server/TileEntityJukeBox.java -@@ -4,6 +4,13 @@ public class TileEntityJukeBox extends TileEntity implements Clearable { - - private ItemStack a; - -+ // Purpur start - pushable TE's -+ @Override -+ public boolean isPushable() { -+ return false; // disabled due to buggy sound -+ } -+ // Purpur end - pushable TE's -+ - public TileEntityJukeBox() { - super(TileEntityTypes.JUKEBOX); - this.a = ItemStack.a; -diff --git a/src/main/java/net/minecraft/server/TileEntityLectern.java b/src/main/java/net/minecraft/server/TileEntityLectern.java -index 6c2b48bdbe..dbe5faf0ed 100644 ---- a/src/main/java/net/minecraft/server/TileEntityLectern.java -+++ b/src/main/java/net/minecraft/server/TileEntityLectern.java -@@ -16,7 +16,7 @@ import org.bukkit.inventory.InventoryHolder; - public class TileEntityLectern extends TileEntity implements Clearable, ITileInventory, ICommandListener { // CraftBukkit - ICommandListener - - // CraftBukkit start - add fields and methods -- public final IInventory inventory = new LecternInventory(); -+ public IInventory inventory = new LecternInventory(); // Purpur - need non-final for `createCopyForPush` - public class LecternInventory implements IInventory { - - public List transaction = new ArrayList<>(); -@@ -136,7 +136,12 @@ public class TileEntityLectern extends TileEntity implements Clearable, ITileInv - @Override - public void clear() {} - }; -- private final IContainerProperties containerProperties = new IContainerProperties() { -+ // Purpur start - pushable TE's -+ private IContainerProperties containerProperties = this.getNewContainerProperties(); // Purpur - need non-final for `createCopyForPush` -+ -+ protected final IContainerProperties getNewContainerProperties() { -+ return new IContainerProperties() { -+ // Purpur end - pushable TE's - @Override - public int getProperty(int i) { - return i == 0 ? TileEntityLectern.this.page : 0; -@@ -155,6 +160,20 @@ public class TileEntityLectern extends TileEntity implements Clearable, ITileInv - return 1; - } - }; -+ // Purpur start - pushable TE's -+ } -+ -+ @Override -+ public TileEntity createCopyForPush(WorldServer world, BlockPosition oldPos, BlockPosition newPos, IBlockData blockData) { -+ TileEntityLectern copy = (TileEntityLectern)super.createCopyForPush(world, oldPos, newPos, blockData); -+ -+ copy.inventory = copy.new LecternInventory(); -+ copy.containerProperties = copy.getNewContainerProperties(); // old properties retains reference to old te -+ -+ return copy; -+ } -+ // Purpur end - pushable TE's -+ - private ItemStack book; - private int page; - private int maxPage; -diff --git a/src/main/java/net/minecraft/server/TileEntityPiston.java b/src/main/java/net/minecraft/server/TileEntityPiston.java -index 946522f636..93c54eb08f 100644 ---- a/src/main/java/net/minecraft/server/TileEntityPiston.java -+++ b/src/main/java/net/minecraft/server/TileEntityPiston.java -@@ -5,10 +5,10 @@ import java.util.List; - - public class TileEntityPiston extends TileEntity implements ITickable { - -- private IBlockData a; -+ private IBlockData a; protected final IBlockData getBlockData() { return this.a; } // Purpur - OBFHELPER - private EnumDirection b; - private boolean c; -- private boolean g; -+ private boolean g; protected final boolean isSource() { return this.g; } // Purpur - OBFHELPER - private static final ThreadLocal h = ThreadLocal.withInitial(() -> { - return null; - }); -@@ -16,12 +16,27 @@ public class TileEntityPiston extends TileEntity implements ITickable { - private float j; - private long k; - -+ // Purpur start - pushable TE's -+ private TileEntity tileEntity; -+ -+ @Override -+ public boolean isPushable() { -+ return false; // fuck no. -+ } -+ // Purpur end - pushable TE's -+ - public TileEntityPiston() { - super(TileEntityTypes.PISTON); - } - - public TileEntityPiston(IBlockData iblockdata, EnumDirection enumdirection, boolean flag, boolean flag1) { -+ // Purpur start - add tileEntity parameter -+ this(iblockdata, enumdirection, flag, flag1, null); -+ } -+ public TileEntityPiston(IBlockData iblockdata, EnumDirection enumdirection, boolean flag, boolean flag1, TileEntity tileEntity) { - this(); -+ this.tileEntity = tileEntity; -+ // Purpur end - add tileEntity parameter - this.a = iblockdata; - this.b = enumdirection; - this.c = flag; -@@ -30,7 +45,7 @@ public class TileEntityPiston extends TileEntity implements ITickable { - - @Override - public NBTTagCompound b() { -- return this.save(new NBTTagCompound()); -+ return this.save(new NBTTagCompound(), false); // Purpur - clients don't need the copied tile entity. - } - - public boolean d() { -@@ -257,7 +272,22 @@ public class TileEntityPiston extends TileEntity implements ITickable { - iblockdata = Block.b(this.a, (GeneratorAccess) this.world, this.position); - } - -- this.world.setTypeAndData(this.position, iblockdata, 3); -+ // Purpur start - pushable TE's -+ if ((iblockdata.isAir() && !this.isSource()) && !this.getBlockData().isAir()) { -+ // if the block can't exist at the location anymore, we need to fire drops for it, as -+ // setTypeAndData wont. -+ -+ // careful - the previous pos is moving_piston, which wont fire drops. So we're safe from dupes. -+ // but the setAir should be before the drop. -+ this.world.setAir(this.position, false); -+ Block.dropItems(this.getBlockData(), this.world, this.position, null, null, ItemStack.NULL_ITEM); -+ } else { -+ this.world.setTypeAndData(this.position, iblockdata, 3, iblockdata.getBlock() == this.getBlockData().getBlock() ? this.tileEntity : null); -+ } -+ if (this.tileEntity != null && this.world.getType(this.position).getBlock() == this.getBlockData().getBlock()) { -+ this.tileEntity.onPostPush(); -+ } -+ // Purpur end - pushable TE's - this.world.a(this.position, iblockdata.getBlock(), this.position); - } - } -@@ -282,7 +312,12 @@ public class TileEntityPiston extends TileEntity implements ITickable { - iblockdata = (IBlockData) iblockdata.set(BlockProperties.C, false); - } - -- this.world.setTypeAndData(this.position, iblockdata, 67); -+ // Purpur start - pushable TE's -+ this.world.setTypeAndData(this.position, iblockdata, 67, this.tileEntity); -+ if (this.tileEntity != null && this.world.getType(this.position).getBlock() == this.getBlockData().getBlock()) { -+ this.tileEntity.onPostPush(); -+ } -+ // Purpur end - pushable TE's - this.world.a(this.position, iblockdata.getBlock(), this.position); - } - } -@@ -309,16 +344,34 @@ public class TileEntityPiston extends TileEntity implements ITickable { - this.j = this.i; - this.c = nbttagcompound.getBoolean("extending"); - this.g = nbttagcompound.getBoolean("source"); -+ // Purpur start - pushable TE's -+ if (nbttagcompound.hasKey("Purpur.tileEntity")) { -+ NBTTagCompound compound = nbttagcompound.getCompound("Purpur.tileEntity"); -+ if (!compound.isEmpty()) { -+ this.tileEntity = TileEntity.create(compound); -+ } -+ } -+ // Purpur end - pushable TE's - } - - @Override - public NBTTagCompound save(NBTTagCompound nbttagcompound) { -+ // Purpur start - add saveTile param -+ return this.save(nbttagcompound, true); -+ } -+ public NBTTagCompound save(NBTTagCompound nbttagcompound, boolean saveTile) { -+ // Purpur end - add saveTile param - super.save(nbttagcompound); - nbttagcompound.set("blockState", GameProfileSerializer.a(this.a)); - nbttagcompound.setInt("facing", this.b.b()); - nbttagcompound.setFloat("progress", this.j); - nbttagcompound.setBoolean("extending", this.c); - nbttagcompound.setBoolean("source", this.g); -+ // Purpur start - pushable TE's -+ if (saveTile && this.tileEntity != null) { -+ nbttagcompound.set("Purpur.tileEntity", this.tileEntity.save(new NBTTagCompound())); -+ } -+ // Purpur end - pushable TE's - return nbttagcompound; - } - -diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java -index 41e977d1e0..1c444a6474 100644 ---- a/src/main/java/net/minecraft/server/World.java -+++ b/src/main/java/net/minecraft/server/World.java -@@ -342,6 +342,15 @@ public abstract class World implements GeneratorAccess, AutoCloseable { - - @Override - public boolean setTypeAndData(BlockPosition blockposition, IBlockData iblockdata, int i) { -+ // Purpur start - add tileEntity parameter -+ return this.setTypeAndData(blockposition, iblockdata, i, null); -+ } -+ public boolean setTypeAndData(BlockPosition blockposition, IBlockData iblockdata, int i, TileEntity tileEntity) { -+ if (tileEntity != null) { -+ // even though we set it later in the call, some calls actually remove it / check it. -+ this.setTileEntity(blockposition, tileEntity); -+ } -+ // Purpur end - add tileEntity parameter - // CraftBukkit start - tree generation - if (this.captureTreeGeneration) { - // Paper start -@@ -374,7 +383,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable { - } - // CraftBukkit end - -- IBlockData iblockdata1 = chunk.setType(blockposition, iblockdata, (i & 64) != 0, (i & 1024) == 0); // CraftBukkit custom NO_PLACE flag -+ IBlockData iblockdata1 = chunk.setType(blockposition, iblockdata, (i & 64) != 0, (i & 1024) == 0, tileEntity); // CraftBukkit custom NO_PLACE flag // Purpur - add tileEntity parameter - this.chunkPacketBlockController.onBlockChange(this, blockposition, iblockdata, iblockdata1, i); // Paper - Anti-Xray - - if (iblockdata1 == null) { -@@ -1111,7 +1120,7 @@ public abstract class World implements GeneratorAccess, AutoCloseable { - while (iterator.hasNext()) { - TileEntity tileentity1 = (TileEntity) iterator.next(); - -- if (tileentity1.getPosition().equals(blockposition)) { -+ if (tileentity != tileentity1 && tileentity1.getPosition().equals(blockposition)) { // Purpur - don't remove us if we double set... - tileentity1.ab_(); - iterator.remove(); - } -diff --git a/src/main/java/net/pl3x/purpur/PurpurConfig.java b/src/main/java/net/pl3x/purpur/PurpurConfig.java -index ab88636cad..defe880a6e 100644 ---- a/src/main/java/net/pl3x/purpur/PurpurConfig.java -+++ b/src/main/java/net/pl3x/purpur/PurpurConfig.java -@@ -206,4 +206,9 @@ public class PurpurConfig { - enchantment.setMaxLevel(maxLevel); - } - } -+ -+ public static boolean pistonsCanPushTileEntities = false; -+ private static void pistonsCanPushTileEntities() { -+ pistonsCanPushTileEntities = getBoolean("settings.blocks.pistons.can-push-tile-entities", pistonsCanPushTileEntities); -+ } - } --- -2.26.2 -