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 4b5fa52..981b818 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 @@ -126,6 +126,7 @@ public abstract class ServerWorldMixin implements ServerWorldExtension { noisiumchunkmanager$serverWorldLightingProvider = new ServerWorldLightingProvider(serverWorld); noisiumchunkmanager$serverWorldChunkManager = new ServerWorldChunkManager( serverWorld, chunkGenerator, noisiumchunkmanager$noiseConfig, this.getServer()::executeSync, + this::noisiumchunkmanager$getServerWorldLightingProvider, noisiumchunkmanager$getServerWorldLightingProvider()::initializeLight, noisiumchunkmanager$getServerWorldLightingProvider()::light, session.getWorldDirectory(worldKey), dataFixer diff --git a/common/src/main/java/io/github/steveplays28/noisiumchunkmanager/mixin/world/ChunkSerializerMixin.java b/common/src/main/java/io/github/steveplays28/noisiumchunkmanager/mixin/world/ChunkSerializerMixin.java index f6250a2..ef6bcf4 100644 --- a/common/src/main/java/io/github/steveplays28/noisiumchunkmanager/mixin/world/ChunkSerializerMixin.java +++ b/common/src/main/java/io/github/steveplays28/noisiumchunkmanager/mixin/world/ChunkSerializerMixin.java @@ -35,13 +35,13 @@ public class ChunkSerializerMixin { @Redirect(method = "deserialize", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/chunk/light/LightingProvider;setRetainData(Lnet/minecraft/util/math/ChunkPos;Z)V")) private static void noisiumchunkmanager$redirectRetainLightingDataToServerWorldLightingProvider(@Nullable LightingProvider instance, @NotNull ChunkPos chunkPosition, boolean retainLightingData, @Local(ordinal = 0, argsOnly = true) @NotNull ServerWorld serverWorld) { - ((ServerWorldExtension) serverWorld).noisiumchunkmanager$getServerWorldLightingProvider().setRetainLightingData( + ((ServerWorldExtension) serverWorld).noisiumchunkmanager$getServerWorldLightingProvider().setRetainData( chunkPosition, retainLightingData); } @Redirect(method = "deserialize", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/chunk/light/LightingProvider;enqueueSectionData(Lnet/minecraft/world/LightType;Lnet/minecraft/util/math/ChunkSectionPos;Lnet/minecraft/world/chunk/ChunkNibbleArray;)V")) private static void noisiumchunkmanager$redirectEnqueueSectionDataToServerWorldLightingProvider(@Nullable LightingProvider instance, @NotNull LightType lightType, @NotNull ChunkSectionPos chunkSectionPosition, @NotNull ChunkNibbleArray chunkLightingDataNibbleArray, @Local(ordinal = 0, argsOnly = true) @NotNull ServerWorld serverWorld) { - ((ServerWorldExtension) serverWorld).noisiumchunkmanager$getServerWorldLightingProvider().enqueueChunkSectionLightingData( + ((ServerWorldExtension) serverWorld).noisiumchunkmanager$getServerWorldLightingProvider().enqueueSectionData( lightType, chunkSectionPosition, chunkLightingDataNibbleArray); } } diff --git a/common/src/main/java/io/github/steveplays28/noisiumchunkmanager/mixin/world/WorldMixin.java b/common/src/main/java/io/github/steveplays28/noisiumchunkmanager/mixin/world/WorldMixin.java index 3d63525..0949a09 100644 --- a/common/src/main/java/io/github/steveplays28/noisiumchunkmanager/mixin/world/WorldMixin.java +++ b/common/src/main/java/io/github/steveplays28/noisiumchunkmanager/mixin/world/WorldMixin.java @@ -8,6 +8,7 @@ import net.minecraft.world.World; import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.ChunkStatus; +import net.minecraft.world.chunk.light.LightingProvider; import org.jetbrains.annotations.NotNull; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -20,6 +21,15 @@ public abstract class WorldMixin { @Shadow public abstract boolean isClient(); + @Inject(method = "getLightingProvider", at = @At(value = "RETURN"), cancellable = true) + private void noisiumchunkmanager$getServerWorldLightingProvider(@NotNull CallbackInfoReturnable cir) { + if (this.isClient()) { + return; + } + + cir.setReturnValue(((ServerWorldExtension) this).noisiumchunkmanager$getServerWorldLightingProvider()); + } + @Inject(method = "getChunk(IILnet/minecraft/world/chunk/ChunkStatus;Z)Lnet/minecraft/world/chunk/Chunk;", at = @At(value = "HEAD"), cancellable = true) private void noisiumchunkmanager$getChunkFromNoisiumServerChunkManager(int chunkPositionX, int chunkPositionZ, @NotNull ChunkStatus leastStatus, boolean create, @NotNull CallbackInfoReturnable cir) { if (this.isClient()) { diff --git a/common/src/main/java/io/github/steveplays28/noisiumchunkmanager/mixin/world/chunk/ProtoChunkMixin.java b/common/src/main/java/io/github/steveplays28/noisiumchunkmanager/mixin/world/chunk/ProtoChunkMixin.java deleted file mode 100644 index 79308b7..0000000 --- a/common/src/main/java/io/github/steveplays28/noisiumchunkmanager/mixin/world/chunk/ProtoChunkMixin.java +++ /dev/null @@ -1,42 +0,0 @@ -package io.github.steveplays28.noisiumchunkmanager.mixin.world.chunk; - -import com.llamalad7.mixinextras.injector.wrapoperation.Operation; -import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; -import io.github.steveplays28.noisiumchunkmanager.server.extension.world.ServerWorldExtension; -import net.minecraft.server.world.ServerWorld; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.HeightLimitView; -import net.minecraft.world.chunk.ProtoChunk; -import net.minecraft.world.chunk.light.LightingProvider; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; - -@Mixin(ProtoChunk.class) -public abstract class ProtoChunkMixin { - @Shadow - public abstract @NotNull HeightLimitView getHeightLimitView(); - - @WrapOperation(method = "setBlockState", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/chunk/light/LightingProvider;setSectionStatus(Lnet/minecraft/util/math/BlockPos;Z)V")) - private void noisiumchunkmanager$redirectSetSectionStatusToServerWorldLightingProvider(@Nullable LightingProvider instance, @NotNull BlockPos blockPosition, boolean notReady, @NotNull Operation original) { - if (getHeightLimitView() instanceof ServerWorld serverWorld) { - ((ServerWorldExtension) serverWorld).noisiumchunkmanager$getServerWorldLightingProvider().setSectionStatus( - blockPosition, notReady); - return; - } - - original.call(instance, blockPosition, notReady); - } - - @WrapOperation(method = "setBlockState", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/chunk/light/LightingProvider;checkBlock(Lnet/minecraft/util/math/BlockPos;)V")) - private void noisiumchunkmanager$redirectCheckBlockToServerWorldLightingProvider(@Nullable LightingProvider instance, @NotNull BlockPos blockPosition, @NotNull Operation original) { - if (getHeightLimitView() instanceof ServerWorld serverWorld) { - ((ServerWorldExtension) serverWorld).noisiumchunkmanager$getServerWorldLightingProvider().checkBlock(blockPosition); - return; - } - - original.call(instance, blockPosition); - } -} diff --git a/common/src/main/java/io/github/steveplays28/noisiumchunkmanager/mixin/world/chunk/light/SkyLightStorageMixin.java b/common/src/main/java/io/github/steveplays28/noisiumchunkmanager/mixin/world/chunk/light/SkyLightStorageMixin.java index 6b25072..7752966 100644 --- a/common/src/main/java/io/github/steveplays28/noisiumchunkmanager/mixin/world/chunk/light/SkyLightStorageMixin.java +++ b/common/src/main/java/io/github/steveplays28/noisiumchunkmanager/mixin/world/chunk/light/SkyLightStorageMixin.java @@ -86,10 +86,15 @@ public static class DataMixin implements SkyLightStorageDataExtension { private int noisiumchunkmanager$columnToTopSectionDefaultReturnValue; @Inject(method = "", at = @At(value = "TAIL")) - private void noisiumchunkmanager$replaceSets(@NotNull Long2ObjectOpenHashMap arrays, @Nullable Long2IntOpenHashMap columnToTopSection, int minSectionY, @NotNull CallbackInfo ci) { + private void noisiumchunkmanager$replaceSets(@NotNull Long2ObjectOpenHashMap arrays, @NotNull Long2IntOpenHashMap columnToTopSection, int minSectionY, @NotNull CallbackInfo ci) { noisiumchunkmanager$columnToTopSection = new ConcurrentHashMap<>(); noisiumchunkmanager$columnToTopSectionDefaultReturnValue = minSectionY; + if (this.columnToTopSection == null) { + return; + } + + noisiumchunkmanager$columnToTopSection.putAll(this.columnToTopSection); this.columnToTopSection = null; } 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 a03a49f..4f7b36e 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 @@ -22,6 +22,7 @@ import net.minecraft.util.math.ChunkPos; import net.minecraft.world.*; import net.minecraft.world.chunk.*; +import net.minecraft.world.chunk.light.LightingProvider; import net.minecraft.world.gen.GenerationStep; import net.minecraft.world.gen.chunk.Blender; import net.minecraft.world.gen.chunk.ChunkGenerator; @@ -41,6 +42,7 @@ import java.util.function.BiFunction; import java.util.function.Consumer; import java.util.function.Function; +import java.util.function.Supplier; import static io.github.steveplays28.noisiumchunkmanager.NoisiumChunkManager.MOD_NAME; @@ -57,6 +59,7 @@ public class ServerWorldChunkManager { private final ChunkGenerator chunkGenerator; private final NoiseConfig noiseConfig; private final Consumer syncRunnableConsumer; + private final Supplier lightingProviderSupplier; private final BiFunction> initializeChunkLightingBiFunction; private final BiFunction> lightChunkBiFunction; private final PersistentStateManager persistentStateManager; @@ -72,11 +75,12 @@ public class ServerWorldChunkManager { private boolean isStopping; @SuppressWarnings("ResultOfMethodCallIgnored") - public ServerWorldChunkManager(@NotNull ServerWorld serverWorld, @NotNull ChunkGenerator chunkGenerator, @NotNull NoiseConfig noiseConfig, @NotNull Consumer syncRunnableConsumer, @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 Path worldDirectoryPath, @NotNull DataFixer dataFixer) { this.serverWorld = serverWorld; this.chunkGenerator = chunkGenerator; this.noiseConfig = noiseConfig; this.syncRunnableConsumer = syncRunnableConsumer; + this.lightingProviderSupplier = lightingProviderSupplier; this.initializeChunkLightingBiFunction = initializeChunkLightingBiFunction; this.lightChunkBiFunction = lightChunkBiFunction; @@ -143,7 +147,7 @@ public ServerWorldChunkManager(@NotNull ServerWorld serverWorld, @NotNull ChunkG return new WorldChunk( serverWorld, generateChunk( - chunkPos, this::getIoWorldChunk, ioWorldChunks::remove, + chunkPos, lightingProviderSupplier, this::getIoWorldChunk, ioWorldChunks::remove, initializeChunkLightingBiFunction, lightChunkBiFunction ), null @@ -206,7 +210,7 @@ public ServerWorldChunkManager(@NotNull ServerWorld serverWorld, @NotNull ChunkG var fetchedWorldChunk = new WorldChunk( serverWorld, generateChunk( - chunkPos, this::getIoWorldChunk, ioWorldChunks::remove, + chunkPos, lightingProviderSupplier, this::getIoWorldChunk, ioWorldChunks::remove, initializeChunkLightingBiFunction, lightChunkBiFunction ), null @@ -348,10 +352,12 @@ private void onBlockChange(@NotNull BlockPos blockPos, @NotNull BlockState oldBl } // TODO: Move this into the constructor as a Supplier - private @NotNull ProtoChunk generateChunk(@NotNull ChunkPos chunkPos, @NotNull Function ioWorldChunkGetFunction, @NotNull Function ioWorldChunkRemoveFunction, @NotNull BiFunction> initializeChunkLightingBiConsumer, @NotNull BiFunction> lightChunkBiConsumer) { + private @NotNull ProtoChunk generateChunk(@NotNull ChunkPos chunkPos, @NotNull Supplier lightingProviderSupplier, @NotNull Function ioWorldChunkGetFunction, @NotNull Function ioWorldChunkRemoveFunction, @NotNull BiFunction> initializeChunkLightingBiConsumer, @NotNull BiFunction> lightChunkBiConsumer) { var protoChunk = new ProtoChunk(chunkPos, UpgradeData.NO_UPGRADE_DATA, serverWorld, serverWorld.getRegistryManager().get(RegistryKeys.BIOME), null ); + protoChunk.setLightingProvider(lightingProviderSupplier.get()); + List chunkRegionChunks = List.of(protoChunk); var chunkRegion = new ChunkRegion(serverWorld, chunkRegionChunks, ChunkStatus.FULL, 1); var blender = Blender.getBlender(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 baf56e0..e534d64 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 @@ -25,24 +25,15 @@ /** * A lighting provider for {@link ServerWorld}s. - * This class cannot extend {@link ServerLightingProvider} or {@link LightingProvider} due to the superclass being hard to change, causing {@link ServerWorldLightingProvider} to require a lot of workarounds to function. + * This class cannot extend {@link ServerLightingProvider} due to the superclass being hard to change, causing {@link ServerWorldLightingProvider} to require a lot of workarounds to function. */ -public class ServerWorldLightingProvider implements LightingView { +@SuppressWarnings("DataFlowIssue") +public class ServerWorldLightingProvider extends LightingProvider { private final @NotNull ServerWorld serverWorld; private final @NotNull Executor threadPoolExecutor; - private final @NotNull ChunkBlockLightProvider blockLightProvider; - private final @NotNull ChunkSkyLightProvider skyLightProvider; public ServerWorldLightingProvider(@NotNull ServerWorld serverWorld) { - this.serverWorld = serverWorld; - - this.threadPoolExecutor = Executors.newFixedThreadPool( - NoisiumChunkManagerConfig.HANDLER.instance().serverWorldChunkManagerLightingThreads, - new ThreadFactoryBuilder().setNameFormat( - "Noisium Server World Lighting Provider " + serverWorld.getDimension().effects() + " %d").build() - ); - - @NotNull var chunkProvider = new ChunkProvider() { + super(new ChunkProvider() { @Override public @Nullable LightSourceView getChunk(int chunkX, int chunkZ) { return serverWorld.getChunk(chunkX, chunkZ); @@ -52,14 +43,14 @@ public ServerWorldLightingProvider(@NotNull ServerWorld serverWorld) { public BlockView getWorld() { return serverWorld; } + }, true, true); + this.serverWorld = serverWorld; - @Override - public void onLightUpdate(@NotNull LightType lightType, @NotNull ChunkSectionPos chunkSectionPosition) { - ServerChunkEvent.LIGHT_UPDATE.invoker().onLightUpdate(lightType, chunkSectionPosition); - } - }; - this.blockLightProvider = new ChunkBlockLightProvider(chunkProvider); - this.skyLightProvider = new ChunkSkyLightProvider(chunkProvider); + this.threadPoolExecutor = Executors.newFixedThreadPool( + NoisiumChunkManagerConfig.HANDLER.instance().serverWorldChunkManagerLightingThreads, + new ThreadFactoryBuilder().setNameFormat( + "Noisium Server World Lighting Provider " + serverWorld.getDimension().effects() + " %d").build() + ); ServerChunkEvent.LIGHT_UPDATE.register(this::onLightUpdateAsync); TickEvent.SERVER_LEVEL_POST.register(instance -> { @@ -109,23 +100,14 @@ public void propagateLight(ChunkPos chunkPosition) { skyLightProvider.propagateLight(chunkPosition); } - @SuppressWarnings("DuplicateBranchesInSwitch") - public @NotNull ChunkLightProvider getChunkLightingView(@NotNull LightType lightType) { - @NotNull ChunkLightProvider chunkLightProvider; - switch (lightType) { - case BLOCK -> chunkLightProvider = blockLightProvider; - case SKY -> chunkLightProvider = skyLightProvider; - default -> chunkLightProvider = skyLightProvider; - } - return chunkLightProvider; - } - - public void setRetainLightingData(@NotNull ChunkPos chunkPosition, boolean retainLightingData) { + @Override + public void setRetainData(@NotNull ChunkPos chunkPosition, boolean retainLightingData) { blockLightProvider.setRetainColumn(chunkPosition, retainLightingData); skyLightProvider.setRetainColumn(chunkPosition, retainLightingData); } - public void enqueueChunkSectionLightingData(@NotNull LightType lightType, @NotNull ChunkSectionPos chunkSectionPosition, @Nullable ChunkNibbleArray chunkLightingDataNibbleArray) { + @Override + public void enqueueSectionData(@NotNull LightType lightType, @NotNull ChunkSectionPos chunkSectionPosition, @Nullable ChunkNibbleArray chunkLightingDataNibbleArray) { var chunkSectionPositionAsLong = chunkSectionPosition.asLong(); switch (lightType) { case BLOCK -> blockLightProvider.enqueueSectionData(chunkSectionPositionAsLong, chunkLightingDataNibbleArray); @@ -133,6 +115,17 @@ public void enqueueChunkSectionLightingData(@NotNull LightType lightType, @NotNu } } + @SuppressWarnings("DuplicateBranchesInSwitch") + public @NotNull ChunkLightProvider getChunkLightingView(@NotNull LightType lightType) { + @NotNull ChunkLightProvider chunkLightProvider; + switch (lightType) { + case BLOCK -> chunkLightProvider = blockLightProvider; + case SKY -> chunkLightProvider = skyLightProvider; + default -> chunkLightProvider = skyLightProvider; + } + return chunkLightProvider; + } + public @NotNull CompletableFuture initializeLight(@NotNull Chunk chunk, boolean retainLightingData) { return CompletableFuture.supplyAsync(() -> { @NotNull var chunkPosition = chunk.getPos(); @@ -144,15 +137,15 @@ public void enqueueChunkSectionLightingData(@NotNull LightType lightType, @NotNu } @NotNull var chunkSectionPosition = ChunkSectionPos.from(chunkPosition, serverWorld.sectionIndexToCoord(i)); - enqueueChunkSectionLightingData( + enqueueSectionData( LightType.SKY, chunkSectionPosition, getChunkLightingView(LightType.SKY).getLightSection(chunkSectionPosition)); - enqueueChunkSectionLightingData( + enqueueSectionData( LightType.BLOCK, chunkSectionPosition, getChunkLightingView(LightType.BLOCK).getLightSection(chunkSectionPosition)); setSectionStatus(chunkSectionPosition, false); } setColumnEnabled(chunkPosition, retainLightingData); - setRetainLightingData(chunkPosition, false); + setRetainData(chunkPosition, false); return chunk; }, threadPoolExecutor); } diff --git a/common/src/main/resources/noisiumchunkmanager-common.mixins.json b/common/src/main/resources/noisiumchunkmanager-common.mixins.json index 816898a..ea50115 100644 --- a/common/src/main/resources/noisiumchunkmanager-common.mixins.json +++ b/common/src/main/resources/noisiumchunkmanager-common.mixins.json @@ -28,7 +28,6 @@ "world.WorldMixin", "world.chunk.ChunkToNibbleArrayMapMixin", "world.chunk.PalettedContainerMixin", - "world.chunk.ProtoChunkMixin", "world.chunk.WorldChunkMixin", "world.chunk.light.BlockLightStorageDataMixin", "world.chunk.light.ChunkLightProviderMixin", diff --git a/common/src/main/resources/noisiumchunkmanager.accesswidener b/common/src/main/resources/noisiumchunkmanager.accesswidener index 1fd5f15..3ee7879 100644 --- a/common/src/main/resources/noisiumchunkmanager.accesswidener +++ b/common/src/main/resources/noisiumchunkmanager.accesswidener @@ -11,5 +11,8 @@ accessible field net/minecraft/world/chunk/PalettedContainer paletteProvider Lne accessible class net/minecraft/world/chunk/PalettedContainer$Data accessible field net/minecraft/world/chunk/PalettedContainer$Data palette Lnet/minecraft/world/chunk/Palette; +accessible field net/minecraft/world/chunk/light/LightingProvider skyLightProvider Lnet/minecraft/world/chunk/light/ChunkLightProvider; +accessible field net/minecraft/world/chunk/light/LightingProvider blockLightProvider Lnet/minecraft/world/chunk/light/ChunkLightProvider; + accessible class net/minecraft/world/chunk/light/SkyLightStorage$Data accessible class net/minecraft/world/chunk/light/BlockLightStorage$Data