Added Chunk#setReadOnly and Chunk#isReadOnly

This commit is contained in:
themode 2020-10-24 00:17:23 +02:00
parent 86d6092547
commit fb26ec0f0b
4 changed files with 70 additions and 37 deletions

View File

@ -63,6 +63,7 @@ public abstract class Chunk implements Viewable, DataContainer {
// Options
private final boolean shouldGenerate;
private boolean readOnly;
// Packet cache
private volatile boolean enableCachePacket;
@ -277,6 +278,24 @@ public abstract class Chunk implements Viewable, DataContainer {
return shouldGenerate;
}
/**
* Gets if this chunk is read-only.
*
* @return true if the chunk is read-only
*/
public boolean isReadOnly() {
return readOnly;
}
/**
* Changes the read state of the chunk.
*
* @param readOnly true to make the chunk read-only, false otherwise
*/
public void setReadOnly(boolean readOnly) {
this.readOnly = readOnly;
}
/**
* Gets if this chunk automatically cache the latest {@link ChunkDataPacket} version.
* <p>

View File

@ -160,6 +160,10 @@ public class InstanceContainer extends Instance {
* @param data the {@link Data}, null if none
*/
private void UNSAFE_setBlock(Chunk chunk, int x, int y, int z, short blockStateId, CustomBlock customBlock, Data data) {
if (chunk.isReadOnly()) {
return;
}
synchronized (chunk) {
final boolean isCustomBlock = customBlock != null;
@ -342,6 +346,11 @@ public class InstanceContainer extends Instance {
final Chunk chunk = getChunkAt(blockPosition);
// Cancel if the chunk is read-only
if (chunk.isReadOnly()) {
return false;
}
// Chunk unloaded, stop here
if (!ChunkUtils.isLoaded(chunk))
return false;

View File

@ -27,6 +27,7 @@ public class StaticChunk extends Chunk {
public StaticChunk(Instance instance, Biome[] biomes, int chunkX, int chunkZ, BlockProvider blockProvider) {
super(instance, biomes, chunkX, chunkZ, false);
this.blockProvider = blockProvider;
setReadOnly(true);
}
@Override

View File

@ -80,46 +80,50 @@ public class BlockPlacementListener {
boolean refreshChunk = false;
if (material.isBlock()) {
final Block block = material.getBlock();
final Set<Entity> entities = instance.getChunkEntities(chunk);
// Check if the player is trying to place a block in an entity
boolean intersect = false;
if (block.isSolid()) {
for (Entity entity : entities) {
intersect = entity.getBoundingBox().intersect(blockPosition);
if (intersect)
break;
}
}
if (!intersect) {
// BlockPlacementRule check
final BlockManager blockManager = MinecraftServer.getBlockManager();
final BlockPlacementRule blockPlacementRule = blockManager.getBlockPlacementRule(block);
final short blockStateId = blockPlacementRule == null ? block.getBlockId() :
blockPlacementRule.blockPlace(instance, block, blockFace, player);
PlayerBlockPlaceEvent playerBlockPlaceEvent = new PlayerBlockPlaceEvent(player, blockStateId, (short) 0, blockPosition, packet.hand);
playerBlockPlaceEvent.consumeBlock(player.getGameMode() != GameMode.CREATIVE);
// BlockPlacementRule check
final boolean canPlace = blockPlacementRule == null || blockPlacementRule.canPlace(instance, blockPosition);
player.callEvent(PlayerBlockPlaceEvent.class, playerBlockPlaceEvent);
if (!playerBlockPlaceEvent.isCancelled() && canPlace) {
final short customBlockId = playerBlockPlaceEvent.getCustomBlockId();
if (customBlockId != 0) {
instance.setSeparateBlocks(blockPosition.getX(), blockPosition.getY(), blockPosition.getZ(), playerBlockPlaceEvent.getBlockStateId(), playerBlockPlaceEvent.getCustomBlockId());
} else {
instance.setBlockStateId(blockPosition.getX(), blockPosition.getY(), blockPosition.getZ(), playerBlockPlaceEvent.getBlockStateId());
if (!chunk.isReadOnly()) {
final Block block = material.getBlock();
final Set<Entity> entities = instance.getChunkEntities(chunk);
// Check if the player is trying to place a block in an entity
boolean intersect = false;
if (block.isSolid()) {
for (Entity entity : entities) {
intersect = entity.getBoundingBox().intersect(blockPosition);
if (intersect)
break;
}
if (playerBlockPlaceEvent.doesConsumeBlock()) {
// Consume the block in the player's hand
final ItemStack newUsedItem = usedItem.consume(1);
}
if (newUsedItem != null) {
playerInventory.setItemInHand(hand, newUsedItem);
if (!intersect) {
// BlockPlacementRule check
final BlockManager blockManager = MinecraftServer.getBlockManager();
final BlockPlacementRule blockPlacementRule = blockManager.getBlockPlacementRule(block);
final short blockStateId = blockPlacementRule == null ? block.getBlockId() :
blockPlacementRule.blockPlace(instance, block, blockFace, player);
PlayerBlockPlaceEvent playerBlockPlaceEvent = new PlayerBlockPlaceEvent(player, blockStateId, (short) 0, blockPosition, packet.hand);
playerBlockPlaceEvent.consumeBlock(player.getGameMode() != GameMode.CREATIVE);
// BlockPlacementRule check
final boolean canPlace = blockPlacementRule == null || blockPlacementRule.canPlace(instance, blockPosition);
player.callEvent(PlayerBlockPlaceEvent.class, playerBlockPlaceEvent);
if (!playerBlockPlaceEvent.isCancelled() && canPlace) {
final short customBlockId = playerBlockPlaceEvent.getCustomBlockId();
if (customBlockId != 0) {
instance.setSeparateBlocks(blockPosition.getX(), blockPosition.getY(), blockPosition.getZ(), playerBlockPlaceEvent.getBlockStateId(), playerBlockPlaceEvent.getCustomBlockId());
} else {
instance.setBlockStateId(blockPosition.getX(), blockPosition.getY(), blockPosition.getZ(), playerBlockPlaceEvent.getBlockStateId());
}
if (playerBlockPlaceEvent.doesConsumeBlock()) {
// Consume the block in the player's hand
final ItemStack newUsedItem = usedItem.consume(1);
if (newUsedItem != null) {
playerInventory.setItemInHand(hand, newUsedItem);
}
}
} else {
refreshChunk = true;
}
} else {
refreshChunk = true;