Skip to content

Commit

Permalink
refactor: Make ServerWorldLightingProvider extend LightingProvider
Browse files Browse the repository at this point in the history
This improves/fixes compatibility with mods such as Distant Horizons.
  • Loading branch information
Steveplays28 committed Jul 25, 2024
1 parent 88223a5 commit 8efa137
Show file tree
Hide file tree
Showing 9 changed files with 61 additions and 86 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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<LightingProvider> 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<Chunk> cir) {
if (this.isClient()) {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,15 @@ public static class DataMixin implements SkyLightStorageDataExtension {
private int noisiumchunkmanager$columnToTopSectionDefaultReturnValue;

@Inject(method = "<init>", at = @At(value = "TAIL"))
private void noisiumchunkmanager$replaceSets(@NotNull Long2ObjectOpenHashMap<Object> arrays, @Nullable Long2IntOpenHashMap columnToTopSection, int minSectionY, @NotNull CallbackInfo ci) {
private void noisiumchunkmanager$replaceSets(@NotNull Long2ObjectOpenHashMap<Object> 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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

Expand All @@ -57,6 +59,7 @@ public class ServerWorldChunkManager {
private final ChunkGenerator chunkGenerator;
private final NoiseConfig noiseConfig;
private final Consumer<Runnable> syncRunnableConsumer;
private final Supplier<LightingProvider> lightingProviderSupplier;
private final BiFunction<Chunk, Boolean, CompletableFuture<Chunk>> initializeChunkLightingBiFunction;
private final BiFunction<Chunk, Boolean, CompletableFuture<Chunk>> lightChunkBiFunction;
private final PersistentStateManager persistentStateManager;
Expand All @@ -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<Runnable> syncRunnableConsumer, @NotNull BiFunction<Chunk, Boolean, CompletableFuture<Chunk>> initializeChunkLightingBiFunction, @NotNull BiFunction<Chunk, Boolean, CompletableFuture<Chunk>> lightChunkBiFunction, @NotNull Path worldDirectoryPath, @NotNull DataFixer dataFixer) {
public ServerWorldChunkManager(@NotNull ServerWorld serverWorld, @NotNull ChunkGenerator chunkGenerator, @NotNull NoiseConfig noiseConfig, @NotNull Consumer<Runnable> syncRunnableConsumer, @NotNull Supplier<LightingProvider> lightingProviderSupplier, @NotNull BiFunction<Chunk, Boolean, CompletableFuture<Chunk>> initializeChunkLightingBiFunction, @NotNull BiFunction<Chunk, Boolean, CompletableFuture<Chunk>> 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;

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -348,10 +352,12 @@ private void onBlockChange(@NotNull BlockPos blockPos, @NotNull BlockState oldBl
}

// TODO: Move this into the constructor as a Supplier<ChunkPos, ProtoChunk>
private @NotNull ProtoChunk generateChunk(@NotNull ChunkPos chunkPos, @NotNull Function<ChunkPos, IoWorldChunk> ioWorldChunkGetFunction, @NotNull Function<ChunkPos, IoWorldChunk> ioWorldChunkRemoveFunction, @NotNull BiFunction<Chunk, Boolean, CompletableFuture<Chunk>> initializeChunkLightingBiConsumer, @NotNull BiFunction<Chunk, Boolean, CompletableFuture<Chunk>> lightChunkBiConsumer) {
private @NotNull ProtoChunk generateChunk(@NotNull ChunkPos chunkPos, @NotNull Supplier<LightingProvider> lightingProviderSupplier, @NotNull Function<ChunkPos, IoWorldChunk> ioWorldChunkGetFunction, @NotNull Function<ChunkPos, IoWorldChunk> ioWorldChunkRemoveFunction, @NotNull BiFunction<Chunk, Boolean, CompletableFuture<Chunk>> initializeChunkLightingBiConsumer, @NotNull BiFunction<Chunk, Boolean, CompletableFuture<Chunk>> lightChunkBiConsumer) {
var protoChunk = new ProtoChunk(chunkPos, UpgradeData.NO_UPGRADE_DATA, serverWorld,
serverWorld.getRegistryManager().get(RegistryKeys.BIOME), null
);
protoChunk.setLightingProvider(lightingProviderSupplier.get());

List<Chunk> chunkRegionChunks = List.of(protoChunk);
var chunkRegion = new ChunkRegion(serverWorld, chunkRegionChunks, ChunkStatus.FULL, 1);
var blender = Blender.getBlender(chunkRegion);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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 -> {
Expand Down Expand Up @@ -109,30 +100,32 @@ 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);
case SKY -> skyLightProvider.enqueueSectionData(chunkSectionPositionAsLong, chunkLightingDataNibbleArray);
}
}

@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<Chunk> initializeLight(@NotNull Chunk chunk, boolean retainLightingData) {
return CompletableFuture.supplyAsync(() -> {
@NotNull var chunkPosition = chunk.getPos();
Expand All @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
3 changes: 3 additions & 0 deletions common/src/main/resources/noisiumchunkmanager.accesswidener
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 8efa137

Please sign in to comment.