mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-20 07:02:32 +01:00
hollow-cube/prevent-block-placement-outside-world (#42)
* Prevent block place above 320 (cherry picked from commitd226c3994a
) * Move position of check (cherry picked from commitff7c4c108f
) * Add unit test (cherry picked from commit68500bf0d0
) * Add min y check (cherry picked from commit0ce77673a9
) --------- Co-authored-by: nucker <nuckermail@gmail.com>
This commit is contained in:
parent
d901eaaed1
commit
8da8a70342
@ -23,11 +23,14 @@ import net.minestom.server.utils.ArrayUtils;
|
|||||||
import net.minestom.server.utils.MathUtils;
|
import net.minestom.server.utils.MathUtils;
|
||||||
import net.minestom.server.utils.ObjectPool;
|
import net.minestom.server.utils.ObjectPool;
|
||||||
import net.minestom.server.utils.chunk.ChunkUtils;
|
import net.minestom.server.utils.chunk.ChunkUtils;
|
||||||
|
import net.minestom.server.utils.validate.Check;
|
||||||
import net.minestom.server.world.biomes.Biome;
|
import net.minestom.server.world.biomes.Biome;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jglrxavpok.hephaistos.nbt.NBT;
|
import org.jglrxavpok.hephaistos.nbt.NBT;
|
||||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@ -39,6 +42,7 @@ import static net.minestom.server.utils.chunk.ChunkUtils.toSectionRelativeCoordi
|
|||||||
* WARNING: not thread-safe.
|
* WARNING: not thread-safe.
|
||||||
*/
|
*/
|
||||||
public class DynamicChunk extends Chunk {
|
public class DynamicChunk extends Chunk {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(DynamicChunk.class);
|
||||||
|
|
||||||
protected List<Section> sections;
|
protected List<Section> sections;
|
||||||
|
|
||||||
@ -60,7 +64,13 @@ public class DynamicChunk extends Chunk {
|
|||||||
public void setBlock(int x, int y, int z, @NotNull Block block,
|
public void setBlock(int x, int y, int z, @NotNull Block block,
|
||||||
@Nullable BlockHandler.Placement placement,
|
@Nullable BlockHandler.Placement placement,
|
||||||
@Nullable BlockHandler.Destroy destroy) {
|
@Nullable BlockHandler.Destroy destroy) {
|
||||||
|
if(y >= instance.getDimensionType().getMaxY() || y < instance.getDimensionType().getMinY()) {
|
||||||
|
LOGGER.warn("tried to set a block outside the world bounds, should be within [{}, {}): {}",
|
||||||
|
instance.getDimensionType().getMinY(), instance.getDimensionType().getMaxY(), y);
|
||||||
|
return;
|
||||||
|
}
|
||||||
assertLock();
|
assertLock();
|
||||||
|
|
||||||
this.lastChange = System.currentTimeMillis();
|
this.lastChange = System.currentTimeMillis();
|
||||||
this.chunkCache.invalidate();
|
this.chunkCache.invalidate();
|
||||||
|
|
||||||
|
@ -33,6 +33,8 @@ import org.jetbrains.annotations.ApiStatus;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
import org.jglrxavpok.hephaistos.nbt.NBTCompound;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import space.vectrix.flare.fastutil.Long2ObjectSyncMap;
|
import space.vectrix.flare.fastutil.Long2ObjectSyncMap;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@ -50,6 +52,8 @@ import static net.minestom.server.utils.chunk.ChunkUtils.*;
|
|||||||
* InstanceContainer is an instance that contains chunks in contrary to SharedInstance.
|
* InstanceContainer is an instance that contains chunks in contrary to SharedInstance.
|
||||||
*/
|
*/
|
||||||
public class InstanceContainer extends Instance {
|
public class InstanceContainer extends Instance {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(InstanceContainer.class);
|
||||||
|
|
||||||
private static final AnvilLoader DEFAULT_LOADER = new AnvilLoader("world");
|
private static final AnvilLoader DEFAULT_LOADER = new AnvilLoader("world");
|
||||||
|
|
||||||
private static final BlockFace[] BLOCK_UPDATE_FACES = new BlockFace[]{
|
private static final BlockFace[] BLOCK_UPDATE_FACES = new BlockFace[]{
|
||||||
@ -129,6 +133,11 @@ public class InstanceContainer extends Instance {
|
|||||||
@Nullable BlockHandler.Placement placement, @Nullable BlockHandler.Destroy destroy,
|
@Nullable BlockHandler.Placement placement, @Nullable BlockHandler.Destroy destroy,
|
||||||
boolean doBlockUpdates, int updateDistance) {
|
boolean doBlockUpdates, int updateDistance) {
|
||||||
if (chunk.isReadOnly()) return;
|
if (chunk.isReadOnly()) return;
|
||||||
|
if(y >= getDimensionType().getMaxY() || y < getDimensionType().getMinY()) {
|
||||||
|
LOGGER.warn("tried to set a block outside the world bounds, should be within [{}, {}): {}", getDimensionType().getMinY(), getDimensionType().getMaxY(), y);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
synchronized (chunk) {
|
synchronized (chunk) {
|
||||||
// Refresh the last block change time
|
// Refresh the last block change time
|
||||||
this.lastBlockChangeTime = System.currentTimeMillis();
|
this.lastBlockChangeTime = System.currentTimeMillis();
|
||||||
|
@ -90,6 +90,7 @@ public class BlockPlacementListener {
|
|||||||
canPlaceBlock = usedItem.meta().canPlaceOn(interactedBlock);
|
canPlaceBlock = usedItem.meta().canPlaceOn(interactedBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Get the newly placed block position
|
// Get the newly placed block position
|
||||||
//todo it feels like it should be possible to have better replacement rules than this, feels pretty scuffed.
|
//todo it feels like it should be possible to have better replacement rules than this, feels pretty scuffed.
|
||||||
Point placementPosition = blockPosition;
|
Point placementPosition = blockPosition;
|
||||||
@ -111,6 +112,9 @@ public class BlockPlacementListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(placementPosition.y() >= instance.getDimensionType().getMaxY()
|
||||||
|
|| placementPosition.y() <= instance.getDimensionType().getMinY()) return;
|
||||||
|
|
||||||
if (!canPlaceBlock) {
|
if (!canPlaceBlock) {
|
||||||
// Send a block change with the real block in the instance to keep the client in sync,
|
// 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
|
// using refreshChunk results in the client not being in sync
|
||||||
@ -150,22 +154,8 @@ public class BlockPlacementListener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// BlockPlacementRule check
|
|
||||||
Block resultBlock = playerBlockPlaceEvent.getBlock();
|
|
||||||
// final BlockPlacementRule blockPlacementRule = BLOCK_MANAGER.getBlockPlacementRule(resultBlock);
|
|
||||||
// if (blockPlacementRule != null && playerBlockPlaceEvent.shouldDoBlockUpdates()) {
|
|
||||||
// Get id from block placement rule instead of the event
|
|
||||||
// resultBlock = blockPlacementRule.blockPlace(new BlockPlacementRule.PlacementState(
|
|
||||||
// instance, resultBlock, blockFace,
|
|
||||||
// placementPosition, cursorPosition,
|
|
||||||
// player.getPosition(), usedItem.meta(), player.isSneaking())
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// if (resultBlock == null) {
|
|
||||||
// refresh(player, chunk);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// Place the block
|
// Place the block
|
||||||
|
Block resultBlock = playerBlockPlaceEvent.getBlock();
|
||||||
player.sendPacket(new AcknowledgeBlockChangePacket(packet.sequence()));
|
player.sendPacket(new AcknowledgeBlockChangePacket(packet.sequence()));
|
||||||
instance.placeBlock(new BlockHandler.PlayerPlacement(resultBlock, instance, placementPosition, player, hand, blockFace,
|
instance.placeBlock(new BlockHandler.PlayerPlacement(resultBlock, instance, placementPosition, player, hand, blockFace,
|
||||||
packet.cursorPositionX(), packet.cursorPositionY(), packet.cursorPositionZ()), playerBlockPlaceEvent.shouldDoBlockUpdates());
|
packet.cursorPositionX(), packet.cursorPositionY(), packet.cursorPositionZ()), playerBlockPlaceEvent.shouldDoBlockUpdates());
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
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));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user