diff --git a/leaf-server/minecraft-patches/features/0139-Async-ChunkSend.patch b/leaf-server/minecraft-patches/features/0139-Async-ChunkSend.patch index 875efee2..4a716527 100644 --- a/leaf-server/minecraft-patches/features/0139-Async-ChunkSend.patch +++ b/leaf-server/minecraft-patches/features/0139-Async-ChunkSend.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Async ChunkSend diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java b/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java -index a35e9fae8f8da0c42f0616c4f78dc396492673aa..31f9556e808c9dea49ba9774cbf736791ed9a687 100644 +index a35e9fae8f8da0c42f0616c4f78dc396492673aa..4818e6d8f2fd098a63e14f15644d2eb25227b6d4 100644 --- a/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java +++ b/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java @@ -22,15 +22,13 @@ import it.unimi.dsi.fastutil.longs.LongComparator; @@ -35,7 +35,7 @@ index a35e9fae8f8da0c42f0616c4f78dc396492673aa..31f9556e808c9dea49ba9774cbf73679 public final class RegionizedPlayerChunkLoader { public static final TicketType PLAYER_TICKET = TicketType.create("chunk_system:player_ticket", Long::compareTo); -@@ -411,18 +411,81 @@ public final class RegionizedPlayerChunkLoader { +@@ -411,18 +411,90 @@ public final class RegionizedPlayerChunkLoader { this.delayedTicketOps.addLast(op); } @@ -49,30 +49,38 @@ index a35e9fae8f8da0c42f0616c4f78dc396492673aa..31f9556e808c9dea49ba9774cbf73679 - ((ChunkSystemChunkHolder)((ChunkSystemServerLevel)this.world).moonrise$getChunkTaskScheduler().chunkHolderManager - .getChunkHolder(chunkX, chunkZ).vanillaChunkHolder).moonrise$addReceivedChunk(this.player); + final long chunkKey = CoordinateUtils.getChunkKey(chunkX, chunkZ); - -- final LevelChunk chunk = ((ChunkSystemLevel)this.world).moonrise$getFullChunkIfLoaded(chunkX, chunkZ); ++ + if (!this.sentChunks.add(chunkKey)) { -+ throw new IllegalStateException(); ++ // Already in our sent list - silently return instead of throwing an exception ++ return; + } -- PlatformHooks.get().onChunkWatch(this.world, chunk, this.player); -- PlayerChunkSender.sendChunk(this.player.connection, this.world, chunk); +- final LevelChunk chunk = ((ChunkSystemLevel)this.world).moonrise$getFullChunkIfLoaded(chunkX, chunkZ); + // Get the chunk now, as we need it for both sync and async paths + final LevelChunk chunk = ((ChunkSystemLevel)this.world).moonrise$getFullChunkIfLoaded(chunkX, chunkZ); + if (chunk == null) { + // Handle case where chunk is no longer loaded ++ this.sentChunks.remove(chunkKey); ++ return; ++ } + ++ // Try to mark the chunk as received by this player ++ try { ++ // This part needs to remain on the main thread as it affects shared state ++ ((ChunkSystemChunkHolder)((ChunkSystemServerLevel)this.world).moonrise$getChunkTaskScheduler().chunkHolderManager ++ .getChunkHolder(chunkX, chunkZ).vanillaChunkHolder).moonrise$addReceivedChunk(this.player); ++ ++ // Call onChunkWatch on the main thread as it might affect server state + PlatformHooks.get().onChunkWatch(this.world, chunk, this.player); +- PlayerChunkSender.sendChunk(this.player.connection, this.world, chunk); ++ } catch (IllegalStateException e) { ++ // This happens if the chunk was already marked as received by this player ++ // Just remove it from our sent list and return + this.sentChunks.remove(chunkKey); return; } - throw new IllegalStateException(); + -+ // This part needs to remain on the main thread as it affects shared state -+ ((ChunkSystemChunkHolder)((ChunkSystemServerLevel)this.world).moonrise$getChunkTaskScheduler().chunkHolderManager -+ .getChunkHolder(chunkX, chunkZ).vanillaChunkHolder).moonrise$addReceivedChunk(this.player); -+ -+ // Call onChunkWatch on the main thread as it might affect server state -+ PlatformHooks.get().onChunkWatch(this.world, chunk, this.player); -+ + // Check if async chunk sending is enabled + if (org.dreeam.leaf.config.modules.async.AsyncChunkSend.enabled) { + // Async implementation