From 9b46a0d0dcca8733014feeeb2f36ed755e4e2518 Mon Sep 17 00:00:00 2001 From: Fabrizio La Rosa Date: Mon, 13 Jul 2020 13:33:20 +0200 Subject: [PATCH] Optimized Island management --- .../songoda/skyblock/biome/BiomeManager.java | 126 ++++++------------ .../skyblock/blockscanner/BlockScanner.java | 7 +- .../skyblock/blockscanner/ChunkLoader.java | 31 ++--- .../skyblock/island/IslandManager.java | 52 +++----- .../skyblock/levelling/IslandScan.java | 20 ++- 5 files changed, 74 insertions(+), 162 deletions(-) diff --git a/src/main/java/com/songoda/skyblock/biome/BiomeManager.java b/src/main/java/com/songoda/skyblock/biome/BiomeManager.java index b5727232..5719ca7d 100644 --- a/src/main/java/com/songoda/skyblock/biome/BiomeManager.java +++ b/src/main/java/com/songoda/skyblock/biome/BiomeManager.java @@ -53,96 +53,46 @@ public class BiomeManager { addUpdatingIsland(island); 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(); + + // 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(), (futureChunk) -> { + Chunk chunk = futureChunk.join(); + if(ServerVersion.isServerVersionAtLeast(ServerVersion.V1_16)){ // TODO Should be 1.15 but it works fine there + setChunkBiome3D(biome, chunk); + } else { + try { + setChunkBiome2D(biome, chunk); + } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { + e.printStackTrace(); + } + } + updateBiomePacket(island, chunk); + + progress.getAndIncrement(); + + if(language.getBoolean("Command.Island.Biome.Progress.Should-Display-Message") && + progress.get() == 1 || progress.get() == chunkAmount || progress.get() % runEveryX == 0){ + final double percent = ((double) progress.get() / (double) chunkAmount) * 100; - ChunkLoader.startChunkLoadingPerChunk(island, world, plugin.isPaperAsync(), (asyncChunk, syncChunk) -> { - Chunk chunk = asyncChunk.join(); - 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(); - } + String message = language.getString("Command.Island.Biome.Progress.Message"); + message = message.replace("%current_updated_chunks%", String.valueOf(progress.get())); + message = message.replace("%max_chunks%", String.valueOf(chunkAmount)); + 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); } - updateBiomePacket(island, chunk); - - progress.getAndIncrement(); - - if(language.getBoolean("Command.Island.Biome.Progress.Should-Display-Message") && - progress.get() == 1 || progress.get() == chunkAmount || progress.get() % runEveryX == 0){ - final double percent = ((double) progress.get() / (double) chunkAmount) * 100; - - String message = language.getString("Command.Island.Biome.Progress.Message"); - message = message.replace("%current_updated_chunks%", String.valueOf(progress.get())); - message = message.replace("%max_chunks%", String.valueOf(chunkAmount)); - 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); - } - } - }, (island1 -> { - removeUpdatingIsland(island1); - if(task != null) { - 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(); - } - })); - } + } + }, (island1 -> { + removeUpdatingIsland(island1); + if(task != null) { + task.onCompleteUpdate(); + } + })); } private void setChunkBiome2D(Biome biome, Chunk chunk) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { diff --git a/src/main/java/com/songoda/skyblock/blockscanner/BlockScanner.java b/src/main/java/com/songoda/skyblock/blockscanner/BlockScanner.java index 8cd3f4bd..054fa1e1 100644 --- a/src/main/java/com/songoda/skyblock/blockscanner/BlockScanner.java +++ b/src/main/java/com/songoda/skyblock/blockscanner/BlockScanner.java @@ -57,12 +57,10 @@ public final class BlockScanner extends BukkitRunnable { private final Queue 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> 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 sub : parts) { queueWork(world, startY, sub); } - } this.threadCount = threadCount; diff --git a/src/main/java/com/songoda/skyblock/blockscanner/ChunkLoader.java b/src/main/java/com/songoda/skyblock/blockscanner/ChunkLoader.java index ebe7d7fb..1ffbeda3 100644 --- a/src/main/java/com/songoda/skyblock/blockscanner/ChunkLoader.java +++ b/src/main/java/com/songoda/skyblock/blockscanner/ChunkLoader.java @@ -16,8 +16,7 @@ import java.util.List; import java.util.concurrent.CompletableFuture; public class ChunkLoader extends BukkitRunnable { - public final List> asyncPositions = new LinkedList<>(); - public final List syncPositions = new LinkedList<>(); + public final List> positions = new LinkedList<>(); private ChunkScannerTask generalTask; private ChunkForChunkScannerTask chunkTask; @@ -60,7 +59,7 @@ public class ChunkLoader extends BukkitRunnable { x = minX; z = minZ; - + if(paper){ this.runTaskAsynchronously(SkyBlock.getInstance()); } else { @@ -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)); - } + positions.add(PaperLib.getChunkAtAsync(world, x >> 4, z >> 4)); } else { - 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)); - } + if(chunkTask != null) { + 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> asyncChunks, List syncChunks); - + void onComplete(List> chunks); } public interface ChunkForChunkScannerTask { - - void onChunkComplete(CompletableFuture asyncChunk, Chunk syncChunk); - + void onChunkComplete(CompletableFuture chunk); } public interface CompleteTask { diff --git a/src/main/java/com/songoda/skyblock/island/IslandManager.java b/src/main/java/com/songoda/skyblock/island/IslandManager.java index 65d5dfe8..d403aa79 100644 --- a/src/main/java/com/songoda/skyblock/island/IslandManager.java +++ b/src/main/java/com/songoda/skyblock/island/IslandManager.java @@ -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, () -> { - 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())); - } + 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")) @@ -654,26 +653,15 @@ public class IslandManager { if (location == null) continue; final World world = worldManager.getWorld(worldList); - - if(plugin.isPaperAsync()){ - ChunkLoader.startChunkLoading(island, IslandWorld.Normal, plugin.isPaperAsync(), (asyncChunks, syncChunks) -> { - List positions = new LinkedList<>(); - for (CompletableFuture chunk : asyncChunks) { - 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 list = syncChunks.stream().map(Chunk::getChunkSnapshot).collect(Collectors.toList()); - - snapshots.put(world, list); - ChunkDeleteSplitter.startDeletion(snapshots); - }); - }, null); - } + + ChunkLoader.startChunkLoading(island, IslandWorld.Normal, plugin.isPaperAsync(), (chunks) -> { + List positions = new LinkedList<>(); + for (CompletableFuture chunk : chunks) { + positions.add(chunk.join()); + } + snapshots.put(world, positions.stream().map(Chunk::getChunkSnapshot).collect(Collectors.toList())); + 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) { diff --git a/src/main/java/com/songoda/skyblock/levelling/IslandScan.java b/src/main/java/com/songoda/skyblock/levelling/IslandScan.java index 26e2504f..eefd5983 100644 --- a/src/main/java/com/songoda/skyblock/levelling/IslandScan.java +++ b/src/main/java/com/songoda/skyblock/levelling/IslandScan.java @@ -196,19 +196,15 @@ public final class IslandScan extends BukkitRunnable { private void populate(Map> snapshots, IslandWorld world, boolean paper, PopulateTask task) { final SkyBlock plugin = SkyBlock.getInstance(); - - ChunkLoader.startChunkLoading(island, IslandWorld.Normal, paper, (asyncPositions, syncPositions) -> { - if(paper){ - List positions = new LinkedList<>(); - for(CompletableFuture chunk : asyncPositions){ - positions.add(chunk.join().getChunkSnapshot()); - } - snapshots.put(plugin.getWorldManager().getWorld(world), positions); - } else { - snapshots.put(plugin.getWorldManager().getWorld(world), syncPositions.stream().map(org.bukkit.Chunk::getChunkSnapshot).collect(Collectors.toList())); - } + + List positions = new LinkedList<>(); + + ChunkLoader.startChunkLoadingPerChunk(island, IslandWorld.Normal, paper, (chunkCompletableFuture) -> + positions.add(chunkCompletableFuture.join().getChunkSnapshot()), + value -> { + snapshots.put(plugin.getWorldManager().getWorld(world), positions); task.onComplete(); - }, null); + }); } private interface PopulateTask {