From 561b4c4f25110ed1ba75a9ebfdb94666efeffff0 Mon Sep 17 00:00:00 2001 From: Steveplays28 Date: Wed, 31 Jul 2024 21:47:14 +0200 Subject: [PATCH] fix: Move lighting to after chunk loading completes This fixes lighting, as before it was most likely lighting `IoWorldChunks`. --- .../mixin/server/world/ServerWorldMixin.java | 7 +++++++ .../server/world/ServerWorldChunkManager.java | 17 ++++++----------- .../lighting/ServerWorldLightingProvider.java | 19 +++++++++++++++++++ .../ticket/ServerWorldTicketTracker.java | 8 ++++++-- 4 files changed, 38 insertions(+), 13 deletions(-) diff --git a/common/src/main/java/io/github/steveplays28/noisiumchunkmanager/mixin/server/world/ServerWorldMixin.java b/common/src/main/java/io/github/steveplays28/noisiumchunkmanager/mixin/server/world/ServerWorldMixin.java index 48e1bbd..70a713a 100644 --- a/common/src/main/java/io/github/steveplays28/noisiumchunkmanager/mixin/server/world/ServerWorldMixin.java +++ b/common/src/main/java/io/github/steveplays28/noisiumchunkmanager/mixin/server/world/ServerWorldMixin.java @@ -149,6 +149,13 @@ protected ServerWorldMixin(MutableWorldProperties properties, RegistryKey this::noisiumchunkmanager$getServerWorldLightingProvider, noisiumchunkmanager$getServerWorldLightingProvider()::initializeLight, noisiumchunkmanager$getServerWorldLightingProvider()::light, + (chunkPosition) -> { + if (noisiumchunkmanager$serverWorldTicketTracker == null) { + return false; + } + + return noisiumchunkmanager$serverWorldTicketTracker.hasTicketAtPosition(chunkPosition); + }, session.getWorldDirectory(worldKey), dataFixer ); noisiumchunkmanager$serverWorldTicketTracker = new ServerWorldTicketTracker( diff --git a/common/src/main/java/io/github/steveplays28/noisiumchunkmanager/server/world/ServerWorldChunkManager.java b/common/src/main/java/io/github/steveplays28/noisiumchunkmanager/server/world/ServerWorldChunkManager.java index 42ad463..5aacbb7 100644 --- a/common/src/main/java/io/github/steveplays28/noisiumchunkmanager/server/world/ServerWorldChunkManager.java +++ b/common/src/main/java/io/github/steveplays28/noisiumchunkmanager/server/world/ServerWorldChunkManager.java @@ -61,6 +61,7 @@ public class ServerWorldChunkManager { private final Supplier lightingProviderSupplier; private final BiFunction> initializeChunkLightingBiFunction; private final BiFunction> lightChunkBiFunction; + private final Function hasTicketAtPositionSupplier; private final PersistentStateManager persistentStateManager; private final PointOfInterestStorage pointOfInterestStorage; private final VersionedChunkStorage versionedChunkStorage; @@ -74,7 +75,7 @@ public class ServerWorldChunkManager { private boolean isStopping; @SuppressWarnings("ResultOfMethodCallIgnored") - public ServerWorldChunkManager(@NotNull ServerWorld serverWorld, @NotNull ChunkGenerator chunkGenerator, @NotNull NoiseConfig noiseConfig, @NotNull Consumer syncRunnableConsumer, @NotNull Supplier lightingProviderSupplier, @NotNull BiFunction> initializeChunkLightingBiFunction, @NotNull BiFunction> lightChunkBiFunction, @NotNull Path worldDirectoryPath, @NotNull DataFixer dataFixer) { + public ServerWorldChunkManager(@NotNull ServerWorld serverWorld, @NotNull ChunkGenerator chunkGenerator, @NotNull NoiseConfig noiseConfig, @NotNull Consumer syncRunnableConsumer, @NotNull Supplier lightingProviderSupplier, @NotNull BiFunction> initializeChunkLightingBiFunction, @NotNull BiFunction> lightChunkBiFunction, @NotNull Function hasTicketAtPositionSupplier, @NotNull Path worldDirectoryPath, @NotNull DataFixer dataFixer) { this.serverWorld = serverWorld; this.chunkGenerator = chunkGenerator; this.noiseConfig = noiseConfig; @@ -82,6 +83,7 @@ public ServerWorldChunkManager(@NotNull ServerWorld serverWorld, @NotNull ChunkG this.lightingProviderSupplier = lightingProviderSupplier; this.initializeChunkLightingBiFunction = initializeChunkLightingBiFunction; this.lightChunkBiFunction = lightChunkBiFunction; + this.hasTicketAtPositionSupplier = hasTicketAtPositionSupplier; var worldDataFile = worldDirectoryPath.resolve("data").toFile(); worldDataFile.mkdirs(); @@ -173,7 +175,7 @@ public ServerWorldChunkManager(@NotNull ServerWorld serverWorld, @NotNull ChunkG syncRunnableConsumer.accept( () -> ServerChunkEvent.WORLD_CHUNK_LOADED.invoker().onWorldChunkLoaded(serverWorld, fetchedWorldChunk)); - if (unloadingWorldChunks.contains(chunkPos)) { + if (unloadingWorldChunks.contains(chunkPos) && !hasTicketAtPositionSupplier.apply(chunkPos)) { loadedWorldChunks.remove(chunkPos); unloadingWorldChunks.remove(chunkPos); syncRunnableConsumer.accept( @@ -217,7 +219,7 @@ public ServerWorldChunkManager(@NotNull ServerWorld serverWorld, @NotNull ChunkG syncRunnableConsumer.accept( () -> ServerChunkEvent.WORLD_CHUNK_LOADED.invoker().onWorldChunkLoaded(serverWorld, fetchedWorldChunk)); - if (unloadingWorldChunks.contains(chunkPos)) { + if (unloadingWorldChunks.contains(chunkPos) && !hasTicketAtPositionSupplier.apply(chunkPos)) { loadedWorldChunks.remove(chunkPos); unloadingWorldChunks.remove(chunkPos); syncRunnableConsumer.accept( @@ -238,7 +240,7 @@ public ServerWorldChunkManager(@NotNull ServerWorld serverWorld, @NotNull ChunkG syncRunnableConsumer.accept( () -> ServerChunkEvent.WORLD_CHUNK_LOADED.invoker().onWorldChunkLoaded(serverWorld, fetchedWorldChunk)); - if (unloadingWorldChunks.contains(chunkPos)) { + if (unloadingWorldChunks.contains(chunkPos) && !hasTicketAtPositionSupplier.apply(chunkPos)) { loadedWorldChunks.remove(chunkPos); unloadingWorldChunks.remove(chunkPos); syncRunnableConsumer.accept( @@ -450,13 +452,6 @@ private void onBlockChange(@NotNull BlockPos blockPos, @NotNull BlockState oldBl ioWorldChunkRemoveFunction.apply(chunkPos); - protoChunk.setStatus(ChunkStatus.INITIALIZE_LIGHT); - protoChunk.refreshSurfaceY(); - initializeChunkLightingBiConsumer.apply(protoChunk, protoChunk.isLightOn()).join(); - - protoChunk.setStatus(ChunkStatus.LIGHT); - lightChunkBiConsumer.apply(protoChunk, protoChunk.isLightOn()).join(); - protoChunk.setStatus(ChunkStatus.SPAWN); chunkGenerator.populateEntities(chunkRegion); diff --git a/common/src/main/java/io/github/steveplays28/noisiumchunkmanager/server/world/lighting/ServerWorldLightingProvider.java b/common/src/main/java/io/github/steveplays28/noisiumchunkmanager/server/world/lighting/ServerWorldLightingProvider.java index 6c0bb7e..446ccef 100644 --- a/common/src/main/java/io/github/steveplays28/noisiumchunkmanager/server/world/lighting/ServerWorldLightingProvider.java +++ b/common/src/main/java/io/github/steveplays28/noisiumchunkmanager/server/world/lighting/ServerWorldLightingProvider.java @@ -2,11 +2,13 @@ import com.google.common.util.concurrent.ThreadFactoryBuilder; import dev.architectury.event.events.common.TickEvent; +import io.github.steveplays28.noisiumchunkmanager.NoisiumChunkManager; import io.github.steveplays28.noisiumchunkmanager.config.NoisiumChunkManagerConfig; import io.github.steveplays28.noisiumchunkmanager.extension.world.chunk.WorldChunkExtension; import io.github.steveplays28.noisiumchunkmanager.server.event.world.chunk.ServerChunkEvent; import io.github.steveplays28.noisiumchunkmanager.server.extension.world.ServerWorldExtension; import io.github.steveplays28.noisiumchunkmanager.util.world.chunk.ChunkUtil; +import net.minecraft.server.world.ChunkTicketType; import net.minecraft.server.world.ServerLightingProvider; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; @@ -16,6 +18,7 @@ import net.minecraft.world.LightType; import net.minecraft.world.chunk.*; import net.minecraft.world.chunk.light.*; +import org.apache.commons.lang3.exception.ExceptionUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -58,6 +61,22 @@ public void onLightUpdate(@NotNull LightType lightType, @NotNull ChunkSectionPos "Noisium Server World Lighting Provider " + serverWorld.getDimension().effects() + " %d").build() ); + ServerChunkEvent.WORLD_CHUNK_LOADED.register((instance, worldChunk) -> { + if (!worldChunk.isLightOn()) { + @NotNull var worldChunkPosition = worldChunk.getPos(); + instance.getChunkManager().addTicket(ChunkTicketType.LIGHT, worldChunkPosition, 1, worldChunkPosition); + initializeLight(worldChunk, false).thenCompose(chunkWithInitializedLighting -> + light(chunkWithInitializedLighting, false)).whenComplete((litChunk, throwable) -> { + if (throwable != null) { + NoisiumChunkManager.LOGGER.error( + "Exception thrown while lighting a chunk asynchronously:\n{}", ExceptionUtils.getStackTrace(throwable)); + return; + } + + instance.getChunkManager().removeTicket(ChunkTicketType.LIGHT, worldChunkPosition, 1, worldChunkPosition); + }); + } + }); ServerChunkEvent.LIGHT_UPDATE.register((instance, lightType, chunkSectionPosition) -> { if (instance != serverWorld) { return; diff --git a/common/src/main/java/io/github/steveplays28/noisiumchunkmanager/server/world/ticket/ServerWorldTicketTracker.java b/common/src/main/java/io/github/steveplays28/noisiumchunkmanager/server/world/ticket/ServerWorldTicketTracker.java index 28e3f90..b3f3c87 100644 --- a/common/src/main/java/io/github/steveplays28/noisiumchunkmanager/server/world/ticket/ServerWorldTicketTracker.java +++ b/common/src/main/java/io/github/steveplays28/noisiumchunkmanager/server/world/ticket/ServerWorldTicketTracker.java @@ -7,8 +7,8 @@ import net.minecraft.util.math.ChunkPos; import org.jetbrains.annotations.NotNull; -import java.util.HashMap; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.BiConsumer; import java.util.function.Consumer; @@ -23,7 +23,7 @@ public ServerWorldTicketTracker(@NotNull ServerWorld serverWorld, @NotNull BiCon this.loadChunksInRadiusBiConsumer = loadChunksInRadiusBiConsumer; this.unloadChunkConsumer = unloadChunkConsumer; - this.tickets = new HashMap<>(); + this.tickets = new ConcurrentHashMap<>(); ServerWorldTicketEvent.TICKET_CREATED.register((ticketServerWorld, ticketType, chunkPosition, radius) -> { if (ticketServerWorld != serverWorld) { @@ -48,6 +48,10 @@ public ServerWorldTicketTracker(@NotNull ServerWorld serverWorld, @NotNull BiCon }); } + public boolean hasTicketAtPosition(@NotNull ChunkPos chunkPosition) { + return this.tickets.containsKey(chunkPosition); + } + private void onTicketCreated(@NotNull ServerWorld serverWorld, @NotNull ChunkTicketType ticketType, @NotNull ChunkPos chunkPosition, int radius) { if (tickets.containsKey(chunkPosition)) { return;