Added check in Chunk class before each interaction, ensuring that it is loaded

This commit is contained in:
Felix Cravic 2020-05-24 22:37:42 +02:00
parent f8ff01349b
commit ea3189023a

View File

@ -16,6 +16,7 @@ import net.minestom.server.instance.block.UpdateConsumer;
import net.minestom.server.network.PacketWriterUtils;
import net.minestom.server.network.packet.server.play.ChunkDataPacket;
import net.minestom.server.utils.BlockPosition;
import net.minestom.server.utils.MathUtils;
import net.minestom.server.utils.PacketUtils;
import net.minestom.server.utils.SerializerUtils;
import net.minestom.server.utils.time.CooldownUtils;
@ -90,6 +91,7 @@ public class Chunk implements Viewable {
}
public void UNSAFE_removeCustomBlock(int x, int y, int z) {
unloadCheck();
this.customBlocksId[getBlockIndex(x, y, z)] = 0; // Set to none
int index = SerializerUtils.coordToChunkIndex(x, y, z);
this.blocksData.remove(index);
@ -101,6 +103,7 @@ public class Chunk implements Viewable {
}
private void setBlock(int x, int y, int z, short blockId, short customId, Data data, UpdateConsumer updateConsumer) {
unloadCheck();
int index = SerializerUtils.coordToChunkIndex(x, y, z);
if (blockId != 0
|| (blockId == 0 && customId != 0 && updateConsumer != null)) { // Allow custom air block for update purpose, refused if no update consumer has been found
@ -148,6 +151,7 @@ public class Chunk implements Viewable {
}
public void setBlockData(int x, int y, int z, Data data) {
unloadCheck();
int index = SerializerUtils.coordToChunkIndex(x, y, z);
if (data != null) {
this.blocksData.put(index, data);
@ -157,6 +161,7 @@ public class Chunk implements Viewable {
}
public short getBlockId(int x, int y, int z) {
unloadCheck();
int index = getBlockIndex(x, y, z);
if (index < 0 || index >= blocksId.length) {
return 0; // TODO: custom invalid block
@ -166,8 +171,9 @@ public class Chunk implements Viewable {
}
public short getCustomBlockId(int x, int y, int z) {
unloadCheck();
int index = getBlockIndex(x, y, z);
if (index < 0 || index >= blocksId.length) {
if (!MathUtils.isBetween(index, 0, blocksId.length)) {
return 0; // TODO: custom invalid block
}
short id = customBlocksId[index];
@ -175,8 +181,9 @@ public class Chunk implements Viewable {
}
public CustomBlock getCustomBlock(int x, int y, int z) {
unloadCheck();
int index = getBlockIndex(x, y, z);
if (index < 0 || index >= blocksId.length) {
if (!MathUtils.isBetween(index, 0, blocksId.length)) {
return null; // TODO: custom invalid block
}
short id = customBlocksId[index];
@ -189,8 +196,9 @@ public class Chunk implements Viewable {
}
protected void refreshBlockValue(int x, int y, int z, short blockId, short customId) {
unloadCheck();
int blockIndex = getBlockIndex(x, y, z);
if (blockIndex < 0 || blockIndex >= blocksId.length) {
if (!MathUtils.isBetween(blockIndex, 0, blocksId.length)) {
return;
}
@ -199,8 +207,9 @@ public class Chunk implements Viewable {
}
protected void refreshBlockId(int x, int y, int z, short blockId) {
unloadCheck();
int blockIndex = getBlockIndex(x, y, z);
if (blockIndex < 0 || blockIndex >= blocksId.length) {
if (!MathUtils.isBetween(blockIndex, 0, blocksId.length)) {
return;
}
@ -219,10 +228,12 @@ public class Chunk implements Viewable {
}
protected Data getData(int index) {
unloadCheck();
return blocksData.get(index);
}
public void updateBlocks(long time, Instance instance) {
unloadCheck();
if (updatableBlocks.isEmpty())
return;
@ -285,6 +296,7 @@ public class Chunk implements Viewable {
}
protected byte[] getSerializedData() throws IOException {
unloadCheck();
ByteArrayOutputStream output = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(output);
@ -375,6 +387,7 @@ public class Chunk implements Viewable {
// UNSAFE
@Override
public boolean addViewer(Player player) {
unloadCheck();
boolean result = this.viewers.add(player);
PlayerChunkLoadEvent playerChunkLoadEvent = new PlayerChunkLoadEvent(player, chunkX, chunkZ);
@ -385,6 +398,7 @@ public class Chunk implements Viewable {
// UNSAFE
@Override
public boolean removeViewer(Player player) {
unloadCheck();
boolean result = this.viewers.remove(player);
PlayerChunkUnloadEvent playerChunkUnloadEvent = new PlayerChunkUnloadEvent(player, chunkX, chunkZ);
@ -413,6 +427,13 @@ public class Chunk implements Viewable {
this.viewers = null;
}
/**
* Ensure that the check is loaded before interaction
*/
private void unloadCheck() {
Check.stateCondition(!isLoaded(), "The chunk " + toString() + " is unloaded, you cannot interact with it");
}
private int getBlockIndex(int x, int y, int z) {
x = x % Chunk.CHUNK_SIZE_X;
z = z % Chunk.CHUNK_SIZE_Z;