From 0c5a1772817875126b88a1c4f58604fed54a3596 Mon Sep 17 00:00:00 2001 From: mworzala Date: Sat, 2 Dec 2023 11:39:19 +0200 Subject: [PATCH] fix: ensure block placements can only happen inside the world border --- .../listener/BlockPlacementListener.java | 7 ++- .../instance/BlockPlaceIntegrationTest.java | 43 +++++++++++++++++++ .../server/instance/BlockPlaceTest.java | 19 -------- 3 files changed, 49 insertions(+), 20 deletions(-) create mode 100644 src/test/java/net/minestom/server/instance/BlockPlaceIntegrationTest.java delete mode 100644 src/test/java/net/minestom/server/instance/BlockPlaceTest.java diff --git a/src/main/java/net/minestom/server/listener/BlockPlacementListener.java b/src/main/java/net/minestom/server/listener/BlockPlacementListener.java index 8d931529e..723f0e139 100644 --- a/src/main/java/net/minestom/server/listener/BlockPlacementListener.java +++ b/src/main/java/net/minestom/server/listener/BlockPlacementListener.java @@ -112,9 +112,14 @@ public class BlockPlacementListener { } } - if(placementPosition.y() >= instance.getDimensionType().getMaxY() + if (placementPosition.y() >= instance.getDimensionType().getMaxY() || placementPosition.y() <= instance.getDimensionType().getMinY()) return; + // Ensure that the final placement position is inside the world border. + if (!instance.getWorldBorder().isInside(placementPosition)) { + canPlaceBlock = false; + } + if (!canPlaceBlock) { // Send a block change with the real block in the instance to keep the client in sync, // using refreshChunk results in the client not being in sync diff --git a/src/test/java/net/minestom/server/instance/BlockPlaceIntegrationTest.java b/src/test/java/net/minestom/server/instance/BlockPlaceIntegrationTest.java new file mode 100644 index 000000000..9a64a0eda --- /dev/null +++ b/src/test/java/net/minestom/server/instance/BlockPlaceIntegrationTest.java @@ -0,0 +1,43 @@ +package net.minestom.server.instance; + +import net.minestom.server.coordinate.Pos; +import net.minestom.server.entity.Player; +import net.minestom.server.instance.block.Block; +import net.minestom.server.instance.block.BlockFace; +import net.minestom.server.item.ItemStack; +import net.minestom.server.item.Material; +import net.minestom.server.listener.BlockPlacementListener; +import net.minestom.server.network.packet.client.play.ClientPlayerBlockPlacementPacket; +import net.minestom.testing.Env; +import net.minestom.testing.EnvTest; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +@EnvTest +public class BlockPlaceIntegrationTest { + + @Test + void testPlacementOutOfLimit(Env env) { + Instance instance = env.createFlatInstance(); + assertDoesNotThrow(() -> instance.setBlock(0, instance.getDimensionType().getMaxY() + 1, 0, Block.STONE)); + assertDoesNotThrow(() -> instance.setBlock(0, instance.getDimensionType().getMinY() - 1, 0, Block.STONE)); + } + + @Test + void testPlacementOutOfBorder(Env env) { + Instance instance = env.createFlatInstance(); + instance.getWorldBorder().setDiameter(1); + var player = env.createPlayer(instance, new Pos(0, 40, 0)); + player.setItemInHand(Player.Hand.MAIN, ItemStack.of(Material.STONE, 5)); + + // Should be air, then we place (this is outside the border) + assertEquals(Block.AIR, instance.getBlock(3, 40, 0)); + var placePacket = new ClientPlayerBlockPlacementPacket(Player.Hand.MAIN, new Pos(3, 39, 0), BlockFace.TOP, 0.5f, 0.5f, 0.5f, false, 1); + BlockPlacementListener.listener(placePacket, player); + + // Should still be air + var placedBlock = instance.getBlock(3, 40, 0); + assertEquals(Block.AIR, placedBlock); + } +} diff --git a/src/test/java/net/minestom/server/instance/BlockPlaceTest.java b/src/test/java/net/minestom/server/instance/BlockPlaceTest.java deleted file mode 100644 index 01dfa9848..000000000 --- a/src/test/java/net/minestom/server/instance/BlockPlaceTest.java +++ /dev/null @@ -1,19 +0,0 @@ -package net.minestom.server.instance; - -import net.minestom.server.instance.block.Block; -import net.minestom.testing.Env; -import net.minestom.testing.EnvTest; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; - -@EnvTest -public class BlockPlaceTest { - - @Test - void testPlacementOutOfLimit(Env env) { - Instance instance = env.createFlatInstance(); - assertDoesNotThrow(() -> instance.setBlock(0, instance.getDimensionType().getMaxY() + 1, 0, Block.STONE)); - assertDoesNotThrow(() -> instance.setBlock(0, instance.getDimensionType().getMinY() - 1, 0, Block.STONE)); - } -}