mirror of
https://github.com/songoda/FabledSkyBlock.git
synced 2025-02-17 04:02:04 +01:00
Chunk loading rewrite
This commit is contained in:
parent
e689218228
commit
8631b3b5cd
@ -116,7 +116,6 @@ public class SkyBlock extends SongodaPlugin {
|
||||
Class.forName("com.destroystokyo.paper.PaperConfig");
|
||||
paper = true;
|
||||
paperAsync = Bukkit.spigot().getPaperConfig().getBoolean("settings.async-chunks.enable", false);
|
||||
paperAsync = false;
|
||||
this.getLogger().info("Enabling Paper hooks");
|
||||
} catch (ClassNotFoundException ignored) {
|
||||
PaperLib.suggestPaper(this);
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.songoda.skyblock.biome;
|
||||
|
||||
import com.songoda.core.compatibility.ServerVersion;
|
||||
import com.songoda.skyblock.SkyBlock;
|
||||
import com.songoda.skyblock.island.Island;
|
||||
import com.songoda.skyblock.island.IslandEnvironment;
|
||||
@ -12,8 +11,6 @@ import org.bukkit.block.Biome;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class BiomeManager {
|
||||
|
||||
@ -25,129 +22,32 @@ public class BiomeManager {
|
||||
|
||||
public void setBiome(Island island, Biome biome) {
|
||||
Location location = island.getLocation(IslandWorld.Normal, IslandEnvironment.Island);
|
||||
int radius = (int) Math.ceil(island.getRadius());
|
||||
|
||||
final List<ChunkSnapshot> snapshotList = new ArrayList<>(3);
|
||||
|
||||
if (location == null) return;
|
||||
|
||||
final World world = location.getWorld();
|
||||
|
||||
|
||||
new ChunkLoader(island, IslandWorld.Normal, skyblock.isPaperAsync(), (asyncPositions, syncPositions) -> {
|
||||
if (skyblock.isPaperAsync()) {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(skyblock, () -> {
|
||||
List<Chunk> positions = new LinkedList<>();
|
||||
for (CompletableFuture<Chunk> chunk : asyncPositions) {
|
||||
positions.add(chunk.join());
|
||||
}
|
||||
for(Chunk chunk : positions){
|
||||
setChunkBiome(biome, chunk);
|
||||
updateBiomePacket(island, chunk);
|
||||
}
|
||||
//positions.stream().map(Chunk::getChunkSnapshot).forEach(snapshotList::add);
|
||||
});
|
||||
|
||||
//Map<World, List<ChunkSnapshot>> snapshots = new HashMap<>(3);
|
||||
//snapshots.put(world, snapshotList);
|
||||
Bukkit.getScheduler().runTaskAsynchronously(skyblock, () -> {
|
||||
//ChunkBiomeSplitter.startUpdating(snapshots, biome, (chunk) -> {
|
||||
// updateBiomePacket(island, chunk);
|
||||
//});
|
||||
|
||||
});
|
||||
} else {
|
||||
//syncPositions.stream().map(Chunk::getChunkSnapshot).forEach(snapshotList::add);
|
||||
|
||||
//Map<World, List<ChunkSnapshot>> snapshots = new HashMap<>(3);
|
||||
//snapshots.put(world, snapshotList);
|
||||
Bukkit.getScheduler().runTaskAsynchronously(skyblock, () -> {
|
||||
//ChunkBiomeSplitter.startUpdating(snapshots, biome, (chunk) -> {
|
||||
// updateBiomePacket(island, chunk);
|
||||
//});
|
||||
for(Chunk chunk : syncPositions){
|
||||
setChunkBiome(biome, chunk);
|
||||
updateBiomePacket(island, chunk);
|
||||
}
|
||||
});
|
||||
}
|
||||
if(skyblock.isPaperAsync()){
|
||||
// We keep it sequentially in order to use less RAM
|
||||
ChunkLoader.startChunkLoadingPerChunk(island, IslandWorld.Normal, skyblock.isPaperAsync(), (asyncChunk, syncChunk) -> {
|
||||
Chunk chunk = asyncChunk.join();
|
||||
setChunkBiome(biome, chunk);
|
||||
updateBiomePacket(island, chunk);
|
||||
});
|
||||
|
||||
/*Bukkit.getScheduler().runTaskAsynchronously(skyblock, () -> {
|
||||
for (int x = location.getBlockX() - radius; x < location.getBlockX() + radius; x++) {
|
||||
for (int z = location.getBlockZ() - radius; z < location.getBlockZ() + radius; z++) {
|
||||
location.getWorld().setBiome(x, z, biome);
|
||||
}
|
||||
}
|
||||
Bukkit.getScheduler().runTask(skyblock, () -> {
|
||||
for (int x = location.getBlockX() - radius; x < location.getBlockX() + radius; x += 16) {
|
||||
for (int z = location.getBlockZ() - radius; z < location.getBlockZ() + radius; z += 16) {
|
||||
Chunk chunk = location.getWorld().getChunkAt(x >> 4, z >> 4);
|
||||
updateBiome(island, chunk);
|
||||
}
|
||||
}
|
||||
});
|
||||
});*/
|
||||
/*Bukkit.getScheduler().runTask(skyblock, () -> {
|
||||
List<Chunk> chunks = new ArrayList<>();
|
||||
|
||||
if(skyblock.isPaperAsync()){
|
||||
} else {
|
||||
ChunkLoader.startChunkLoading(island, IslandWorld.Normal, skyblock.isPaperAsync(), (asyncChunks, syncChunks) -> {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(skyblock, () -> {
|
||||
for (int x = location.getBlockX() - radius; x < location.getBlockX() + radius; x += 16) {
|
||||
for (int z = location.getBlockZ() - radius; z < location.getBlockZ() + radius; z += 16) {
|
||||
try {
|
||||
Chunk chunk = PaperLib.getChunkAtAsync(location.getWorld(), x >> 4, z >> 4).get();
|
||||
setChunkBiome(biome, chunk);
|
||||
chunks.add(chunk);
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
Bukkit.getScheduler().runTask(skyblock, () -> {
|
||||
for(Chunk chunk : chunks){
|
||||
updateBiomePacket(island, chunk);
|
||||
}
|
||||
});
|
||||
});
|
||||
} else {
|
||||
int x = location.getBlockX() - radius;
|
||||
Bukkit.getScheduler().runTaskTimer(skyblock, () -> {
|
||||
|
||||
}, 2L, 2L);
|
||||
while (x < location.getBlockX() + radius) {
|
||||
int z = location.getBlockZ() - radius;
|
||||
while (z < location.getBlockZ() + radius) {
|
||||
chunks.add(location.getWorld().getChunkAt(x >> 4, z >> 4));
|
||||
z += 16;
|
||||
}
|
||||
x += 16;
|
||||
}
|
||||
Bukkit.getScheduler().runTaskAsynchronously(skyblock, () -> {
|
||||
for(Chunk chunk : chunks){
|
||||
syncChunks.forEach(chunk -> {
|
||||
setChunkBiome(biome, chunk);
|
||||
}
|
||||
Bukkit.getScheduler().runTask(skyblock, () -> {
|
||||
for(Chunk chunk : chunks){
|
||||
updateBiomePacket(island, chunk);
|
||||
}
|
||||
updateBiomePacket(island, chunk);
|
||||
});
|
||||
});
|
||||
}
|
||||
});*/
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void setChunkBiome(Biome biome, Chunk chunk) {
|
||||
//location.getWorld().loadChunk(chunk);
|
||||
for(int xx = 0; xx < 16; xx++){
|
||||
for(int zz = 0; zz < 16; zz++){
|
||||
if(ServerVersion.isServerVersionAtLeast(ServerVersion.V1_15)){
|
||||
for(int y = 0; y<256; y++){
|
||||
chunk.getBlock(xx, y, zz).setBiome(biome);
|
||||
}
|
||||
} else {
|
||||
chunk.getBlock(xx, 0, zz).setBiome(biome);
|
||||
}
|
||||
chunk.getBlock(xx, 0, zz).setBiome(biome);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,8 @@ public class ChunkLoader extends BukkitRunnable {
|
||||
|
||||
private ChunkScannerTask generalTask;
|
||||
private ChunkForChunkScannerTask chunkTask;
|
||||
private final boolean paper;
|
||||
private boolean chunkForChunk;
|
||||
private boolean paper;
|
||||
private World world;
|
||||
private int x;
|
||||
private int z;
|
||||
@ -29,7 +30,9 @@ public class ChunkLoader extends BukkitRunnable {
|
||||
private int maxX;
|
||||
private int maxZ;
|
||||
|
||||
private ChunkLoader(Island island, IslandWorld islandWorld, boolean paper, boolean chunkForChunk) {
|
||||
private ChunkLoader(Island island, IslandWorld islandWorld, boolean paper, boolean chunkForChunk, ChunkForChunkScannerTask chunkTask) {
|
||||
this.chunkTask = chunkTask;
|
||||
this.chunkForChunk = chunkForChunk;
|
||||
this.paper = paper;
|
||||
Location islandLocation = island.getLocation(islandWorld, IslandEnvironment.Island);
|
||||
|
||||
@ -49,19 +52,63 @@ public class ChunkLoader extends BukkitRunnable {
|
||||
x = minX;
|
||||
z = minZ;
|
||||
|
||||
// TODO Paper
|
||||
this.runTaskTimer(SkyBlock.getInstance(), 1L, 0L);
|
||||
if(paper){
|
||||
this.runTaskAsynchronously(SkyBlock.getInstance());
|
||||
} else {
|
||||
this.runTaskTimer(SkyBlock.getInstance(), 1L, 0L);
|
||||
}
|
||||
}
|
||||
|
||||
private ChunkLoader(Island island, IslandWorld islandWorld, boolean paper, boolean chunkForChunk, ChunkScannerTask generalTask) {
|
||||
this.generalTask = generalTask;
|
||||
this.chunkForChunk = chunkForChunk;
|
||||
this.paper = paper;
|
||||
Location islandLocation = island.getLocation(islandWorld, IslandEnvironment.Island);
|
||||
|
||||
if (islandLocation == null) return;
|
||||
|
||||
world = islandLocation.getWorld();
|
||||
|
||||
Location minLocation = new Location(world, islandLocation.getBlockX() - island.getRadius(), 0, islandLocation.getBlockZ() - island.getRadius());
|
||||
Location maxLocation = new Location(world, islandLocation.getBlockX() + island.getRadius(), world.getMaxHeight(), islandLocation.getBlockZ() + island.getRadius());
|
||||
|
||||
int minX = Math.min(maxLocation.getBlockX(), minLocation.getBlockX());
|
||||
minZ = Math.min(maxLocation.getBlockZ(), minLocation.getBlockZ());
|
||||
|
||||
maxX = Math.max(maxLocation.getBlockX(), minLocation.getBlockX());
|
||||
maxZ = Math.max(maxLocation.getBlockZ(), minLocation.getBlockZ());
|
||||
|
||||
x = minX;
|
||||
z = minZ;
|
||||
|
||||
if(paper){
|
||||
this.runTaskAsynchronously(SkyBlock.getInstance());
|
||||
} else {
|
||||
this.runTaskTimer(SkyBlock.getInstance(), 1L, 0L);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
for(int i = 0; i < 50; i++){ // TODO Config for chunk per tick
|
||||
for(int i = 0; i < 50 || paper; i++){ // TODO Config for chunk per tick
|
||||
if(x < maxX){
|
||||
if(z < maxZ){
|
||||
if(paper){
|
||||
asyncPositions.add(PaperLib.getChunkAtAsync(world, x >> 4, z >> 4));
|
||||
if(!chunkForChunk){
|
||||
if(paper){
|
||||
asyncPositions.add(PaperLib.getChunkAtAsync(world, x >> 4, z >> 4));
|
||||
} else {
|
||||
syncPositions.add(world.getChunkAt(x >> 4, z >> 4));
|
||||
}
|
||||
} else {
|
||||
syncPositions.add(world.getChunkAt(x >> 4, z >> 4));
|
||||
if(paper){
|
||||
if(chunkTask != null) {
|
||||
chunkTask.onChunkComplete(PaperLib.getChunkAtAsync(world, x >> 4, z >> 4), null);
|
||||
}
|
||||
} else {
|
||||
if(chunkTask != null) {
|
||||
chunkTask.onChunkComplete(null, world.getChunkAt(x >> 4, z >> 4));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
z += 16;
|
||||
@ -74,17 +121,17 @@ public class ChunkLoader extends BukkitRunnable {
|
||||
generalTask.onComplete(asyncPositions, syncPositions);
|
||||
}
|
||||
this.cancel();
|
||||
return;
|
||||
}
|
||||
}
|
||||
Bukkit.broadcastMessage("Async: " + asyncPositions.size() + " Sync: " + syncPositions.size());
|
||||
}
|
||||
|
||||
public static void startChunkLoading(Island island, IslandWorld islandWorld, boolean paper, ChunkScannerTask task){
|
||||
new ChunkLoader(island, islandWorld, paper, false);
|
||||
new ChunkLoader(island, islandWorld, paper, false, task);
|
||||
}
|
||||
|
||||
public static void startChunkLoadingPerChunk(Island island, IslandWorld islandWorld, boolean paper, ChunkForChunkScannerTask task){
|
||||
new ChunkLoader(island, islandWorld, paper, true);
|
||||
new ChunkLoader(island, islandWorld, paper, true, task);
|
||||
}
|
||||
|
||||
public interface ChunkScannerTask {
|
||||
@ -95,7 +142,7 @@ public class ChunkLoader extends BukkitRunnable {
|
||||
|
||||
public interface ChunkForChunkScannerTask {
|
||||
|
||||
void onChunkComplete(CompletableFuture<Chunk> asyncChunks, List<Chunk> syncChunks);
|
||||
void onChunkComplete(CompletableFuture<Chunk> asyncChunk, Chunk syncChunk);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -654,7 +654,27 @@ public class IslandManager {
|
||||
|
||||
final World world = worldManager.getWorld(worldList);
|
||||
|
||||
new ChunkLoader(island, IslandWorld.Normal, skyblock.isPaperAsync(), (asyncPositions, syncPositions) -> {
|
||||
if(skyblock.isPaperAsync()){
|
||||
ChunkLoader.startChunkLoading(island, IslandWorld.Normal, skyblock.isPaperAsync(), (asyncChunks, syncChunks) -> {
|
||||
List<Chunk> positions = new LinkedList<>();
|
||||
for (CompletableFuture<Chunk> chunk : asyncChunks) {
|
||||
positions.add(chunk.join());
|
||||
}
|
||||
snapshots.put(world, positions.stream().map(Chunk::getChunkSnapshot).collect(Collectors.toList()));
|
||||
ChunkDeleteSplitter.startDeletion(snapshots);
|
||||
});
|
||||
} else {
|
||||
ChunkLoader.startChunkLoading(island, IslandWorld.Normal, skyblock.isPaperAsync(), (asyncChunks, syncChunks) -> {
|
||||
Bukkit.getScheduler().runTask(skyblock, () -> {
|
||||
final List<ChunkSnapshot> list = syncChunks.stream().map(Chunk::getChunkSnapshot).collect(Collectors.toList());
|
||||
|
||||
snapshots.put(world, list);
|
||||
ChunkDeleteSplitter.startDeletion(snapshots);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/*new ChunkLoader(island, IslandWorld.Normal, skyblock.isPaperAsync(), (asyncPositions, syncPositions) -> {
|
||||
if(skyblock.isPaperAsync()){
|
||||
Bukkit.getScheduler().runTaskAsynchronously(skyblock, () -> {
|
||||
List<Chunk> positions = new LinkedList<>();
|
||||
@ -670,7 +690,7 @@ public class IslandManager {
|
||||
snapshots.put(world, list);
|
||||
ChunkDeleteSplitter.startDeletion(snapshots);
|
||||
}
|
||||
});
|
||||
});*/
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ public class ChunkDeleteSplitter extends BukkitRunnable {
|
||||
}
|
||||
|
||||
private void start() {
|
||||
BlockScanner.startScanner(snapshots, false, false, (blocks) -> {
|
||||
BlockScanner.startScanner(snapshots, true, true, false, (blocks) -> {
|
||||
this.blocks = blocks;
|
||||
this.runTaskTimer(SkyBlock.getInstance(), 20, 20);
|
||||
});
|
||||
|
@ -65,32 +65,48 @@ public final class IslandScan extends BukkitRunnable {
|
||||
|
||||
if (skyblock.isPaperAsync()) {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
|
||||
populate(snapshots, IslandWorld.Normal, true);
|
||||
if (hasNether) populate(snapshots, IslandWorld.Nether, true);
|
||||
if (hasEnd) populate(snapshots, IslandWorld.End, true);
|
||||
initScan(skyblock, hasNether, hasEnd, snapshots);
|
||||
});
|
||||
} else {
|
||||
initScan(skyblock, hasNether, hasEnd, snapshots);
|
||||
}
|
||||
|
||||
BlockScanner.startScanner(snapshots, false, false, (blocks) -> {
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
private void initScan(SkyBlock skyblock, boolean hasNether, boolean hasEnd, Map<World, List<ChunkSnapshot>> snapshots) {
|
||||
populate(snapshots, IslandWorld.Normal, skyblock.isPaperAsync(), () -> {
|
||||
|
||||
if (hasNether) {
|
||||
populate(snapshots, IslandWorld.Nether, skyblock.isPaperAsync(), () -> {
|
||||
if (hasEnd) {
|
||||
populate(snapshots, IslandWorld.End, skyblock.isPaperAsync(), () -> {
|
||||
BlockScanner.startScanner(snapshots, true, true, false, (blocks) -> {
|
||||
this.blocks = blocks;
|
||||
this.blocksSize = blocks.size();
|
||||
this.runTaskTimer(SkyBlock.getInstance(), 20, 20);
|
||||
|
||||
});
|
||||
});
|
||||
} else {
|
||||
BlockScanner.startScanner(snapshots, true, true, false, (blocks) -> {
|
||||
this.blocks = blocks;
|
||||
this.blocksSize = blocks.size();
|
||||
this.runTaskTimer(SkyBlock.getInstance(), 20, 20);
|
||||
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
BlockScanner.startScanner(snapshots, true, true, false, (blocks) -> {
|
||||
this.blocks = blocks;
|
||||
this.blocksSize = blocks.size();
|
||||
this.runTaskTimer(SkyBlock.getInstance(), 20, 20);
|
||||
|
||||
});
|
||||
});
|
||||
} else {
|
||||
populate(snapshots, IslandWorld.Normal, false);
|
||||
if (hasNether) populate(snapshots, IslandWorld.Nether, false);
|
||||
if (hasEnd) populate(snapshots, IslandWorld.End, false);
|
||||
|
||||
BlockScanner.startScanner(snapshots, false, false, (blocks) -> {
|
||||
this.blocks = blocks;
|
||||
this.blocksSize = blocks.size();
|
||||
this.runTaskTimer(SkyBlock.getInstance(), 20, 20);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
return this;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void finalizeBlocks() {
|
||||
@ -178,11 +194,11 @@ public final class IslandScan extends BukkitRunnable {
|
||||
});
|
||||
}
|
||||
|
||||
private void populate(Map<World, List<ChunkSnapshot>> snapshots, IslandWorld world, boolean paper) {
|
||||
private void populate(Map<World, List<ChunkSnapshot>> snapshots, IslandWorld world, boolean paper, PopulateTask task) {
|
||||
|
||||
final SkyBlock skyblock = SkyBlock.getInstance();
|
||||
|
||||
new ChunkLoader(island, IslandWorld.Normal, paper, (asyncPositions, syncPositions) -> {
|
||||
ChunkLoader.startChunkLoading(island, IslandWorld.Normal, paper, (asyncPositions, syncPositions) -> {
|
||||
if(paper){
|
||||
List<ChunkSnapshot> positions = new LinkedList<>();
|
||||
for(CompletableFuture<Chunk> chunk : asyncPositions){
|
||||
@ -192,9 +208,14 @@ public final class IslandScan extends BukkitRunnable {
|
||||
} else {
|
||||
snapshots.put(skyblock.getWorldManager().getWorld(world), syncPositions.stream().map(org.bukkit.Chunk::getChunkSnapshot).collect(Collectors.toList()));
|
||||
}
|
||||
task.onComplete();
|
||||
});
|
||||
}
|
||||
|
||||
private interface PopulateTask {
|
||||
void onComplete();
|
||||
}
|
||||
|
||||
public Set<Location> getDoubleBlocks() {
|
||||
return doubleBlocks;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user