Merge pull request #4188 from ZockiRR/v3.0

Async chunk loading for spigot/paper 1.21.3/1.21.4
This commit is contained in:
mikeprimm 2025-04-01 18:30:12 -05:00 committed by GitHub
commit 10e6739811
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 52 additions and 2 deletions

View file

@ -67,7 +67,7 @@ public class BukkitVersionHelperSpigot121_3 extends BukkitVersionHelper {
@Override
public boolean isUnsafeAsync() {
return true;
return false;
}
/**

View file

@ -6,7 +6,9 @@ import net.minecraft.world.level.biome.BiomeBase;
import net.minecraft.world.level.biome.BiomeFog;
import net.minecraft.world.level.chunk.Chunk;
import net.minecraft.world.level.chunk.storage.SerializableChunkData;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_21_R2.CraftServer;
import org.bukkit.craftbukkit.v1_21_R2.CraftWorld;
import org.dynmap.DynmapChunk;
import org.dynmap.bukkit.helper.BukkitWorld;
@ -17,7 +19,10 @@ import org.dynmap.common.chunk.GenericMapChunkCache;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.concurrent.CancellationException;
import java.util.concurrent.CompletableFuture;
import java.util.function.Supplier;
/**
* Container for managing chunks - dependent upon using chunk snapshots, since rendering is off server thread
@ -31,6 +36,19 @@ public class MapChunkCache121_3 extends GenericMapChunkCache {
super(cc);
}
@Override
protected Supplier<GenericChunk> getLoadedChunkAsync(DynmapChunk chunk) {
CompletableFuture<Optional<SerializableChunkData>> chunkData = CompletableFuture.supplyAsync(() -> {
CraftWorld cw = (CraftWorld) w;
Chunk c = cw.getHandle().getChunkIfLoaded(chunk.x, chunk.z);
if (c == null || !c.q) { // !c.loaded
return Optional.empty();
}
return Optional.of(SerializableChunkData.a(cw.getHandle(), c)); // SerializableChunkData.copyOf
}, ((CraftServer) Bukkit.getServer()).getServer());
return () -> chunkData.join().map(SerializableChunkData::a).map(NBT.NBTCompound::new).map(this::parseChunkFromNBT).orElse(null); // SerializableChunkData::write
}
protected GenericChunk getLoadedChunk(DynmapChunk chunk) {
CraftWorld cw = (CraftWorld) w;
if (!cw.isChunkLoaded(chunk.x, chunk.z)) return null;
@ -41,6 +59,13 @@ public class MapChunkCache121_3 extends GenericMapChunkCache {
return nbt != null ? parseChunkFromNBT(new NBT.NBTCompound(nbt)) : null;
}
@Override
protected Supplier<GenericChunk> loadChunkAsync(DynmapChunk chunk) {
CraftWorld cw = (CraftWorld) w;
CompletableFuture<Optional<NBTTagCompound>> genericChunk = cw.getHandle().m().a.d(new ChunkCoordIntPair(chunk.x, chunk.z)); // WorldServer.getChunkSource().chunkMap.read(new ChunkCoordIntPair(chunk.x, chunk.z))
return () -> genericChunk.join().map(NBT.NBTCompound::new).map(this::parseChunkFromNBT).orElse(null);
}
protected GenericChunk loadChunk(DynmapChunk chunk) {
CraftWorld cw = (CraftWorld) w;
NBTTagCompound nbt = null;

View file

@ -67,7 +67,7 @@ public class BukkitVersionHelperSpigot121_4 extends BukkitVersionHelper {
@Override
public boolean isUnsafeAsync() {
return true;
return false;
}
/**

View file

@ -6,7 +6,9 @@ import net.minecraft.world.level.biome.BiomeBase;
import net.minecraft.world.level.biome.BiomeFog;
import net.minecraft.world.level.chunk.Chunk;
import net.minecraft.world.level.chunk.storage.SerializableChunkData;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_21_R3.CraftServer;
import org.bukkit.craftbukkit.v1_21_R3.CraftWorld;
import org.dynmap.DynmapChunk;
import org.dynmap.bukkit.helper.BukkitWorld;
@ -17,7 +19,10 @@ import org.dynmap.common.chunk.GenericMapChunkCache;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.concurrent.CancellationException;
import java.util.concurrent.CompletableFuture;
import java.util.function.Supplier;
/**
* Container for managing chunks - dependent upon using chunk snapshots, since rendering is off server thread
@ -31,6 +36,19 @@ public class MapChunkCache121_4 extends GenericMapChunkCache {
super(cc);
}
@Override
protected Supplier<GenericChunk> getLoadedChunkAsync(DynmapChunk chunk) {
CompletableFuture<Optional<SerializableChunkData>> chunkData = CompletableFuture.supplyAsync(() -> {
CraftWorld cw = (CraftWorld) w;
Chunk c = cw.getHandle().getChunkIfLoaded(chunk.x, chunk.z);
if (c == null || !c.q) { // !c.loaded
return Optional.empty();
}
return Optional.of(SerializableChunkData.a(cw.getHandle(), c)); // SerializableChunkData.copyOf
}, ((CraftServer) Bukkit.getServer()).getServer());
return () -> chunkData.join().map(SerializableChunkData::a).map(NBT.NBTCompound::new).map(this::parseChunkFromNBT).orElse(null); // SerializableChunkData::write
}
protected GenericChunk getLoadedChunk(DynmapChunk chunk) {
CraftWorld cw = (CraftWorld) w;
if (!cw.isChunkLoaded(chunk.x, chunk.z)) return null;
@ -41,6 +59,13 @@ public class MapChunkCache121_4 extends GenericMapChunkCache {
return nbt != null ? parseChunkFromNBT(new NBT.NBTCompound(nbt)) : null;
}
@Override
protected Supplier<GenericChunk> loadChunkAsync(DynmapChunk chunk) {
CraftWorld cw = (CraftWorld) w;
CompletableFuture<Optional<NBTTagCompound>> genericChunk = cw.getHandle().m().a.d(new ChunkCoordIntPair(chunk.x, chunk.z)); // WorldServer.getChunkSource().chunkMap.read(new ChunkCoordIntPair(chunk.x, chunk.z))
return () -> genericChunk.join().map(NBT.NBTCompound::new).map(this::parseChunkFromNBT).orElse(null);
}
protected GenericChunk loadChunk(DynmapChunk chunk) {
CraftWorld cw = (CraftWorld) w;
NBTTagCompound nbt = null;