Optimized Island management

This commit is contained in:
Fabrizio La Rosa 2020-07-13 13:33:20 +02:00
parent 5c0305e950
commit 9b46a0d0dc
5 changed files with 74 additions and 162 deletions

View File

@ -54,15 +54,14 @@ public class BiomeManager {
if (island.getLocation(world, IslandEnvironment.Island) == null) return;
if(plugin.isPaperAsync()){
// We keep it sequentially in order to use less RAM
int chunkAmount = (int) Math.ceil(Math.pow(island.getSize()/16d, 2d));
AtomicInteger progress = new AtomicInteger();
ChunkLoader.startChunkLoadingPerChunk(island, world, plugin.isPaperAsync(), (asyncChunk, syncChunk) -> {
Chunk chunk = asyncChunk.join();
ChunkLoader.startChunkLoadingPerChunk(island, world, plugin.isPaperAsync(), (futureChunk) -> {
Chunk chunk = futureChunk.join();
if(ServerVersion.isServerVersionAtLeast(ServerVersion.V1_16)){ // TODO Should be 1.15 but it works fine there
setChunkBiome3D(biome, chunk); // 2D for the moment
setChunkBiome3D(biome, chunk);
} else {
try {
setChunkBiome2D(biome, chunk);
@ -94,55 +93,6 @@ public class BiomeManager {
task.onCompleteUpdate();
}
}));
} else {
ChunkLoader.startChunkLoading(island, world, plugin.isPaperAsync(), (asyncChunks, syncChunks) -> {
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
int progress = 0;
for(Chunk chunk : syncChunks){
if(ServerVersion.isServerVersionAtLeast(ServerVersion.V1_16)){ // TODO Should be 1.15 but it works fine there
setChunkBiome3D(biome, chunk); // 2D for the moment
} else {
try {
setChunkBiome2D(biome, chunk);
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
}
if(ServerVersion.isServerVersionAtLeast(ASYNC_OBFUSCATOR_VERSION)) {
updateBiomePacket(island, chunk);
}
progress++;
if(language.getBoolean("Command.Island.Biome.Progress.Should-Display-Message") &&
progress == 1 || progress == syncChunks.size() || progress % runEveryX == 0){
final double percent = ((double) progress / (double) syncChunks.size()) * 100;
String message = language.getString("Command.Island.Biome.Progress.Message");
message = message.replace("%current_updated_chunks%", String.valueOf(progress));
message = message.replace("%max_chunks%", String.valueOf(syncChunks.size()));
message = message.replace("%percent_whole%", String.valueOf((int) percent));
message = message.replace("%percent%", NumberFormat.getInstance().format(percent));
for (Player player : SkyBlock.getInstance().getIslandManager().getPlayersAtIsland(island)) {
plugin.getMessageManager().sendMessage(player, message);
}
}
}
if(ServerVersion.isServerVersionBelow(ASYNC_OBFUSCATOR_VERSION)) {
Bukkit.getScheduler().runTask(plugin, () -> {
for(Chunk chunk : syncChunks){
updateBiomePacket(island, chunk);
}
});
}
});
}, (island1 -> {
removeUpdatingIsland(island1);
if(task != null) {
task.onCompleteUpdate();
}
}));
}
}
private void setChunkBiome2D(Biome biome, Chunk chunk) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {

View File

@ -57,12 +57,10 @@ public final class BlockScanner extends BukkitRunnable {
private final Queue<BlockInfo> blocks;
private final ScannerTasks tasks;
private boolean ignoreLiquids;
private boolean ignoreLiquidsY;
private boolean ignoreAir;
private final boolean ignoreLiquids;
private final boolean ignoreAir;
private BlockScanner(Map<World, List<ChunkSnapshot>> snapshots, boolean ignoreLiquids, boolean ignoreLiquidsY, boolean ignoreAir, boolean ignoreY, ScannerTasks tasks) {
this.ignoreLiquidsY = ignoreLiquidsY;
this.ignoreLiquids = ignoreLiquids;
this.ignoreAir = ignoreAir;
this.blocks = new ConcurrentLinkedQueue<>();
@ -105,7 +103,6 @@ public final class BlockScanner extends BukkitRunnable {
for (List<ChunkSnapshot> sub : parts) {
queueWork(world, startY, sub);
}
}
this.threadCount = threadCount;

View File

@ -16,8 +16,7 @@ import java.util.List;
import java.util.concurrent.CompletableFuture;
public class ChunkLoader extends BukkitRunnable {
public final List<CompletableFuture<Chunk>> asyncPositions = new LinkedList<>();
public final List<Chunk> syncPositions = new LinkedList<>();
public final List<CompletableFuture<Chunk>> positions = new LinkedList<>();
private ChunkScannerTask generalTask;
private ChunkForChunkScannerTask chunkTask;
@ -109,20 +108,10 @@ public class ChunkLoader extends BukkitRunnable {
if(x < maxX){
if(z < maxZ){
if(!chunkForChunk){
if(paper){
asyncPositions.add(PaperLib.getChunkAtAsync(world, x >> 4, z >> 4));
} else {
syncPositions.add(world.getChunkAt(x >> 4, z >> 4));
}
} else {
if(paper){
if(chunkTask != null) {
chunkTask.onChunkComplete(PaperLib.getChunkAtAsync(world, x >> 4, z >> 4), null);
}
positions.add(PaperLib.getChunkAtAsync(world, x >> 4, z >> 4));
} else {
if(chunkTask != null) {
chunkTask.onChunkComplete(null, world.getChunkAt(x >> 4, z >> 4));
}
chunkTask.onChunkComplete(PaperLib.getChunkAtAsync(world, x >> 4, z >> 4));
}
}
@ -133,7 +122,7 @@ public class ChunkLoader extends BukkitRunnable {
}
} else {
if(generalTask != null) {
generalTask.onComplete(asyncPositions, syncPositions);
generalTask.onComplete(positions);
}
if(completeTask != null) {
completeTask.onComplete(island);
@ -153,15 +142,11 @@ public class ChunkLoader extends BukkitRunnable {
}
public interface ChunkScannerTask {
void onComplete(List<CompletableFuture<Chunk>> asyncChunks, List<Chunk> syncChunks);
void onComplete(List<CompletableFuture<Chunk>> chunks);
}
public interface ChunkForChunkScannerTask {
void onChunkComplete(CompletableFuture<Chunk> asyncChunk, Chunk syncChunk);
void onChunkComplete(CompletableFuture<Chunk> chunk);
}
public interface CompleteTask {

View File

@ -177,8 +177,8 @@ public class IslandManager {
}
posX = posX * offset;
posY = posY * offset;
islandPositionList.setX((double) posX);
islandPositionList.setZ((double) posY);
islandPositionList.setX(posX);
islandPositionList.setZ(posY);
// Check if there was an island at this position
int oldFormatPos = oldSystemIslands.get(world);
Location islandLocation = new org.bukkit.Location(plugin.getWorldManager().getWorld(world), islandPositionList.getX(), islandHeight, islandPositionList.getZ());
@ -281,15 +281,14 @@ public class IslandManager {
}
Biome biome = cBiome.getBiome();
Bukkit.getServer().getScheduler().runTaskLater(plugin, () -> {
Bukkit.getServer().getScheduler().runTaskLater(plugin, () ->
plugin.getBiomeManager().setBiome(island, IslandWorld.Normal, biome, () -> {
if (structure.getCommands() != null) {
for (String commandList : structure.getCommands()) {
Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), commandList.replace("%player", player.getName()));
}
}
});
}, 20L);
}), 20L);
// Recalculate island level after 5 seconds
if (configLoad.getBoolean("Island.Levelling.ScanAutomatically"))
@ -655,25 +654,14 @@ public class IslandManager {
final World world = worldManager.getWorld(worldList);
if(plugin.isPaperAsync()){
ChunkLoader.startChunkLoading(island, IslandWorld.Normal, plugin.isPaperAsync(), (asyncChunks, syncChunks) -> {
ChunkLoader.startChunkLoading(island, IslandWorld.Normal, plugin.isPaperAsync(), (chunks) -> {
List<Chunk> positions = new LinkedList<>();
for (CompletableFuture<Chunk> chunk : asyncChunks) {
for (CompletableFuture<Chunk> chunk : chunks) {
positions.add(chunk.join());
}
snapshots.put(world, positions.stream().map(Chunk::getChunkSnapshot).collect(Collectors.toList()));
ChunkDeleteSplitter.startDeletion(snapshots);
}, null);
} else {
ChunkLoader.startChunkLoading(island, IslandWorld.Normal, plugin.isPaperAsync(), (asyncChunks, syncChunks) -> {
Bukkit.getScheduler().runTask(plugin, () -> {
final List<ChunkSnapshot> list = syncChunks.stream().map(Chunk::getChunkSnapshot).collect(Collectors.toList());
snapshots.put(world, list);
ChunkDeleteSplitter.startDeletion(snapshots);
});
}, null);
}
}
}
@ -826,8 +814,6 @@ public class IslandManager {
Location islandLocation = fileManager.getLocation(config, "Location.Normal.Island", false);
if (LocationUtil.isLocationAtLocationRadius(location, islandLocation, size)) {
UUID islandOwnerUUID = UUID.fromString(fileList.getName().replace(".yml", ""));
// return this.loadIsland(Bukkit.getOfflinePlayer(islandOwnerUUID));
return;
}
} catch (Exception e) {
@ -835,8 +821,6 @@ public class IslandManager {
}
}
}
return;
}
public void unloadIsland(Island island, org.bukkit.OfflinePlayer player) {

View File

@ -197,18 +197,14 @@ public final class IslandScan extends BukkitRunnable {
final SkyBlock plugin = SkyBlock.getInstance();
ChunkLoader.startChunkLoading(island, IslandWorld.Normal, paper, (asyncPositions, syncPositions) -> {
if(paper){
List<ChunkSnapshot> positions = new LinkedList<>();
for(CompletableFuture<Chunk> chunk : asyncPositions){
positions.add(chunk.join().getChunkSnapshot());
}
ChunkLoader.startChunkLoadingPerChunk(island, IslandWorld.Normal, paper, (chunkCompletableFuture) ->
positions.add(chunkCompletableFuture.join().getChunkSnapshot()),
value -> {
snapshots.put(plugin.getWorldManager().getWorld(world), positions);
} else {
snapshots.put(plugin.getWorldManager().getWorld(world), syncPositions.stream().map(org.bukkit.Chunk::getChunkSnapshot).collect(Collectors.toList()));
}
task.onComplete();
}, null);
});
}
private interface PopulateTask {