9
0
mirror of https://github.com/BX-Team/DivineMC.git synced 2025-12-19 14:59:25 +00:00
Files
DivineMC/divinemc-server/minecraft-patches/features/0027-Async-Chunk-Sending.patch
2025-04-24 19:47:15 +03:00

88 lines
4.9 KiB
Diff

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) {