mirror of
https://github.com/PurpurMC/Purpur.git
synced 2026-02-17 16:37:43 +01:00
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)
This commit is contained in:
2
Paper
2
Paper
Submodule Paper updated: 83e832b44c...9ffaa44ae1
@@ -1 +1 @@
|
||||
1.15.2--72e6dee61f700df6e67fc888ef11eb97202b7dd8
|
||||
1.15.2--bde4d33a1afce5fd1cbad2c640a028ab3ea7fd1c
|
||||
|
||||
206
patches/server/0125-PaperPR-3550-Fix-more-exploits.patch
Normal file
206
patches/server/0125-PaperPR-3550-Fix-more-exploits.patch
Normal file
@@ -0,0 +1,206 @@
|
||||
From c17ddd1bb257b49ab887fd8371c3ff0588cb7270 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] 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
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
From d5525ef160f81107273a8900513f869ae4f284d3 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] 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
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
From 42e0355d159e2e4f8f931b2f0d9599a9ef541754 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
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
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
From 6b6fcb9d7ec44fbb629145a1a2d37770d5b60fb8 Mon Sep 17 00:00:00 2001
|
||||
From f3054cc2a7f88ef976d520a933e31ae19f7266b6 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <spottedleaf@spottedleaf.dev>
|
||||
Date: Fri, 3 Apr 2020 02:21:13 -0700
|
||||
Subject: [PATCH] Tuinity - Always able to execute tasks on the main server
|
||||
@@ -1,43 +0,0 @@
|
||||
From 64b50bd6c8b3b0556d1813ce6be147d741628fcc Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
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
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
From d4eb2bae7ba3e08c51270950cb62e7019c5365ca Mon Sep 17 00:00:00 2001
|
||||
From afb1d97066c5a40f9613a6cf66e85d4e67e948c2 Mon Sep 17 00:00:00 2001
|
||||
From: tr7zw <tr7zw@live.de>
|
||||
Date: Thu, 5 Mar 2020 23:08:01 +0100
|
||||
Subject: [PATCH] YAPFA - Disable mojang profiler
|
||||
@@ -1,29 +0,0 @@
|
||||
From 9ecbe216e237d1ec36d673217db1c26e514748be Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
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
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
From 4720840046eea35a58d5f4a60bc7337f5ca9bce9 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
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
|
||||
|
||||
@@ -1,714 +0,0 @@
|
||||
From 5a033005a5db9a2fa0d3c1dbff281d56469988ae Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <spottedleaf@spottedleaf.dev>
|
||||
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<TileEntityChest> implements IBlockWaterlogged {
|
||||
|
||||
public static final BlockStateDirection FACING = BlockFacingHorizontal.FACING;
|
||||
- public static final BlockStateEnum<BlockPropertyChestType> c = BlockProperties.ay;
|
||||
+ public static final BlockStateEnum<BlockPropertyChestType> c = BlockProperties.ay; public static final BlockStateEnum<BlockPropertyChestType> 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<org.bukkit.entity.HumanEntity> 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<HumanEntity> transaction = new java.util.ArrayList<HumanEntity>();
|
||||
@@ -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<BlockPosition> i;
|
||||
+ private final List<BlockPosition> i; private final List<BlockPosition> 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<MinecraftKey, Integer> n;
|
||||
protected final Recipes<? extends RecipeCooking> c;
|
||||
|
||||
protected TileEntityFurnace(TileEntityTypes<?> tileentitytypes, Recipes<? extends RecipeCooking> 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<Item, Integer> f() {
|
||||
Map<Item, Integer> 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<HumanEntity> 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<EnumDirection> 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
|
||||
|
||||
Reference in New Issue
Block a user