diff --git a/sources/src/main/java/io/akarin/api/internal/mixin/IMixinChunk.java b/sources/src/main/java/io/akarin/api/internal/mixin/IMixinChunk.java index 7dd2723b1..33b97c3da 100644 --- a/sources/src/main/java/io/akarin/api/internal/mixin/IMixinChunk.java +++ b/sources/src/main/java/io/akarin/api/internal/mixin/IMixinChunk.java @@ -25,4 +25,6 @@ public interface IMixinChunk { void setNeighborChunk(int index, @Nullable Chunk chunk); void setLightUpdateTime(long time); + + void setPendingLightUpdate(); } \ No newline at end of file diff --git a/sources/src/main/java/io/akarin/server/mixin/lighting/MixinChunk.java b/sources/src/main/java/io/akarin/server/mixin/lighting/MixinChunk.java index 3d8190288..95e8bf9f2 100644 --- a/sources/src/main/java/io/akarin/server/mixin/lighting/MixinChunk.java +++ b/sources/src/main/java/io/akarin/server/mixin/lighting/MixinChunk.java @@ -108,6 +108,11 @@ public abstract class MixinChunk implements IMixinChunk { return this.pendingLightUpdates; } + @Override + public void setPendingLightUpdate() { + this.isLightPopulated = false; + } + @Override public long getLightUpdateTime() { return this.lightUpdateTime; @@ -130,7 +135,7 @@ public abstract class MixinChunk implements IMixinChunk { this.ticked = true; - if (!this.isLightPopulated && this.isTerrainPopulated && !neighbors.isEmpty()) { + if ((true || !this.isLightPopulated) && this.isTerrainPopulated && !neighbors.isEmpty()) { lightExecutorService.execute(() -> { this.checkLightAsync(neighbors); }); @@ -170,12 +175,47 @@ public abstract class MixinChunk implements IMixinChunk { return this.checkWorldLightFor(enumSkyBlock, pos); } + @Inject(method = "h(Z)V", at = @At("HEAD"), cancellable = true) + private void onRecheckGaps(CallbackInfo ci) { + if (this.world.getMinecraftServer().isStopped() || lightExecutorService.isShutdown()) { + return; + } + + if (this.isUnloading()) { + return; + } + final List neighborChunks = this.getSurroundingChunks(); + if (neighborChunks.isEmpty()) { + this.isGapLightingUpdated = true; + return; + } + + if (Akari.isPrimaryThread()) { + try { + lightExecutorService.execute(() -> { + this.recheckGapsAsync(neighborChunks); + }); + } catch (RejectedExecutionException ex) { + // This could happen if ServerHangWatchdog kills the server + // between the start of the method and the execute() call. + if (!this.world.getMinecraftServer().isStopped() && !lightExecutorService.isShutdown()) { + throw ex; + } + } + } else { + this.recheckGapsAsync(neighborChunks); + } + ci.cancel(); + } + /** * Rechecks chunk gaps async. * * @param neighbors A thread-safe list of surrounding neighbor chunks */ private void recheckGapsAsync(List neighbors) { + this.isLightPopulated = false; + for (int i = 0; i < 16; ++i) { for (int j = 0; j < 16; ++j) { if (this.updateSkylightColumns[i + j * 16]) { @@ -201,7 +241,7 @@ public abstract class MixinChunk implements IMixinChunk { } } - // this.isGapLightingUpdated = false; + this.isGapLightingUpdated = false; } } @@ -272,13 +312,12 @@ public abstract class MixinChunk implements IMixinChunk { BlockPosition blockpos = new BlockPosition(this.locX << 4, 0, this.locZ << 4); if (this.world.worldProvider.m()) { // OBFHELPER: hasSkyLight - reCheckLight: - + CHECK_LIGHT: for (int i = 0; i < 16; ++i) { for (int j = 0; j < 16; ++j) { if (!this.checkLightAsync(i, j, neighbors)) { this.isLightPopulated = false; - break reCheckLight; + break CHECK_LIGHT; } } } diff --git a/sources/src/main/java/io/akarin/server/mixin/lighting/MixinWorld.java b/sources/src/main/java/io/akarin/server/mixin/lighting/MixinWorld.java index 4d55cf0ef..d09d94a33 100644 --- a/sources/src/main/java/io/akarin/server/mixin/lighting/MixinWorld.java +++ b/sources/src/main/java/io/akarin/server/mixin/lighting/MixinWorld.java @@ -26,7 +26,6 @@ package io.akarin.server.mixin.lighting; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; - import net.minecraft.server.BlockPosition; import net.minecraft.server.Chunk; import net.minecraft.server.EnumSkyBlock; diff --git a/sources/src/main/java/net/minecraft/server/Chunk.java b/sources/src/main/java/net/minecraft/server/Chunk.java index 42acb6d9a..7ac8a24e0 100644 --- a/sources/src/main/java/net/minecraft/server/Chunk.java +++ b/sources/src/main/java/net/minecraft/server/Chunk.java @@ -2,8 +2,8 @@ package net.minecraft.server; import com.destroystokyo.paper.exception.ServerInternalException; import com.google.common.base.Predicate; -import com.google.common.collect.Maps; import com.google.common.collect.Queues; + import java.util.Arrays; import java.util.Collection; import java.util.Iterator;