diff --git a/patches/server/Rewrite-chunk-system.patch b/patches/server/Rewrite-chunk-system.patch index dd7931972d..f44dbd1b53 100644 --- a/patches/server/Rewrite-chunk-system.patch +++ b/patches/server/Rewrite-chunk-system.patch @@ -845,6 +845,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 if (this.cachedBlockPropagators == null) { return; } +@@ -0,0 +0,0 @@ public final class StarLightInterface { + } + } + +- public LightQueue.ChunkTasks blockChange(final BlockPos pos) { ++ public io.papermc.paper.chunk.system.light.LightQueue.ChunkTasks blockChange(final BlockPos pos) { // Paper - rewrite chunk system + if (this.world == null || pos.getY() < WorldUtil.getMinBlockY(this.world) || pos.getY() > WorldUtil.getMaxBlockY(this.world)) { // empty world + return null; + } +@@ -0,0 +0,0 @@ public final class StarLightInterface { + return this.lightQueue.queueBlockChange(pos); + } + +- public LightQueue.ChunkTasks sectionChange(final SectionPos pos, final boolean newEmptyValue) { ++ public io.papermc.paper.chunk.system.light.LightQueue.ChunkTasks sectionChange(final SectionPos pos, final boolean newEmptyValue) { // Paper - rewrite chunk system + if (this.world == null) { // empty world + return null; + } @@ -0,0 +0,0 @@ public final class StarLightInterface { } @@ -905,7 +923,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + throw new UnsupportedOperationException("No longer implemented, task draining is now performed by the light thread"); // Paper - replace light queue } - protected static final class LightQueue { + public static final class LightQueue { diff --git a/src/main/java/co/aikar/timings/TimingsExport.java b/src/main/java/co/aikar/timings/TimingsExport.java index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644 --- a/src/main/java/co/aikar/timings/TimingsExport.java @@ -6036,7 +6054,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + } + -+ public CompletableFuture queueBlockChange(final BlockPos pos) { ++ public ChunkTasks queueBlockChange(final BlockPos pos) { + final ChunkTasks tasks; + synchronized (this) { + tasks = this.chunkTasks.computeIfAbsent(CoordinateUtils.getChunkKey(pos), (final long keyInMap) -> { @@ -6047,10 +6065,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + tasks.schedule(); + -+ return tasks.onComplete; ++ return tasks; + } + -+ public CompletableFuture queueSectionChange(final SectionPos pos, final boolean newEmptyValue) { ++ public ChunkTasks queueSectionChange(final SectionPos pos, final boolean newEmptyValue) { + final ChunkTasks tasks; + synchronized (this) { + tasks = this.chunkTasks.computeIfAbsent(CoordinateUtils.getChunkKey(pos), (final long keyInMap) -> { @@ -6065,10 +6083,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + tasks.schedule(); + -+ return tasks.onComplete; ++ return tasks; + } + -+ public CompletableFuture queueChunkLightTask(final ChunkPos pos, final BooleanSupplier lightTask, final PrioritisedExecutor.Priority priority) { ++ public ChunkTasks queueChunkLightTask(final ChunkPos pos, final BooleanSupplier lightTask, final PrioritisedExecutor.Priority priority) { + final ChunkTasks tasks; + synchronized (this) { + tasks = this.chunkTasks.computeIfAbsent(CoordinateUtils.getChunkKey(pos), (final long keyInMap) -> { @@ -6082,10 +6100,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + tasks.schedule(); + -+ return tasks.onComplete; ++ return tasks; + } + -+ public CompletableFuture queueChunkSkylightEdgeCheck(final SectionPos pos, final ShortCollection sections) { ++ public ChunkTasks queueChunkSkylightEdgeCheck(final SectionPos pos, final ShortCollection sections) { + final ChunkTasks tasks; + synchronized (this) { + tasks = this.chunkTasks.computeIfAbsent(CoordinateUtils.getChunkKey(pos), (final long keyInMap) -> { @@ -6101,10 +6119,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + tasks.schedule(); + -+ return tasks.onComplete; ++ return tasks; + } + -+ public CompletableFuture queueChunkBlocklightEdgeCheck(final SectionPos pos, final ShortCollection sections) { ++ public ChunkTasks queueChunkBlocklightEdgeCheck(final SectionPos pos, final ShortCollection sections) { + final ChunkTasks tasks; + + synchronized (this) { @@ -6121,7 +6139,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + tasks.schedule(); + -+ return tasks.onComplete; ++ return tasks; + } + + public void removeChunk(final ChunkPos pos) { @@ -6134,20 +6152,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + } + -+ protected static final class ChunkTasks implements Runnable { -+ -+ final Set changedPositions = new HashSet<>(); -+ Boolean[] changedSectionSet; -+ ShortOpenHashSet queuedEdgeChecksSky; -+ ShortOpenHashSet queuedEdgeChecksBlock; -+ List lightTasks; -+ -+ final CompletableFuture onComplete = new CompletableFuture<>(); ++ public static final class ChunkTasks implements Runnable { + ++ public final CompletableFuture onComplete = new CompletableFuture<>(); ++ public boolean isTicketAdded; + public final long chunkCoordinate; ++ + private final StarLightInterface lightEngine; + private final LightQueue queue; + private final PrioritisedExecutor.PrioritisedTask task; ++ private final Set changedPositions = new HashSet<>(); ++ private Boolean[] changedSectionSet; ++ private ShortOpenHashSet queuedEdgeChecksSky; ++ private ShortOpenHashSet queuedEdgeChecksBlock; ++ private List lightTasks; + + public ChunkTasks(final long chunkCoordinate, final StarLightInterface lightEngine, final LightQueue queue) { + this(chunkCoordinate, lightEngine, queue, PrioritisedExecutor.Priority.NORMAL); @@ -20276,6 +20294,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 this.theLightEngine.relightChunks(chunks, (ChunkPos chunkPos) -> { chunkLightCallback.accept(chunkPos); ((java.util.concurrent.Executor)((ServerLevel)this.theLightEngine.getWorld()).getChunkSource().mainThreadProcessor).execute(() -> { +@@ -0,0 +0,0 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl + private final Long2IntOpenHashMap chunksBeingWorkedOn = new Long2IntOpenHashMap(); + + private void queueTaskForSection(final int chunkX, final int chunkY, final int chunkZ, +- final Supplier runnable) { ++ final Supplier runnable) { // Paper - rewrite chunk system + final ServerLevel world = (ServerLevel)this.theLightEngine.getWorld(); + + final ChunkAccess center = this.theLightEngine.getAnyChunkNow(chunkX, chunkZ); +@@ -0,0 +0,0 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl + + final long key = CoordinateUtils.getChunkKey(chunkX, chunkZ); + +- final ca.spottedleaf.starlight.common.light.StarLightInterface.LightQueue.ChunkTasks updateFuture = runnable.get(); ++ final io.papermc.paper.chunk.system.light.LightQueue.ChunkTasks updateFuture = runnable.get(); // Paper - rewrite chunk system + + if (updateFuture == null) { + // not scheduled @@ -0,0 +0,0 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl } diff --git a/patches/server/Starlight.patch b/patches/server/Starlight.patch index 15bd634d36..7bc4fb686c 100644 --- a/patches/server/Starlight.patch +++ b/patches/server/Starlight.patch @@ -3233,7 +3233,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return this.hasBlockLight; + } + -+ protected int getSkyLightValue(final BlockPos blockPos, final ChunkAccess chunk) { ++ public int getSkyLightValue(final BlockPos blockPos, final ChunkAccess chunk) { + if (!this.hasSkyLight) { + return 0; + } @@ -3303,7 +3303,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return 15; + } + -+ protected int getBlockLightValue(final BlockPos blockPos, final ChunkAccess chunk) { ++ public int getBlockLightValue(final BlockPos blockPos, final ChunkAccess chunk) { + if (!this.hasBlockLight) { + return 0; + } @@ -3422,7 +3422,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + } + -+ public CompletableFuture blockChange(final BlockPos pos) { ++ public LightQueue.ChunkTasks blockChange(final BlockPos pos) { + if (this.world == null || pos.getY() < WorldUtil.getMinBlockY(this.world) || pos.getY() > WorldUtil.getMaxBlockY(this.world)) { // empty world + return null; + } @@ -3430,7 +3430,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return this.lightQueue.queueBlockChange(pos); + } + -+ public CompletableFuture sectionChange(final SectionPos pos, final boolean newEmptyValue) { ++ public LightQueue.ChunkTasks sectionChange(final SectionPos pos, final boolean newEmptyValue) { + if (this.world == null) { // empty world + return null; + } @@ -3613,7 +3613,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + } + -+ protected static final class LightQueue { ++ public static final class LightQueue { + + protected final Long2ObjectLinkedOpenHashMap chunkTasks = new Long2ObjectLinkedOpenHashMap<>(); + protected final StarLightInterface manager; @@ -3626,13 +3626,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return this.chunkTasks.isEmpty(); + } + -+ public synchronized CompletableFuture queueBlockChange(final BlockPos pos) { ++ public synchronized LightQueue.ChunkTasks queueBlockChange(final BlockPos pos) { + final ChunkTasks tasks = this.chunkTasks.computeIfAbsent(CoordinateUtils.getChunkKey(pos), ChunkTasks::new); + tasks.changedPositions.add(pos.immutable()); -+ return tasks.onComplete; ++ return tasks; + } + -+ public synchronized CompletableFuture queueSectionChange(final SectionPos pos, final boolean newEmptyValue) { ++ public synchronized LightQueue.ChunkTasks queueSectionChange(final SectionPos pos, final boolean newEmptyValue) { + final ChunkTasks tasks = this.chunkTasks.computeIfAbsent(CoordinateUtils.getChunkKey(pos), ChunkTasks::new); + + if (tasks.changedSectionSet == null) { @@ -3640,20 +3640,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + tasks.changedSectionSet[pos.getY() - this.manager.minSection] = Boolean.valueOf(newEmptyValue); + -+ return tasks.onComplete; ++ return tasks; + } + -+ public synchronized CompletableFuture queueChunkLighting(final ChunkPos pos, final Runnable lightTask) { ++ public synchronized LightQueue.ChunkTasks queueChunkLighting(final ChunkPos pos, final Runnable lightTask) { + final ChunkTasks tasks = this.chunkTasks.computeIfAbsent(CoordinateUtils.getChunkKey(pos), ChunkTasks::new); + if (tasks.lightTasks == null) { + tasks.lightTasks = new ArrayList<>(); + } + tasks.lightTasks.add(lightTask); + -+ return tasks.onComplete; ++ return tasks; + } + -+ public synchronized CompletableFuture queueChunkSkylightEdgeCheck(final SectionPos pos, final ShortCollection sections) { ++ public synchronized LightQueue.ChunkTasks queueChunkSkylightEdgeCheck(final SectionPos pos, final ShortCollection sections) { + final ChunkTasks tasks = this.chunkTasks.computeIfAbsent(CoordinateUtils.getChunkKey(pos), ChunkTasks::new); + + ShortOpenHashSet queuedEdges = tasks.queuedEdgeChecksSky; @@ -3662,10 +3662,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + queuedEdges.addAll(sections); + -+ return tasks.onComplete; ++ return tasks; + } + -+ public synchronized CompletableFuture queueChunkBlocklightEdgeCheck(final SectionPos pos, final ShortCollection sections) { ++ public synchronized LightQueue.ChunkTasks queueChunkBlocklightEdgeCheck(final SectionPos pos, final ShortCollection sections) { + final ChunkTasks tasks = this.chunkTasks.computeIfAbsent(CoordinateUtils.getChunkKey(pos), ChunkTasks::new); + + ShortOpenHashSet queuedEdges = tasks.queuedEdgeChecksBlock; @@ -3674,7 +3674,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + } + queuedEdges.addAll(sections); + -+ return tasks.onComplete; ++ return tasks; + } + + public void removeChunk(final ChunkPos pos) { @@ -3694,7 +3694,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + return this.chunkTasks.removeFirst(); + } + -+ protected static final class ChunkTasks { ++ public static final class ChunkTasks { + + public final Set changedPositions = new ObjectOpenHashSet<>(); + public Boolean[] changedSectionSet; @@ -3702,6 +3702,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + public ShortOpenHashSet queuedEdgeChecksBlock; + public List lightTasks; + ++ public boolean isTicketAdded = false; + public final CompletableFuture onComplete = new CompletableFuture<>(); + + public final long chunkCoordinate; @@ -4614,7 +4615,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + private final Long2IntOpenHashMap chunksBeingWorkedOn = new Long2IntOpenHashMap(); + -+ private void queueTaskForSection(final int chunkX, final int chunkY, final int chunkZ, final Supplier> runnable) { ++ private void queueTaskForSection(final int chunkX, final int chunkY, final int chunkZ, ++ final Supplier runnable) { + final ServerLevel world = (ServerLevel)this.theLightEngine.getWorld(); + + final ChunkAccess center = this.theLightEngine.getAnyChunkNow(chunkX, chunkZ); @@ -4641,20 +4643,26 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + + final long key = CoordinateUtils.getChunkKey(chunkX, chunkZ); + -+ final CompletableFuture updateFuture = runnable.get(); ++ final ca.spottedleaf.starlight.common.light.StarLightInterface.LightQueue.ChunkTasks updateFuture = runnable.get(); + + if (updateFuture == null) { + // not scheduled + return; + } + ++ if (updateFuture.isTicketAdded) { ++ // ticket already added ++ return; ++ } ++ updateFuture.isTicketAdded = true; ++ + final int references = this.chunksBeingWorkedOn.addTo(key, 1); + if (references == 0) { + final ChunkPos pos = new ChunkPos(chunkX, chunkZ); + world.getChunkSource().addRegionTicket(ca.spottedleaf.starlight.common.light.StarLightInterface.CHUNK_WORK_TICKET, pos, 0, pos); + } + -+ updateFuture.thenAcceptAsync((final Void ignore) -> { ++ updateFuture.onComplete.thenAcceptAsync((final Void ignore) -> { + final int newReferences = this.chunksBeingWorkedOn.get(key); + if (newReferences == 1) { + this.chunksBeingWorkedOn.remove(key); @@ -4668,8 +4676,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + LOGGER.error("Failed to remove ticket level for post chunk task " + new ChunkPos(chunkX, chunkZ), thr); + } + }); -+ } -+ + } + + @Override + public boolean hasLightWork() { + // route to new light engine @@ -4689,11 +4697,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000 + if (sky == 15) return 15; + final int block = this.theLightEngine.getBlockReader().getLightValue(pos); + return Math.max(sky, block); - } ++ } + // Paper end - replace light engine imp - ++ @Override public void close() { + } @@ -0,0 +0,0 @@ public class ThreadedLevelLightEngine extends LevelLightEngine implements AutoCl @Override