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 59c848863..90894dd17 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 @@ -124,14 +124,18 @@ public abstract class MixinChunk implements IMixinChunk { private void onTickHead(boolean skipRecheckGaps, CallbackInfo ci) { final List neighbors = this.getSurroundingChunks(); if (this.isGapLightingUpdated && this.world.worldProvider.m() && !skipRecheckGaps && !neighbors.isEmpty()) { // PAIL: isGapLightingUpdated - hasSkyLight - this.recheckGapsAsync(neighbors); + this.lightExecutorService.execute(() -> { + this.recheckGapsAsync(neighbors); + }); this.isGapLightingUpdated = false; } this.ticked = true; if (!this.isLightPopulated && this.isTerrainPopulated && !neighbors.isEmpty()) { - this.checkLightAsync(neighbors); + this.lightExecutorService.execute(() -> { + this.checkLightAsync(neighbors); + }); // set to true to avoid requeuing the same task when not finished this.isLightPopulated = true; } @@ -228,7 +232,7 @@ public abstract class MixinChunk implements IMixinChunk { @Inject(method = "o()V", at = @At("HEAD"), cancellable = true) private void checkLightHead(CallbackInfo ci) { - if (this.world.getMinecraftServer().isStopped()) { + if (this.world.getMinecraftServer().isStopped() || this.lightExecutorService.isShutdown()) { return; } @@ -243,11 +247,13 @@ public abstract class MixinChunk implements IMixinChunk { if (Akari.isPrimaryThread()) { // Akarin try { - this.checkLightAsync(neighborChunks); + this.lightExecutorService.execute(() -> { + this.checkLightAsync(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()) { + if (!this.world.getMinecraftServer().isStopped() && !this.lightExecutorService.isShutdown()) { throw ex; } } @@ -445,7 +451,9 @@ public abstract class MixinChunk implements IMixinChunk { @Inject(method = "c(III)V", at = @At("HEAD"), cancellable = true) private void onRelightBlock(int x, int y, int z, CallbackInfo ci) { - this.relightBlockAsync(x, y, z); + this.lightExecutorService.execute(() -> { + this.relightBlockAsync(x, y, z); + }); ci.cancel(); } @@ -464,7 +472,7 @@ public abstract class MixinChunk implements IMixinChunk { j = y; } - while (j > 0 && this.getBlockData(x, j - 1, z).c() == 0) { + while (j > 0 && this.getBlockData(x, j - 1, z).c() == 0) { // PAIL: getLightOpacity --j; } @@ -481,7 +489,7 @@ public abstract class MixinChunk implements IMixinChunk { if (extendedblockstorage2 != Chunk.EMPTY_CHUNK_SECTION) { extendedblockstorage2.a(x, j1 & 15, z, 15); // PAIL: setSkyLight - this.world.m(new BlockPosition((this.locX << 4) + x, j1, (this.locZ << 4) + z)); // PAIL: notifyLightSet + // this.world.m(new BlockPosition((this.locX << 4) + x, j1, (this.locZ << 4) + z)); // PAIL: notifyLightSet - client side } } } else { @@ -490,7 +498,7 @@ public abstract class MixinChunk implements IMixinChunk { if (extendedblockstorage != Chunk.EMPTY_CHUNK_SECTION) { extendedblockstorage.a(x, i1 & 15, z, 0); // PAIL: setSkyLight - this.world.m(new BlockPosition((this.locX << 4) + x, i1, (this.locZ << 4) + z)); // PAIL: notifyLightSet + // this.world.m(new BlockPosition((this.locX << 4) + x, i1, (this.locZ << 4) + z)); // PAIL: notifyLightSet - client side } } } 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 66c2854ac..78c2bb908 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 @@ -42,6 +42,5 @@ public abstract class MixinWorld { @Shadow(aliases = "c") public abstract boolean checkLightFor(EnumSkyBlock lightType, BlockPosition pos); @Shadow public abstract MinecraftServer getMinecraftServer(); @Shadow public abstract boolean areChunksLoaded(BlockPosition center, int radius, boolean allowEmpty); - @Shadow(aliases = "m") public abstract void notifyLightSet(BlockPosition pos); @Shadow public abstract Chunk getChunkIfLoaded(int x, int z); } diff --git a/sources/src/main/java/io/akarin/server/mixin/lighting/MixinWorldServer.java b/sources/src/main/java/io/akarin/server/mixin/lighting/MixinWorldServer.java index 492297974..94cb9a58d 100644 --- a/sources/src/main/java/io/akarin/server/mixin/lighting/MixinWorldServer.java +++ b/sources/src/main/java/io/akarin/server/mixin/lighting/MixinWorldServer.java @@ -54,9 +54,9 @@ public abstract class MixinWorldServer extends MixinWorld implements IMixinWorld private static final short XZ_MASK = 0xF; private static final short Y_SHORT_MASK = 0xFF; - private final ExecutorService lightExecutorService = preparExecutorService();; + private final ExecutorService lightExecutorService = getExecutorService();; - private ExecutorService preparExecutorService() { + private ExecutorService getExecutorService() { return AkarinGlobalConfig.asyncLightingWorkStealing ? Executors.newFixedThreadPool(AkarinGlobalConfig.asyncLightingThreads, new ThreadFactoryBuilder().setNameFormat("Akarin Async Light Thread").build()) : Executors.newWorkStealingPool(AkarinGlobalConfig.asyncLightingThreads); } @@ -79,7 +79,7 @@ public abstract class MixinWorldServer extends MixinWorld implements IMixinWorld int i1 = pos.getX(); int j1 = pos.getY(); int k1 = pos.getZ(); - + if (l > k) { this.J[j++] = 133152; // PAIL: lightUpdateBlockList } else if (l < k) { @@ -98,7 +98,7 @@ public abstract class MixinWorldServer extends MixinWorld implements IMixinWorld this.setLightForAsync(lightType, blockpos, 0, currentChunk, neighbors); // Sponge - use thread safe method if (l2 > 0) { - int j3 = MathHelper.a(i2 - i1); // TODO MathHelper + int j3 = MathHelper.a(i2 - i1); // abs int k3 = MathHelper.a(j2 - j1); int l3 = MathHelper.a(k2 - k1); @@ -237,13 +237,13 @@ public abstract class MixinWorldServer extends MixinWorld implements IMixinWorld if (northWestChunk != null) { neighbors.add(northWestChunk); } - + for (Chunk neighborChunk : neighbors) { final IMixinChunk neighbor = (IMixinChunk) neighborChunk; neighbor.getPendingLightUpdates().incrementAndGet(); neighbor.setLightUpdateTime(chunk.getWorld().getTime()); } - + if (Akari.isPrimaryThread()) { // Akarin this.lightExecutorService.execute(() -> { this.checkLightAsync(lightType, pos, chunk, neighbors); @@ -285,15 +285,15 @@ public abstract class MixinWorldServer extends MixinWorld implements IMixinWorld if (pos.getY() < 0) { pos = new BlockPosition(pos.getX(), 0, pos.getZ()); } - if (!(pos.isValidLocation())) { + if (!pos.isValidLocation()) { return lightType.c; // PAIL: defaultLightValue } final Chunk chunk = this.getLightChunk(pos, currentChunk, neighbors); if (chunk == null || chunk.isUnloading()) { - return lightType.c; // PAIL: defaultLightValue + return 0; // Akarin - fixes cave light - defaultLightValue -> 0 } - + return chunk.getBrightness(lightType, pos); } @@ -345,8 +345,8 @@ public abstract class MixinWorldServer extends MixinWorld implements IMixinWorld if (pos.isValidLocation()) { final Chunk chunk = this.getLightChunk(pos, currentChunk, neighbors); if (chunk != null && !chunk.isUnloading()) { - chunk.a(type, pos, lightValue); // PAIL: setBrightness - this.notifyLightSet(pos); + chunk.a(type, pos, lightValue); // PAIL: setLightFor + // this.notifyLightSet(pos); - client side } } }