fix: ensure block placements can only happen inside the world border

(cherry picked from commit 0c5a177281)
This commit is contained in:
mworzala 2023-12-02 11:39:19 +02:00 committed by Matt Worzala
parent 9b794c2077
commit 58c03cc8d2
3 changed files with 49 additions and 20 deletions

View File

@ -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

View File

@ -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);
}
}

View File

@ -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));
}
}