diff --git a/src/main/java/com/songoda/skyblock/island/IslandLevel.java b/src/main/java/com/songoda/skyblock/island/IslandLevel.java index 24a86936..cb361b31 100644 --- a/src/main/java/com/songoda/skyblock/island/IslandLevel.java +++ b/src/main/java/com/songoda/skyblock/island/IslandLevel.java @@ -29,23 +29,24 @@ public class IslandLevel { this.skyblock = skyblock; this.ownerUUID = ownerUUID; - Config config = skyblock.getFileManager().getConfig(new File(new File(skyblock.getDataFolder().toString() + "/level-data"), ownerUUID.toString() + ".yml")); - FileConfiguration configLoad = config.getFileConfiguration(); + final Config config = skyblock.getFileManager().getConfig(new File(new File(skyblock.getDataFolder().toString() + "/level-data"), ownerUUID.toString() + ".yml")); + final FileConfiguration configLoad = config.getFileConfiguration(); - Map materials; + final ConfigurationSection section = configLoad.getConfigurationSection("Levelling.Materials"); + final Map materials; - ConfigurationSection materialSection = configLoad.getConfigurationSection("Leveling.Materials"); + if (section != null) { + final Set keys = section.getKeys(false); + materials = new HashMap<>(keys.size()); - if (materialSection != null) { - Set keys = materialSection.getKeys(false); - materials = new HashMap<>(keys.size() * 2); + for (String material : keys) { - for (String material : materialSection.getKeys(false)) { - - final ConfigurationSection current = materialSection.getConfigurationSection(material); + ConfigurationSection current = section.getConfigurationSection(material); if (current.isSet("Amount")) materials.put(material, current.getLong("Amount")); + } + } else { materials = new HashMap<>(); } @@ -71,10 +72,11 @@ public class IslandLevel { ConfigurationSection current = materialSection.getConfigurationSection(entry.getKey()); if (current == null) continue; - + long pointsRequired = current.getLong("Points", 0); if (pointsRequired != 0) pointsEarned = pointsEarned + (entry.getValue() * pointsRequired); + } return pointsEarned; diff --git a/src/main/java/com/songoda/skyblock/island/IslandManager.java b/src/main/java/com/songoda/skyblock/island/IslandManager.java index 7682c017..8ae6b53c 100644 --- a/src/main/java/com/songoda/skyblock/island/IslandManager.java +++ b/src/main/java/com/songoda/skyblock/island/IslandManager.java @@ -1,8 +1,38 @@ package com.songoda.skyblock.island; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Chunk; +import org.bukkit.ChunkSnapshot; +import org.bukkit.GameMode; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Biome; +import org.bukkit.block.Block; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.plugin.IllegalPluginAccessException; + import com.google.common.base.Preconditions; import com.songoda.skyblock.SkyBlock; -import com.songoda.skyblock.api.event.island.*; +import com.songoda.skyblock.api.event.island.IslandCreateEvent; +import com.songoda.skyblock.api.event.island.IslandDeleteEvent; +import com.songoda.skyblock.api.event.island.IslandLoadEvent; +import com.songoda.skyblock.api.event.island.IslandOwnershipTransferEvent; +import com.songoda.skyblock.api.event.island.IslandUnloadEvent; import com.songoda.skyblock.ban.BanManager; import com.songoda.skyblock.config.FileManager; import com.songoda.skyblock.config.FileManager.Config; @@ -10,6 +40,7 @@ import com.songoda.skyblock.cooldown.CooldownManager; import com.songoda.skyblock.cooldown.CooldownType; import com.songoda.skyblock.invite.Invite; import com.songoda.skyblock.invite.InviteManager; +import com.songoda.skyblock.island.removal.ChunkDeleteSplitter; import com.songoda.skyblock.message.MessageManager; import com.songoda.skyblock.playerdata.PlayerData; import com.songoda.skyblock.playerdata.PlayerDataManager; @@ -32,18 +63,6 @@ import com.songoda.skyblock.utils.world.WorldBorder; import com.songoda.skyblock.utils.world.block.BlockDegreesType; import com.songoda.skyblock.visit.VisitManager; import com.songoda.skyblock.world.WorldManager; -import org.bukkit.*; -import org.bukkit.block.Biome; -import org.bukkit.block.Block; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.entity.Player; -import org.bukkit.plugin.IllegalPluginAccessException; - -import java.io.File; -import java.io.IOException; -import java.util.*; public class IslandManager { @@ -383,6 +402,8 @@ public class IslandManager { } } + int j = 0; + public void deleteIsland(Island island) { ScoreboardManager scoreboardManager = skyblock.getScoreboardManager(); PlayerDataManager playerDataManager = skyblock.getPlayerDataManager(); @@ -396,17 +417,13 @@ public class IslandManager { Bukkit.getScheduler().runTaskLater(skyblock, () -> { org.bukkit.World world = worldManager.getWorld(worldList); Location location = island.getLocation(worldList, IslandEnvironment.Island); + if (location == null) return; - int size = island.getSize(); - int xx = location.getBlockX() - size / 2; - int zz = location.getBlockZ() - size / 2; - for (int x = xx; x < xx + size; x++) { - for (int z = zz; z < zz + size; z++) { - for (int y = 0; y < world.getMaxHeight(); y++) { - new Location(world, x, y, z).getBlock().setType(Material.AIR); - } - } - } + + List snapshots = com.songoda.skyblock.levelling.Chunk.getChunksToScan(island, worldList).stream().map(ch -> world.getChunkAt(ch.getX(), ch.getZ())) + .map(chunk -> chunk.getChunkSnapshot()).collect(Collectors.toList()); + + ChunkDeleteSplitter.startDeleting(world, snapshots); }, i); i += 20L; } diff --git a/src/main/java/com/songoda/skyblock/island/IslandWorld.java b/src/main/java/com/songoda/skyblock/island/IslandWorld.java index 4471f1e0..6d8df9e2 100644 --- a/src/main/java/com/songoda/skyblock/island/IslandWorld.java +++ b/src/main/java/com/songoda/skyblock/island/IslandWorld.java @@ -12,7 +12,7 @@ public enum IslandWorld { Normal, Nether, End; public static List getIslandWorlds() { - List islandWorlds = new ArrayList<>(); + List islandWorlds = new ArrayList<>(3); WorldManager worldManager = SkyBlock.getInstance().getWorldManager(); if (worldManager.getWorld(Normal) != null) diff --git a/src/main/java/com/songoda/skyblock/island/removal/ChunkDeleteSplitter.java b/src/main/java/com/songoda/skyblock/island/removal/ChunkDeleteSplitter.java new file mode 100644 index 00000000..1e3827de --- /dev/null +++ b/src/main/java/com/songoda/skyblock/island/removal/ChunkDeleteSplitter.java @@ -0,0 +1,95 @@ +package com.songoda.skyblock.island.removal; + +import java.util.Iterator; +import java.util.List; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; + +import org.bukkit.Bukkit; +import org.bukkit.ChunkSnapshot; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.scheduler.BukkitRunnable; + +import com.google.common.collect.Lists; +import com.songoda.skyblock.SkyBlock; + +public final class ChunkDeleteSplitter extends BukkitRunnable { + + private int completedNum; + + private final World world; + private final int threadCount; + private final Queue toRemove; + + private ChunkDeleteSplitter(World world, List snapshots) { + this.toRemove = new ConcurrentLinkedQueue<>(); + this.world = world; + + final List> parts = Lists.partition(snapshots, 32); + + this.threadCount = parts.size(); + + for (List sub : parts) { + queueWork(sub); + } + } + + private void queueWork(List subList) { + Bukkit.getServer().getScheduler().runTaskAsynchronously(SkyBlock.getInstance(), () -> { + for (ChunkSnapshot shot : subList) { + for (int x = 0; x < 16; x++) { + for (int z = 0; z < 16; z++) { + for (int y = 0; y < 256; y++) { + final Material type = shot.getBlockType(x, y, z); + + if (type == Material.AIR) continue; + + toRemove.add(new XYZPair(x, y, z)); + } + } + } + } + increment(); + }); + } + + private synchronized void increment() { + completedNum++; + } + + private synchronized int get() { + return completedNum; + } + + @Override + public void run() { + if (get() != threadCount) return; + + int deleteAmount = 0; + + for (Iterator it = toRemove.iterator(); it.hasNext();) { + + if (deleteAmount == 10000) break; + + final XYZPair pair = it.next(); + + world.getBlockAt(pair.getX(), pair.getY(), pair.getZ()).setType(Material.AIR); + + deleteAmount++; + it.remove(); + } + + if (toRemove.isEmpty()) { + cancel(); + } + } + + public static void startDeleting(World world, List snapshots) { + + final ChunkDeleteSplitter splitter = new ChunkDeleteSplitter(world, snapshots); + + splitter.runTaskTimer(SkyBlock.getInstance(), 5, 5); + } + +} diff --git a/src/main/java/com/songoda/skyblock/island/removal/XYZPair.java b/src/main/java/com/songoda/skyblock/island/removal/XYZPair.java new file mode 100644 index 00000000..c9e07703 --- /dev/null +++ b/src/main/java/com/songoda/skyblock/island/removal/XYZPair.java @@ -0,0 +1,27 @@ +package com.songoda.skyblock.island.removal; + +public class XYZPair { + + private final int x; + private final int y; + private final int z; + + public XYZPair(final int x, final int y, final int z) { + this.x = x; + this.y = y; + this.z = z; + } + + public int getX() { + return x; + } + + public int getY() { + return y; + } + + public int getZ() { + return z; + } + +} diff --git a/src/main/java/com/songoda/skyblock/leaderboard/LeaderboardManager.java b/src/main/java/com/songoda/skyblock/leaderboard/LeaderboardManager.java index 2498d027..dc6919d6 100644 --- a/src/main/java/com/songoda/skyblock/leaderboard/LeaderboardManager.java +++ b/src/main/java/com/songoda/skyblock/leaderboard/LeaderboardManager.java @@ -42,9 +42,11 @@ public class LeaderboardManager { visitManager.loadIslands(); - List islandLevels = new ArrayList<>(); - List islandBanks = new ArrayList<>(); - List islandVotes = new ArrayList<>(); + int arraySize = visitManager.getIslands().size(); + + List islandLevels = new ArrayList<>(arraySize); + List islandBanks = new ArrayList<>(arraySize); + List islandVotes = new ArrayList<>(arraySize); boolean enableExemptions = skyblock.getFileManager().getConfig(new File(skyblock.getDataFolder(), "config.yml")) .getFileConfiguration().getBoolean("Island.Leaderboard.Exemptions.Enable"); @@ -87,7 +89,7 @@ public class LeaderboardManager { VisitManager visitManager = skyblock.getVisitManager(); visitManager.loadIslands(); - List leaderboardPlayers = new ArrayList<>(); + List leaderboardPlayers = new ArrayList<>(visitManager.getIslands().size()); switch (type) { case Level: @@ -145,9 +147,11 @@ public class LeaderboardManager { } public Leaderboard getLeaderboardFromPosition(Leaderboard.Type type, int position) { - for (Leaderboard leaderboardPlayerList : leaderboardStorage) - if (leaderboardPlayerList.getType() == type && leaderboardPlayerList.getPosition() == position) + for (Leaderboard leaderboardPlayerList : leaderboardStorage) { + if (leaderboardPlayerList.getType() == type && leaderboardPlayerList.getPosition() == position) { return leaderboardPlayerList; + } + } return null; } diff --git a/src/main/java/com/songoda/skyblock/levelling/Chunk.java b/src/main/java/com/songoda/skyblock/levelling/Chunk.java index f6d659e1..d9b097ce 100644 --- a/src/main/java/com/songoda/skyblock/levelling/Chunk.java +++ b/src/main/java/com/songoda/skyblock/levelling/Chunk.java @@ -12,8 +12,11 @@ import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.Player; import java.io.File; +import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; import java.util.Set; public class Chunk { @@ -43,7 +46,7 @@ public class Chunk { for (IslandWorld islandWorld : IslandWorld.getIslandWorlds()) { if (islandWorld == IslandWorld.Normal || (islandWorld == IslandWorld.Nether && hasNether) || (islandWorld == IslandWorld.End && hasEnd)) { - this.getChunksToScan(islandWorld); + chunkPositions.addAll(getChunksToScan(island, islandWorld)); } } @@ -130,12 +133,15 @@ public class Chunk { } } - private void getChunksToScan(IslandWorld islandWorld) { - Location islandLocation = this.island.getLocation(islandWorld, IslandEnvironment.Island); + public static List getChunksToScan(Island island, IslandWorld islandWorld) { + Location islandLocation = island.getLocation(islandWorld, IslandEnvironment.Island); + + if (islandLocation == null) return new ArrayList<>(0); + World world = islandLocation.getWorld(); - Location minLocation = new Location(world, islandLocation.getBlockX() - this.island.getRadius(), 0, islandLocation.getBlockZ() - this.island.getRadius()); - Location maxLocation = new Location(world, islandLocation.getBlockX() + this.island.getRadius(), world.getMaxHeight(), islandLocation.getBlockZ() + this.island.getRadius()); + 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()); int minZ = Math.min(maxLocation.getBlockZ(), minLocation.getBlockZ()); @@ -143,10 +149,14 @@ public class Chunk { int maxX = Math.max(maxLocation.getBlockX(), minLocation.getBlockX()); int maxZ = Math.max(maxLocation.getBlockZ(), minLocation.getBlockZ()); + List positions = new LinkedList<>(); + for (int x = minX; x < maxX + 16; x += 16) { for (int z = minZ; z < maxZ + 16; z += 16) { - this.chunkPositions.add(new ChunkPosition(world, x >> 4, z >> 4)); + positions.add(new ChunkPosition(world, x >> 4, z >> 4)); } } + + return positions; } } diff --git a/src/main/java/com/songoda/skyblock/listeners/Portal.java b/src/main/java/com/songoda/skyblock/listeners/Portal.java index 1c0df2d7..f623ea07 100644 --- a/src/main/java/com/songoda/skyblock/listeners/Portal.java +++ b/src/main/java/com/songoda/skyblock/listeners/Portal.java @@ -174,7 +174,7 @@ public class Portal implements Listener { } - public class Tick { + public static class Tick { private int tick = 1; private long last = System.currentTimeMillis() - 1001; diff --git a/src/main/java/com/songoda/skyblock/listeners/Respawn.java b/src/main/java/com/songoda/skyblock/listeners/Respawn.java index 93b5b723..a7a255b5 100644 --- a/src/main/java/com/songoda/skyblock/listeners/Respawn.java +++ b/src/main/java/com/songoda/skyblock/listeners/Respawn.java @@ -38,10 +38,11 @@ public class Respawn implements Listener { FileConfiguration configLoad = config.getFileConfiguration(); if (configLoad.getBoolean("Island.Death.Respawn.Island")) { - Island island = islandManager.getIslandAtLocation(player.getLocation()); + Location playerLocation = player.getLocation(); + Island island = islandManager.getIslandAtLocation(playerLocation); if (island != null) { - Location playerLocation = player.getLocation().clone(), islandLocation; + Location islandLocation; IslandWorld world = worldManager.getIslandWorld(player.getWorld()); if (island.hasRole(IslandRole.Member, player.getUniqueId()) @@ -67,10 +68,8 @@ public class Respawn implements Listener { if (config.getFileConfiguration().getString("Location.Spawn") == null) { Bukkit.getServer().getLogger().log(Level.WARNING, "SkyBlock | Error: A spawn point hasn't been set."); } else { - Location playerLocation = player.getLocation().clone(), - spawnLocation = fileManager.getLocation(config, "Location.Spawn", true); - Bukkit.getServer().getPluginManager() - .callEvent(new PlayerTeleportEvent(player, playerLocation, spawnLocation)); + Location playerLocation = player.getLocation(), spawnLocation = fileManager.getLocation(config, "Location.Spawn", true); + Bukkit.getServer().getPluginManager().callEvent(new PlayerTeleportEvent(player, playerLocation, spawnLocation)); event.setRespawnLocation(spawnLocation); } } diff --git a/src/main/java/com/songoda/skyblock/menus/admin/Generator.java b/src/main/java/com/songoda/skyblock/menus/admin/Generator.java index 930f931f..ebca7c9f 100644 --- a/src/main/java/com/songoda/skyblock/menus/admin/Generator.java +++ b/src/main/java/com/songoda/skyblock/menus/admin/Generator.java @@ -118,7 +118,7 @@ public class Generator implements Listener { com.songoda.skyblock.generator.Generator generator = generatorManager .getGenerator(((Generator.Viewer) playerData.getViewer()).getName()); - List permissionLore = new ArrayList<>(); + final List permissionLore; if (generator.isPermission()) { permissionLore = configLoad diff --git a/src/main/java/com/songoda/skyblock/message/MessageManager.java b/src/main/java/com/songoda/skyblock/message/MessageManager.java index 47604246..97d98c45 100644 --- a/src/main/java/com/songoda/skyblock/message/MessageManager.java +++ b/src/main/java/com/songoda/skyblock/message/MessageManager.java @@ -36,7 +36,7 @@ public class MessageManager { messages.add(ChatColor.translateAlternateColorCodes('&', messageList)); } - sender.sendMessage(messages.toArray(new String[0])); + sender.sendMessage(messages.toArray(new String[messages.size()])); } else { sender.sendMessage(ChatColor.translateAlternateColorCodes('&', message)); } @@ -50,7 +50,7 @@ public class MessageManager { messages.add(ChatColor.stripColor(ChatColor.translateAlternateColorCodes('&', messageList))); } - sender.sendMessage(messages.toArray(new String[0])); + sender.sendMessage(messages.toArray(new String[messages.size()])); } else { sender.sendMessage(ChatColor.stripColor(ChatColor.translateAlternateColorCodes('&', message))); } diff --git a/src/main/java/com/songoda/skyblock/placeholder/EZPlaceholder.java b/src/main/java/com/songoda/skyblock/placeholder/EZPlaceholder.java index 72959a5f..b15c0902 100644 --- a/src/main/java/com/songoda/skyblock/placeholder/EZPlaceholder.java +++ b/src/main/java/com/songoda/skyblock/placeholder/EZPlaceholder.java @@ -13,18 +13,16 @@ import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.entity.Player; -import org.bukkit.event.Listener; import java.io.File; import java.util.List; -public class EZPlaceholder extends PlaceholderExpansion implements Listener { +public class EZPlaceholder extends PlaceholderExpansion { private final SkyBlock skyblock; public EZPlaceholder(SkyBlock skyblock) { this.skyblock = skyblock; - Bukkit.getPluginManager().registerEvents(this, skyblock); } public String getIdentifier() { diff --git a/src/main/java/com/songoda/skyblock/placeholder/PlaceholderManager.java b/src/main/java/com/songoda/skyblock/placeholder/PlaceholderManager.java index 586ae92e..dbdee052 100644 --- a/src/main/java/com/songoda/skyblock/placeholder/PlaceholderManager.java +++ b/src/main/java/com/songoda/skyblock/placeholder/PlaceholderManager.java @@ -400,7 +400,7 @@ public class PlaceholderManager { } public List getPlaceholders() { - List placeholders = new ArrayList<>(); + List placeholders = new ArrayList<>(25); placeholders.add("fabledskyblock_island_exists"); placeholders.add("fabledskyblock_island_isopen"); placeholders.add("fabledskyblock_island_size"); diff --git a/src/main/java/com/songoda/skyblock/stackable/StackableManager.java b/src/main/java/com/songoda/skyblock/stackable/StackableManager.java index 4f4bb160..0e24a1f7 100644 --- a/src/main/java/com/songoda/skyblock/stackable/StackableManager.java +++ b/src/main/java/com/songoda/skyblock/stackable/StackableManager.java @@ -84,11 +84,8 @@ public class StackableManager { public Stackable getStack(Location location, Material material) { Stackable stackable = stacks.get(location); - - if (stackable != null && stackable.getMaterial() == material) - return stacks.get(location); - else - return null; + + return stackable != null && stackable.getMaterial() == material ? stackable : null; } public Stackable addStack(Stackable stackable) { diff --git a/src/main/java/com/songoda/skyblock/upgrade/UpgradeManager.java b/src/main/java/com/songoda/skyblock/upgrade/UpgradeManager.java index bed17488..c92b80db 100644 --- a/src/main/java/com/songoda/skyblock/upgrade/UpgradeManager.java +++ b/src/main/java/com/songoda/skyblock/upgrade/UpgradeManager.java @@ -59,11 +59,8 @@ public class UpgradeManager { } public List getUpgrades(Upgrade.Type type) { - if (upgradeStorage.containsKey(type)) { - return upgradeStorage.get(type); - } + return upgradeStorage.get(type); - return null; } public void addUpgrade(Upgrade.Type type, int value) { diff --git a/src/main/java/com/songoda/skyblock/utils/world/LocationUtil.java b/src/main/java/com/songoda/skyblock/utils/world/LocationUtil.java index 3f52cebb..ca2afb80 100644 --- a/src/main/java/com/songoda/skyblock/utils/world/LocationUtil.java +++ b/src/main/java/com/songoda/skyblock/utils/world/LocationUtil.java @@ -237,16 +237,16 @@ public final class LocationUtil { int rndX = rnd.nextInt(xRange); int rndZ = rnd.nextInt(zRange); - if (loadChunk) { - Chunk chunk = world.getChunkAt(new Location(world, rndX, 10, rndZ)); - world.loadChunk(chunk); - } + if (loadChunk) world.getChunkAt(new Location(world, rndX, 10, rndZ)); double rndY = -1; if (world.getEnvironment() == Environment.NETHER) { + + Location rndLoc = new Location(world, rndX, 0, rndZ); + for (int i = 120; i > 0; i--) { - Location rndLoc = new Location(world, rndX, i, rndZ); + rndLoc.setY(i); if (rndLoc.getBlock().getType() != Material.AIR && rndLoc.clone().add(0.0D, 1.0D, 0.0D).getBlock().getType() == Material.AIR @@ -254,7 +254,6 @@ public final class LocationUtil { && rndLoc.clone().add(0.0D, 3.0D, 0.0D).getBlock().getType() == Material.AIR && rndLoc.clone().add(0.0D, 4.0D, 0.0D).getBlock().getType() == Material.AIR) { rndY = i; - break; } } diff --git a/src/main/java/com/songoda/skyblock/visit/VisitManager.java b/src/main/java/com/songoda/skyblock/visit/VisitManager.java index c49d3419..08a36c2d 100644 --- a/src/main/java/com/songoda/skyblock/visit/VisitManager.java +++ b/src/main/java/com/songoda/skyblock/visit/VisitManager.java @@ -33,8 +33,7 @@ public class VisitManager { public void onDisable() { HashMap visitIslands = getIslands(); - for (UUID visitIslandList : visitIslands.keySet()) { - Visit visit = visitIslands.get(visitIslandList); + for (Visit visit : visitIslands.values()) { visit.save(); } }