From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: NONPLAYT <76615486+NONPLAYT@users.noreply.github.com> Date: Mon, 3 Mar 2025 19:29:13 +0300 Subject: [PATCH] Async Chunk Sending diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java b/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java index 78f2d7c698a4f2c21a473627c3017a9751f80cf1..aabfaa370e4bcb8db61e831072b28684482ed938 100644 --- a/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java +++ b/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java @@ -53,6 +53,8 @@ public final class RegionizedPlayerChunkLoader { public static final int LOADED_TICKET_LEVEL = ChunkTaskScheduler.getTicketLevel(ChunkStatus.EMPTY); public static final int TICK_TICKET_LEVEL = ChunkHolderManager.ENTITY_TICKING_TICKET_LEVEL; + private static final org.apache.logging.log4j.Logger LOGGER = org.apache.logging.log4j.LogManager.getLogger("RegionizedPlayerChunkLoader"); // DivineMC - Async Chunk Sending + public static final class ViewDistanceHolder { private volatile ViewDistances viewDistances; @@ -424,17 +426,61 @@ public final class RegionizedPlayerChunkLoader { } private void sendChunk(final int chunkX, final int chunkZ) { - if (this.sentChunks.add(CoordinateUtils.getChunkKey(chunkX, chunkZ))) { - ((ChunkSystemChunkHolder)((ChunkSystemServerLevel)this.world).moonrise$getChunkTaskScheduler().chunkHolderManager - .getChunkHolder(chunkX, chunkZ).vanillaChunkHolder).moonrise$addReceivedChunk(this.player); + // DivineMC start - Async Chunk Sending + final long chunkKey = CoordinateUtils.getChunkKey(chunkX, chunkZ); + + if (!this.sentChunks.add(chunkKey)) return; - final LevelChunk chunk = ((ChunkSystemLevel)this.world).moonrise$getFullChunkIfLoaded(chunkX, chunkZ); + final LevelChunk chunk = ((ChunkSystemLevel) this.world).moonrise$getFullChunkIfLoaded(chunkX, chunkZ); + if (chunk == null) { + this.sentChunks.remove(chunkKey); + return; + } + try { + ((ChunkSystemServerLevel) this.world).moonrise$getChunkTaskScheduler().chunkHolderManager.getChunkHolder(chunkX, chunkZ).vanillaChunkHolder.moonrise$addReceivedChunk(this.player); PlatformHooks.get().onChunkWatch(this.world, chunk, this.player); - PlayerChunkSender.sendChunk(this.player.connection, this.world, chunk); + } catch (IllegalStateException e) { + this.sentChunks.remove(chunkKey); return; } - throw new IllegalStateException(); + + if (org.bxteam.divinemc.DivineConfig.asyncChunkSendingEnabled) { + net.minecraft.Util.backgroundExecutor().execute(() -> { + try { + // Modified from PlayerChunkSender#sendChunk + final net.minecraft.server.network.ServerGamePacketListenerImpl connection = this.player.connection; + final ServerLevel serverLevel = this.world; + + final net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket packet = new net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket( + chunk, serverLevel.getLightEngine(), null, null, + serverLevel.chunkPacketBlockController.shouldModify(this.player, chunk) + ); + + serverLevel.getServer().execute(() -> { + if (this.removed || !this.sentChunks.contains(chunkKey)) return; + + connection.send(packet); + + if (io.papermc.paper.event.packet.PlayerChunkLoadEvent.getHandlerList().getRegisteredListeners().length > 0) { + new io.papermc.paper.event.packet.PlayerChunkLoadEvent( + new org.bukkit.craftbukkit.CraftChunk(chunk), + this.player.getBukkitEntity() + ).callEvent(); + } + + net.minecraft.network.protocol.game.DebugPackets.sendPoiPacketsForChunk(serverLevel, chunk.getPos()); + }); + } catch (Exception e) { + LOGGER.error("Failed to send chunk asynchronously!", e); + + if (!this.removed) this.sentChunks.remove(chunkKey); + } + }); + } else { + PlayerChunkSender.sendChunk(this.player.connection, this.world, chunk); + } + // DivineMC end - Async Chunk Sending } private void sendUnloadChunk(final int chunkX, final int chunkZ) {