diff --git a/src/main/java/com/songoda/skyblock/SkyBlock.java b/src/main/java/com/songoda/skyblock/SkyBlock.java index f8d7a38e..568c9f69 100644 --- a/src/main/java/com/songoda/skyblock/SkyBlock.java +++ b/src/main/java/com/songoda/skyblock/SkyBlock.java @@ -14,7 +14,7 @@ import com.songoda.skyblock.hologram.HologramManager; import com.songoda.skyblock.invite.InviteManager; import com.songoda.skyblock.island.IslandManager; import com.songoda.skyblock.leaderboard.LeaderboardManager; -import com.songoda.skyblock.levelling.LevellingManager; +import com.songoda.skyblock.levelling.rework.IslandLevelManager; import com.songoda.skyblock.limit.LimitationInstanceHandler; import com.songoda.skyblock.listeners.*; import com.songoda.skyblock.menus.Rollback; @@ -64,7 +64,7 @@ public class SkyBlock extends JavaPlugin { private ScoreboardManager scoreboardManager; private InviteManager inviteManager; private BiomeManager biomeManager; - private LevellingManager levellingManager; + private IslandLevelManager levellingManager; private CommandManager commandManager; private StructureManager structureManager; private StackableManager stackableManager; @@ -110,7 +110,7 @@ public class SkyBlock extends JavaPlugin { inviteManager = new InviteManager(this); biomeManager = new BiomeManager(this); - levellingManager = new LevellingManager(this); + levellingManager = new IslandLevelManager(); commandManager = new CommandManager(this); structureManager = new StructureManager(this); soundManager = new SoundManager(this); @@ -277,7 +277,7 @@ public class SkyBlock extends JavaPlugin { return biomeManager; } - public LevellingManager getLevellingManager() { + public IslandLevelManager getLevellingManager() { return levellingManager; } diff --git a/src/main/java/com/songoda/skyblock/api/levelling/LevellingManager.java b/src/main/java/com/songoda/skyblock/api/levelling/LevellingManager.java index 672975f6..ba6be39b 100644 --- a/src/main/java/com/songoda/skyblock/api/levelling/LevellingManager.java +++ b/src/main/java/com/songoda/skyblock/api/levelling/LevellingManager.java @@ -5,9 +5,9 @@ import com.songoda.skyblock.api.island.Island; public class LevellingManager { - private final com.songoda.skyblock.levelling.LevellingManager levellingManager; + private final com.songoda.skyblock.levelling.rework.IslandLevelManager levellingManager; - public LevellingManager(com.songoda.skyblock.levelling.LevellingManager levellingManager) { + public LevellingManager(com.songoda.skyblock.levelling.rework.IslandLevelManager levellingManager) { this.levellingManager = levellingManager; } @@ -16,6 +16,6 @@ public class LevellingManager { */ public void calculatePoints(Island island) { Preconditions.checkArgument(island != null, "Cannot calculate points to null island"); - this.levellingManager.calculatePoints(null, island.getIsland()); + this.levellingManager.startScan(null, island.getIsland()); } } diff --git a/src/main/java/com/songoda/skyblock/island/removal/XYZPair.java b/src/main/java/com/songoda/skyblock/blockscanner/BlockInfo.java similarity index 51% rename from src/main/java/com/songoda/skyblock/island/removal/XYZPair.java rename to src/main/java/com/songoda/skyblock/blockscanner/BlockInfo.java index c9e07703..1db0f4fe 100644 --- a/src/main/java/com/songoda/skyblock/island/removal/XYZPair.java +++ b/src/main/java/com/songoda/skyblock/blockscanner/BlockInfo.java @@ -1,15 +1,20 @@ -package com.songoda.skyblock.island.removal; +package com.songoda.skyblock.blockscanner; -public class XYZPair { +import org.bukkit.World; + +public final class BlockInfo { + + private final World world; private final int x; private final int y; private final int z; - public XYZPair(final int x, final int y, final int z) { + public BlockInfo(World world, int x, int y, int z) { this.x = x; this.y = y; this.z = z; + this.world = world; } public int getX() { @@ -24,4 +29,8 @@ public class XYZPair { return z; } + public World getWorld() { + return world; + } + } diff --git a/src/main/java/com/songoda/skyblock/blockscanner/BlockScanner.java b/src/main/java/com/songoda/skyblock/blockscanner/BlockScanner.java new file mode 100644 index 00000000..f0bebbeb --- /dev/null +++ b/src/main/java/com/songoda/skyblock/blockscanner/BlockScanner.java @@ -0,0 +1,136 @@ +package com.songoda.skyblock.blockscanner; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +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; +import com.songoda.skyblock.utils.version.NMSUtil; + +public final class BlockScanner extends BukkitRunnable { + + private static final Method ID_FIELD; + + static { + Method temp = null; + + try { + temp = ChunkSnapshot.class.getMethod("getBlockTypeId", int.class, int.class, int.class); + } catch (NoSuchMethodException ignored) { + + } + + ID_FIELD = temp; + } + + public static int getBlockTypeID(ChunkSnapshot snapshot, int x, int y, int z) { + + int id = 0; + + try { + id = (Integer) ID_FIELD.invoke(snapshot, x, y, z); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + e.printStackTrace(); + } + + return id; + } + + private final static int VERSION = NMSUtil.getVersionNumber(); + + private int completedNum; + + private final int threadCount; + private final Queue blocks; + private final ScannerTasks tasks; + + private BlockScanner(Map> snapshots, ScannerTasks tasks) { + this.blocks = new ConcurrentLinkedQueue<>(); + this.tasks = tasks; + + int threadCount = 0; + + for (Entry> entry : snapshots.entrySet()) { + + final List> parts = Lists.partition(entry.getValue(), 16); + + threadCount += parts.size(); + + for (List sub : parts) { + queueWork(entry.getKey(), sub); + } + + } + + this.threadCount = threadCount; + } + + private void queueWork(World world, List subList) { + Bukkit.getServer().getScheduler().runTaskAsynchronously(SkyBlock.getInstance(), () -> { + for (ChunkSnapshot shot : subList) { + + final int cX = shot.getX() << 4; + final int cZ = shot.getZ() << 4; + + for (int x = 0; x < 16; x++) { + for (int z = 0; z < 16; z++) { + for (int y = 0; y < 256; y++) { + + final Material type = VERSION > 12 ? shot.getBlockType(x, y, z) : MaterialIDHelper.getLegacyMaterial(getBlockTypeID(shot, x, y, z)); + + if (type == Material.AIR) continue; + + blocks.add(new BlockInfo(world, x + (cX), y, z + (cZ))); + } + } + } + } + increment(); + }); + } + + private synchronized int increment() { + completedNum += 1; + return completedNum; + } + + private synchronized int get() { + return completedNum; + } + + @Override + public void run() { + if (get() != threadCount) return; + + tasks.onComplete(blocks); + cancel(); + } + + public static void startScanner(Map> snapshots, ScannerTasks tasks) { + + if (snapshots == null) throw new IllegalArgumentException("snapshots cannot be null"); + if (tasks == null) throw new IllegalArgumentException("tasks cannot be null"); + + final BlockScanner scanner = new BlockScanner(snapshots, tasks); + + scanner.runTaskTimer(SkyBlock.getInstance(), 5, 5); + } + + public static interface ScannerTasks { + + void onComplete(Queue blocks); + + } + +} diff --git a/src/main/java/com/songoda/skyblock/blockscanner/MaterialIDHelper.java b/src/main/java/com/songoda/skyblock/blockscanner/MaterialIDHelper.java new file mode 100644 index 00000000..8a6dbd45 --- /dev/null +++ b/src/main/java/com/songoda/skyblock/blockscanner/MaterialIDHelper.java @@ -0,0 +1,40 @@ +package com.songoda.skyblock.blockscanner; + +import java.util.HashMap; +import java.util.Map; + +import org.bukkit.Material; + +import com.songoda.skyblock.utils.version.NMSUtil; + +@SuppressWarnings("deprecation") +public final class MaterialIDHelper { + + private final static int VERSION = NMSUtil.getVersionNumber(); + + private MaterialIDHelper() { + + } + + private final static Map MATERIALS; + + static { + MATERIALS = new HashMap<>(); + + if (VERSION > 12) { + for (Material type : Material.values()) { + if (type.isLegacy()) MATERIALS.put(type.getId(), type); + } + } else { + for (Material type : Material.values()) { + MATERIALS.put(type.getId(), type); + } + } + + } + + public static Material getLegacyMaterial(int id) { + return MATERIALS.get(id); + } + +} diff --git a/src/main/java/com/songoda/skyblock/command/commands/admin/LevelScanCommand.java b/src/main/java/com/songoda/skyblock/command/commands/admin/LevelScanCommand.java index 524fbbe3..384d5420 100644 --- a/src/main/java/com/songoda/skyblock/command/commands/admin/LevelScanCommand.java +++ b/src/main/java/com/songoda/skyblock/command/commands/admin/LevelScanCommand.java @@ -4,7 +4,7 @@ import com.songoda.skyblock.command.SubCommand; import com.songoda.skyblock.config.FileManager; import com.songoda.skyblock.island.Island; import com.songoda.skyblock.island.IslandManager; -import com.songoda.skyblock.levelling.LevellingManager; +import com.songoda.skyblock.levelling.rework.IslandLevelManager; import com.songoda.skyblock.message.MessageManager; import com.songoda.skyblock.sound.SoundManager; import com.songoda.skyblock.utils.version.Sounds; @@ -30,7 +30,7 @@ public class LevelScanCommand extends SubCommand { } private void onCommand(CommandSender sender, String[] args) { - LevellingManager levellingManager = skyblock.getLevellingManager(); + IslandLevelManager levellingManager = skyblock.getLevellingManager(); MessageManager messageManager = skyblock.getMessageManager(); IslandManager islandManager = skyblock.getIslandManager(); SoundManager soundManager = skyblock.getSoundManager(); @@ -54,7 +54,7 @@ public class LevelScanCommand extends SubCommand { return; } - levellingManager.calculatePoints(sender instanceof Player ? (Player) sender : null, island); + levellingManager.startScan(sender instanceof Player ? (Player) sender : null, island); messageManager.sendMessage(sender, configLoad.getString("Command.Island.Admin.LevelScan.Started.Message")); soundManager.playSound(sender, Sounds.VILLAGER_YES.bukkitSound(), 1.0F, 1.0F); diff --git a/src/main/java/com/songoda/skyblock/command/commands/admin/ReloadCommand.java b/src/main/java/com/songoda/skyblock/command/commands/admin/ReloadCommand.java index 9f731479..76a29ec7 100644 --- a/src/main/java/com/songoda/skyblock/command/commands/admin/ReloadCommand.java +++ b/src/main/java/com/songoda/skyblock/command/commands/admin/ReloadCommand.java @@ -14,7 +14,7 @@ import com.songoda.skyblock.config.FileManager; import com.songoda.skyblock.config.FileManager.Config; import com.songoda.skyblock.generator.GeneratorManager; import com.songoda.skyblock.leaderboard.LeaderboardManager; -import com.songoda.skyblock.levelling.LevellingManager; +import com.songoda.skyblock.levelling.rework.IslandLevelManager; import com.songoda.skyblock.limit.LimitationInstanceHandler; import com.songoda.skyblock.message.MessageManager; import com.songoda.skyblock.scoreboard.ScoreboardManager; @@ -83,9 +83,8 @@ public class ReloadCommand extends SubCommand { generatorManager.registerGenerators(); } - LevellingManager levellingManager = skyblock.getLevellingManager(); - levellingManager.unregisterMaterials(); - levellingManager.registerMaterials(); + IslandLevelManager levellingManager = skyblock.getLevellingManager(); + levellingManager.reloadWorth(); Bukkit.getScheduler().runTaskAsynchronously(skyblock, () -> { leaderboardManager.clearLeaderboard(); diff --git a/src/main/java/com/songoda/skyblock/command/commands/island/LevelCommand.java b/src/main/java/com/songoda/skyblock/command/commands/island/LevelCommand.java index a45ac8f8..ed502b2d 100644 --- a/src/main/java/com/songoda/skyblock/command/commands/island/LevelCommand.java +++ b/src/main/java/com/songoda/skyblock/command/commands/island/LevelCommand.java @@ -8,7 +8,7 @@ import com.songoda.skyblock.cooldown.CooldownPlayer; import com.songoda.skyblock.cooldown.CooldownType; import com.songoda.skyblock.island.Island; import com.songoda.skyblock.island.IslandManager; -import com.songoda.skyblock.levelling.LevellingManager; +import com.songoda.skyblock.levelling.rework.IslandLevelManager; import com.songoda.skyblock.menus.Levelling; import com.songoda.skyblock.message.MessageManager; import com.songoda.skyblock.playerdata.PlayerDataManager; @@ -31,7 +31,7 @@ public class LevelCommand extends SubCommand { @Override public void onCommandByPlayer(Player player, String[] args) { PlayerDataManager playerDataManager = skyblock.getPlayerDataManager(); - LevellingManager levellingManager = skyblock.getLevellingManager(); + IslandLevelManager levellingManager = skyblock.getLevellingManager(); CooldownManager cooldownManager = skyblock.getCooldownManager(); MessageManager messageManager = skyblock.getMessageManager(); IslandManager islandManager = skyblock.getIslandManager(); @@ -138,7 +138,7 @@ public class LevelCommand extends SubCommand { cooldownManager.createPlayer(CooldownType.Levelling, Bukkit.getServer().getOfflinePlayer(island.getOwnerUUID())); - levellingManager.calculatePoints(player, island); + levellingManager.startScan(player, island); } else { messageManager.sendMessage(player, configLoad.getString("Command.Island.Level.Loading.Message")); soundManager.playSound(player, Sounds.CHEST_OPEN.bukkitSound(), 1.0F, 1.0F); diff --git a/src/main/java/com/songoda/skyblock/command/commands/island/ValueCommand.java b/src/main/java/com/songoda/skyblock/command/commands/island/ValueCommand.java index 5c9bee82..7992e63a 100644 --- a/src/main/java/com/songoda/skyblock/command/commands/island/ValueCommand.java +++ b/src/main/java/com/songoda/skyblock/command/commands/island/ValueCommand.java @@ -3,8 +3,7 @@ package com.songoda.skyblock.command.commands.island; import com.songoda.skyblock.command.SubCommand; import com.songoda.skyblock.config.FileManager; import com.songoda.skyblock.config.FileManager.Config; -import com.songoda.skyblock.levelling.LevellingManager; -import com.songoda.skyblock.levelling.LevellingMaterial; +import com.songoda.skyblock.levelling.rework.IslandLevelManager; import com.songoda.skyblock.message.MessageManager; import com.songoda.skyblock.sound.SoundManager; import com.songoda.skyblock.utils.NumberUtil; @@ -23,7 +22,7 @@ public class ValueCommand extends SubCommand { @SuppressWarnings("deprecation") @Override public void onCommandByPlayer(Player player, String[] args) { - LevellingManager levellingManager = skyblock.getLevellingManager(); + IslandLevelManager levellingManager = skyblock.getLevellingManager(); MessageManager messageManager = skyblock.getMessageManager(); SoundManager soundManager = skyblock.getSoundManager(); FileManager fileManager = skyblock.getFileManager(); @@ -38,24 +37,18 @@ public class ValueCommand extends SubCommand { Materials materials = null; if (NMSUtil.getVersionNumber() < 13) { - materials = Materials.requestMaterials(player.getItemInHand().getType().name(), - (byte) player.getItemInHand().getDurability()); + materials = Materials.requestMaterials(player.getItemInHand().getType().name(), (byte) player.getItemInHand().getDurability()); } else { materials = Materials.fromString(player.getItemInHand().getType().name()); } - if (materials != null && levellingManager.containsMaterial(materials)) { - LevellingMaterial material = levellingManager.getMaterial(materials); - double level = (double) material.getPoints() - / (double) fileManager.getConfig(new File(skyblock.getDataFolder(), "config.yml")) - .getFileConfiguration().getInt("Island.Levelling.Division"); + if (materials != null && levellingManager.hasWorth(materials)) { + long worth = levellingManager.getWorth(materials); + double level = (double) worth / (double) fileManager.getConfig(new File(skyblock.getDataFolder(), "config.yml")).getFileConfiguration().getInt("Island.Levelling.Division"); messageManager.sendMessage(player, - configLoad.getString("Command.Island.Value.Value.Message") - .replace("%material", - WordUtils.capitalizeFully(materials.name().toLowerCase().replace("_", " "))) - .replace("%points", "" + material.getPoints()) - .replace("%level", "" + NumberUtil.formatNumberByDecimal(level))); + configLoad.getString("Command.Island.Value.Value.Message").replace("%material", WordUtils.capitalizeFully(materials.name().toLowerCase().replace("_", " "))) + .replace("%points", "" + worth).replace("%level", "" + NumberUtil.formatNumberByDecimal(level))); soundManager.playSound(player, Sounds.VILLAGER_YES.bukkitSound(), 1.0F, 1.0F); } else { messageManager.sendMessage(player, configLoad.getString("Command.Island.Value.None.Message")); diff --git a/src/main/java/com/songoda/skyblock/island/IslandManager.java b/src/main/java/com/songoda/skyblock/island/IslandManager.java index 8ae6b53c..ebeb0190 100644 --- a/src/main/java/com/songoda/skyblock/island/IslandManager.java +++ b/src/main/java/com/songoda/skyblock/island/IslandManager.java @@ -13,11 +13,11 @@ 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.World; import org.bukkit.block.Biome; import org.bukkit.block.Block; import org.bukkit.configuration.ConfigurationSection; @@ -81,18 +81,15 @@ public class IslandManager { FileConfiguration configLoad = config.getFileConfiguration(); for (IslandWorld worldList : IslandWorld.values()) { - ConfigurationSection configSection = configLoad - .getConfigurationSection("World." + worldList.name() + ".nextAvailableLocation"); - islandPositions - .add(new IslandPosition(worldList, configSection.getDouble("x"), configSection.getDouble("z"))); + ConfigurationSection configSection = configLoad.getConfigurationSection("World." + worldList.name() + ".nextAvailableLocation"); + islandPositions.add(new IslandPosition(worldList, configSection.getDouble("x"), configSection.getDouble("z"))); } for (Player all : Bukkit.getOnlinePlayers()) { loadIsland(all); } for (Island island : getIslands().values()) { - if (island.isAlwaysLoaded()) - loadIslandAtLocation(island.getLocation(IslandWorld.Normal, IslandEnvironment.Island)); + if (island.isAlwaysLoaded()) loadIslandAtLocation(island.getLocation(IslandWorld.Normal, IslandEnvironment.Island)); } } @@ -113,8 +110,7 @@ public class IslandManager { for (IslandPosition islandPositionList : islandPositions) { if (islandPositionList.getWorld() == world) { - ConfigurationSection configSection = configLoad - .createSection("World." + world.name() + ".nextAvailableLocation"); + ConfigurationSection configSection = configLoad.createSection("World." + world.name() + ".nextAvailableLocation"); configSection.set("x", islandPositionList.getX()); configSection.set("z", islandPositionList.getZ()); } @@ -166,11 +162,9 @@ public class IslandManager { FileManager fileManager = skyblock.getFileManager(); BanManager banManager = skyblock.getBanManager(); - if (fileManager.getConfig(new File(skyblock.getDataFolder(), "locations.yml")).getFileConfiguration() - .getString("Location.Spawn") == null) { + if (fileManager.getConfig(new File(skyblock.getDataFolder(), "locations.yml")).getFileConfiguration().getString("Location.Spawn") == null) { skyblock.getMessageManager().sendMessage(player, - fileManager.getConfig(new File(skyblock.getDataFolder(), "language.yml")).getFileConfiguration() - .getString("Island.Creator.Error.Message")); + fileManager.getConfig(new File(skyblock.getDataFolder(), "language.yml")).getFileConfiguration().getString("Island.Creator.Error.Message")); skyblock.getSoundManager().playSound(player, Sounds.ANVIL_LAND.bukkitSound(), 1.0F, 1.0F); return false; @@ -185,18 +179,13 @@ public class IslandManager { if (!visitManager.hasIsland(island.getOwnerUUID())) { visitManager.createIsland(island.getOwnerUUID(), - new IslandLocation[]{island.getIslandLocation(IslandWorld.Normal, IslandEnvironment.Island), - island.getIslandLocation(IslandWorld.Nether, IslandEnvironment.Island), - island.getIslandLocation(IslandWorld.End, IslandEnvironment.Island)}, - island.getSize(), - island.getRole(IslandRole.Member).size() + island.getRole(IslandRole.Operator).size() + 1, - island.getBankBalance(), - visitManager.getIslandSafeLevel(island.getOwnerUUID()), island.getLevel(), - island.getMessage(IslandMessage.Signature), island.isOpen()); + new IslandLocation[] { island.getIslandLocation(IslandWorld.Normal, IslandEnvironment.Island), island.getIslandLocation(IslandWorld.Nether, IslandEnvironment.Island), + island.getIslandLocation(IslandWorld.End, IslandEnvironment.Island) }, + island.getSize(), island.getRole(IslandRole.Member).size() + island.getRole(IslandRole.Operator).size() + 1, island.getBankBalance(), + visitManager.getIslandSafeLevel(island.getOwnerUUID()), island.getLevel(), island.getMessage(IslandMessage.Signature), island.isOpen()); } - if (!banManager.hasIsland(island.getOwnerUUID())) - banManager.createIsland(island.getOwnerUUID()); + if (!banManager.hasIsland(island.getOwnerUUID())) banManager.createIsland(island.getOwnerUUID()); Bukkit.getServer().getScheduler().runTaskAsynchronously(skyblock, () -> { Config config = fileManager.getConfig(new File(skyblock.getDataFolder(), "config.yml")); @@ -216,7 +205,6 @@ public class IslandManager { for (int i = maximumSize; i > minimumSize; i--) { if (player.hasPermission("fabledskyblock.size." + i) || player.hasPermission("fabledskyblock.*")) { island.setSize(i); - break; } } @@ -225,14 +213,11 @@ public class IslandManager { Config config = fileManager.getConfig(new File(skyblock.getDataFolder(), "config.yml")); FileConfiguration configLoad = config.getFileConfiguration(); - if (configLoad.getBoolean("Island.Creation.Cooldown.Creation.Enable") - && !player.hasPermission("fabledskyblock.bypass.cooldown") - && !player.hasPermission("fabledskyblock.bypass.*") + if (configLoad.getBoolean("Island.Creation.Cooldown.Creation.Enable") && !player.hasPermission("fabledskyblock.bypass.cooldown") && !player.hasPermission("fabledskyblock.bypass.*") && !player.hasPermission("fabledskyblock.*")) skyblock.getCooldownManager().createPlayer(CooldownType.Creation, player); - Bukkit.getScheduler().runTaskAsynchronously(skyblock, () -> - Bukkit.getServer().getPluginManager().callEvent(new IslandCreateEvent(island.getAPIWrapper(), player))); + Bukkit.getScheduler().runTaskAsynchronously(skyblock, () -> Bukkit.getServer().getPluginManager().callEvent(new IslandCreateEvent(island.getAPIWrapper(), player))); skyblock.getPlayerDataManager().getPlayerData(player).setIsland(player.getUniqueId()); @@ -240,8 +225,7 @@ public class IslandManager { Config languageConfig = fileManager.getConfig(new File(skyblock.getDataFolder(), "language.yml")); Scoreboard scoreboard = scoreboardManager.getScoreboard(player); - scoreboard.setDisplayName(ChatColor.translateAlternateColorCodes('&', - languageConfig.getFileConfiguration().getString("Scoreboard.Island.Solo.Displayname"))); + scoreboard.setDisplayName(ChatColor.translateAlternateColorCodes('&', languageConfig.getFileConfiguration().getString("Scoreboard.Island.Solo.Displayname"))); scoreboard.setDisplayList(languageConfig.getFileConfiguration().getStringList("Scoreboard.Island.Solo.Empty.Displaylines")); scoreboard.run(); } @@ -249,8 +233,7 @@ public class IslandManager { Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(skyblock, () -> { if (structure.getCommands() != null) { for (String commandList : structure.getCommands()) { - Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), - commandList.replace("%player", player.getName())); + Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), commandList.replace("%player", player.getName())); } } @@ -258,9 +241,7 @@ public class IslandManager { player.setFallDistance(0.0F); }, configLoad.getInt("Island.Creation.TeleportTimeout") * 20); - String biomeName = fileManager - .getConfig(new File(skyblock.getDataFolder(), "config.yml")).getFileConfiguration() - .getString("Island.Biome.Default.Type").toUpperCase(); + String biomeName = fileManager.getConfig(new File(skyblock.getDataFolder(), "config.yml")).getFileConfiguration().getString("Island.Biome.Default.Type").toUpperCase(); SBiome sBiome; try { sBiome = SBiome.valueOf(biomeName); @@ -269,12 +250,11 @@ public class IslandManager { } Biome biome = sBiome.getBiome(); - Bukkit.getServer().getScheduler().runTaskLater(skyblock, () -> skyblock.getBiomeManager() - .setBiome(island, biome), 20L); + Bukkit.getServer().getScheduler().runTaskLater(skyblock, () -> skyblock.getBiomeManager().setBiome(island, biome), 20L); // Recalculate island level after 5 seconds if (configLoad.getBoolean("Island.Levelling.ScanAutomatically")) - Bukkit.getServer().getScheduler().runTaskLater(skyblock, () -> skyblock.getLevellingManager().calculatePoints(null, island), 100L); + Bukkit.getServer().getScheduler().runTaskLater(skyblock, () -> skyblock.getLevellingManager().startScan(null, island), 100L); return true; } @@ -288,8 +268,7 @@ public class IslandManager { return; } - if (island.hasRole(IslandRole.Member, player.getUniqueId()) - || island.hasRole(IslandRole.Operator, player.getUniqueId())) { + if (island.hasRole(IslandRole.Member, player.getUniqueId()) || island.hasRole(IslandRole.Operator, player.getUniqueId())) { UUID uuid2 = island.getOwnerUUID(); island.save(); @@ -307,40 +286,32 @@ public class IslandManager { island.setPassword(null); } - File oldCoopDataFile = new File(new File(skyblock.getDataFolder().toString() + "/coop-data"), - uuid2.toString() + ".yml"); + File oldCoopDataFile = new File(new File(skyblock.getDataFolder().toString() + "/coop-data"), uuid2.toString() + ".yml"); fileManager.unloadConfig(oldCoopDataFile); if (fileManager.isFileExist(oldCoopDataFile)) { - File newCoopDataFile = new File(new File(skyblock.getDataFolder().toString() + "/coop-data"), - player.getUniqueId().toString() + ".yml"); + File newCoopDataFile = new File(new File(skyblock.getDataFolder().toString() + "/coop-data"), player.getUniqueId().toString() + ".yml"); fileManager.unloadConfig(newCoopDataFile); oldCoopDataFile.renameTo(newCoopDataFile); } - File oldLevelDataFile = new File(new File(skyblock.getDataFolder().toString() + "/level-data"), - uuid2.toString() + ".yml"); - File newLevelDataFile = new File(new File(skyblock.getDataFolder().toString() + "/level-data"), - player.getUniqueId().toString() + ".yml"); + File oldLevelDataFile = new File(new File(skyblock.getDataFolder().toString() + "/level-data"), uuid2.toString() + ".yml"); + File newLevelDataFile = new File(new File(skyblock.getDataFolder().toString() + "/level-data"), player.getUniqueId().toString() + ".yml"); fileManager.unloadConfig(oldLevelDataFile); fileManager.unloadConfig(newLevelDataFile); oldLevelDataFile.renameTo(newLevelDataFile); - File oldSettingDataFile = new File(new File(skyblock.getDataFolder().toString() + "/setting-data"), - uuid2.toString() + ".yml"); - File newSettingDataFile = new File(new File(skyblock.getDataFolder().toString() + "/setting-data"), - player.getUniqueId().toString() + ".yml"); + File oldSettingDataFile = new File(new File(skyblock.getDataFolder().toString() + "/setting-data"), uuid2.toString() + ".yml"); + File newSettingDataFile = new File(new File(skyblock.getDataFolder().toString() + "/setting-data"), player.getUniqueId().toString() + ".yml"); fileManager.unloadConfig(oldSettingDataFile); fileManager.unloadConfig(newSettingDataFile); oldSettingDataFile.renameTo(newSettingDataFile); - File oldIslandDataFile = new File(new File(skyblock.getDataFolder().toString() + "/island-data"), - uuid2.toString() + ".yml"); - File newIslandDataFile = new File(new File(skyblock.getDataFolder().toString() + "/island-data"), - player.getUniqueId().toString() + ".yml"); + File oldIslandDataFile = new File(new File(skyblock.getDataFolder().toString() + "/island-data"), uuid2.toString() + ".yml"); + File newIslandDataFile = new File(new File(skyblock.getDataFolder().toString() + "/island-data"), player.getUniqueId().toString() + ".yml"); fileManager.unloadConfig(oldIslandDataFile); fileManager.unloadConfig(newIslandDataFile); @@ -370,8 +341,7 @@ public class IslandManager { removeIsland(uuid2); islandStorage.put(player.getUniqueId(), island); - Bukkit.getServer().getPluginManager() - .callEvent(new IslandOwnershipTransferEvent(island.getAPIWrapper(), player)); + Bukkit.getServer().getPluginManager().callEvent(new IslandOwnershipTransferEvent(island.getAPIWrapper(), player)); ArrayList islandMembers = new ArrayList<>(); islandMembers.addAll(island.getRole(IslandRole.Member)); @@ -382,8 +352,7 @@ public class IslandManager { Player targetPlayer = Bukkit.getServer().getPlayer(islandMemberList); if (targetPlayer == null) { - File configFile = new File(new File(skyblock.getDataFolder().toString() + "/player-data"), - islandMemberList.toString() + ".yml"); + File configFile = new File(new File(skyblock.getDataFolder().toString() + "/player-data"), islandMemberList.toString() + ".yml"); configLoad = YamlConfiguration.loadConfiguration(configFile); configLoad.set("Island.Owner", player.getUniqueId().toString()); @@ -403,7 +372,7 @@ public class IslandManager { } int j = 0; - + public void deleteIsland(Island island) { ScoreboardManager scoreboardManager = skyblock.getScoreboardManager(); PlayerDataManager playerDataManager = skyblock.getPlayerDataManager(); @@ -412,22 +381,25 @@ public class IslandManager { WorldManager worldManager = skyblock.getWorldManager(); // Delete island from world. - long i = 0; + + final Map> snapshots = new HashMap<>(3); + for (IslandWorld worldList : IslandWorld.getIslandWorlds()) { - Bukkit.getScheduler().runTaskLater(skyblock, () -> { - org.bukkit.World world = worldManager.getWorld(worldList); - Location location = island.getLocation(worldList, IslandEnvironment.Island); - if (location == null) return; + final Location location = island.getLocation(worldList, IslandEnvironment.Island); - 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()); + if (location == null) continue; - ChunkDeleteSplitter.startDeleting(world, snapshots); - }, i); - i += 20L; + final World world = worldManager.getWorld(worldList); + + final List list = com.songoda.skyblock.levelling.ChunkUtil.getChunksToScan(island, worldList).stream().map(chunk -> chunk.getChunkSnapshot()) + .collect(Collectors.toList()); + + snapshots.put(world, list); } + ChunkDeleteSplitter.startDeletion(snapshots); + skyblock.getVisitManager().deleteIsland(island.getOwnerUUID()); skyblock.getBanManager().deleteIsland(island.getOwnerUUID()); skyblock.getVisitManager().removeVisitors(island, VisitManager.Removal.Deleted); @@ -445,9 +417,8 @@ public class IslandManager { configLoad = config.getFileConfiguration(); for (Player all : Bukkit.getOnlinePlayers()) { - if ((island.hasRole(IslandRole.Member, all.getUniqueId()) - || island.hasRole(IslandRole.Operator, all.getUniqueId()) - || island.hasRole(IslandRole.Owner, all.getUniqueId())) && playerDataManager.hasPlayerData(all)) { + if ((island.hasRole(IslandRole.Member, all.getUniqueId()) || island.hasRole(IslandRole.Operator, all.getUniqueId()) || island.hasRole(IslandRole.Owner, all.getUniqueId())) + && playerDataManager.hasPlayerData(all)) { PlayerData playerData = playerDataManager.getPlayerData(all); playerData.setOwner(null); playerData.setMemberSince(null); @@ -456,8 +427,7 @@ public class IslandManager { if (scoreboardManager != null) { Scoreboard scoreboard = scoreboardManager.getScoreboard(all); - scoreboard.setDisplayName(ChatColor.translateAlternateColorCodes('&', - configLoad.getString("Scoreboard.Tutorial.Displayname"))); + scoreboard.setDisplayName(ChatColor.translateAlternateColorCodes('&', configLoad.getString("Scoreboard.Tutorial.Displayname"))); scoreboard.setDisplayList(configLoad.getStringList("Scoreboard.Tutorial.Displaylines")); scoreboard.run(); } @@ -467,8 +437,7 @@ public class IslandManager { } if (cooldownEnabled) { - if (!all.hasPermission("fabledskyblock.bypass.cooldown") && !all.hasPermission("fabledskyblock.bypass.*") - && !all.hasPermission("fabledskyblock.*")) { + if (!all.hasPermission("fabledskyblock.bypass.cooldown") && !all.hasPermission("fabledskyblock.bypass.*") && !all.hasPermission("fabledskyblock.*")) { skyblock.getCooldownManager().createPlayer(CooldownType.Creation, all); } } @@ -485,14 +454,10 @@ public class IslandManager { } } - fileManager.deleteConfig(new File(new File(skyblock.getDataFolder().toString() + "/coop-data"), - island.getOwnerUUID().toString() + ".yml")); - fileManager.deleteConfig(new File(new File(skyblock.getDataFolder().toString() + "/level-data"), - island.getOwnerUUID().toString() + ".yml")); - fileManager.deleteConfig(new File(new File(skyblock.getDataFolder().toString() + "/setting-data"), - island.getOwnerUUID().toString() + ".yml")); - fileManager.deleteConfig(new File(new File(skyblock.getDataFolder().toString() + "/island-data"), - island.getOwnerUUID().toString() + ".yml")); + fileManager.deleteConfig(new File(new File(skyblock.getDataFolder().toString() + "/coop-data"), island.getOwnerUUID().toString() + ".yml")); + fileManager.deleteConfig(new File(new File(skyblock.getDataFolder().toString() + "/level-data"), island.getOwnerUUID().toString() + ".yml")); + fileManager.deleteConfig(new File(new File(skyblock.getDataFolder().toString() + "/setting-data"), island.getOwnerUUID().toString() + ".yml")); + fileManager.deleteConfig(new File(new File(skyblock.getDataFolder().toString() + "/island-data"), island.getOwnerUUID().toString() + ".yml")); Bukkit.getServer().getPluginManager().callEvent(new IslandDeleteEvent(island.getAPIWrapper())); @@ -501,17 +466,12 @@ public class IslandManager { public void deleteIslandData(UUID uuid) { FileManager fileManager = skyblock.getFileManager(); - fileManager - .deleteConfig(new File(skyblock.getDataFolder().toString() + "/island-data", uuid.toString() + ".yml")); + fileManager.deleteConfig(new File(skyblock.getDataFolder().toString() + "/island-data", uuid.toString() + ".yml")); fileManager.deleteConfig(new File(skyblock.getDataFolder().toString() + "/ban-data", uuid.toString() + ".yml")); - fileManager - .deleteConfig(new File(skyblock.getDataFolder().toString() + "/coop-data", uuid.toString() + ".yml")); - fileManager - .deleteConfig(new File(skyblock.getDataFolder().toString() + "/level-data", uuid.toString() + ".yml")); - fileManager.deleteConfig( - new File(skyblock.getDataFolder().toString() + "/setting-data", uuid.toString() + ".yml")); - fileManager - .deleteConfig(new File(skyblock.getDataFolder().toString() + "/visit-data", uuid.toString() + ".yml")); + fileManager.deleteConfig(new File(skyblock.getDataFolder().toString() + "/coop-data", uuid.toString() + ".yml")); + fileManager.deleteConfig(new File(skyblock.getDataFolder().toString() + "/level-data", uuid.toString() + ".yml")); + fileManager.deleteConfig(new File(skyblock.getDataFolder().toString() + "/setting-data", uuid.toString() + ".yml")); + fileManager.deleteConfig(new File(skyblock.getDataFolder().toString() + "/visit-data", uuid.toString() + ".yml")); } public Island loadIsland(org.bukkit.OfflinePlayer player) { @@ -521,13 +481,11 @@ public class IslandManager { UUID islandOwnerUUID = null; - Config config = fileManager.getConfig(new File(new File(skyblock.getDataFolder().toString() + "/player-data"), - player.getUniqueId().toString() + ".yml")); + Config config = fileManager.getConfig(new File(new File(skyblock.getDataFolder().toString() + "/player-data"), player.getUniqueId().toString() + ".yml")); FileConfiguration configLoad = config.getFileConfiguration(); if (isIslandExist(player.getUniqueId())) { - if (configLoad.getString("Island.Owner") == null - || !configLoad.getString("Island.Owner").equals(player.getUniqueId().toString())) { + if (configLoad.getString("Island.Owner") == null || !configLoad.getString("Island.Owner").equals(player.getUniqueId().toString())) { deleteIslandData(player.getUniqueId()); configLoad.set("Island.Owner", null); @@ -545,8 +503,7 @@ public class IslandManager { if (containsIsland(islandOwnerUUID)) { return getIsland(player); } else { - config = fileManager.getConfig(new File(skyblock.getDataFolder().toString() + "/island-data", - islandOwnerUUID.toString() + ".yml")); + config = fileManager.getConfig(new File(skyblock.getDataFolder().toString() + "/island-data", islandOwnerUUID.toString() + ".yml")); if (config.getFileConfiguration().getString("Location") == null) { deleteIslandData(islandOwnerUUID); @@ -564,15 +521,10 @@ public class IslandManager { if (!visitManager.hasIsland(island.getOwnerUUID())) { visitManager.createIsland(island.getOwnerUUID(), - new IslandLocation[]{ - island.getIslandLocation(IslandWorld.Normal, IslandEnvironment.Island), - island.getIslandLocation(IslandWorld.Nether, IslandEnvironment.Island), - island.getIslandLocation(IslandWorld.End, IslandEnvironment.Island)}, - island.getSize(), - island.getRole(IslandRole.Member).size() + island.getRole(IslandRole.Operator).size() + 1, - island.getBankBalance(), - visitManager.getIslandSafeLevel(island.getOwnerUUID()), island.getLevel(), - island.getMessage(IslandMessage.Signature), island.isOpen()); + new IslandLocation[] { island.getIslandLocation(IslandWorld.Normal, IslandEnvironment.Island), + island.getIslandLocation(IslandWorld.Nether, IslandEnvironment.Island), island.getIslandLocation(IslandWorld.End, IslandEnvironment.Island) }, + island.getSize(), island.getRole(IslandRole.Member).size() + island.getRole(IslandRole.Operator).size() + 1, island.getBankBalance(), + visitManager.getIslandSafeLevel(island.getOwnerUUID()), island.getLevel(), island.getMessage(IslandMessage.Signature), island.isOpen()); } if (!banManager.hasIsland(island.getOwnerUUID())) { @@ -592,8 +544,7 @@ public class IslandManager { FileManager fileManager = skyblock.getFileManager(); File configFile = new File(skyblock.getDataFolder().toString() + "/island-data"); - if (!configFile.exists()) - return null; + if (!configFile.exists()) return null; for (File fileList : configFile.listFiles()) { if (fileList != null && fileList.getName().contains(".yml") && fileList.getName().length() > 35) { @@ -632,10 +583,8 @@ public class IslandManager { if (island.isDeleted()) return; island.save(); - - int islandMembers = island.getRole(IslandRole.Member).size() + island.getRole(IslandRole.Operator).size() + 1, - islandVisitors = getVisitorsAtIsland(island).size(); + int islandMembers = island.getRole(IslandRole.Member).size() + island.getRole(IslandRole.Operator).size() + 1, islandVisitors = getVisitorsAtIsland(island).size(); boolean unloadIsland = true; for (Player all : Bukkit.getOnlinePlayers()) { @@ -643,29 +592,23 @@ public class IslandManager { continue; } - if (island.hasRole(IslandRole.Member, all.getUniqueId()) - || island.hasRole(IslandRole.Operator, all.getUniqueId()) - || island.hasRole(IslandRole.Owner, all.getUniqueId()) || island.getCoopType(all.getUniqueId()) == IslandCoop.NORMAL) { + if (island.hasRole(IslandRole.Member, all.getUniqueId()) || island.hasRole(IslandRole.Operator, all.getUniqueId()) || island.hasRole(IslandRole.Owner, all.getUniqueId()) + || island.getCoopType(all.getUniqueId()) == IslandCoop.NORMAL) { if (scoreboardManager != null) { try { if (islandMembers == 1 && islandVisitors == 0) { Scoreboard scoreboard = scoreboardManager.getScoreboard(all); - scoreboard.setDisplayName(ChatColor.translateAlternateColorCodes('&', - configLoad.getString("Scoreboard.Island.Solo.Displayname"))); - scoreboard.setDisplayList( - configLoad.getStringList("Scoreboard.Island.Solo.Empty.Displaylines")); + scoreboard.setDisplayName(ChatColor.translateAlternateColorCodes('&', configLoad.getString("Scoreboard.Island.Solo.Displayname"))); + scoreboard.setDisplayList(configLoad.getStringList("Scoreboard.Island.Solo.Empty.Displaylines")); scoreboard.run(); } else if (islandVisitors == 0) { Scoreboard scoreboard = scoreboardManager.getScoreboard(all); - scoreboard.setDisplayName(ChatColor.translateAlternateColorCodes('&', - configLoad.getString("Scoreboard.Island.Team.Displayname"))); - scoreboard.setDisplayList( - configLoad.getStringList("Scoreboard.Island.Team.Empty.Displaylines")); + scoreboard.setDisplayName(ChatColor.translateAlternateColorCodes('&', configLoad.getString("Scoreboard.Island.Team.Displayname"))); + scoreboard.setDisplayList(configLoad.getStringList("Scoreboard.Island.Team.Empty.Displaylines")); HashMap displayVariables = new HashMap<>(); displayVariables.put("%owner", configLoad.getString("Scoreboard.Island.Team.Word.Owner")); - displayVariables.put("%operator", - configLoad.getString("Scoreboard.Island.Team.Word.Operator")); + displayVariables.put("%operator", configLoad.getString("Scoreboard.Island.Team.Word.Operator")); displayVariables.put("%member", configLoad.getString("Scoreboard.Island.Team.Word.Member")); scoreboard.setDisplayVariables(displayVariables); @@ -683,8 +626,7 @@ public class IslandManager { return; } - unloadIsland = fileManager.getConfig(new File(skyblock.getDataFolder(), "config.yml")).getFileConfiguration() - .getBoolean("Island.Visitor.Unload"); + unloadIsland = fileManager.getConfig(new File(skyblock.getDataFolder(), "config.yml")).getFileConfiguration().getBoolean("Island.Visitor.Unload"); if (unloadIsland) { VisitManager visitManager = skyblock.getVisitManager(); @@ -707,12 +649,9 @@ public class IslandManager { } } - fileManager.unloadConfig( - new File(new File(skyblock.getDataFolder().toString() + "/coop-data"), island.getOwnerUUID() + ".yml")); - fileManager.unloadConfig(new File(new File(skyblock.getDataFolder().toString() + "/setting-data"), - island.getOwnerUUID() + ".yml")); - fileManager.unloadConfig(new File(new File(skyblock.getDataFolder().toString() + "/island-data"), - island.getOwnerUUID() + ".yml")); + fileManager.unloadConfig(new File(new File(skyblock.getDataFolder().toString() + "/coop-data"), island.getOwnerUUID() + ".yml")); + fileManager.unloadConfig(new File(new File(skyblock.getDataFolder().toString() + "/setting-data"), island.getOwnerUUID() + ".yml")); + fileManager.unloadConfig(new File(new File(skyblock.getDataFolder().toString() + "/island-data"), island.getOwnerUUID() + ".yml")); islandStorage.remove(island.getOwnerUUID()); @@ -734,18 +673,15 @@ public class IslandManager { org.bukkit.Location location; if (environmentList == IslandEnvironment.Island) { - location = fileManager.getLocation(config, - "Location." + world.name() + "." + environmentList.name(), true); + location = fileManager.getLocation(config, "Location." + world.name() + "." + environmentList.name(), true); } else { - location = fileManager.getLocation(config, - "Location." + world.name() + ".Spawn." + environmentList.name(), true); + location = fileManager.getLocation(config, "Location." + world.name() + ".Spawn." + environmentList.name(), true); } island.addLocation(world, environmentList, worldManager.getLocation(location, world)); } - Bukkit.getServer().getScheduler().runTask(skyblock, - () -> removeSpawnProtection(island.getLocation(world, IslandEnvironment.Island))); + Bukkit.getServer().getScheduler().runTask(skyblock, () -> removeSpawnProtection(island.getLocation(world, IslandEnvironment.Island))); } public void resetIsland(Island island) { @@ -757,8 +693,7 @@ public class IslandManager { } public void pasteStructure(Island island, IslandWorld world) { - if (!isIslandWorldUnlocked(island, world)) - return; + if (!isIslandWorldUnlocked(island, world)) return; StructureManager structureManager = skyblock.getStructureManager(); FileManager fileManager = skyblock.getFileManager(); @@ -773,8 +708,7 @@ public class IslandManager { org.bukkit.Location islandLocation = prepareNextAvailableLocation(world); - Config config = fileManager.getConfig( - new File(skyblock.getDataFolder().toString() + "/island-data", island.getOwnerUUID() + ".yml")); + Config config = fileManager.getConfig(new File(skyblock.getDataFolder().toString() + "/island-data", island.getOwnerUUID() + ".yml")); for (IslandEnvironment environmentList : IslandEnvironment.values()) { if (environmentList == IslandEnvironment.Island) { @@ -793,15 +727,15 @@ public class IslandManager { try { String structureFileName = null; switch (world) { - case Normal: - structureFileName = structure.getOverworldFile(); - break; - case Nether: - structureFileName = structure.getNetherFile(); - break; - case End: - structureFileName = structure.getEndFile(); - break; + case Normal: + structureFileName = structure.getOverworldFile(); + break; + case Nether: + structureFileName = structure.getNetherFile(); + break; + case End: + structureFileName = structure.getEndFile(); + break; } boolean isStructureFile = structureFileName.endsWith(".structure"); @@ -809,8 +743,7 @@ public class IslandManager { Float[] direction; if (isStructureFile) { - direction = StructureUtil.pasteStructure(StructureUtil.loadStructure(structureFile), - island.getLocation(world, IslandEnvironment.Island), BlockDegreesType.ROTATE_360); + direction = StructureUtil.pasteStructure(StructureUtil.loadStructure(structureFile), island.getLocation(world, IslandEnvironment.Island), BlockDegreesType.ROTATE_360); } else { direction = SchematicUtil.pasteSchematic(structureFile, island.getLocation(world, IslandEnvironment.Island)); } @@ -836,9 +769,7 @@ public class IslandManager { */ public void unlockIslandWorld(Island island, IslandWorld islandWorld) { FileManager fileManager = skyblock.getFileManager(); - Config islandData = fileManager - .getConfig(new File(new File(skyblock.getDataFolder().toString() + "/island-data"), - island.getOwnerUUID().toString() + ".yml")); + Config islandData = fileManager.getConfig(new File(new File(skyblock.getDataFolder().toString() + "/island-data"), island.getOwnerUUID().toString() + ".yml")); FileConfiguration configLoadIslandData = islandData.getFileConfiguration(); configLoadIslandData.set("Unlocked." + islandWorld.name(), true); @@ -847,7 +778,7 @@ public class IslandManager { // Recalculate island level after 5 seconds if (fileManager.getConfig(new File(this.skyblock.getDataFolder(), "config.yml")).getFileConfiguration().getBoolean("Island.Levelling.ScanAutomatically")) { - Bukkit.getServer().getScheduler().runTaskLater(skyblock, () -> skyblock.getLevellingManager().calculatePoints(null, island), 100L); + Bukkit.getServer().getScheduler().runTaskLater(skyblock, () -> skyblock.getLevellingManager().startScan(null, island), 100L); } } @@ -859,13 +790,10 @@ public class IslandManager { * @return true if the island world is unlocked, otherwise false */ public boolean isIslandWorldUnlocked(Island island, IslandWorld islandWorld) { - if (islandWorld == IslandWorld.Normal) - return true; + if (islandWorld == IslandWorld.Normal) return true; FileManager fileManager = skyblock.getFileManager(); - Config islandData = fileManager - .getConfig(new File(new File(skyblock.getDataFolder().toString() + "/island-data"), - island.getOwnerUUID().toString() + ".yml")); + Config islandData = fileManager.getConfig(new File(new File(skyblock.getDataFolder().toString() + "/island-data"), island.getOwnerUUID().toString() + ".yml")); FileConfiguration configLoadIslandData = islandData.getFileConfiguration(); boolean unlocked = configLoadIslandData.getBoolean("Unlocked." + islandWorld.name()); @@ -873,8 +801,7 @@ public class IslandManager { Config config = fileManager.getConfig(new File(skyblock.getDataFolder(), "config.yml")); FileConfiguration configLoad = config.getFileConfiguration(); double price = configLoad.getDouble("Island.World." + islandWorld.name() + ".UnlockPrice"); - if (price == -1) - unlocked = true; + if (price == -1) unlocked = true; } return unlocked; @@ -907,43 +834,31 @@ public class IslandManager { Config languageConfig = fileManager.getConfig(new File(skyblock.getDataFolder(), "language.yml")); FileConfiguration configLoad = languageConfig.getFileConfiguration(); - if (island.hasRole(IslandRole.Member, player.getUniqueId()) - || island.hasRole(IslandRole.Operator, player.getUniqueId()) - || island.hasRole(IslandRole.Owner, player.getUniqueId())) { + if (island.hasRole(IslandRole.Member, player.getUniqueId()) || island.hasRole(IslandRole.Operator, player.getUniqueId()) || island.hasRole(IslandRole.Owner, player.getUniqueId())) { player.teleport(island.getLocation(IslandWorld.Normal, IslandEnvironment.Visitor)); player.setFallDistance(0.0F); } else { if (scoreboardManager != null) { - int islandVisitors = getVisitorsAtIsland(island).size(), - islandMembers = island.getRole(IslandRole.Member).size() - + island.getRole(IslandRole.Operator).size() + 1; + int islandVisitors = getVisitorsAtIsland(island).size(), islandMembers = island.getRole(IslandRole.Member).size() + island.getRole(IslandRole.Operator).size() + 1; if (islandVisitors == 0) { for (Player all : Bukkit.getOnlinePlayers()) { PlayerData targetPlayerData = skyblock.getPlayerDataManager().getPlayerData(all); - if (targetPlayerData.getOwner() != null - && targetPlayerData.getOwner().equals(island.getOwnerUUID())) { + if (targetPlayerData.getOwner() != null && targetPlayerData.getOwner().equals(island.getOwnerUUID())) { Scoreboard scoreboard = scoreboardManager.getScoreboard(all); if (islandMembers == 1) { - scoreboard.setDisplayName(ChatColor.translateAlternateColorCodes('&', - configLoad.getString("Scoreboard.Island.Solo.Displayname"))); - scoreboard.setDisplayList( - configLoad.getStringList("Scoreboard.Island.Solo.Occupied.Displaylines")); + scoreboard.setDisplayName(ChatColor.translateAlternateColorCodes('&', configLoad.getString("Scoreboard.Island.Solo.Displayname"))); + scoreboard.setDisplayList(configLoad.getStringList("Scoreboard.Island.Solo.Occupied.Displaylines")); } else { - scoreboard.setDisplayName(ChatColor.translateAlternateColorCodes('&', - configLoad.getString("Scoreboard.Island.Team.Displayname"))); - scoreboard.setDisplayList( - configLoad.getStringList("Scoreboard.Island.Team.Occupied.Displaylines")); + scoreboard.setDisplayName(ChatColor.translateAlternateColorCodes('&', configLoad.getString("Scoreboard.Island.Team.Displayname"))); + scoreboard.setDisplayList(configLoad.getStringList("Scoreboard.Island.Team.Occupied.Displaylines")); HashMap displayVariables = new HashMap<>(); - displayVariables.put("%owner", - configLoad.getString("Scoreboard.Island.Team.Word.Owner")); - displayVariables.put("%operator", - configLoad.getString("Scoreboard.Island.Team.Word.Operator")); - displayVariables.put("%member", - configLoad.getString("Scoreboard.Island.Team.Word.Member")); + displayVariables.put("%owner", configLoad.getString("Scoreboard.Island.Team.Word.Owner")); + displayVariables.put("%operator", configLoad.getString("Scoreboard.Island.Team.Word.Operator")); + displayVariables.put("%member", configLoad.getString("Scoreboard.Island.Team.Word.Member")); scoreboard.setDisplayVariables(displayVariables); } @@ -961,8 +876,7 @@ public class IslandManager { List islandWelcomeMessage = island.getMessage(IslandMessage.Welcome); - if (skyblock.getFileManager().getConfig(new File(skyblock.getDataFolder(), "config.yml")) - .getFileConfiguration().getBoolean("Island.Visitor.Welcome.Enable") + if (skyblock.getFileManager().getConfig(new File(skyblock.getDataFolder(), "config.yml")).getFileConfiguration().getBoolean("Island.Visitor.Welcome.Enable") && islandWelcomeMessage.size() != 0) { for (String islandWelcomeMessageList : islandWelcomeMessage) { player.sendMessage(ChatColor.translateAlternateColorCodes('&', islandWelcomeMessageList)); @@ -995,8 +909,7 @@ public class IslandManager { if (!island.isCoopPlayer(visitorList)) { Player targetPlayer = Bukkit.getServer().getPlayer(visitorList); LocationUtil.teleportPlayerToSpawn(targetPlayer); - messageManager.sendMessage(targetPlayer, configLoad.getString("Island.Visit.Closed.Island.Message") - .replace("%player", islandOwnerPlayerName)); + messageManager.sendMessage(targetPlayer, configLoad.getString("Island.Visit.Closed.Island.Message").replace("%player", islandOwnerPlayerName)); } } } @@ -1005,10 +918,10 @@ public class IslandManager { PlayerDataManager playerDataManager = skyblock.getPlayerDataManager(); UUID uuid = offlinePlayer.getUniqueId(); - if (islandProxies.containsKey(uuid)) - uuid = islandProxies.get(uuid); + if (islandProxies.containsKey(uuid)) uuid = islandProxies.get(uuid); - // TODO: Find out how this can be fixed without this, for some reason IslandManager tries to load PlayerDataManager before it's even loaded + // TODO: Find out how this can be fixed without this, for some reason + // IslandManager tries to load PlayerDataManager before it's even loaded if (playerDataManager == null) return null; if (islandStorage.containsKey(uuid)) { @@ -1054,8 +967,7 @@ public class IslandManager { } public boolean isIslandExist(UUID uuid) { - return skyblock.getFileManager().isFileExist( - new File(new File(skyblock.getDataFolder().toString() + "/island-data"), uuid.toString() + ".yml")); + return skyblock.getFileManager().isFileExist(new File(new File(skyblock.getDataFolder().toString() + "/island-data"), uuid.toString() + ".yml")); } /* @@ -1088,25 +1000,20 @@ public class IslandManager { public boolean hasPermission(Player player, org.bukkit.Location location, String setting) { Island island = getIslandAtLocation(location); - if (island == null) - return true; + if (island == null) return true; - if (player.hasPermission("fabledskyblock.bypass." + setting.toLowerCase())) - return true; + if (player.hasPermission("fabledskyblock.bypass." + setting.toLowerCase())) return true; - if (island.getSetting(island.getRole(player), setting).getStatus()) - return true; + if (island.getSetting(island.getRole(player), setting).getStatus()) return true; - if (island.isCoopPlayer(player.getUniqueId()) && island.getSetting(IslandRole.Coop, setting).getStatus()) - return true; + if (island.isCoopPlayer(player.getUniqueId()) && island.getSetting(IslandRole.Coop, setting).getStatus()) return true; return island.getSetting(IslandRole.Visitor, setting).getStatus(); } public boolean hasSetting(org.bukkit.Location location, IslandRole role, String setting) { Island island = getIslandAtLocation(location); - if (island == null) - return false; + if (island == null) return false; return island.getSetting(role, setting).getStatus(); } @@ -1129,9 +1036,7 @@ public class IslandManager { Set membersOnline = new HashSet<>(); for (Player all : Bukkit.getOnlinePlayers()) { - if (island.hasRole(IslandRole.Member, all.getUniqueId()) - || island.hasRole(IslandRole.Operator, all.getUniqueId()) - || island.hasRole(IslandRole.Owner, all.getUniqueId())) { + if (island.hasRole(IslandRole.Member, all.getUniqueId()) || island.hasRole(IslandRole.Operator, all.getUniqueId()) || island.hasRole(IslandRole.Owner, all.getUniqueId())) { membersOnline.add(all.getUniqueId()); } } @@ -1205,8 +1110,7 @@ public class IslandManager { Island island = getIslandAtLocation(player.getLocation()); if (island != null) { - Config config = skyblock.getFileManager() - .getConfig(new File(skyblock.getDataFolder(), "config.yml")); + Config config = skyblock.getFileManager().getConfig(new File(skyblock.getDataFolder(), "config.yml")); FileConfiguration configLoad = config.getFileConfiguration(); if (!island.isWeatherSynchronized()) { @@ -1223,12 +1127,9 @@ public class IslandManager { } if (configLoad.getBoolean("Island.WorldBorder.Enable") && island.isBorder()) { - WorldBorder.send(player, island.getBorderColor(), island.getSize(), - island.getLocation(worldManager.getIslandWorld(player.getWorld()), - IslandEnvironment.Island)); + WorldBorder.send(player, island.getBorderColor(), island.getSize(), island.getLocation(worldManager.getIslandWorld(player.getWorld()), IslandEnvironment.Island)); } else { - WorldBorder.send(player, null, 1.4999992E7D, - new org.bukkit.Location(player.getWorld(), 0, 0, 0)); + WorldBorder.send(player, null, 1.4999992E7D, new org.bukkit.Location(player.getWorld(), 0, 0, 0)); } } } @@ -1241,9 +1142,9 @@ public class IslandManager { } public void updateFlight(Player player) { - // The player can fly in other worlds if they are in creative or have another plugin's fly permission. - if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR - || player.hasPermission("essentials.fly") || player.hasPermission("cmi.command.fly")) + // The player can fly in other worlds if they are in creative or have another + // plugin's fly permission. + if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR || player.hasPermission("essentials.fly") || player.hasPermission("cmi.command.fly")) return; Island island = getIslandAtLocation(player.getLocation()); @@ -1258,8 +1159,7 @@ public class IslandManager { Bukkit.getServer().getScheduler().runTask(skyblock, () -> player.setAllowFlight(upgradeEnabled)); } - if (island == null || setPlayerFlying) - return; + if (island == null || setPlayerFlying) return; boolean hasGlobalFlyPermission = player.hasPermission("fabledskyblock.*") || player.hasPermission("fabledskyblock.fly.*"); boolean hasOwnIslandFlyPermission = player.hasPermission("fabledskyblock.fly") && island.getRole(player) != null && island.getRole(player) != IslandRole.Visitor; @@ -1294,7 +1194,7 @@ public class IslandManager { FileConfiguration configLoad = config.getFileConfiguration(); boolean coopPlayers = island.getSetting(IslandRole.Operator, "CoopPlayers").getStatus(); - + for (Player all : Bukkit.getOnlinePlayers()) { if (uuid != null && all.getUniqueId().equals(uuid)) { continue; @@ -1309,15 +1209,14 @@ public class IslandManager { for (UUID coopPlayerAtIslandList : getCoopPlayersAtIsland(island)) { Player targetPlayer = Bukkit.getServer().getPlayer(coopPlayerAtIslandList); - - if(island.getCoopType(coopPlayerAtIslandList) == IslandCoop.NORMAL) continue; - + + if (island.getCoopType(coopPlayerAtIslandList) == IslandCoop.NORMAL) continue; + if (targetPlayer != null) { LocationUtil.teleportPlayerToSpawn(targetPlayer); if (coopPlayers) { - messageManager.sendMessage(targetPlayer, - configLoad.getString("Island.Coop.Removed.Operator.Message")); + messageManager.sendMessage(targetPlayer, configLoad.getString("Island.Coop.Removed.Operator.Message")); } else { messageManager.sendMessage(targetPlayer, configLoad.getString("Island.Coop.Removed.Owner.Message")); } @@ -1341,8 +1240,7 @@ public class IslandManager { settings.put("Damage", true); for (String settingList : settings.keySet()) { - if (configLoad.getBoolean("Island.Settings." + settingList + ".Enable") - && island.getSetting(IslandRole.Owner, settingList).getStatus() == settings.get(settingList)) { + if (configLoad.getBoolean("Island.Settings." + settingList + ".Enable") && island.getSetting(IslandRole.Owner, settingList).getStatus() == settings.get(settingList)) { safeLevel++; } } @@ -1354,8 +1252,7 @@ public class IslandManager { WorldManager worldManager = skyblock.getWorldManager(); if (island.isBorder()) { - if (skyblock.getFileManager().getConfig(new File(skyblock.getDataFolder(), "config.yml")) - .getFileConfiguration().getBoolean("Island.WorldBorder.Enable")) { + if (skyblock.getFileManager().getConfig(new File(skyblock.getDataFolder(), "config.yml")).getFileConfiguration().getBoolean("Island.WorldBorder.Enable")) { for (IslandWorld worldList : IslandWorld.getIslandWorlds()) { if (worldList == IslandWorld.Nether) { if (NMSUtil.getVersionNumber() < 13) { @@ -1364,8 +1261,7 @@ public class IslandManager { } for (Player all : getPlayersAtIsland(island)) { - WorldBorder.send(all, island.getBorderColor(), island.getSize(), island - .getLocation(worldManager.getIslandWorld(all.getWorld()), IslandEnvironment.Island)); + WorldBorder.send(all, island.getBorderColor(), island.getSize(), island.getLocation(worldManager.getIslandWorld(all.getWorld()), IslandEnvironment.Island)); } } } @@ -1442,8 +1338,7 @@ public class IslandManager { public boolean isLocationAtIsland(Island island, org.bukkit.Location location, IslandWorld world) { Location islandLocation = island.getLocation(world, IslandEnvironment.Island); - if (islandLocation == null) - return false; + if (islandLocation == null) return false; return LocationUtil.isLocationAtLocationRadius(location.clone().add(0.5, 0, 0.5), islandLocation, island.getRadius() + 1); } diff --git a/src/main/java/com/songoda/skyblock/island/removal/ChunkDeleteSplitter.java b/src/main/java/com/songoda/skyblock/island/removal/ChunkDeleteSplitter.java index 1e3827de..2052aa6f 100644 --- a/src/main/java/com/songoda/skyblock/island/removal/ChunkDeleteSplitter.java +++ b/src/main/java/com/songoda/skyblock/island/removal/ChunkDeleteSplitter.java @@ -2,94 +2,61 @@ package com.songoda.skyblock.island.removal; import java.util.Iterator; import java.util.List; +import java.util.Map; 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.block.Block; import org.bukkit.scheduler.BukkitRunnable; -import com.google.common.collect.Lists; import com.songoda.skyblock.SkyBlock; +import com.songoda.skyblock.blockscanner.BlockInfo; +import com.songoda.skyblock.blockscanner.BlockScanner; -public final class ChunkDeleteSplitter extends BukkitRunnable { +public class ChunkDeleteSplitter extends BukkitRunnable { - private int completedNum; + private final Map> snapshots; + private Queue blocks; - 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 ChunkDeleteSplitter(Map> snapshots) { + this.snapshots = snapshots; + start(); } - 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 void start() { + BlockScanner.startScanner(snapshots, (blocks) -> { + this.blocks = blocks; + this.runTaskTimer(SkyBlock.getInstance(), 20, 20); }); } - 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();) { + for (Iterator it = blocks.iterator(); it.hasNext();) { - if (deleteAmount == 10000) break; + if (deleteAmount == 3500) break; - final XYZPair pair = it.next(); + final BlockInfo pair = it.next(); + final Block block = pair.getWorld().getBlockAt(pair.getX(), pair.getY(), pair.getZ()); - world.getBlockAt(pair.getX(), pair.getY(), pair.getZ()).setType(Material.AIR); + block.setType(Material.AIR); deleteAmount++; it.remove(); } - if (toRemove.isEmpty()) { + if (blocks.isEmpty()) { cancel(); } } - public static void startDeleting(World world, List snapshots) { - - final ChunkDeleteSplitter splitter = new ChunkDeleteSplitter(world, snapshots); - - splitter.runTaskTimer(SkyBlock.getInstance(), 5, 5); + public static void startDeletion(Map> snapshots) { + new ChunkDeleteSplitter(snapshots); } } diff --git a/src/main/java/com/songoda/skyblock/levelling/Chunk.java b/src/main/java/com/songoda/skyblock/levelling/Chunk.java deleted file mode 100644 index d9b097ce..00000000 --- a/src/main/java/com/songoda/skyblock/levelling/Chunk.java +++ /dev/null @@ -1,162 +0,0 @@ -package com.songoda.skyblock.levelling; - -import com.songoda.skyblock.SkyBlock; -import com.songoda.skyblock.island.Island; -import com.songoda.skyblock.island.IslandEnvironment; -import com.songoda.skyblock.island.IslandWorld; -import com.songoda.skyblock.utils.version.NMSUtil; -import net.md_5.bungee.api.ChatMessageType; -import net.md_5.bungee.api.chat.TextComponent; -import org.bukkit.*; -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 { - - private static final int MAX_CHUNKS = 150; - private final SkyBlock skyblock; - private Island island; - - private int initialNumberOfChunks = -1; - private Set chunkPositions = new HashSet<>(); - private Set chunkSnapshots = new HashSet<>(); - private boolean isReady = false; - private boolean isFinished = false; - - public Chunk(SkyBlock skyblock, Island island) { - this.skyblock = skyblock; - this.island = island; - } - - public void prepareInitial() { - Bukkit.getScheduler().runTask(this.skyblock, () -> { - FileConfiguration config = this.skyblock.getFileManager().getConfig(new File(this.skyblock.getDataFolder(), "config.yml")).getFileConfiguration(); - FileConfiguration islandData = this.skyblock.getFileManager().getConfig(new File(new File(this.skyblock.getDataFolder().toString() + "/island-data"), this.island.getOwnerUUID().toString() + ".yml")).getFileConfiguration(); - - boolean hasNether = config.getBoolean("Island.World.Nether.Enable") && islandData.getBoolean("Unlocked.Nether", false); - boolean hasEnd = config.getBoolean("Island.World.End.Enable") && islandData.getBoolean("Unlocked.End", false); - - for (IslandWorld islandWorld : IslandWorld.getIslandWorlds()) { - if (islandWorld == IslandWorld.Normal || (islandWorld == IslandWorld.Nether && hasNether) || (islandWorld == IslandWorld.End && hasEnd)) { - chunkPositions.addAll(getChunksToScan(island, islandWorld)); - } - } - - this.initialNumberOfChunks = this.chunkPositions.size(); - - this.prepareNextChunkSnapshots(); - }); - } - - public boolean isReadyToScan() { - return this.isReady; - } - - public Set getAvailableChunkSnapshots() { - this.isReady = false; - return this.chunkSnapshots; - } - - public boolean isFinished() { - return this.isFinished; - } - - public void prepareNextChunkSnapshots() { - boolean isWildStackerEnabled = Bukkit.getPluginManager().isPluginEnabled("WildStacker"); - - Bukkit.getScheduler().runTask(this.skyblock, () -> { - this.chunkSnapshots.clear(); - - Iterator it = this.chunkPositions.iterator(); - if (!it.hasNext()) { - this.isReady = true; - this.isFinished = true; - this.sendFinishedMessage(); - return; - } - - int percentComplete = (int) ((1 - ((double) this.chunkPositions.size() / this.initialNumberOfChunks)) * 100); - this.sendPercentMessage(percentComplete); - - while (it.hasNext() && this.chunkSnapshots.size() < MAX_CHUNKS) { - ChunkPosition chunkPosition = it.next(); - World world = chunkPosition.getWorld(); - int x = chunkPosition.getX(); - int z = chunkPosition.getZ(); - - // Try to load the chunk, but don't generate anything and ignore if we couldn't get it - if (world.isChunkLoaded(x, z) || world.loadChunk(x, z, false)) { - org.bukkit.Chunk chunk = world.getChunkAt(x, z); - ChunkSnapshot chunkSnapshot = chunk.getChunkSnapshot(); - if (isWildStackerEnabled) { - this.chunkSnapshots.add(new WildStackerChunkSnapshotWrapper(chunkSnapshot, com.bgsoftware.wildstacker.api.WildStackerAPI.getWildStacker().getSystemManager().getStackedSnapshot(chunk, true))); - } else { - this.chunkSnapshots.add(new ChunkSnapshotWrapper(chunkSnapshot)); - } - } - it.remove(); - } - - this.isReady = true; - }); - } - - private void sendPercentMessage(int percent) { - if (NMSUtil.getVersionNumber() > 8) { - String message = ChatColor.translateAlternateColorCodes('&', - this.skyblock.getFileManager() - .getConfig(new File(this.skyblock.getDataFolder(), "language.yml")) - .getFileConfiguration().getString("Command.Island.Level.Scanning.Progress.Message") - .replace("%percent", String.valueOf(percent))); - for (Player player : this.skyblock.getIslandManager().getPlayersAtIsland(this.island)) { - player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(message)); - } - } - } - - private void sendFinishedMessage() { - if (NMSUtil.getVersionNumber() > 8) { - String message = ChatColor.translateAlternateColorCodes('&', this.skyblock.getFileManager() - .getConfig(new File(this.skyblock.getDataFolder(), "language.yml")) - .getFileConfiguration().getString("Command.Island.Level.Scanning.Finished.Message")); - for (Player player : this.skyblock.getIslandManager().getPlayersAtIsland(this.island)) { - player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(message)); - } - } - } - - 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() - 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()); - - 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) { - positions.add(new ChunkPosition(world, x >> 4, z >> 4)); - } - } - - return positions; - } -} diff --git a/src/main/java/com/songoda/skyblock/levelling/ChunkPosition.java b/src/main/java/com/songoda/skyblock/levelling/ChunkPosition.java deleted file mode 100644 index 0e0c3d66..00000000 --- a/src/main/java/com/songoda/skyblock/levelling/ChunkPosition.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.songoda.skyblock.levelling; - -import org.bukkit.World; - -public class ChunkPosition { - private World world; - private int x, z; - - public ChunkPosition(World world, int x, int z) { - this.world = world; - this.x = x; - this.z = z; - } - - public World getWorld() { - return this.world; - } - - public int getX() { - return this.x; - } - - public int getZ() { - return this.z; - } -} diff --git a/src/main/java/com/songoda/skyblock/levelling/ChunkSnapshotWrapper.java b/src/main/java/com/songoda/skyblock/levelling/ChunkSnapshotWrapper.java deleted file mode 100644 index 4634addc..00000000 --- a/src/main/java/com/songoda/skyblock/levelling/ChunkSnapshotWrapper.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.songoda.skyblock.levelling; - -import org.bukkit.ChunkSnapshot; - -public class ChunkSnapshotWrapper extends LevelChunkSnapshotWrapper { - - public ChunkSnapshotWrapper(ChunkSnapshot chunkSnapshot) { - super(chunkSnapshot); - } - - @Override - public boolean hasWildStackerData() { - return false; - } - -} diff --git a/src/main/java/com/songoda/skyblock/levelling/ChunkUtil.java b/src/main/java/com/songoda/skyblock/levelling/ChunkUtil.java new file mode 100644 index 00000000..63bcc64f --- /dev/null +++ b/src/main/java/com/songoda/skyblock/levelling/ChunkUtil.java @@ -0,0 +1,43 @@ +package com.songoda.skyblock.levelling; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.World; + +import com.songoda.skyblock.island.Island; +import com.songoda.skyblock.island.IslandEnvironment; +import com.songoda.skyblock.island.IslandWorld; + +public class ChunkUtil { + + 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() - 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()); + + int maxX = Math.max(maxLocation.getBlockX(), minLocation.getBlockX()); + int maxZ = Math.max(maxLocation.getBlockZ(), minLocation.getBlockZ()); + + final List positions = new LinkedList<>(); + + for (int x = minX; x < maxX + 16; x += 16) { + for (int z = minZ; z < maxZ + 16; z += 16) { + positions.add(world.getChunkAt(x >> 4, z >> 4)); + } + } + + return positions; + } +} diff --git a/src/main/java/com/songoda/skyblock/levelling/LevelChunkSnapshotWrapper.java b/src/main/java/com/songoda/skyblock/levelling/LevelChunkSnapshotWrapper.java deleted file mode 100644 index 81aa5335..00000000 --- a/src/main/java/com/songoda/skyblock/levelling/LevelChunkSnapshotWrapper.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.songoda.skyblock.levelling; - -import org.bukkit.ChunkSnapshot; - -public abstract class LevelChunkSnapshotWrapper { - - private ChunkSnapshot chunkSnapshot; - - public LevelChunkSnapshotWrapper(ChunkSnapshot chunkSnapshot) { - this.chunkSnapshot = chunkSnapshot; - } - - public ChunkSnapshot getChunkSnapshot() { - return this.chunkSnapshot; - } - - abstract boolean hasWildStackerData(); - -} diff --git a/src/main/java/com/songoda/skyblock/levelling/LevellingManager.java b/src/main/java/com/songoda/skyblock/levelling/LevellingManager.java deleted file mode 100644 index 22de9fcc..00000000 --- a/src/main/java/com/songoda/skyblock/levelling/LevellingManager.java +++ /dev/null @@ -1,443 +0,0 @@ -package com.songoda.skyblock.levelling; - -import com.songoda.skyblock.SkyBlock; -import com.songoda.skyblock.api.event.island.IslandLevelChangeEvent; -import com.songoda.skyblock.config.FileManager.Config; -import com.songoda.skyblock.island.Island; -import com.songoda.skyblock.island.IslandLevel; -import com.songoda.skyblock.island.IslandManager; -import com.songoda.skyblock.island.IslandWorld; -import com.songoda.skyblock.menus.Levelling; -import com.songoda.skyblock.message.MessageManager; -import com.songoda.skyblock.stackable.Stackable; -import com.songoda.skyblock.stackable.StackableManager; -import com.songoda.skyblock.utils.version.Materials; -import com.songoda.skyblock.utils.version.NMSUtil; -import com.songoda.skyblock.utils.version.Sounds; -import com.songoda.skyblock.world.WorldManager; -import org.bukkit.*; -import org.bukkit.block.CreatureSpawner; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.Player; -import org.bukkit.scheduler.BukkitRunnable; - -import java.io.File; -import java.util.*; -import java.util.logging.Level; - -public class LevellingManager { - - private final SkyBlock skyblock; - - private Island activelyScanningIsland = null; - private Queue islandsInQueue = new LinkedList<>(); - private List materialStorage = new ArrayList<>(); - - public LevellingManager(SkyBlock skyblock) { - this.skyblock = skyblock; - - registerMaterials(); - } - - public void calculatePoints(Player player, Island island) { - IslandManager islandManager = skyblock.getIslandManager(); - WorldManager worldManager = skyblock.getWorldManager(); - MessageManager messageManager = skyblock.getMessageManager(); - StackableManager stackableManager = skyblock.getStackableManager(); - - FileConfiguration languageConfig = this.skyblock.getFileManager().getConfig(new File(this.skyblock.getDataFolder(), "language.yml")).getFileConfiguration(); - - if (!this.isIslandLevelBeingScanned(island) && player != null && islandManager.getIslandPlayerAt(player) != island) { - messageManager.sendMessage(player, languageConfig.getString("Command.Island.Level.Scanning.NotOnIsland.Message")); - return; - } - - if (this.activelyScanningIsland != null) { - this.islandsInQueue.add(new QueuedIsland(player, island)); - - String queuedMessage = languageConfig.getString("Command.Island.Level.Scanning.Queued.Message"); - islandManager.getPlayersAtIsland(island).forEach(x -> messageManager.sendMessage(x, queuedMessage)); - - return; - } - - this.activelyScanningIsland = island; - - String nowScanningMessage = languageConfig.getString("Command.Island.Level.Scanning.Started.Message"); - islandManager.getPlayersAtIsland(island).forEach(x -> messageManager.sendMessage(x, nowScanningMessage)); - - Chunk chunk = new Chunk(skyblock, island); - chunk.prepareInitial(); - - int NMSVersion = NMSUtil.getVersionNumber(); - - int height = 0; - - for (IslandWorld worldList : IslandWorld.getIslandWorlds()) { - org.bukkit.World world = worldManager.getWorld(worldList); - - if (height == 0 || height > world.getMaxHeight()) { - height = world.getMaxHeight(); - } - } - - int worldMaxHeight = height; - - boolean isEpicSpawnersEnabled = Bukkit.getPluginManager().isPluginEnabled("EpicSpawners"); - boolean isUltimateStackerEnabled = Bukkit.getPluginManager().isPluginEnabled("UltimateStacker"); - - Map levellingData = new HashMap<>(); - Set spawnerLocations = new HashSet<>(); // These have to be checked synchronously :( - Set epicSpawnerLocations = new HashSet<>(); - Set ultimateStackerSpawnerLocations = new HashSet<>(); - - List blacklistedMaterials = new ArrayList<>(); - blacklistedMaterials.add(Materials.AIR.getPostMaterial()); - blacklistedMaterials.add(Materials.WATER.getPostMaterial()); - blacklistedMaterials.add(Materials.LEGACY_STATIONARY_WATER.getPostMaterial()); - blacklistedMaterials.add(Materials.LAVA.getPostMaterial()); - blacklistedMaterials.add(Materials.LEGACY_STATIONARY_LAVA.getPostMaterial()); - - new BukkitRunnable() { - @Override - public void run() { - if (!chunk.isReadyToScan()) - return; - - try { - if (chunk.isFinished()) { - Bukkit.getScheduler().scheduleSyncDelayedTask(skyblock, () -> finalizeMaterials(levellingData, spawnerLocations, epicSpawnerLocations, ultimateStackerSpawnerLocations, player, island), 1); - cancel(); - return; - } - - for (LevelChunkSnapshotWrapper chunkSnapshotList : chunk.getAvailableChunkSnapshots()) { - for (int x = 0; x < 16; x++) { - for (int z = 0; z < 16; z++) { - for (int y = 0; y < worldMaxHeight; y++) { - ChunkSnapshot chunkSnapshot = chunkSnapshotList.getChunkSnapshot(); - - try { - org.bukkit.Material blockMaterial; - int blockData = 0; - EntityType spawnerType = null; - - if (NMSVersion > 12) { - blockMaterial = chunkSnapshot.getBlockType(x, y, z); - } else { - LegacyChunkSnapshotData data = LegacyChunkSnapshotFetcher.fetch(chunkSnapshot, x, y, z); - - blockMaterial = data.getMaterial(); - blockData = data.getData(); - } - - if (blacklistedMaterials.contains(blockMaterial)) - continue; - - long amount = 1; - - if (blockMaterial == Materials.SPAWNER.parseMaterial()) { - World world = Bukkit.getWorld(chunkSnapshot.getWorldName()); - Location location = new Location(world, chunkSnapshot.getX() * 16 + x, y, chunkSnapshot.getZ() * 16 + z); - - if (isEpicSpawnersEnabled) { - com.songoda.epicspawners.EpicSpawners epicSpawners = com.songoda.epicspawners.EpicSpawners.getInstance(); - if (epicSpawners.getSpawnerManager().isSpawner(location)) { - com.songoda.epicspawners.spawners.spawner.Spawner spawner = epicSpawners.getSpawnerManager().getSpawnerFromWorld(location); - if (spawner != null) - epicSpawnerLocations.add(location); - continue; - } - } else if (isUltimateStackerEnabled) { - com.songoda.ultimatestacker.spawner.SpawnerStack spawnerStack = com.songoda.ultimatestacker.UltimateStacker.getInstance().getSpawnerStackManager().getSpawner(location); - if (spawnerStack != null) - ultimateStackerSpawnerLocations.add(location); - continue; - } - - if (chunkSnapshotList.hasWildStackerData()) { - com.bgsoftware.wildstacker.api.objects.StackedSnapshot snapshot = ((WildStackerChunkSnapshotWrapper) chunkSnapshotList).getStackedSnapshot(); - if (snapshot.isStackedSpawner(location)) { - Map.Entry spawnerData = snapshot.getStackedSpawner(location); - amount = spawnerData.getKey(); - spawnerType = spawnerData.getValue(); - } - } - - if (spawnerType == null) { - spawnerLocations.add(location); - continue; - } - } else { - if (chunkSnapshotList.hasWildStackerData()) { - com.bgsoftware.wildstacker.api.objects.StackedSnapshot snapshot = ((WildStackerChunkSnapshotWrapper) chunkSnapshotList).getStackedSnapshot(); - World world = Bukkit.getWorld(chunkSnapshot.getWorldName()); - Location location = new Location(world, chunkSnapshot.getX() * 16 + x, y, chunkSnapshot.getZ() * 16 + z); - if (snapshot.isStackedBarrel(location)) { - Map.Entry barrelData = snapshot.getStackedBarrel(location); - amount = barrelData.getKey(); - blockMaterial = barrelData.getValue(); - if (NMSUtil.getVersionNumber() > 12 && blockMaterial.name().startsWith("LEGACY_")) { - blockMaterial = Material.matchMaterial(blockMaterial.name().replace("LEGACY_", "")); - } - } - } - - if (stackableManager != null && stackableManager.getStackableMaterials().contains(blockMaterial) && amount == 1) { - World world = Bukkit.getWorld(chunkSnapshot.getWorldName()); - Location location = new Location(world, chunkSnapshot.getX() * 16 + x, y, chunkSnapshot.getZ() * 16 + z); - if (stackableManager.isStacked(location)) { - Stackable stackable = stackableManager.getStack(location, blockMaterial); - if (stackable != null) { - amount = stackable.getSize(); - } - } - } - } - - LevellingData data = new LevellingData(blockMaterial, (byte) blockData, spawnerType); - Long totalAmountInteger = levellingData.get(data); - long totalAmount = totalAmountInteger == null ? amount : totalAmountInteger + amount; - levellingData.put(data, totalAmount); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - } - } - - chunk.prepareNextChunkSnapshots(); - } catch (Exception ex) { - skyblock.getLogger().severe("An error occurred while scanning an island. This is a severe error."); - } - } - }.runTaskTimerAsynchronously(skyblock, 0L, 1L); - } - - private void finalizeMaterials(Map levellingData, Set spawnerLocations, Set epicSpawnerLocations, Set ultimateStackerSpawnerLocations, Player player, Island island) { - for (Location location : spawnerLocations) { - if (!(location.getBlock().getState() instanceof CreatureSpawner)) - continue; - - int amount = 1; - EntityType spawnerType = ((CreatureSpawner) location.getBlock().getState()).getSpawnedType(); - - LevellingData data = new LevellingData(Materials.SPAWNER.parseMaterial(), (byte) 0, spawnerType); - Long totalAmountInteger = levellingData.get(data); - long totalAmount = totalAmountInteger == null ? amount : totalAmountInteger + amount; - levellingData.put(data, totalAmount); - } - - for (Location location : epicSpawnerLocations) { - com.songoda.epicspawners.EpicSpawners epicSpawners = com.songoda.epicspawners.EpicSpawners.getInstance(); - if (epicSpawners.getSpawnerManager().isSpawner(location)) { - com.songoda.epicspawners.spawners.spawner.Spawner spawner = epicSpawners.getSpawnerManager().getSpawnerFromWorld(location); - if (spawner == null) - continue; - - int amount = spawner.getFirstStack().getStackSize(); - EntityType spawnerType = spawner.getCreatureSpawner().getSpawnedType(); - - LevellingData data = new LevellingData(Materials.SPAWNER.parseMaterial(), (byte) 0, spawnerType); - Long totalAmountInteger = levellingData.get(data); - long totalAmount = totalAmountInteger == null ? amount : totalAmountInteger + amount; - levellingData.put(data, totalAmount); - } - } - - for (Location location : ultimateStackerSpawnerLocations) { - com.songoda.ultimatestacker.spawner.SpawnerStack spawnerStack = com.songoda.ultimatestacker.UltimateStacker.getInstance().getSpawnerStackManager().getSpawner(location); - if (spawnerStack == null) - continue; - - int amount = spawnerStack.getAmount(); - EntityType spawnerType = ((CreatureSpawner) location.getBlock().getState()).getSpawnedType(); - - LevellingData data = new LevellingData(Materials.SPAWNER.parseMaterial(), (byte) 0, spawnerType); - Long totalAmountInteger = levellingData.get(data); - long totalAmount = totalAmountInteger == null ? amount : totalAmountInteger + amount; - levellingData.put(data, totalAmount); - } - - Map materials = new HashMap<>(); - for (LevellingData data : levellingData.keySet()) { - long amount = levellingData.get(data); - if (data.getMaterials() != null) { - materials.put(data.getMaterials().name(), amount); - } - } - - if (materials.size() == 0) { - if (player != null) { - skyblock.getMessageManager().sendMessage(player, skyblock.getFileManager() - .getConfig(new File(skyblock.getDataFolder(), "language.yml")) - .getFileConfiguration().getString("Command.Island.Level.Materials.Message")); - skyblock.getSoundManager().playSound(player, Sounds.VILLAGER_NO.bukkitSound(), 1.0F, 1.0F); - } - } else { - IslandLevel level = island.getLevel(); - level.setLastCalculatedPoints(level.getPoints()); - level.setLastCalculatedLevel(level.getLevel()); - level.setMaterials(materials); - - Bukkit.getServer().getPluginManager().callEvent(new IslandLevelChangeEvent(island.getAPIWrapper(), island.getAPIWrapper().getLevel())); - - if (player != null) { - Levelling.getInstance().open(player); - } - } - - MessageManager messageManager = skyblock.getMessageManager(); - FileConfiguration languageConfig = this.skyblock.getFileManager().getConfig(new File(this.skyblock.getDataFolder(), "language.yml")).getFileConfiguration(); - String nowScanningMessage = languageConfig.getString("Command.Island.Level.Scanning.Done.Message"); - skyblock.getIslandManager().getPlayersAtIsland(island).forEach(x -> messageManager.sendMessage(x, nowScanningMessage)); - - this.activelyScanningIsland = null; - QueuedIsland nextInQueue = this.islandsInQueue.poll(); - if (nextInQueue != null) - this.calculatePoints(nextInQueue.getPlayer(), nextInQueue.getIsland()); - } - - public void registerMaterials() { - Config config = skyblock.getFileManager().getConfig(new File(skyblock.getDataFolder(), "levelling.yml")); - FileConfiguration configLoad = config.getFileConfiguration(); - - if (configLoad.getString("Materials") != null) { - for (String materialKey : configLoad.getConfigurationSection("Materials").getKeys(false)) { - try { - Materials material = Materials.fromString(materialKey); - if (!material.isAvailable() || material.getPostItem() == null) continue; - - if (!containsMaterial(material)) { - addMaterial(material, configLoad.getLong("Materials." + materialKey + ".Points")); - } - } catch (Exception e) { - Bukkit.getServer().getLogger().log(Level.WARNING, "SkyBlock | Error: The material '" + materialKey - + "' is not a Material type. Make sure the material name is a 1.14 material name. Please correct this in the 'levelling.yml' file."); - } - } - } - } - - public boolean isIslandLevelBeingScanned(Island island) { - return this.islandsInQueue.stream().anyMatch(x -> x.getIsland() == island) || this.activelyScanningIsland == island; - } - - public void unregisterMaterials() { - materialStorage.clear(); - } - - public void addMaterial(Materials materials, long points) { - materialStorage.add(new LevellingMaterial(materials, points)); - } - - public void removeMaterial(LevellingMaterial material) { - materialStorage.remove(material); - } - - public boolean containsMaterial(Materials materials) { - for (LevellingMaterial materialList : materialStorage) { - if (materialList.getMaterials().name().equals(materials.name())) { - return true; - } - } - - return false; - } - - public LevellingMaterial getMaterial(Materials materials) { - for (LevellingMaterial materialList : materialStorage) { - if (materialList.getMaterials().name().equals(materials.name())) { - return materialList; - } - } - - return null; - } - - public List getMaterials() { - return materialStorage; - } - - private static class LevellingData { - private final static int version = NMSUtil.getVersionNumber(); - - private final Material material; - private final byte data; - private final EntityType spawnerType; - - private LevellingData(Material material, byte data, EntityType spawnerType) { - this.material = material; - this.data = data; - this.spawnerType = spawnerType; - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof LevellingData)) return false; - LevellingData data = (LevellingData) obj; - if (this == obj) return true; - if (version > 12) { - return this.material == data.material && this.spawnerType == data.spawnerType; - } else { - if (this.data == 0 && data.data == 0) - return this.material == data.material && this.spawnerType == data.spawnerType; - - Materials thisMaterials = Materials.requestMaterials(this.material.name(), this.data); - Materials otherMaterials = Materials.requestMaterials(this.material.name(), (byte) 0); - - return thisMaterials == otherMaterials && this.spawnerType == data.spawnerType; - } - } - - @Override - public int hashCode() { - if (version > 12) { - return Objects.hash(this.material, this.spawnerType); - } else { - if (this.data == 0) - return Objects.hash(this.material, true, this.spawnerType); - - Materials thisMaterials = Materials.requestMaterials(this.material.name(), this.data); - Materials otherMaterials = Materials.requestMaterials(this.material.name(), (byte) 0); - - return Objects.hash(this.material, thisMaterials == otherMaterials, this.spawnerType); - } - } - - private Materials getMaterials() { - if (this.spawnerType != null) { - return Materials.getSpawner(this.spawnerType); - } - - if (NMSUtil.getVersionNumber() > 12) { - try { - return Materials.fromString(this.material.name()); - } catch (Exception ignored) { - } - } - - return Materials.getMaterials(this.material, this.data); - } - } - - private static class QueuedIsland { - private final Player player; - private final Island island; - - public QueuedIsland(Player player, Island island) { - this.player = player; - this.island = island; - } - - public Player getPlayer() { - return this.player; - } - - public Island getIsland() { - return this.island; - } - } -} diff --git a/src/main/java/com/songoda/skyblock/levelling/WildStackerChunkSnapshotWrapper.java b/src/main/java/com/songoda/skyblock/levelling/WildStackerChunkSnapshotWrapper.java deleted file mode 100644 index d8da7559..00000000 --- a/src/main/java/com/songoda/skyblock/levelling/WildStackerChunkSnapshotWrapper.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.songoda.skyblock.levelling; - -import com.bgsoftware.wildstacker.api.objects.StackedSnapshot; -import org.bukkit.ChunkSnapshot; - -public class WildStackerChunkSnapshotWrapper extends LevelChunkSnapshotWrapper { - - private StackedSnapshot stackedSnapshot; - - public WildStackerChunkSnapshotWrapper(ChunkSnapshot chunkSnapshot, StackedSnapshot stackedSnapshot) { - super(chunkSnapshot); - this.stackedSnapshot = stackedSnapshot; - } - - @Override - public boolean hasWildStackerData() { - return true; - } - - public StackedSnapshot getStackedSnapshot() { - return this.stackedSnapshot; - } - -} diff --git a/src/main/java/com/songoda/skyblock/levelling/rework/IslandLevelManager.java b/src/main/java/com/songoda/skyblock/levelling/rework/IslandLevelManager.java new file mode 100644 index 00000000..13dbbb30 --- /dev/null +++ b/src/main/java/com/songoda/skyblock/levelling/rework/IslandLevelManager.java @@ -0,0 +1,194 @@ +package com.songoda.skyblock.levelling.rework; + +import java.io.File; +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.block.CreatureSpawner; +import org.bukkit.configuration.Configuration; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; +import org.bukkit.plugin.PluginManager; + +import com.songoda.skyblock.SkyBlock; +import com.songoda.skyblock.blockscanner.BlockInfo; +import com.songoda.skyblock.island.Island; +import com.songoda.skyblock.levelling.rework.amount.AmountMaterialPair; +import com.songoda.skyblock.levelling.rework.calculator.Calculator; +import com.songoda.skyblock.levelling.rework.calculator.CalculatorRegistry; +import com.songoda.skyblock.levelling.rework.calculator.impl.EpicSpawnerCalculator; +import com.songoda.skyblock.levelling.rework.calculator.impl.UltimateStackerCalculator; +import com.songoda.skyblock.levelling.rework.calculator.impl.WildStackerCalculator; +import com.songoda.skyblock.message.MessageManager; +import com.songoda.skyblock.utils.version.Materials; +import com.songoda.skyblock.utils.version.NMSUtil; + +public final class IslandLevelManager { + + private final static int VERSION = NMSUtil.getVersionNumber(); + private Map inScan; + private Map worth; + private Map cachedPairs; + + public IslandLevelManager() { + this.inScan = new HashMap<>(); + this.worth = new EnumMap<>(Materials.class); + this.cachedPairs = new EnumMap<>(Materials.class); + registerCalculators(); + reloadWorth(); + } + + public void startScan(Player attemptScanner, Island island) { + + if (!Bukkit.isPrimaryThread()) { + Bukkit.getScheduler().runTask(SkyBlock.getInstance(), () -> startScan(attemptScanner, island)); + return; + } + + if (island == null) throw new IllegalArgumentException("island cannot be null"); + + Configuration config = SkyBlock.getInstance().getFileManager().getConfig(new File(SkyBlock.getInstance().getDataFolder(), "language.yml")).getFileConfiguration(); + MessageManager messageManager = SkyBlock.getInstance().getMessageManager(); + + if (inScan.containsKey(island)) { + if (attemptScanner != null) messageManager.sendMessage(attemptScanner, config.getString("Command.Island.Level.Scanning.InScan.Message")); + return; + } + + if (attemptScanner != null) { + + if(SkyBlock.getInstance().getIslandManager().getIslandPlayerAt(attemptScanner) != island) { + messageManager.sendMessage(attemptScanner, config.getString("Command.Island.Level.Scanning.NotOnIsland.Message")); + return; + } + + messageManager.sendMessage(attemptScanner, config.getString("Command.Island.Level.Scanning.Started.Message")); + } + + inScan.put(island, new IslandScan(island).start()); + } + + public boolean isScanning(Island island) { + return inScan.containsKey(island); + } + + void stopScan(Island island) { + + final IslandScan scan = inScan.get(island); + + if (scan == null) return; + + inScan.remove(island); + } + + public void reloadWorth() { + worth.clear(); + + final Configuration config = SkyBlock.getInstance().getFileManager().getConfig(new File(SkyBlock.getInstance().getDataFolder(), "levelling.yml")).getFileConfiguration(); + final ConfigurationSection materialSection = config.getConfigurationSection("Materials"); + + if (materialSection == null) return; + + for (String key : materialSection.getKeys(false)) { + + final ConfigurationSection current = materialSection.getConfigurationSection(key); + + final Materials material = Materials.fromString(key); + + if (material.isAvailable() || material.getPostItem() == null) continue; + + worth.put(material, current.getLong("Points")); + } + } + + public void addWorth(Materials material, long points) { + worth.put(material, points); + } + + public void removeWorth(Materials material) { + worth.remove(material); + } + + public List getWorthsAsLevelingMaterials() { + + final List materials = new ArrayList<>(worth.size()); + + for (Entry entry : worth.entrySet()) { + materials.add(new LevellingMaterial(entry.getKey(), entry.getValue())); + } + + return materials; + } + + public Map getWorths() { + return worth; + } + + public long getWorth(Materials material) { + return worth.getOrDefault(material, 0L); + } + + public boolean hasWorth(Materials material) { + return worth.containsKey(material); + } + + private void registerCalculators() { + final Material spawner = Materials.SPAWNER.parseMaterial(); + final PluginManager pm = Bukkit.getPluginManager(); + + if (pm.isPluginEnabled("EpicSpawners")) CalculatorRegistry.registerCalculator(new EpicSpawnerCalculator(), spawner); + if (pm.isPluginEnabled("UltimateStacker")) CalculatorRegistry.registerCalculator(new UltimateStackerCalculator(), spawner); + if (pm.isPluginEnabled("WildStacker")) CalculatorRegistry.registerCalculator(new WildStackerCalculator(), spawner); + } + + private static final AmountMaterialPair EMPTY = new AmountMaterialPair(null, 0); + + @SuppressWarnings("deprecation") + public AmountMaterialPair getAmountAndType(BlockInfo info) { + + final Block block = info.getWorld().getBlockAt(info.getX(), info.getY(), info.getZ()); + final Material blockType = block.getType(); + + if (blockType == Material.AIR) return EMPTY; + + Materials finalType = VERSION > 12 ? Materials.fromString(blockType.name()) : Materials.requestMaterials(blockType.name(), block.getData()); + + if (finalType == null) return EMPTY; + if (finalType == Materials.SPAWNER) finalType = Materials.getSpawner(((CreatureSpawner) block.getState()).getSpawnedType()); + + final List calculators = CalculatorRegistry.getCalculators(blockType); + final long stackSize = SkyBlock.getInstance().getStackableManager().getStackSizeOf(block.getLocation(), blockType); + + if (calculators == null) { + + if (stackSize > 1) return new AmountMaterialPair(finalType, stackSize); + + AmountMaterialPair cachedPair = cachedPairs.get(finalType); + + if (cachedPair != null) return cachedPair; + + cachedPair = new AmountMaterialPair(finalType, 1); + cachedPairs.put(finalType, cachedPair); + + return cachedPair; + } + + long amount = 0; + + for (Calculator calc : calculators) { + amount += calc.getAmount(block); + } + + if (amount == 0) amount = 1; + + return new AmountMaterialPair(finalType, amount + stackSize); + } + +} diff --git a/src/main/java/com/songoda/skyblock/levelling/rework/IslandScan.java b/src/main/java/com/songoda/skyblock/levelling/rework/IslandScan.java new file mode 100644 index 00000000..3ae2ce63 --- /dev/null +++ b/src/main/java/com/songoda/skyblock/levelling/rework/IslandScan.java @@ -0,0 +1,164 @@ +package com.songoda.skyblock.levelling.rework; + +import java.io.File; +import java.text.NumberFormat; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Queue; +import java.util.stream.Collectors; + +import org.bukkit.Bukkit; +import org.bukkit.ChunkSnapshot; +import org.bukkit.World; +import org.bukkit.configuration.Configuration; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + +import com.songoda.skyblock.SkyBlock; +import com.songoda.skyblock.api.event.island.IslandLevelChangeEvent; +import com.songoda.skyblock.blockscanner.BlockInfo; +import com.songoda.skyblock.blockscanner.BlockScanner; +import com.songoda.skyblock.island.Island; +import com.songoda.skyblock.island.IslandLevel; +import com.songoda.skyblock.island.IslandWorld; +import com.songoda.skyblock.levelling.ChunkUtil; +import com.songoda.skyblock.levelling.rework.amount.AmountMaterialPair; +import com.songoda.skyblock.levelling.rework.amount.BlockAmount; +import com.songoda.skyblock.message.MessageManager; +import com.songoda.skyblock.utils.version.Materials; + +public final class IslandScan extends BukkitRunnable { + + private static final NumberFormat FORMATTER = NumberFormat.getInstance();; + + private final Island island; + private final Map amounts; + private final Configuration config; + private final int runEveryX; + + private int totalScanned; + private int blocksSize; + private Queue blocks; + + public IslandScan(Island island) { + if (island == null) throw new IllegalArgumentException("island cannot be null"); + this.island = island; + this.amounts = new EnumMap<>(Materials.class); + this.config = SkyBlock.getInstance().getFileManager().getConfig(new File(SkyBlock.getInstance().getDataFolder(), "language.yml")).getFileConfiguration(); + this.runEveryX = config.getInt("Command.Island.Level.Scanning.Progress.Display-Every-X-Scan"); + } + + public IslandScan start() { + final SkyBlock skyblock = SkyBlock.getInstance(); + + final FileConfiguration config = skyblock.getFileManager().getConfig(new File(skyblock.getDataFolder(), "config.yml")).getFileConfiguration(); + final FileConfiguration islandData = skyblock.getFileManager() + .getConfig(new File(new File(skyblock.getDataFolder().toString() + "/island-data"), this.island.getOwnerUUID().toString() + ".yml")).getFileConfiguration(); + + final boolean hasNether = config.getBoolean("Island.World.Nether.Enable") && islandData.getBoolean("Unlocked.Nether", false); + final boolean hasEnd = config.getBoolean("Island.World.End.Enable") && islandData.getBoolean("Unlocked.End", false); + + final Map> snapshots = new HashMap<>(3); + + populate(snapshots, IslandWorld.Normal); + if (hasNether) populate(snapshots, IslandWorld.Nether); + if (hasEnd) populate(snapshots, IslandWorld.End); + + BlockScanner.startScanner(snapshots, (blocks) -> { + this.blocks = blocks; + this.blocksSize = blocks.size(); + this.runTaskTimer(SkyBlock.getInstance(), 20, 20); + + }); + return this; + } + + private void finalizeBlocks() { + + final Map materials = new HashMap<>(amounts.size()); + + for (Entry entry : amounts.entrySet()) { + materials.put(entry.getKey().name(), entry.getValue().getAmount()); + } + + final IslandLevel level = island.getLevel(); + + level.setMaterials(materials); + level.setLastCalculatedLevel(level.getLevel()); + level.setLastCalculatedPoints(level.getPoints()); + + Bukkit.getServer().getPluginManager().callEvent(new IslandLevelChangeEvent(island.getAPIWrapper(), island.getAPIWrapper().getLevel())); + } + + private int executions; + + @Override + public void run() { + executions += 1; + + int scanned = 0; + + for (Iterator it = blocks.iterator(); it.hasNext();) { + + final BlockInfo info = it.next(); + + if (scanned == 8500) break; + + final AmountMaterialPair pair = SkyBlock.getInstance().getLevellingManager().getAmountAndType(info); + + if (pair.getType() != null) { + + BlockAmount cachedAmount = amounts.get(pair.getType()); + + if (cachedAmount == null) { + cachedAmount = new BlockAmount(pair.getAmount()); + } else { + cachedAmount.increaseAmount(pair.getAmount()); + } + + amounts.put(pair.getType(), cachedAmount); + } + + scanned += 1; + it.remove(); + } + + totalScanned += scanned; + + if (blocks.isEmpty()) { + finalizeBlocks(); + cancel(); + SkyBlock.getInstance().getLevellingManager().stopScan(island); + } + + if (config.getBoolean("Command.Island.Level.Scanning.Progress.Should-Display-Message") && executions == 1 || totalScanned == blocksSize || executions % runEveryX == 0) { + + String message = config.getString("Command.Island.Level.Scanning.Progress.Message"); + message = message.replace("%current_scanned_blocks%", String.valueOf(totalScanned)); + message = message.replace("%max_blocks%", String.valueOf(blocksSize)); + message = message.replace("%percent%", FORMATTER.format(((double) totalScanned / (double) blocksSize) * 100)); + + final boolean displayComplete = totalScanned == blocksSize && config.getBoolean("Command.Island.Level.Scanning.Finished.Should-Display-Message"); + final MessageManager messageManager = SkyBlock.getInstance().getMessageManager(); + + for (Player player : SkyBlock.getInstance().getIslandManager().getPlayersAtIsland(island)) { + messageManager.sendMessage(player, message); + if (displayComplete) messageManager.sendMessage(player, config.getString("Command.Island.Level.Scanning.Finished.Message")); + } + } + + } + + private void populate(Map> snapshots, IslandWorld world) { + + final SkyBlock skyblock = SkyBlock.getInstance(); + + snapshots.put(skyblock.getWorldManager().getWorld(world), ChunkUtil.getChunksToScan(island, world).stream().map(org.bukkit.Chunk::getChunkSnapshot).collect(Collectors.toList())); + } + +} diff --git a/src/main/java/com/songoda/skyblock/levelling/LevellingMaterial.java b/src/main/java/com/songoda/skyblock/levelling/rework/LevellingMaterial.java similarity index 87% rename from src/main/java/com/songoda/skyblock/levelling/LevellingMaterial.java rename to src/main/java/com/songoda/skyblock/levelling/rework/LevellingMaterial.java index 3e906c57..e5c91013 100644 --- a/src/main/java/com/songoda/skyblock/levelling/LevellingMaterial.java +++ b/src/main/java/com/songoda/skyblock/levelling/rework/LevellingMaterial.java @@ -1,9 +1,10 @@ -package com.songoda.skyblock.levelling; +package com.songoda.skyblock.levelling.rework; -import com.songoda.skyblock.utils.version.Materials; import org.bukkit.inventory.ItemStack; -public class LevellingMaterial { +import com.songoda.skyblock.utils.version.Materials; + +public final class LevellingMaterial { private Materials materials; private long points; diff --git a/src/main/java/com/songoda/skyblock/levelling/rework/amount/AmountMaterialPair.java b/src/main/java/com/songoda/skyblock/levelling/rework/amount/AmountMaterialPair.java new file mode 100644 index 00000000..a9a39ad1 --- /dev/null +++ b/src/main/java/com/songoda/skyblock/levelling/rework/amount/AmountMaterialPair.java @@ -0,0 +1,23 @@ +package com.songoda.skyblock.levelling.rework.amount; + +import com.songoda.skyblock.utils.version.Materials; + +public class AmountMaterialPair { + + private final long amount; + private final Materials material; + + public AmountMaterialPair(Materials type, long amount) { + this.amount = amount; + this.material = type; + } + + public long getAmount() { + return amount; + } + + public Materials getType() { + return material; + } + +} diff --git a/src/main/java/com/songoda/skyblock/levelling/rework/amount/BlockAmount.java b/src/main/java/com/songoda/skyblock/levelling/rework/amount/BlockAmount.java new file mode 100644 index 00000000..5bd5f038 --- /dev/null +++ b/src/main/java/com/songoda/skyblock/levelling/rework/amount/BlockAmount.java @@ -0,0 +1,23 @@ +package com.songoda.skyblock.levelling.rework.amount; + +public class BlockAmount { + + private long amount; + + public BlockAmount(long amount) { + this.amount = amount; + } + + public long getAmount() { + return amount; + } + + public void increaseAmount(long by) { + this.amount += by; + } + + public void setAmount(long newValue) { + this.amount = newValue; + } + +} diff --git a/src/main/java/com/songoda/skyblock/levelling/rework/calculator/Calculator.java b/src/main/java/com/songoda/skyblock/levelling/rework/calculator/Calculator.java new file mode 100644 index 00000000..a50bd46f --- /dev/null +++ b/src/main/java/com/songoda/skyblock/levelling/rework/calculator/Calculator.java @@ -0,0 +1,9 @@ +package com.songoda.skyblock.levelling.rework.calculator; + +import org.bukkit.block.Block; + +public interface Calculator { + + long getAmount(Block block); + +} diff --git a/src/main/java/com/songoda/skyblock/levelling/rework/calculator/CalculatorRegistry.java b/src/main/java/com/songoda/skyblock/levelling/rework/calculator/CalculatorRegistry.java new file mode 100644 index 00000000..c04079d9 --- /dev/null +++ b/src/main/java/com/songoda/skyblock/levelling/rework/calculator/CalculatorRegistry.java @@ -0,0 +1,34 @@ +package com.songoda.skyblock.levelling.rework.calculator; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.bukkit.Material; + +public final class CalculatorRegistry { + + private CalculatorRegistry() { + + } + + private static final Map> calculators = new HashMap<>(); + + public static void registerCalculator(Calculator calculator, Material to) { + + List list = calculators.get(to); + + if (list == null) { + list = new ArrayList<>(); + calculators.put(to, list); + } + + list.add(calculator); + } + + public static List getCalculators(Material type) { + return calculators.get(type); + } + +} diff --git a/src/main/java/com/songoda/skyblock/levelling/rework/calculator/SpawnerCalculator.java b/src/main/java/com/songoda/skyblock/levelling/rework/calculator/SpawnerCalculator.java new file mode 100644 index 00000000..9c50eb98 --- /dev/null +++ b/src/main/java/com/songoda/skyblock/levelling/rework/calculator/SpawnerCalculator.java @@ -0,0 +1,15 @@ +package com.songoda.skyblock.levelling.rework.calculator; + +import org.bukkit.block.Block; +import org.bukkit.block.CreatureSpawner; + +public interface SpawnerCalculator extends Calculator { + + @Override + default long getAmount(Block block) { + return getSpawnerAmount((CreatureSpawner) block.getState()); + } + + long getSpawnerAmount(CreatureSpawner spawner); + +} diff --git a/src/main/java/com/songoda/skyblock/levelling/rework/calculator/impl/EpicSpawnerCalculator.java b/src/main/java/com/songoda/skyblock/levelling/rework/calculator/impl/EpicSpawnerCalculator.java new file mode 100644 index 00000000..3012f1b3 --- /dev/null +++ b/src/main/java/com/songoda/skyblock/levelling/rework/calculator/impl/EpicSpawnerCalculator.java @@ -0,0 +1,17 @@ +package com.songoda.skyblock.levelling.rework.calculator.impl; + +import org.bukkit.block.CreatureSpawner; + +import com.songoda.epicspawners.EpicSpawners; +import com.songoda.epicspawners.spawners.spawner.Spawner; +import com.songoda.skyblock.levelling.rework.calculator.SpawnerCalculator; + +public class EpicSpawnerCalculator implements SpawnerCalculator { + + @Override + public long getSpawnerAmount(CreatureSpawner spawner) { + final Spawner epic = EpicSpawners.getInstance().getSpawnerManager().getSpawnerFromWorld(spawner.getLocation()); + return epic == null ? 0 : epic.getFirstStack().getStackSize(); + } + +} diff --git a/src/main/java/com/songoda/skyblock/levelling/rework/calculator/impl/UltimateStackerCalculator.java b/src/main/java/com/songoda/skyblock/levelling/rework/calculator/impl/UltimateStackerCalculator.java new file mode 100644 index 00000000..66a1716a --- /dev/null +++ b/src/main/java/com/songoda/skyblock/levelling/rework/calculator/impl/UltimateStackerCalculator.java @@ -0,0 +1,19 @@ +package com.songoda.skyblock.levelling.rework.calculator.impl; + +import org.bukkit.block.CreatureSpawner; + +import com.songoda.skyblock.levelling.rework.calculator.SpawnerCalculator; +import com.songoda.ultimatestacker.UltimateStacker; +import com.songoda.ultimatestacker.spawner.SpawnerStack; + +public class UltimateStackerCalculator implements SpawnerCalculator { + + @Override + public long getSpawnerAmount(CreatureSpawner spawner) { + if (!UltimateStacker.getInstance().getConfig().getBoolean("Spawners.Enabled")) return 0; + + final SpawnerStack stack = UltimateStacker.getInstance().getSpawnerStackManager().getSpawner(spawner.getLocation()); + return stack == null ? 0 : stack.getAmount(); + } + +} diff --git a/src/main/java/com/songoda/skyblock/levelling/rework/calculator/impl/WildStackerCalculator.java b/src/main/java/com/songoda/skyblock/levelling/rework/calculator/impl/WildStackerCalculator.java new file mode 100644 index 00000000..f8c06501 --- /dev/null +++ b/src/main/java/com/songoda/skyblock/levelling/rework/calculator/impl/WildStackerCalculator.java @@ -0,0 +1,17 @@ +package com.songoda.skyblock.levelling.rework.calculator.impl; + +import org.bukkit.block.CreatureSpawner; + +import com.bgsoftware.wildstacker.api.WildStackerAPI; +import com.bgsoftware.wildstacker.api.objects.StackedSpawner; +import com.songoda.skyblock.levelling.rework.calculator.SpawnerCalculator; + +public class WildStackerCalculator implements SpawnerCalculator { + + @Override + public long getSpawnerAmount(CreatureSpawner spawner) { + final StackedSpawner stacked = WildStackerAPI.getStackedSpawner(spawner); + return stacked == null ? 0 : stacked.getStackAmount(); + } + +} diff --git a/src/main/java/com/songoda/skyblock/listeners/Block.java b/src/main/java/com/songoda/skyblock/listeners/Block.java index 64430555..c1573319 100644 --- a/src/main/java/com/songoda/skyblock/listeners/Block.java +++ b/src/main/java/com/songoda/skyblock/listeners/Block.java @@ -42,7 +42,7 @@ import com.songoda.skyblock.island.IslandLevel; import com.songoda.skyblock.island.IslandManager; import com.songoda.skyblock.island.IslandRole; import com.songoda.skyblock.island.IslandWorld; -import com.songoda.skyblock.levelling.LevellingManager; +import com.songoda.skyblock.levelling.rework.IslandLevelManager; import com.songoda.skyblock.limit.impl.BlockLimitation; import com.songoda.skyblock.stackable.Stackable; import com.songoda.skyblock.stackable.StackableManager; @@ -187,7 +187,7 @@ public class Block implements Listener { IslandManager islandManager = skyblock.getIslandManager(); WorldManager worldManager = skyblock.getWorldManager(); - LevellingManager levellingManager = skyblock.getLevellingManager(); + IslandLevelManager levellingManager = skyblock.getLevellingManager(); if (!worldManager.isIslandWorld(block.getWorld())) return; IslandWorld world = worldManager.getIslandWorld(block.getWorld()); @@ -198,7 +198,7 @@ public class Block implements Listener { return; } - if (levellingManager.isIslandLevelBeingScanned(island)) { + if (levellingManager.isScanning(island)) { skyblock.getMessageManager().sendMessage(player, skyblock.getFileManager().getConfig(new File(skyblock.getDataFolder(), "language.yml")) .getFileConfiguration().getString("Command.Island.Level.Scanning.BlockPlacing.Message")); diff --git a/src/main/java/com/songoda/skyblock/listeners/Interact.java b/src/main/java/com/songoda/skyblock/listeners/Interact.java index b1d0feb2..9d76890b 100644 --- a/src/main/java/com/songoda/skyblock/listeners/Interact.java +++ b/src/main/java/com/songoda/skyblock/listeners/Interact.java @@ -6,7 +6,7 @@ import com.songoda.skyblock.island.Island; import com.songoda.skyblock.island.IslandLevel; import com.songoda.skyblock.island.IslandManager; import com.songoda.skyblock.island.IslandWorld; -import com.songoda.skyblock.levelling.LevellingManager; +import com.songoda.skyblock.levelling.rework.IslandLevelManager; import com.songoda.skyblock.limit.impl.BlockLimitation; import com.songoda.skyblock.message.MessageManager; import com.songoda.skyblock.sound.SoundManager; @@ -70,7 +70,7 @@ public class Interact implements Listener { IslandManager islandManager = skyblock.getIslandManager(); SoundManager soundManager = skyblock.getSoundManager(); StackableManager stackableManager = skyblock.getStackableManager(); - LevellingManager levellingManager = skyblock.getLevellingManager(); + IslandLevelManager levellingManager = skyblock.getLevellingManager(); Island island = islandManager.getIslandAtLocation(player.getLocation()); if (island == null) { @@ -149,7 +149,7 @@ public class Interact implements Listener { if (event.getHand() == EquipmentSlot.OFF_HAND) return; } - if (levellingManager.isIslandLevelBeingScanned(island)) { + if (levellingManager.isScanning(island)) { skyblock.getMessageManager().sendMessage(player, skyblock.getFileManager().getConfig(new File(skyblock.getDataFolder(), "language.yml")) .getFileConfiguration().getString("Command.Island.Level.Scanning.BlockPlacing.Message")); diff --git a/src/main/java/com/songoda/skyblock/menus/Levelling.java b/src/main/java/com/songoda/skyblock/menus/Levelling.java index d227646f..87c18b46 100644 --- a/src/main/java/com/songoda/skyblock/menus/Levelling.java +++ b/src/main/java/com/songoda/skyblock/menus/Levelling.java @@ -10,7 +10,7 @@ import com.songoda.skyblock.cooldown.CooldownType; import com.songoda.skyblock.island.Island; import com.songoda.skyblock.island.IslandLevel; import com.songoda.skyblock.island.IslandManager; -import com.songoda.skyblock.levelling.LevellingManager; +import com.songoda.skyblock.levelling.rework.IslandLevelManager; import com.songoda.skyblock.message.MessageManager; import com.songoda.skyblock.placeholder.Placeholder; import com.songoda.skyblock.playerdata.PlayerData; @@ -55,7 +55,7 @@ public class Levelling { SkyBlock skyblock = SkyBlock.getInstance(); PlayerDataManager playerDataManager = skyblock.getPlayerDataManager(); - LevellingManager levellingManager = skyblock.getLevellingManager(); + IslandLevelManager levellingManager = skyblock.getLevellingManager(); CooldownManager cooldownManager = skyblock.getCooldownManager(); MessageManager messageManager = skyblock.getMessageManager(); IslandManager islandManager = skyblock.getIslandManager(); @@ -155,7 +155,7 @@ public class Levelling { cooldownManager.createPlayer(CooldownType.Levelling, Bukkit.getServer().getOfflinePlayer(island.getOwnerUUID())); - levellingManager.calculatePoints(player, island); + levellingManager.startScan(player, island); }); } else if ((is.getType() == SkullUtil.createItemStack().getType()) && (is.hasItemMeta())) { PlayerData playerData1 = skyblock.getPlayerDataManager().getPlayerData(player); diff --git a/src/main/java/com/songoda/skyblock/menus/admin/Levelling.java b/src/main/java/com/songoda/skyblock/menus/admin/Levelling.java index 39d5da8f..e4074f1e 100644 --- a/src/main/java/com/songoda/skyblock/menus/admin/Levelling.java +++ b/src/main/java/com/songoda/skyblock/menus/admin/Levelling.java @@ -3,8 +3,8 @@ package com.songoda.skyblock.menus.admin; import com.songoda.skyblock.SkyBlock; import com.songoda.skyblock.config.FileManager; import com.songoda.skyblock.config.FileManager.Config; -import com.songoda.skyblock.levelling.LevellingManager; -import com.songoda.skyblock.levelling.LevellingMaterial; +import com.songoda.skyblock.levelling.rework.IslandLevelManager; +import com.songoda.skyblock.levelling.rework.LevellingMaterial; import com.songoda.skyblock.message.MessageManager; import com.songoda.skyblock.placeholder.Placeholder; import com.songoda.skyblock.playerdata.PlayerData; @@ -51,12 +51,12 @@ public class Levelling implements Listener { public void open(Player player) { SkyBlock skyblock = SkyBlock.getInstance(); - LevellingManager levellingManager = skyblock.getLevellingManager(); + IslandLevelManager levellingManager = skyblock.getLevellingManager(); FileManager fileManager = skyblock.getFileManager(); PlayerData playerData = skyblock.getPlayerDataManager().getPlayerData(player); - List levellingMaterials = levellingManager.getMaterials(); + List levellingMaterials = levellingManager.getWorthsAsLevelingMaterials(); // Filter out materials that won't be displayed in the GUI properly Inventory testInventory = Bukkit.createInventory(null, 9); @@ -153,7 +153,7 @@ public class Levelling implements Listener { if (event.getCurrentItem() != null && event.getCurrentItem().getType() != Material.AIR) { SkyBlock skyblock = SkyBlock.getInstance(); - LevellingManager levellingManager = skyblock.getLevellingManager(); + IslandLevelManager levellingManager = skyblock.getLevellingManager(); MessageManager messageManager = skyblock.getMessageManager(); SoundManager soundManager = skyblock.getSoundManager(); FileManager fileManager = skyblock.getFileManager(); @@ -298,7 +298,7 @@ public class Levelling implements Listener { } if (is.hasItemMeta() && is.getItemMeta().hasDisplayName()) { - for (LevellingMaterial materialList : levellingManager.getMaterials()) { + for (LevellingMaterial materialList : levellingManager.getWorthsAsLevelingMaterials()) { Materials materials = materialList.getMaterials(); if (event.getCurrentItem().getType() == MaterialUtil.correctMaterial(materials.parseMaterial()) @@ -316,7 +316,7 @@ public class Levelling implements Listener { messageManager.sendMessage(player, configLoad.getString("Island.Admin.Levelling.Permission.Message")); soundManager.playSound(player, Sounds.ANVIL_LAND.bukkitSound(), 1.0F, 1.0F); - } else if (levellingManager.containsMaterial(materials)) { + } else if (levellingManager.hasWorth(materials)) { if (event1.getName().matches("[0-9]+")) { int materialPoints = Integer.valueOf(event1.getName()); materialList.setPoints(materialPoints); @@ -378,7 +378,7 @@ public class Levelling implements Listener { gui.setSlot(AbstractAnvilGUI.AnvilSlot.INPUT_LEFT, is); gui.open(); } else if (event.getClick() == ClickType.RIGHT) { - levellingManager.removeMaterial(materialList); + levellingManager.removeWorth(materialList.getMaterials()); open(player); messageManager.sendMessage(player, @@ -417,14 +417,13 @@ public class Levelling implements Listener { materials = Materials.fromString(event.getCurrentItem().getType().name()); } - if (levellingManager.containsMaterial(materials)) { + if (levellingManager.hasWorth(materials)) { messageManager.sendMessage(player, configLoad.getString("Island.Admin.Levelling.Already.Message")); soundManager.playSound(player, Sounds.ANVIL_LAND.bukkitSound(), 1.0F, 1.0F); - return; } - levellingManager.addMaterial(materials, 0); + levellingManager.addWorth(materials, 0); open(player); messageManager.sendMessage(player, configLoad.getString("Island.Admin.Levelling.Added.Message") diff --git a/src/main/java/com/songoda/skyblock/placeholder/PlaceholderManager.java b/src/main/java/com/songoda/skyblock/placeholder/PlaceholderManager.java index dbdee052..357c18c3 100644 --- a/src/main/java/com/songoda/skyblock/placeholder/PlaceholderManager.java +++ b/src/main/java/com/songoda/skyblock/placeholder/PlaceholderManager.java @@ -1,5 +1,17 @@ package com.songoda.skyblock.placeholder; +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.entity.Player; +import org.bukkit.plugin.PluginManager; + import com.songoda.skyblock.SkyBlock; import com.songoda.skyblock.config.FileManager.Config; import com.songoda.skyblock.invite.Invite; @@ -8,21 +20,12 @@ import com.songoda.skyblock.island.IslandManager; import com.songoda.skyblock.island.IslandRole; import com.songoda.skyblock.leaderboard.Leaderboard; import com.songoda.skyblock.leaderboard.LeaderboardManager; -import com.songoda.skyblock.levelling.LevellingManager; +import com.songoda.skyblock.levelling.rework.IslandLevelManager; +import com.songoda.skyblock.upgrade.Upgrade; +import com.songoda.skyblock.upgrade.Upgrade.Type; import com.songoda.skyblock.utils.NumberUtil; import com.songoda.skyblock.utils.version.Materials; import com.songoda.skyblock.visit.VisitManager; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.entity.Player; -import org.bukkit.plugin.PluginManager; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.UUID; public class PlaceholderManager { @@ -66,7 +69,7 @@ public class PlaceholderManager { public String getPlaceholder(Player player, String placeholder) { IslandManager islandManager = skyblock.getIslandManager(); VisitManager visitManager = skyblock.getVisitManager(); - LevellingManager levellingManager = skyblock.getLevellingManager(); + IslandLevelManager levellingManager = skyblock.getLevellingManager(); Island island = islandManager.getIsland(player); @@ -389,11 +392,29 @@ public class PlaceholderManager { return ChatColor.translateAlternateColorCodes('&', configLoad.getString("Placeholder.fabledskyblock_level_block_value.Invalid.Message")); } else { - long blockValue = levellingManager.getMaterial(materials).getPoints(); + long blockValue = levellingManager.getWorth(materials); return ChatColor.translateAlternateColorCodes('&', configLoad.getString("Placeholder.fabledskyblock_level_block_value.Non-empty.Message") .replace("%placeholder", NumberUtil.formatNumberByDecimal(blockValue))); } + } else if (placeholder.toLowerCase().startsWith("fabledskyblock_island_has_upgrade_")) { + Type type; + + final String lower = placeholder.replace("fabledskyblock_island_has_upgrade_", "").toLowerCase(); + + if (lower.isEmpty()) return ""; + + final String toParse = lower.substring(0, 1).toUpperCase() + lower.substring(1); + + try { + type = Upgrade.Type.valueOf(toParse); + } catch (IllegalArgumentException ignored) { + type = null; + } + + if (type == null) return "Invalid type '" + toParse + "'"; + + return Boolean.toString(island.hasUpgrade(type)); } return ""; diff --git a/src/main/java/com/songoda/skyblock/stackable/StackableManager.java b/src/main/java/com/songoda/skyblock/stackable/StackableManager.java index 0e24a1f7..d2e0e270 100644 --- a/src/main/java/com/songoda/skyblock/stackable/StackableManager.java +++ b/src/main/java/com/songoda/skyblock/stackable/StackableManager.java @@ -4,6 +4,7 @@ import com.songoda.skyblock.SkyBlock; import com.songoda.skyblock.config.FileManager; import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.block.Block; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; @@ -12,7 +13,7 @@ import java.util.*; public class StackableManager { - //ToDO: Should pobably be a GUI for this + // ToDO: Should pobably be a GUI for this private final SkyBlock skyblock; private Set stackableMaterials = EnumSet.noneOf(Material.class); @@ -69,7 +70,7 @@ public class StackableManager { public Set getStackableMaterials() { return Collections.unmodifiableSet(stackableMaterials); } - + public boolean isStackableMaterial(Material material) { return stackableMaterials.contains(material); } @@ -84,7 +85,7 @@ public class StackableManager { public Stackable getStack(Location location, Material material) { Stackable stackable = stacks.get(location); - + return stackable != null && stackable.getMaterial() == material ? stackable : null; } @@ -96,4 +97,10 @@ public class StackableManager { stackable.setSize(0); stacks.remove(stackable.getLocation()); } + + public long getStackSizeOf(Location loc, Material type) { + final Stackable stack = getStack(loc, type); + + return stack == null ? 0 : stack.getSize(); + } } diff --git a/src/main/java/com/songoda/skyblock/utils/version/Materials.java b/src/main/java/com/songoda/skyblock/utils/version/Materials.java index 9fb252d4..af6f889f 100644 --- a/src/main/java/com/songoda/skyblock/utils/version/Materials.java +++ b/src/main/java/com/songoda/skyblock/utils/version/Materials.java @@ -6,7 +6,10 @@ import org.bukkit.entity.EntityType; import org.bukkit.inventory.ItemStack; import java.lang.reflect.Method; +import java.util.Collections; +import java.util.EnumSet; import java.util.HashMap; +import java.util.Set; public enum Materials { @@ -1054,7 +1057,13 @@ public enum Materials { ZOMBIE_SPAWN_EGG("MONSTER_EGG", 0), ZOMBIE_VILLAGER_SPAWN_EGG("MONSTER_EGG", 0), ZOMBIE_WALL_HEAD("SKULL", 0); + + private static final Set ALL = Collections.unmodifiableSet(EnumSet.allOf(Materials.class)); + public static Set getAllMaterials(){ + return ALL; + } + static int newV = -1; private static HashMap cachedSearch = new HashMap<>(); String old13Mat; @@ -1096,17 +1105,20 @@ public enum Materials { } public static Materials requestMaterials(String name, byte data) { - if (cachedSearch.containsKey(name.toUpperCase() + "," + data)) - return cachedSearch.get(name.toUpperCase() + "," + data); + + final String blockName = name.toUpperCase() + "," + data; + Materials cached = cachedSearch.get(blockName); + + if (cached != null) return cached; Materials pmat = internalRequestMaterials(name, data); if (pmat != null || data == 0) { - cachedSearch.put(name.toUpperCase() + "," + data, pmat); + cachedSearch.put(blockName, pmat); return pmat; } pmat = internalRequestMaterials(name, (byte) 0); - cachedSearch.put(name.toUpperCase() + "," + data, pmat); + cachedSearch.put(blockName, pmat); return pmat; } @@ -1114,7 +1126,7 @@ public enum Materials { Materials pmat = null; // Try 1.13+ names - for (Materials mat : Materials.values()) { + for (Materials mat : ALL) { if (name.equalsIgnoreCase(mat.name())) { if (pmat == null) pmat = mat; @@ -1125,7 +1137,7 @@ public enum Materials { } // Try 1.12- names - for (Materials mat : Materials.values()) { + for (Materials mat : ALL) { if (name.equalsIgnoreCase(mat.old12Mat)) { if (pmat == null) pmat = mat; @@ -1216,7 +1228,7 @@ public enum Materials { try { return Materials.valueOf(mat.toString()); } catch (IllegalArgumentException e) { - for (Materials xmat : Materials.values()) { + for (Materials xmat : ALL) { if (xmat.old12Mat.equalsIgnoreCase(mat.toString())) { return xmat; } diff --git a/src/main/resources/language.yml b/src/main/resources/language.yml index 6503bf9a..4afc7667 100644 --- a/src/main/resources/language.yml +++ b/src/main/resources/language.yml @@ -78,18 +78,19 @@ Command: Scanning: Finished: Message: '&aIsland level scan complete!' + Should-Display-Message: false Progress: - Message: '&eScanning Island level: &b%percent%' + Message: '&fScanned &a%current_scanned_blocks%&f/&b%max_blocks% &fblocks ( &a%percent%&f%&f )' + Should-Display-Message: true + Display-Every-X-Scan: 3 NotOnIsland: Message: '&bSkyBlock &8| &cError&8: &eYou cannot initiate an Island level scan without being on your Island.' BlockPlacing: Message: '&bSkyBlock &8 | &cError:&8: &eYou cannot place blocks during an Island level scan. Please wait for the scan to finish.' Started: - Message: '&bSkyBlock &8| &aInfo&8: &eA level scan has started on this island.' - Queued: - Message: '&bSkyBlock &8| &aInfo&8: &eA level scan has been &aqueued&e for this island. The scan will start as soon as all other queued scans are complete.' - Done: - Message: '&bSkyBlock &8| &aInfo&8: &eThe scan has completed.' + Message: '&bSkyBlock &8| &aInfo&8: &eStarting the island chunk scan. The block scan will start after this is complete.' + InScan: + Message: '&bSkyBlock &8| &aInfo&8: &eThis island is already being scanned.' Cooldown: Word: Minute: minute(s) @@ -329,7 +330,7 @@ Command: NoIsland: Message: '&bSkyBlock &8| &cError&8: &eA player with that name does not own an island.' Started: - Message: '&bSkyBlock &8| &aInfo&8: &eThe level scan has been queued or started.' + Message: '&bSkyBlock &8| &aInfo&8: &eThe level scan has been started.' Owner: Invalid: Message: '&bSkyBlock &8| &cError&8: &eInvalid: /island admin Owner '