mirror of
https://github.com/Minestom/Minestom.git
synced 2024-09-28 22:47:41 +02:00
Ensure proper chunk synchronization
This commit is contained in:
parent
058e645c33
commit
055cc409ed
@ -60,6 +60,7 @@ public class DynamicChunk extends Chunk {
|
||||
|
||||
@Override
|
||||
public void setBlock(int x, int y, int z, @NotNull Block block) {
|
||||
assertLock();
|
||||
this.lastChange = System.currentTimeMillis();
|
||||
this.chunkCache.invalidate();
|
||||
this.lightCache.invalidate();
|
||||
@ -91,6 +92,7 @@ public class DynamicChunk extends Chunk {
|
||||
|
||||
@Override
|
||||
public void setBiome(int x, int y, int z, @NotNull Biome biome) {
|
||||
assertLock();
|
||||
this.chunkCache.invalidate();
|
||||
Section section = getSectionAt(y);
|
||||
section.biomePalette().set(
|
||||
@ -124,6 +126,7 @@ public class DynamicChunk extends Chunk {
|
||||
|
||||
@Override
|
||||
public @Nullable Block getBlock(int x, int y, int z, @NotNull Condition condition) {
|
||||
assertLock();
|
||||
if (y < minSection * CHUNK_SECTION_SIZE || y >= maxSection * CHUNK_SECTION_SIZE)
|
||||
return Block.AIR; // Out of bounds
|
||||
|
||||
@ -144,6 +147,7 @@ public class DynamicChunk extends Chunk {
|
||||
|
||||
@Override
|
||||
public @NotNull Biome getBiome(int x, int y, int z) {
|
||||
assertLock();
|
||||
final Section section = getSectionAt(y);
|
||||
final int id = section.biomePalette()
|
||||
.get(toSectionRelativeCoordinate(x) / 4, toSectionRelativeCoordinate(y) / 4, toSectionRelativeCoordinate(z) / 4);
|
||||
@ -255,4 +259,8 @@ public class DynamicChunk extends Chunk {
|
||||
clonedSections, entries.clone(), entityIds, updater.reference(instance),
|
||||
TagReadable.fromCompound(Objects.requireNonNull(getTag(Tag.NBT))));
|
||||
}
|
||||
|
||||
private void assertLock() {
|
||||
assert Thread.holdsLock(this) : "Chunk must be locked before access";
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ import net.minestom.server.network.packet.server.play.UnloadChunkPacket;
|
||||
import net.minestom.server.utils.PacketUtils;
|
||||
import net.minestom.server.utils.async.AsyncUtils;
|
||||
import net.minestom.server.utils.block.BlockUtils;
|
||||
import net.minestom.server.utils.chunk.ChunkCache;
|
||||
import net.minestom.server.utils.chunk.ChunkSupplier;
|
||||
import net.minestom.server.utils.validate.Check;
|
||||
import net.minestom.server.world.DimensionType;
|
||||
@ -492,6 +493,7 @@ public class InstanceContainer extends Instance {
|
||||
* @param blockPosition the position of the modified block
|
||||
*/
|
||||
private void executeNeighboursBlockPlacementRule(@NotNull Point blockPosition) {
|
||||
ChunkCache cache = new ChunkCache(this, null, null);
|
||||
for (int offsetX = -1; offsetX < 2; offsetX++) {
|
||||
for (int offsetY = -1; offsetY < 2; offsetY++) {
|
||||
for (int offsetZ = -1; offsetZ < 2; offsetZ++) {
|
||||
@ -502,10 +504,9 @@ public class InstanceContainer extends Instance {
|
||||
final int neighborZ = blockPosition.blockZ() + offsetZ;
|
||||
if (neighborY < getDimensionType().getMinY() || neighborY > getDimensionType().getTotalHeight())
|
||||
continue;
|
||||
final Chunk chunk = getChunkAt(neighborX, neighborZ);
|
||||
if (chunk == null) continue;
|
||||
|
||||
final Block neighborBlock = chunk.getBlock(neighborX, neighborY, neighborZ);
|
||||
final Block neighborBlock = cache.getBlock(neighborX, neighborY, neighborZ, Condition.TYPE);
|
||||
if (neighborBlock == null)
|
||||
continue;
|
||||
final BlockPlacementRule neighborBlockPlacementRule = MinecraftServer.getBlockManager().getBlockPlacementRule(neighborBlock);
|
||||
if (neighborBlockPlacementRule == null) continue;
|
||||
|
||||
|
@ -35,6 +35,10 @@ public final class ChunkCache implements Block.Getter {
|
||||
if (chunk == null || chunk.getChunkX() != chunkX || chunk.getChunkZ() != chunkZ) {
|
||||
this.chunk = chunk = this.instance.getChunk(chunkX, chunkZ);
|
||||
}
|
||||
return chunk != null ? chunk.getBlock(x, y, z, condition) : defaultBlock;
|
||||
if (chunk != null) {
|
||||
synchronized (chunk) {
|
||||
return chunk.getBlock(x, y, z, condition);
|
||||
}
|
||||
} else return defaultBlock;
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,10 @@ public final class EntityUtils {
|
||||
final Pos entityPosition = entity.getPosition();
|
||||
// TODO: check entire bounding box
|
||||
try {
|
||||
final Block block = chunk.getBlock(entityPosition.sub(0, 1, 0));
|
||||
final Block block;
|
||||
synchronized (chunk) {
|
||||
block = chunk.getBlock(entityPosition.sub(0, 1, 0));
|
||||
}
|
||||
return block.isSolid();
|
||||
} catch (NullPointerException e) {
|
||||
// Probably an entity at the border of an unloaded chunk
|
||||
|
Loading…
Reference in New Issue
Block a user