diff --git a/src/main/java/net/minestom/server/instance/Chunk.java b/src/main/java/net/minestom/server/instance/Chunk.java index e2327e266..ce068d7e5 100644 --- a/src/main/java/net/minestom/server/instance/Chunk.java +++ b/src/main/java/net/minestom/server/instance/Chunk.java @@ -17,6 +17,7 @@ import net.minestom.server.network.packet.server.play.ChunkDataPacket; import net.minestom.server.network.packet.server.play.UpdateLightPacket; import net.minestom.server.network.player.PlayerConnection; import net.minestom.server.utils.MathUtils; +import net.minestom.server.utils.PacketUtils; import net.minestom.server.utils.Position; import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.chunk.ChunkCallback; @@ -459,7 +460,7 @@ public abstract class Chunk implements Viewable, DataContainer { * * @param player the player */ - protected void sendChunk(@NotNull Player player) { + protected synchronized void sendChunk(@NotNull Player player) { // Only send loaded chunk if (!isLoaded()) return; @@ -503,7 +504,7 @@ public abstract class Chunk implements Viewable, DataContainer { * * @param player the player to update the chunk to */ - public void sendChunkUpdate(@NotNull Player player) { + public synchronized void sendChunkUpdate(@NotNull Player player) { final PlayerConnection playerConnection = player.getPlayerConnection(); playerConnection.sendPacket(getFreshFullDataPacket()); } @@ -511,14 +512,8 @@ public abstract class Chunk implements Viewable, DataContainer { /** * Sends a full {@link ChunkDataPacket} to all chunk viewers. */ - public void sendChunkUpdate() { - final Set chunkViewers = getViewers(); - if (!chunkViewers.isEmpty()) { - chunkViewers.forEach(player -> { - final PlayerConnection playerConnection = player.getPlayerConnection(); - playerConnection.sendPacket(getFreshFullDataPacket()); - }); - } + public synchronized void sendChunkUpdate() { + PacketUtils.sendGroupedPacket(getViewers(), getFreshFullDataPacket()); } /** @@ -528,7 +523,7 @@ public abstract class Chunk implements Viewable, DataContainer { * @param player the player to send the packet to * @throws IllegalArgumentException if {@code section} is not a valid section */ - public void sendChunkSectionUpdate(int section, @NotNull Player player) { + public synchronized void sendChunkSectionUpdate(int section, @NotNull Player player) { if (!PlayerUtils.isNettyClient(player)) return; Check.argCondition(!MathUtils.isBetween(section, 0, CHUNK_SECTION_COUNT), diff --git a/src/main/java/net/minestom/server/instance/batch/ChunkBatch.java b/src/main/java/net/minestom/server/instance/batch/ChunkBatch.java index 40440a5e7..aed940473 100644 --- a/src/main/java/net/minestom/server/instance/batch/ChunkBatch.java +++ b/src/main/java/net/minestom/server/instance/batch/ChunkBatch.java @@ -116,17 +116,24 @@ public class ChunkBatch implements InstanceBatch { */ public void flushChunkGenerator(@NotNull ChunkGenerator chunkGenerator, @Nullable ChunkCallback callback) { BLOCK_BATCH_POOL.execute(() -> { - final List populators = chunkGenerator.getPopulators(); - final boolean hasPopulator = populators != null && !populators.isEmpty(); + synchronized (chunk) { + final List populators = chunkGenerator.getPopulators(); + final boolean hasPopulator = populators != null && !populators.isEmpty(); - chunkGenerator.generateChunkData(this, chunk.getChunkX(), chunk.getChunkZ()); + chunkGenerator.generateChunkData(this, chunk.getChunkX(), chunk.getChunkZ()); - if (hasPopulator) { - for (ChunkPopulator chunkPopulator : populators) { - chunkPopulator.populateChunk(this, chunk); + if (hasPopulator) { + for (ChunkPopulator chunkPopulator : populators) { + chunkPopulator.populateChunk(this, chunk); + } } } + // Refresh chunk for viewers + this.chunk.sendChunkUpdate(); + + this.instance.refreshLastBlockChangeTime(); + // Safe callback instance.scheduleNextTick(inst -> { OptionalCallback.execute(callback, chunk); diff --git a/src/main/java/net/minestom/server/utils/cache/TemporaryCache.java b/src/main/java/net/minestom/server/utils/cache/TemporaryCache.java index 07ea8a51f..960626a20 100644 --- a/src/main/java/net/minestom/server/utils/cache/TemporaryCache.java +++ b/src/main/java/net/minestom/server/utils/cache/TemporaryCache.java @@ -23,7 +23,7 @@ public class TemporaryCache { // Identifier = time protected ConcurrentHashMap cacheTime = new ConcurrentHashMap<>(); - private long keepTime; + private final long keepTime; /** * Creates a new temporary cache. @@ -42,13 +42,13 @@ public class TemporaryCache { } /** - * Caches an object + * Caches an object. * * @param identifier the object identifier * @param value the object to cache * @param time the current time in milliseconds */ - public synchronized void cacheObject(@NotNull UUID identifier, T value, long time) { + public void cacheObject(@NotNull UUID identifier, T value, long time) { this.cache.put(identifier, value); this.cacheTime.put(identifier, time); }