From 9d1a5c7476a5bfb0110270815e255d8a2fd7d7e1 Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 19 Nov 2023 18:08:47 -0800 Subject: [PATCH] Changed top ten internally to use islands instead of players as keys (#295) Added %[gamemode]_top_weighted_value_x% placeholder https://github.com/BentoBoxWorld/Level/issues/294 --- .../world/bentobox/level/LevelsManager.java | 841 +++++++++--------- .../bentobox/level/PlaceholderManager.java | 240 ++--- .../level/commands/AdminStatsCommand.java | 145 ++- .../level/commands/AdminTopCommand.java | 44 +- .../level/commands/AdminTopRemoveCommand.java | 55 +- .../listeners/IslandActivitiesListeners.java | 80 +- .../bentobox/level/objects/TopTenData.java | 33 +- .../bentobox/level/panels/TopLevelPanel.java | 618 ++++++------- .../bentobox/level/LevelsManagerTest.java | 527 ++++++----- .../level/PlaceholderManagerTest.java | 222 ++--- .../level/commands/AdminStatsCommandTest.java | 226 ++--- .../commands/AdminTopRemoveCommandTest.java | 254 +++--- 12 files changed, 1611 insertions(+), 1674 deletions(-) diff --git a/src/main/java/world/bentobox/level/LevelsManager.java b/src/main/java/world/bentobox/level/LevelsManager.java index fa8083d..e9193d7 100644 --- a/src/main/java/world/bentobox/level/LevelsManager.java +++ b/src/main/java/world/bentobox/level/LevelsManager.java @@ -32,452 +32,429 @@ import world.bentobox.level.objects.LevelsData; import world.bentobox.level.objects.TopTenData; public class LevelsManager { - private static final String INTOPTEN = "intopten"; - private static final TreeMap LEVELS; - private static final BigInteger THOUSAND = BigInteger.valueOf(1000); - static { - LEVELS = new TreeMap<>(); + private static final String INTOPTEN = "intopten"; + private static final TreeMap LEVELS; + private static final BigInteger THOUSAND = BigInteger.valueOf(1000); + static { + LEVELS = new TreeMap<>(); - LEVELS.put(THOUSAND, "k"); - LEVELS.put(THOUSAND.pow(2), "M"); - LEVELS.put(THOUSAND.pow(3), "G"); - LEVELS.put(THOUSAND.pow(4), "T"); - } - private final Level addon; + LEVELS.put(THOUSAND, "k"); + LEVELS.put(THOUSAND.pow(2), "M"); + LEVELS.put(THOUSAND.pow(3), "G"); + LEVELS.put(THOUSAND.pow(4), "T"); + } + private final Level addon; - // Database handler for level data - private final Database handler; - // A cache of island levels. - private final Map levelsCache; - // Top ten lists - private final Map topTenLists; + // Database handler for level data + private final Database handler; + // A cache of island levels. + private final Map levelsCache; + // Top ten lists + private final Map topTenLists; - public LevelsManager(Level addon) { - this.addon = addon; - // Get the BentoBox database - // Set up the database handler to store and retrieve data - // Note that these are saved by the BentoBox database - handler = new Database<>(addon, IslandLevels.class); - // Initialize the cache - levelsCache = new HashMap<>(); - // Initialize top ten lists - topTenLists = new ConcurrentHashMap<>(); - } + public LevelsManager(Level addon) { + this.addon = addon; + // Get the BentoBox database + // Set up the database handler to store and retrieve data + // Note that these are saved by the BentoBox database + handler = new Database<>(addon, IslandLevels.class); + // Initialize the cache + levelsCache = new HashMap<>(); + // Initialize top ten lists + topTenLists = new ConcurrentHashMap<>(); + } - public void migrate() { - Database oldDb = new Database<>(addon, LevelsData.class); - oldDb.loadObjects().forEach(ld -> { - try { - UUID owner = UUID.fromString(ld.getUniqueId()); - // Step through each world - ld.getLevels().keySet().stream() - // World - .map(Bukkit::getWorld).filter(Objects::nonNull) - // Island - .map(w -> addon.getIslands().getIsland(w, owner)).filter(Objects::nonNull).forEach(i -> { - // Make new database entry - World w = i.getWorld(); - IslandLevels il = new IslandLevels(i.getUniqueId()); - il.setInitialLevel(ld.getInitialLevel(w)); - il.setLevel(ld.getLevel(w)); - il.setMdCount(ld.getMdCount(w)); - il.setPointsToNextLevel(ld.getPointsToNextLevel(w)); - il.setUwCount(ld.getUwCount(w)); - // Save it - handler.saveObjectAsync(il); - }); - // Now delete the old database entry - oldDb.deleteID(ld.getUniqueId()); - } catch (Exception e) { - addon.logError("Could not migrate level data database! " + e.getMessage()); - e.printStackTrace(); - return; - } - }); - } - - /** - * Add a score to the top players list - * - * @param world - world - * @param targetPlayer - target player - * @param lv - island level - */ - private void addToTopTen(@NonNull World world, @NonNull UUID targetPlayer, long lv) { - // Get top ten - Map topTen = topTenLists.computeIfAbsent(world, k -> new TopTenData(world)).getTopTen(); - // Remove this player from the top list no matter what (we'll put them back - // later if required) - topTen.remove(targetPlayer); - - // Get the island - Island island = addon.getIslands().getIsland(world, targetPlayer); - if (island != null && island.getOwner() != null && hasTopTenPerm(world, island.getOwner())) { - // Insert the owner into the top ten - topTen.put(island.getOwner(), lv); - } - } - - /** - * Add an island to a top ten - * - * @param island - island to add - * @param lv - level - * @return true if successful, false if not added - */ - private boolean addToTopTen(Island island, long lv) { - if (island != null && island.getOwner() != null && hasTopTenPerm(island.getWorld(), island.getOwner())) { - topTenLists.computeIfAbsent(island.getWorld(), k -> new TopTenData(island.getWorld())).getTopTen() - .put(island.getOwner(), lv); - return true; - } - return false; - } - - /** - * Calculate the island level, set all island member's levels to the result and - * try to add the owner to the top ten - * - * @param targetPlayer - uuid of targeted player - owner or team member - * @param island - island to calculate - * @return completable future with the results of the calculation - */ - public CompletableFuture calculateLevel(UUID targetPlayer, Island island) { - CompletableFuture result = new CompletableFuture<>(); - // Fire pre-level calc event - IslandPreLevelEvent e = new IslandPreLevelEvent(targetPlayer, island); - Bukkit.getPluginManager().callEvent(e); - if (e.isCancelled()) { - return CompletableFuture.completedFuture(null); - } - // Add island to the pipeline - addon.getPipeliner().addIsland(island).thenAccept(r -> { - // Results are irrelevant because the island is unowned or deleted, or - // IslandLevelCalcEvent is cancelled - if (r == null || fireIslandLevelCalcEvent(targetPlayer, island, r)) { - result.complete(null); - } - // Save result - setIslandResults(island.getWorld(), island.getOwner(), r); - // Save the island scan details - result.complete(r); - }); - return result; - } - - /** - * Fires the IslandLevelCalculatedEvent and returns true if it is canceled - * - * @param targetPlayer - target player - * @param island - island - * @param results - results set - * @return true if canceled - */ - private boolean fireIslandLevelCalcEvent(UUID targetPlayer, Island island, Results results) { - // Fire post calculation event - IslandLevelCalculatedEvent ilce = new IslandLevelCalculatedEvent(targetPlayer, island, results); - Bukkit.getPluginManager().callEvent(ilce); - if (ilce.isCancelled()) - return true; - // Set the values if they were altered - results.setLevel((Long) ilce.getKeyValues().getOrDefault("level", results.getLevel())); - results.setInitialLevel((Long) ilce.getKeyValues().getOrDefault("initialLevel", results.getInitialLevel())); - results.setDeathHandicap((int) ilce.getKeyValues().getOrDefault("deathHandicap", results.getDeathHandicap())); - results.setPointsToNextLevel( - (Long) ilce.getKeyValues().getOrDefault("pointsToNextLevel", results.getPointsToNextLevel())); - results.setTotalPoints((Long) ilce.getKeyValues().getOrDefault("totalPoints", results.getTotalPoints())); - return ((Boolean) ilce.getKeyValues().getOrDefault("isCancelled", false)); - } - - /** - * Get the string representation of the level. May be converted to shorthand - * notation, e.g., 104556 = 10.5k - * - * @param lvl - long value to represent - * @return string of the level. - */ - public String formatLevel(@Nullable Long lvl) { - if (lvl == null) - return ""; - String level = String.valueOf(lvl); - // Asking for the level of another player - if (addon.getSettings().isShorthand()) { - BigInteger levelValue = BigInteger.valueOf(lvl); - - Map.Entry stage = LEVELS.floorEntry(levelValue); - - if (stage != null) { // level > 1000 - // 1 052 -> 1.0k - // 1 527 314 -> 1.5M - // 3 874 130 021 -> 3.8G - // 4 002 317 889 -> 4.0T - level = new DecimalFormat("#.#").format( - levelValue.divide(stage.getKey().divide(THOUSAND)).doubleValue() / 1000.0) + stage.getValue(); - } - } - return level; - } - - /** - * Get the initial level of the island. Used to zero island levels - * - * @param island - island - * @return initial level of island - */ - public long getInitialLevel(Island island) { - return getLevelsData(island).getInitialLevel(); - } - - /** - * Get level of island from cache for a player. - * - * @param world - world where the island is - * @param targetPlayer - target player UUID - * @return Level of the player's island or zero if player is unknown or UUID is - * null - */ - public long getIslandLevel(@NonNull World world, @Nullable UUID targetPlayer) { - if (targetPlayer == null) - return 0L; - // Get the island - Island island = addon.getIslands().getIsland(world, targetPlayer); - return island == null ? 0L : getLevelsData(island).getLevel(); - } - - /** - * Get the maximum level ever given to this island - * - * @param world - world where the island is - * @param targetPlayer - target player UUID - * @return Max level of the player's island or zero if player is unknown or UUID - * is null - */ - public long getIslandMaxLevel(@NonNull World world, @Nullable UUID targetPlayer) { - if (targetPlayer == null) - return 0L; - // Get the island - Island island = addon.getIslands().getIsland(world, targetPlayer); - return island == null ? 0L : getLevelsData(island).getMaxLevel(); - } - - /** - * Returns a formatted string of the target player's island level - * - * @param world - world where the island is - * @param targetPlayer - target player's UUID - * @return Formatted level of player or zero if player is unknown or UUID is - * null - */ - public String getIslandLevelString(@NonNull World world, @Nullable UUID targetPlayer) { - return formatLevel(getIslandLevel(world, targetPlayer)); - } - - /** - * Load a level data for the island from the cache or database. - * - * @param island - UUID of island - * @return IslandLevels object - */ - @NonNull - public IslandLevels getLevelsData(@NonNull Island island) { - String id = island.getUniqueId(); - if (levelsCache.containsKey(id)) { - return levelsCache.get(id); - } - // Get from database if not in cache - if (handler.objectExists(id)) { - IslandLevels ld = handler.loadObject(id); - if (ld != null) { - levelsCache.put(id, ld); - } else { - handler.deleteID(id); - levelsCache.put(id, new IslandLevels(id)); - } - } else { - levelsCache.put(id, new IslandLevels(id)); - } - // Return cached value - return levelsCache.get(id); - } - - /** - * Get the number of points required until the next level since the last level - * calc - * - * @param world - world where the island is - * @param targetPlayer - target player UUID - * @return string with the number required or blank if the player is unknown - */ - public String getPointsToNextString(@NonNull World world, @Nullable UUID targetPlayer) { - if (targetPlayer == null) - return ""; - Island island = addon.getIslands().getIsland(world, targetPlayer); - return island == null ? "" : String.valueOf(getLevelsData(island).getPointsToNextLevel()); - } - - /** - * Get the top ten for this world. Returns offline players or players with the - * intopten permission. - * - * @param world - world requested - * @param size - size of the top ten - * @return sorted top ten map - */ - @NonNull - public Map getTopTen(@NonNull World world, int size) { - createAndCleanRankings(world); - // Return the sorted map - return Collections.unmodifiableMap(topTenLists.get(world).getTopTen().entrySet().stream() - .filter(e -> addon.getIslands().hasIsland(world, e.getKey())).filter(l -> l.getValue() > 0) - .sorted(Collections.reverseOrder(Map.Entry.comparingByValue())).limit(size) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new))); - } - - void createAndCleanRankings(@NonNull World world) { - topTenLists.computeIfAbsent(world, TopTenData::new); - // Remove player from top ten if they are online and do not have the perm - topTenLists.get(world).getTopTen().keySet().removeIf(u -> !hasTopTenPerm(world, u)); - } - - /** - * @return the topTenLists - */ - public Map getTopTenLists() { - return topTenLists; - } - - /** - * Get the rank of the player in the rankings - * - * @param world - world - * @param uuid - player UUID - * @return rank placing - note - placing of 1 means top ranked - */ - public int getRank(@NonNull World world, UUID uuid) { - createAndCleanRankings(world); - Stream> stream = topTenLists.get(world).getTopTen().entrySet().stream() - .filter(e -> addon.getIslands().hasIsland(world, e.getKey())).filter(l -> l.getValue() > 0) - .sorted(Collections.reverseOrder(Map.Entry.comparingByValue())); - return (int) (stream.takeWhile(x -> !x.getKey().equals(uuid)).map(Map.Entry::getKey).count() + 1); - } - - /** - * Checks if player has the correct top ten perm to have their level saved - * - * @param world - * @param targetPlayer - * @return true if player has the perm or the player is offline - */ - boolean hasTopTenPerm(@NonNull World world, @NonNull UUID targetPlayer) { - String permPrefix = addon.getPlugin().getIWM().getPermissionPrefix(world); - return Bukkit.getPlayer(targetPlayer) == null - || Bukkit.getPlayer(targetPlayer).hasPermission(permPrefix + INTOPTEN); - } - - /** - * Loads all the top tens from the database - */ - public void loadTopTens() { - topTenLists.clear(); - Bukkit.getScheduler().runTaskAsynchronously(addon.getPlugin(), () -> { - addon.log("Generating rankings"); - handler.loadObjects().forEach(il -> { - if (il.getLevel() > 0) { - addon.getIslands().getIslandById(il.getUniqueId()) - .ifPresent(i -> this.addToTopTen(i, il.getLevel())); - } + public void migrate() { + Database oldDb = new Database<>(addon, LevelsData.class); + oldDb.loadObjects().forEach(ld -> { + try { + UUID owner = UUID.fromString(ld.getUniqueId()); + // Step through each world + ld.getLevels().keySet().stream() + // World + .map(Bukkit::getWorld).filter(Objects::nonNull) + // Island + .map(w -> addon.getIslands().getIsland(w, owner)).filter(Objects::nonNull).forEach(i -> { + // Make new database entry + World w = i.getWorld(); + IslandLevels il = new IslandLevels(i.getUniqueId()); + il.setInitialLevel(ld.getInitialLevel(w)); + il.setLevel(ld.getLevel(w)); + il.setMdCount(ld.getMdCount(w)); + il.setPointsToNextLevel(ld.getPointsToNextLevel(w)); + il.setUwCount(ld.getUwCount(w)); + // Save it + handler.saveObjectAsync(il); }); - topTenLists.keySet().forEach(w -> addon.log("Generated rankings for " + w.getName())); - }); - } + // Now delete the old database entry + oldDb.deleteID(ld.getUniqueId()); + } catch (Exception e) { + addon.logError("Could not migrate level data database! " + e.getMessage()); + e.printStackTrace(); + return; + } + }); + } - /** - * Removes a player from a world's top ten and removes world from player's level - * data - * - * @param world - world - * @param uuid - the player's uuid - */ - public void removeEntry(World world, UUID uuid) { - if (topTenLists.containsKey(world)) { - topTenLists.get(world).getTopTen().remove(uuid); + /** + * Add an island to a top ten + * + * @param island - island to add + * @param lv - level + * @return true if successful, false if not added + */ + private boolean addToTopTen(Island island, long lv) { + if (island != null && island.getOwner() != null && hasTopTenPerm(island.getWorld(), island.getOwner())) { + topTenLists.computeIfAbsent(island.getWorld(), k -> new TopTenData(island.getWorld())).getTopTen() + .put(island.getUniqueId(), lv); + return true; + } + return false; + } + + /** + * Calculate the island level, set all island member's levels to the result and + * try to add the owner to the top ten + * + * @param targetPlayer - uuid of targeted player - owner or team member + * @param island - island to calculate + * @return completable future with the results of the calculation + */ + public CompletableFuture calculateLevel(UUID targetPlayer, Island island) { + CompletableFuture result = new CompletableFuture<>(); + // Fire pre-level calc event + IslandPreLevelEvent e = new IslandPreLevelEvent(targetPlayer, island); + Bukkit.getPluginManager().callEvent(e); + if (e.isCancelled()) { + return CompletableFuture.completedFuture(null); + } + // Add island to the pipeline + addon.getPipeliner().addIsland(island).thenAccept(r -> { + // Results are irrelevant because the island is unowned or deleted, or + // IslandLevelCalcEvent is cancelled + if (r == null || fireIslandLevelCalcEvent(targetPlayer, island, r)) { + result.complete(null); + } + // Save result + setIslandResults(island, r); + // Save the island scan details + result.complete(r); + }); + return result; + } + + /** + * Fires the IslandLevelCalculatedEvent and returns true if it is canceled + * + * @param targetPlayer - target player + * @param island - island + * @param results - results set + * @return true if canceled + */ + private boolean fireIslandLevelCalcEvent(UUID targetPlayer, Island island, Results results) { + // Fire post calculation event + IslandLevelCalculatedEvent ilce = new IslandLevelCalculatedEvent(targetPlayer, island, results); + Bukkit.getPluginManager().callEvent(ilce); + if (ilce.isCancelled()) + return true; + // Set the values if they were altered + results.setLevel((Long) ilce.getKeyValues().getOrDefault("level", results.getLevel())); + results.setInitialLevel((Long) ilce.getKeyValues().getOrDefault("initialLevel", results.getInitialLevel())); + results.setDeathHandicap((int) ilce.getKeyValues().getOrDefault("deathHandicap", results.getDeathHandicap())); + results.setPointsToNextLevel( + (Long) ilce.getKeyValues().getOrDefault("pointsToNextLevel", results.getPointsToNextLevel())); + results.setTotalPoints((Long) ilce.getKeyValues().getOrDefault("totalPoints", results.getTotalPoints())); + return ((Boolean) ilce.getKeyValues().getOrDefault("isCancelled", false)); + } + + /** + * Get the string representation of the level. May be converted to shorthand + * notation, e.g., 104556 = 10.5k + * + * @param lvl - long value to represent + * @return string of the level. + */ + public String formatLevel(@Nullable Long lvl) { + if (lvl == null) + return ""; + String level = String.valueOf(lvl); + // Asking for the level of another player + if (addon.getSettings().isShorthand()) { + BigInteger levelValue = BigInteger.valueOf(lvl); + + Map.Entry stage = LEVELS.floorEntry(levelValue); + + if (stage != null) { // level > 1000 + // 1 052 -> 1.0k + // 1 527 314 -> 1.5M + // 3 874 130 021 -> 3.8G + // 4 002 317 889 -> 4.0T + level = new DecimalFormat("#.#").format( + levelValue.divide(stage.getKey().divide(THOUSAND)).doubleValue() / 1000.0) + stage.getValue(); + } + } + return level; + } + + /** + * Get the initial level of the island. Used to zero island levels + * + * @param island - island + * @return initial level of island + */ + public long getInitialLevel(Island island) { + return getLevelsData(island).getInitialLevel(); + } + + /** + * Get level of island from cache for a player. + * + * @param world - world where the island is + * @param targetPlayer - target player UUID + * @return Level of the player's island or zero if player is unknown or UUID is + * null + */ + public long getIslandLevel(@NonNull World world, @Nullable UUID targetPlayer) { + if (targetPlayer == null) + return 0L; + // Get the island + Island island = addon.getIslands().getIsland(world, targetPlayer); + return island == null ? 0L : getLevelsData(island).getLevel(); + } + + /** + * Get the maximum level ever given to this island + * + * @param world - world where the island is + * @param targetPlayer - target player UUID + * @return Max level of the player's island or zero if player is unknown or UUID + * is null + */ + public long getIslandMaxLevel(@NonNull World world, @Nullable UUID targetPlayer) { + if (targetPlayer == null) + return 0L; + // Get the island + Island island = addon.getIslands().getIsland(world, targetPlayer); + return island == null ? 0L : getLevelsData(island).getMaxLevel(); + } + + /** + * Returns a formatted string of the target player's island level + * + * @param world - world where the island is + * @param targetPlayer - target player's UUID + * @return Formatted level of player or zero if player is unknown or UUID is + * null + */ + public String getIslandLevelString(@NonNull World world, @Nullable UUID targetPlayer) { + return formatLevel(getIslandLevel(world, targetPlayer)); + } + + /** + * Load a level data for the island from the cache or database. + * + * @param island - UUID of island + * @return IslandLevels object + */ + @NonNull + public IslandLevels getLevelsData(@NonNull Island island) { + String id = island.getUniqueId(); + if (levelsCache.containsKey(id)) { + return levelsCache.get(id); + } + // Get from database if not in cache + if (handler.objectExists(id)) { + IslandLevels ld = handler.loadObject(id); + if (ld != null) { + levelsCache.put(id, ld); + } else { + handler.deleteID(id); + levelsCache.put(id, new IslandLevels(id)); + } + } else { + levelsCache.put(id, new IslandLevels(id)); + } + // Return cached value + return levelsCache.get(id); + } + + /** + * Get the number of points required until the next level since the last level + * calc + * + * @param world - world where the island is + * @param targetPlayer - target player UUID + * @return string with the number required or blank if the player is unknown + */ + public String getPointsToNextString(@NonNull World world, @Nullable UUID targetPlayer) { + if (targetPlayer == null) + return ""; + Island island = addon.getIslands().getIsland(world, targetPlayer); + return island == null ? "" : String.valueOf(getLevelsData(island).getPointsToNextLevel()); + } + + /** + * Get the top ten for this world. Returns offline players or players with the + * intopten permission. + * + * @param world - world requested + * @param size - size of the top ten + * @return sorted top ten map. The key is the island unique ID + */ + @NonNull + public Map getTopTen(@NonNull World world, int size) { + createAndCleanRankings(world); + // Return the sorted map + return Collections.unmodifiableMap(topTenLists.get(world).getTopTen().entrySet().stream() + .filter(l -> l.getValue() > 0).sorted(Collections.reverseOrder(Map.Entry.comparingByValue())) + .limit(size) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new))); + } + + void createAndCleanRankings(@NonNull World world) { + topTenLists.computeIfAbsent(world, TopTenData::new); + // Remove player from top ten if they are online and do not have the perm + topTenLists.get(world).getTopTen().keySet().removeIf(u -> addon.getIslands().getIslandById(u) + .filter(i -> i.getOwner() == null || !hasTopTenPerm(world, i.getOwner())).isPresent()); + } + + /** + * @return the topTenLists + */ + public Map getTopTenLists() { + return topTenLists; + } + + /** + * Get the rank of the player in the rankings + * + * @param world - world + * @param uuid - player UUID + * @return rank placing - note - placing of 1 means top ranked + */ + public int getRank(@NonNull World world, UUID uuid) { + createAndCleanRankings(world); + Stream> stream = topTenLists.get(world).getTopTen().entrySet().stream() + .filter(l -> l.getValue() > 0).sorted(Collections.reverseOrder(Map.Entry.comparingByValue())); + // Get player's current island + Island island = addon.getIslands().getIsland(world, uuid); + String id = island == null ? null : island.getUniqueId(); + return (int) (stream.takeWhile(x -> !x.getKey().equals(id)).map(Map.Entry::getKey).count() + 1); + } + + /** + * Checks if player has the correct top ten perm to have their level saved + * + * @param world + * @param targetPlayer + * @return true if player has the perm or the player is offline + */ + boolean hasTopTenPerm(@NonNull World world, @NonNull UUID targetPlayer) { + String permPrefix = addon.getPlugin().getIWM().getPermissionPrefix(world); + return Bukkit.getPlayer(targetPlayer) == null + || Bukkit.getPlayer(targetPlayer).hasPermission(permPrefix + INTOPTEN); + } + + /** + * Loads all the top tens from the database + */ + public void loadTopTens() { + topTenLists.clear(); + Bukkit.getScheduler().runTaskAsynchronously(addon.getPlugin(), () -> { + addon.log("Generating rankings"); + handler.loadObjects().forEach(il -> { + if (il.getLevel() > 0) { + addon.getIslands().getIslandById(il.getUniqueId()) + .ifPresent(i -> this.addToTopTen(i, il.getLevel())); } + }); + topTenLists.keySet().forEach(w -> addon.log("Generated rankings for " + w.getName())); + }); + } + /** + * Removes an island from a world's top ten + * + * @param world - world + * @param uuid - the island's uuid + */ + public void removeEntry(World world, String uuid) { + if (topTenLists.containsKey(world)) { + topTenLists.get(world).getTopTen().remove(uuid); } - /** - * Set an initial island level - * - * @param island - the island to set. Must have a non-null world - * @param lv - initial island level - */ - public void setInitialIslandLevel(@NonNull Island island, long lv) { - if (island.getWorld() == null) - return; - levelsCache.computeIfAbsent(island.getUniqueId(), IslandLevels::new).setInitialLevel(lv); - handler.saveObjectAsync(levelsCache.get(island.getUniqueId())); - } + } - /** - * Set the island level for the owner of the island that targetPlayer is a - * member - * - * @param world - world - * @param targetPlayer - player, may be a team member - * @param lv - level - */ - public void setIslandLevel(@NonNull World world, @NonNull UUID targetPlayer, long lv) { - // Get the island - Island island = addon.getIslands().getIsland(world, targetPlayer); - if (island != null) { - String id = island.getUniqueId(); - IslandLevels il = levelsCache.computeIfAbsent(id, IslandLevels::new); - // Remove the initial level - if (addon.getSettings().isZeroNewIslandLevels()) { - il.setLevel(lv - il.getInitialLevel()); - } else { - il.setLevel(lv); - } - handler.saveObjectAsync(levelsCache.get(id)); - // Update TopTen - addToTopTen(world, targetPlayer, levelsCache.get(id).getLevel()); - } + /** + * Set an initial island level + * + * @param island - the island to set. Must have a non-null world + * @param lv - initial island level + */ + public void setInitialIslandLevel(@NonNull Island island, long lv) { + if (island.getWorld() == null) + return; + levelsCache.computeIfAbsent(island.getUniqueId(), IslandLevels::new).setInitialLevel(lv); + handler.saveObjectAsync(levelsCache.get(island.getUniqueId())); + } + /** + * Set the island level for the owner of the island that targetPlayer is a + * member + * + * @param world - world + * @param island - island + * @param lv - level + */ + public void setIslandLevel(@NonNull World world, @NonNull UUID targetPlayer, long lv) { + // Get the island + Island island = addon.getIslands().getIsland(world, targetPlayer); + if (island != null) { + String id = island.getUniqueId(); + IslandLevels il = levelsCache.computeIfAbsent(id, IslandLevels::new); + // Remove the initial level + if (addon.getSettings().isZeroNewIslandLevels()) { + il.setLevel(lv - il.getInitialLevel()); + } else { + il.setLevel(lv); + } + handler.saveObjectAsync(levelsCache.get(id)); + // Update TopTen + addToTopTen(island, levelsCache.get(id).getLevel()); } + } - /** - * Set the island level for the owner of the island that targetPlayer is a - * member - * - * @param world - world - * @param owner - owner of the island - * @param r - results of the calculation - */ - private void setIslandResults(World world, @NonNull UUID owner, Results r) { - // Get the island - Island island = addon.getIslands().getIsland(world, owner); - if (island == null) - return; - IslandLevels ld = levelsCache.computeIfAbsent(island.getUniqueId(), IslandLevels::new); - ld.setLevel(r.getLevel()); - ld.setUwCount(Maps.asMap(r.getUwCount().elementSet(), elem -> r.getUwCount().count(elem))); - ld.setMdCount(Maps.asMap(r.getMdCount().elementSet(), elem -> r.getMdCount().count(elem))); - ld.setPointsToNextLevel(r.getPointsToNextLevel()); - ld.setTotalPoints(r.getTotalPoints()); - levelsCache.put(island.getUniqueId(), ld); - handler.saveObjectAsync(ld); - // Update TopTen - addToTopTen(world, owner, ld.getLevel()); - } + /** + * Set the island level for the owner of the island that targetPlayer is a + * member + * + * @param world - world + * @param owner - owner of the island + * @param r - results of the calculation + */ + private void setIslandResults(Island island, Results r) { + if (island == null) + return; + IslandLevels ld = levelsCache.computeIfAbsent(island.getUniqueId(), IslandLevels::new); + ld.setLevel(r.getLevel()); + ld.setUwCount(Maps.asMap(r.getUwCount().elementSet(), elem -> r.getUwCount().count(elem))); + ld.setMdCount(Maps.asMap(r.getMdCount().elementSet(), elem -> r.getMdCount().count(elem))); + ld.setPointsToNextLevel(r.getPointsToNextLevel()); + ld.setTotalPoints(r.getTotalPoints()); + levelsCache.put(island.getUniqueId(), ld); + handler.saveObjectAsync(ld); + // Update TopTen + addToTopTen(island, ld.getLevel()); + } - /** - * Removes island from cache when it is deleted - * - * @param uniqueId - id of island - */ - public void deleteIsland(String uniqueId) { - levelsCache.remove(uniqueId); - handler.deleteID(uniqueId); - } + /** + * Removes island from cache when it is deleted + * + * @param uniqueId - id of island + */ + public void deleteIsland(String uniqueId) { + levelsCache.remove(uniqueId); + handler.deleteID(uniqueId); + } } diff --git a/src/main/java/world/bentobox/level/PlaceholderManager.java b/src/main/java/world/bentobox/level/PlaceholderManager.java index 5e02a2c..8277a64 100644 --- a/src/main/java/world/bentobox/level/PlaceholderManager.java +++ b/src/main/java/world/bentobox/level/PlaceholderManager.java @@ -2,10 +2,13 @@ package world.bentobox.level; import java.util.Collections; import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; import java.util.UUID; import java.util.stream.Collectors; import org.bukkit.World; +import org.eclipse.jdt.annotation.Nullable; import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.addons.GameModeAddon; @@ -18,6 +21,7 @@ import world.bentobox.level.objects.TopTenData; /** * Handles Level placeholders + * * @author tastybento * */ @@ -27,150 +31,180 @@ public class PlaceholderManager { private final BentoBox plugin; public PlaceholderManager(Level addon) { - this.addon = addon; - this.plugin = addon.getPlugin(); + this.addon = addon; + this.plugin = addon.getPlugin(); } - + protected void registerPlaceholders(GameModeAddon gm) { - if (plugin.getPlaceholdersManager() == null) return; - PlaceholdersManager bpm = plugin.getPlaceholdersManager(); - // Island Level - bpm.registerPlaceholder(addon, - gm.getDescription().getName().toLowerCase() + "_island_level", - user -> addon.getManager().getIslandLevelString(gm.getOverWorld(), user.getUniqueId())); - bpm.registerPlaceholder(addon, - gm.getDescription().getName().toLowerCase() + "_island_level_raw", - user -> String.valueOf(addon.getManager().getIslandLevel(gm.getOverWorld(), user.getUniqueId()))); - bpm.registerPlaceholder(addon, - gm.getDescription().getName().toLowerCase() + "_island_total_points", - user -> { - IslandLevels data = addon.getManager().getLevelsData(addon.getIslands().getIsland(gm.getOverWorld(), user)); - return data.getTotalPoints()+""; - }); + if (plugin.getPlaceholdersManager() == null) + return; + PlaceholdersManager bpm = plugin.getPlaceholdersManager(); + // Island Level + bpm.registerPlaceholder(addon, gm.getDescription().getName().toLowerCase() + "_island_level", + user -> addon.getManager().getIslandLevelString(gm.getOverWorld(), user.getUniqueId())); + // Unformatted island level + bpm.registerPlaceholder(addon, gm.getDescription().getName().toLowerCase() + "_island_level_raw", + user -> String.valueOf(addon.getManager().getIslandLevel(gm.getOverWorld(), user.getUniqueId()))); + // Total number of points counted before applying level formula + bpm.registerPlaceholder(addon, gm.getDescription().getName().toLowerCase() + "_island_total_points", user -> { + IslandLevels data = addon.getManager().getLevelsData(addon.getIslands().getIsland(gm.getOverWorld(), user)); + return data.getTotalPoints() + ""; + }); + // Points to the next level for player + bpm.registerPlaceholder(addon, gm.getDescription().getName().toLowerCase() + "_points_to_next_level", + user -> addon.getManager().getPointsToNextString(gm.getOverWorld(), user.getUniqueId())); + // Maximum level this island has ever been. Current level maybe lower. + bpm.registerPlaceholder(addon, gm.getDescription().getName().toLowerCase() + "_island_level_max", + user -> String.valueOf(addon.getManager().getIslandMaxLevel(gm.getOverWorld(), user.getUniqueId()))); - bpm.registerPlaceholder(addon, - gm.getDescription().getName().toLowerCase() + "_points_to_next_level", - user -> addon.getManager().getPointsToNextString(gm.getOverWorld(), user.getUniqueId())); - bpm.registerPlaceholder(addon, - gm.getDescription().getName().toLowerCase() + "_island_level_max", - user -> String.valueOf(addon.getManager().getIslandMaxLevel(gm.getOverWorld(), user.getUniqueId()))); + // Visited Island Level + bpm.registerPlaceholder(addon, gm.getDescription().getName().toLowerCase() + "_visited_island_level", + user -> getVisitedIslandLevel(gm, user)); - // Visited Island Level - bpm.registerPlaceholder(addon, - gm.getDescription().getName().toLowerCase() + "_visited_island_level", user -> getVisitedIslandLevel(gm, user)); + // Register Top Ten Placeholders + for (int i = 1; i < 11; i++) { + final int rank = i; + // Name + bpm.registerPlaceholder(addon, gm.getDescription().getName().toLowerCase() + "_top_name_" + i, + u -> getRankName(gm.getOverWorld(), rank)); + // Island Name + bpm.registerPlaceholder(addon, gm.getDescription().getName().toLowerCase() + "_top_island_name_" + i, + u -> getRankIslandName(gm.getOverWorld(), rank)); + // Members + bpm.registerPlaceholder(addon, gm.getDescription().getName().toLowerCase() + "_top_members_" + i, + u -> getRankMembers(gm.getOverWorld(), rank)); + // Level + bpm.registerPlaceholder(addon, gm.getDescription().getName().toLowerCase() + "_top_value_" + i, + u -> getRankLevel(gm.getOverWorld(), rank)); + // Weighted Level (Level / number of members) + bpm.registerPlaceholder(addon, gm.getDescription().getName().toLowerCase() + "_top_weighted_value_" + i, + u -> getWeightedRankLevel(gm.getOverWorld(), rank)); + } - // Register Top Ten Placeholders - for (int i = 1; i < 11; i++) { - final int rank = i; - // Name - bpm.registerPlaceholder(addon, - gm.getDescription().getName().toLowerCase() + "_top_name_" + i, u -> getRankName(gm.getOverWorld(), rank)); - // Island Name - bpm.registerPlaceholder(addon, - gm.getDescription().getName().toLowerCase() + "_top_island_name_" + i, u -> getRankIslandName(gm.getOverWorld(), rank)); - // Members - bpm.registerPlaceholder(addon, - gm.getDescription().getName().toLowerCase() + "_top_members_" + i, u -> getRankMembers(gm.getOverWorld(), rank)); - // Level - bpm.registerPlaceholder(addon, - gm.getDescription().getName().toLowerCase() + "_top_value_" + i, u -> getRankLevel(gm.getOverWorld(), rank)); - } - - // Personal rank - bpm.registerPlaceholder(addon, - gm.getDescription().getName().toLowerCase() + "_rank_value", u -> getRankValue(gm.getOverWorld(), u)); + // Personal rank + bpm.registerPlaceholder(addon, gm.getDescription().getName().toLowerCase() + "_rank_value", + u -> getRankValue(gm.getOverWorld(), u)); } /** - * Get the name of the player who holds the rank in this world + * Get the name of the owner of the island who holds the rank in this world. + * * @param world world - * @param rank rank 1 to 10 + * @param rank rank 1 to 10 * @return rank name */ String getRankName(World world, int rank) { - if (rank < 1) rank = 1; - if (rank > Level.TEN) rank = Level.TEN; - return addon.getPlayers().getName(addon.getManager().getTopTen(world, Level.TEN).keySet().stream().skip(rank - 1L).limit(1L).findFirst().orElse(null)); + // Ensure rank is within bounds + rank = Math.max(1, Math.min(rank, Level.TEN)); + @Nullable + UUID owner = addon.getManager().getTopTen(world, Level.TEN).keySet().stream().skip(rank - 1L).limit(1L) + .findFirst().flatMap(addon.getIslands()::getIslandById).map(Island::getOwner).orElse(null); + + return addon.getPlayers().getName(owner); } /** * Get the island name for this rank + * * @param world world - * @param rank rank 1 to 10 + * @param rank rank 1 to 10 * @return name of island or nothing if there isn't one */ String getRankIslandName(World world, int rank) { - if (rank < 1) rank = 1; - if (rank > Level.TEN) rank = Level.TEN; - UUID owner = addon.getManager().getTopTen(world, Level.TEN).keySet().stream().skip(rank - 1L).limit(1L).findFirst().orElse(null); - if (owner != null) { - Island island = addon.getIslands().getIsland(world, owner); - if (island != null) { - return island.getName() == null ? "" : island.getName(); - } - } - return ""; + // Ensure rank is within bounds + rank = Math.max(1, Math.min(rank, Level.TEN)); + return addon.getManager().getTopTen(world, Level.TEN).keySet().stream().skip(rank - 1L).limit(1L).findFirst() + .flatMap(addon.getIslands()::getIslandById).map(Island::getName).orElse(""); } /** * Gets a comma separated string of island member names + * * @param world world - * @param rank rank to request + * @param rank rank to request * @return comma separated string of island member names */ String getRankMembers(World world, int rank) { - if (rank < 1) rank = 1; - if (rank > Level.TEN) rank = Level.TEN; - UUID owner = addon.getManager().getTopTen(world, Level.TEN).keySet().stream().skip(rank - 1L).limit(1L).findFirst().orElse(null); - if (owner != null) { - Island island = addon.getIslands().getIsland(world, owner); - if (island != null) { - // Sort members by rank - return island.getMembers().entrySet().stream() - .filter(e -> e.getValue() >= RanksManager.MEMBER_RANK) - .sorted(Collections.reverseOrder(Map.Entry.comparingByValue())) - .map(Map.Entry::getKey) - .map(addon.getPlayers()::getName) - .collect(Collectors.joining(",")); - } - } - return ""; + // Ensure rank is within bounds + rank = Math.max(1, Math.min(rank, Level.TEN)); + Optional island = addon.getManager().getTopTen(world, Level.TEN).keySet().stream().skip(rank - 1L) + .limit(1L).findFirst().flatMap(addon.getIslands()::getIslandById); + + if (island.isPresent()) { + // Sort members by rank + return island.get().getMembers().entrySet().stream().filter(e -> e.getValue() >= RanksManager.MEMBER_RANK) + .sorted(Collections.reverseOrder(Map.Entry.comparingByValue())).map(Map.Entry::getKey) + .map(addon.getPlayers()::getName).collect(Collectors.joining(",")); + } + return ""; + } + + /** + * Gets the weighted level, which is the level / number of players + * + * @param world world + * @param rank level + * @return weighted level + */ + String getWeightedRankLevel(World world, int rank) { + // Ensure rank is within bounds + rank = Math.max(1, Math.min(rank, Level.TEN)); + + // Retrieve the top ten entries + Map topTen = addon.getManager().getTopTen(world, Level.TEN); + if (topTen.isEmpty()) { + return ""; + } + + // Find the entry corresponding to the rank + Entry entry = topTen.entrySet().stream().skip(rank - 1).findFirst().orElse(null); + if (entry == null) { + return ""; + } + + // Calculate the score + Island island = addon.getIslands().getIslandById(entry.getKey()).orElse(null); + if (island == null || island.getMemberSet().isEmpty()) { + return ""; + } + + double score = (double) entry.getValue() / island.getMemberSet().size(); + + // Format and return the level + return addon.getManager().formatLevel((long) score); + } String getRankLevel(World world, int rank) { - if (rank < 1) rank = 1; - if (rank > Level.TEN) rank = Level.TEN; - return addon.getManager() - .formatLevel(addon.getManager() - .getTopTen(world, Level.TEN) - .values() - .stream() - .skip(rank - 1L) - .limit(1L) - .findFirst() - .orElse(null)); + // Ensure rank is within bounds + rank = Math.max(1, Math.min(rank, Level.TEN)); + return addon.getManager().formatLevel(addon.getManager().getTopTen(world, Level.TEN).values().stream() + .skip(rank - 1L).limit(1L).findFirst().orElse(null)); } - + /** * Return the rank of the player in a world + * * @param world world - * @param user player + * @param user player * @return rank where 1 is the top rank. */ private String getRankValue(World world, User user) { - if (user == null) { - return ""; - } - // Get the island level for this user - long level = addon.getManager().getIslandLevel(world, user.getUniqueId()); - return String.valueOf(addon.getManager().getTopTenLists().getOrDefault(world, new TopTenData(world)).getTopTen().values().stream().filter(l -> l > level).count() + 1); + if (user == null) { + return ""; + } + // Get the island level for this user + long level = addon.getManager().getIslandLevel(world, user.getUniqueId()); + return String.valueOf(addon.getManager().getTopTenLists().getOrDefault(world, new TopTenData(world)).getTopTen() + .values().stream().filter(l -> l > level).count() + 1); } String getVisitedIslandLevel(GameModeAddon gm, User user) { - if (user == null || !gm.inWorld(user.getWorld())) return ""; - return addon.getIslands().getIslandAt(user.getLocation()) - .map(island -> addon.getManager().getIslandLevelString(gm.getOverWorld(), island.getOwner())) - .orElse("0"); + if (user == null || !gm.inWorld(user.getWorld())) + return ""; + return addon.getIslands().getIslandAt(user.getLocation()) + .map(island -> addon.getManager().getIslandLevelString(gm.getOverWorld(), island.getOwner())) + .orElse("0"); } } diff --git a/src/main/java/world/bentobox/level/commands/AdminStatsCommand.java b/src/main/java/world/bentobox/level/commands/AdminStatsCommand.java index 78d5a05..180c41e 100644 --- a/src/main/java/world/bentobox/level/commands/AdminStatsCommand.java +++ b/src/main/java/world/bentobox/level/commands/AdminStatsCommand.java @@ -6,7 +6,6 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.TreeMap; -import java.util.UUID; import java.util.stream.Collectors; import org.bukkit.World; @@ -19,81 +18,81 @@ import world.bentobox.level.objects.TopTenData; public class AdminStatsCommand extends CompositeCommand { - private final Level level; + private final Level level; - public AdminStatsCommand(Level addon, CompositeCommand parent) { - super(parent, "stats"); - this.level = addon; - new AdminTopRemoveCommand(addon, this); + public AdminStatsCommand(Level addon, CompositeCommand parent) { + super(parent, "stats"); + this.level = addon; + new AdminTopRemoveCommand(addon, this); + } + + @Override + public void setup() { + this.setPermission("admin.stats"); + this.setOnlyPlayer(false); + this.setDescription("admin.stats.description"); + } + + @Override + public boolean execute(User user, String label, List args) { + user.sendMessage("admin.stats.title"); + Map topTenLists = level.getManager().getTopTenLists(); + if (topTenLists.isEmpty()) { + user.sendMessage("admin.stats.no-data"); + return false; } + for (Entry en : topTenLists.entrySet()) { + user.sendMessage("admin.stats.world", TextVariables.NAME, + level.getPlugin().getIWM().getWorldName(en.getKey())); + Map topTen = en.getValue().getTopTen(); + if (topTen.isEmpty()) { + user.sendMessage("admin.stats.no-data"); + return false; + } - @Override - public void setup() { - this.setPermission("admin.stats"); - this.setOnlyPlayer(false); - this.setDescription("admin.stats.description"); + // Calculating basic statistics + long sum = 0, max = Long.MIN_VALUE, min = Long.MAX_VALUE; + Map levelFrequency = new HashMap<>(); + + for (Long level : topTen.values()) { + sum += level; + max = Math.max(max, level); + min = Math.min(min, level); + levelFrequency.merge(level, 1, Integer::sum); + } + + double average = sum / (double) topTen.size(); + List sortedLevels = topTen.values().stream().sorted().collect(Collectors.toList()); + long median = sortedLevels.get(sortedLevels.size() / 2); + Long mode = Collections.max(levelFrequency.entrySet(), Map.Entry.comparingByValue()).getKey(); + + // Logging basic statistics + user.sendMessage("admin.stats.average-level", TextVariables.NUMBER, String.valueOf(average)); + user.sendMessage("admin.stats.median-level", TextVariables.NUMBER, String.valueOf(median)); + user.sendMessage("admin.stats.mode-level", TextVariables.NUMBER, String.valueOf(mode)); + user.sendMessage("admin.stats.highest-level", TextVariables.NUMBER, String.valueOf(max)); + user.sendMessage("admin.stats.lowest-level", TextVariables.NUMBER, String.valueOf(min)); + + // Grouping data for distribution analysis + Map rangeMap = new TreeMap<>(); + for (Long level : topTen.values()) { + String range = getRange(level); + rangeMap.merge(range, 1, Integer::sum); + } + + // Logging distribution + user.sendMessage("admin.stats.distribution"); + for (Map.Entry entry : rangeMap.entrySet()) { + user.sendMessage( + entry.getKey() + ": " + entry.getValue() + " " + user.getTranslation("admin.stats.islands")); + } } + return true; + } - @Override - public boolean execute(User user, String label, List args) { - user.sendMessage("admin.stats.title"); - Map topTenLists = level.getManager().getTopTenLists(); - if (topTenLists.isEmpty()) { - user.sendMessage("admin.stats.no-data"); - return false; - } - for (Entry en : topTenLists.entrySet()) { - user.sendMessage("admin.stats.world", TextVariables.NAME, - level.getPlugin().getIWM().getWorldName(en.getKey())); - Map topTen = en.getValue().getTopTen(); - if (topTen.isEmpty()) { - user.sendMessage("admin.stats.no-data"); - return false; - } - - // Calculating basic statistics - long sum = 0, max = Long.MIN_VALUE, min = Long.MAX_VALUE; - Map levelFrequency = new HashMap<>(); - - for (Long level : topTen.values()) { - sum += level; - max = Math.max(max, level); - min = Math.min(min, level); - levelFrequency.merge(level, 1, Integer::sum); - } - - double average = sum / (double) topTen.size(); - List sortedLevels = topTen.values().stream().sorted().collect(Collectors.toList()); - long median = sortedLevels.get(sortedLevels.size() / 2); - Long mode = Collections.max(levelFrequency.entrySet(), Map.Entry.comparingByValue()).getKey(); - - // Logging basic statistics - user.sendMessage("admin.stats.average-level", TextVariables.NUMBER, String.valueOf(average)); - user.sendMessage("admin.stats.median-level", TextVariables.NUMBER, String.valueOf(median)); - user.sendMessage("admin.stats.mode-level", TextVariables.NUMBER, String.valueOf(mode)); - user.sendMessage("admin.stats.highest-level", TextVariables.NUMBER, String.valueOf(max)); - user.sendMessage("admin.stats.lowest-level", TextVariables.NUMBER, String.valueOf(min)); - - // Grouping data for distribution analysis - Map rangeMap = new TreeMap<>(); - for (Long level : topTen.values()) { - String range = getRange(level); - rangeMap.merge(range, 1, Integer::sum); - } - - // Logging distribution - user.sendMessage("admin.stats.distribution"); - for (Map.Entry entry : rangeMap.entrySet()) { - user.sendMessage( - entry.getKey() + ": " + entry.getValue() + " " + user.getTranslation("admin.stats.islands")); - } - } - return true; - } - - private static String getRange(long level) { - long rangeStart = level / 100 * 100; - long rangeEnd = rangeStart + 99; - return rangeStart + "-" + rangeEnd; - } + private static String getRange(long level) { + long rangeStart = level / 100 * 100; + long rangeEnd = rangeStart + 99; + return rangeStart + "-" + rangeEnd; + } } diff --git a/src/main/java/world/bentobox/level/commands/AdminTopCommand.java b/src/main/java/world/bentobox/level/commands/AdminTopCommand.java index 9144107..9287e14 100644 --- a/src/main/java/world/bentobox/level/commands/AdminTopCommand.java +++ b/src/main/java/world/bentobox/level/commands/AdminTopCommand.java @@ -2,7 +2,7 @@ package world.bentobox.level.commands; import java.util.List; import java.util.Map; -import java.util.UUID; +import java.util.Optional; import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.user.User; @@ -14,36 +14,32 @@ public class AdminTopCommand extends CompositeCommand { private final Level levelPlugin; public AdminTopCommand(Level addon, CompositeCommand parent) { - super(parent, "top", "topten"); - this.levelPlugin = addon; - new AdminTopRemoveCommand(addon, this); + super(parent, "top", "topten"); + this.levelPlugin = addon; + new AdminTopRemoveCommand(addon, this); } @Override public void setup() { - this.setPermission("admin.top"); - this.setOnlyPlayer(false); - this.setDescription("admin.top.description"); + this.setPermission("admin.top"); + this.setOnlyPlayer(false); + this.setDescription("admin.top.description"); } @Override public boolean execute(User user, String label, List args) { - user.sendMessage("island.top.gui-title"); - int rank = 0; - for (Map.Entry topTen : levelPlugin.getManager().getTopTen(getWorld(), Level.TEN).entrySet()) { - Island island = getPlugin().getIslands().getIsland(getWorld(), topTen.getKey()); - if (island != null) { - rank++; - user.sendMessage("admin.top.display", - "[rank]", - String.valueOf(rank), - "[name]", - this.getPlugin().getPlayers().getUser(island.getOwner()).getName(), - "[level]", - String.valueOf(topTen.getValue())); - } - } - - return true; + user.sendMessage("island.top.gui-title"); + int rank = 0; + for (Map.Entry topTen : levelPlugin.getManager().getTopTen(getWorld(), Level.TEN).entrySet()) { + Optional is = getPlugin().getIslands().getIslandById(topTen.getKey()); + if (is.isPresent()) { + Island island = is.get(); + rank++; + user.sendMessage("admin.top.display", "[rank]", String.valueOf(rank), "[name]", + this.getPlugin().getPlayers().getUser(island.getOwner()).getName(), "[level]", + String.valueOf(topTen.getValue())); + } + } + return true; } } diff --git a/src/main/java/world/bentobox/level/commands/AdminTopRemoveCommand.java b/src/main/java/world/bentobox/level/commands/AdminTopRemoveCommand.java index b54ca3e..1c51fb9 100644 --- a/src/main/java/world/bentobox/level/commands/AdminTopRemoveCommand.java +++ b/src/main/java/world/bentobox/level/commands/AdminTopRemoveCommand.java @@ -6,10 +6,12 @@ import java.util.Optional; import world.bentobox.bentobox.api.commands.CompositeCommand; import world.bentobox.bentobox.api.localization.TextVariables; import world.bentobox.bentobox.api.user.User; +import world.bentobox.bentobox.database.objects.Island; import world.bentobox.level.Level; /** * Removes a player from the top ten + * * @author tastybento * */ @@ -19,46 +21,53 @@ public class AdminTopRemoveCommand extends CompositeCommand { private User target; public AdminTopRemoveCommand(Level addon, CompositeCommand parent) { - super(parent, "remove", "delete"); - this.addon = addon; + super(parent, "remove", "delete"); + this.addon = addon; } @Override public void setup() { - this.setPermission("admin.top.remove"); - this.setOnlyPlayer(false); - this.setParametersHelp("admin.top.remove.parameters"); - this.setDescription("admin.top.remove.description"); + this.setPermission("admin.top.remove"); + this.setOnlyPlayer(false); + this.setParametersHelp("admin.top.remove.parameters"); + this.setDescription("admin.top.remove.description"); } - /* (non-Javadoc) - * @see world.bentobox.bentobox.api.commands.BentoBoxCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List) + /* + * (non-Javadoc) + * + * @see world.bentobox.bentobox.api.commands.BentoBoxCommand#canExecute(world. + * bentobox.bentobox.api.user.User, java.lang.String, java.util.List) */ @Override public boolean canExecute(User user, String label, List args) { - if (args.size() != 1) { - this.showHelp(this, user); - return false; - } - target = getPlayers().getUser(args.get(0)); - if (target == null) { - user.sendMessage("general.errors.unknown-player", TextVariables.NAME, args.get(0)); - return false; - } + if (args.size() != 1) { + this.showHelp(this, user); + return false; + } + target = getPlayers().getUser(args.get(0)); + if (target == null) { + user.sendMessage("general.errors.unknown-player", TextVariables.NAME, args.get(0)); + return false; + } - return true; + return true; } @Override public boolean execute(User user, String label, List args) { - addon.getManager().removeEntry(getWorld(), target.getUniqueId()); - user.sendMessage("general.success"); - return true; + // Removes islands that this target is an owner of + getIslands().getIslands(getWorld(), target.getUniqueId()).stream() + .filter(is -> target.getUniqueId().equals(is.getOwner())) + .forEach(island -> addon.getManager().removeEntry(getWorld(), island.getUniqueId())); + user.sendMessage("general.success"); + return true; } @Override public Optional> tabComplete(User user, String alias, List args) { - return Optional.of(addon.getManager().getTopTen(getWorld(), Level.TEN).keySet().stream().map(addon.getPlayers()::getName) - .filter(n -> !n.isEmpty()).toList()); + return Optional.of(addon.getManager().getTopTen(getWorld(), Level.TEN).keySet().stream() + .map(getIslands()::getIslandById).flatMap(Optional::stream).map(Island::getOwner) + .map(addon.getPlayers()::getName).filter(n -> !n.isEmpty()).toList()); } } diff --git a/src/main/java/world/bentobox/level/listeners/IslandActivitiesListeners.java b/src/main/java/world/bentobox/level/listeners/IslandActivitiesListeners.java index 05bdfc2..4a75f5c 100644 --- a/src/main/java/world/bentobox/level/listeners/IslandActivitiesListeners.java +++ b/src/main/java/world/bentobox/level/listeners/IslandActivitiesListeners.java @@ -1,7 +1,5 @@ package world.bentobox.level.listeners; -import java.util.UUID; - import org.bukkit.World; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; @@ -21,7 +19,9 @@ import world.bentobox.bentobox.database.objects.Island; import world.bentobox.level.Level; /** - * Listens for new islands or ownership changes and sets the level to zero automatically + * Listens for new islands or ownership changes and sets the level to zero + * automatically + * * @author tastybento * */ @@ -33,93 +33,89 @@ public class IslandActivitiesListeners implements Listener { * @param addon - addon */ public IslandActivitiesListeners(Level addon) { - this.addon = addon; + this.addon = addon; } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onNewIsland(IslandCreatedEvent e) { - if (addon.getSettings().isZeroNewIslandLevels()) { - zeroIsland(e.getIsland()); - } + if (addon.getSettings().isZeroNewIslandLevels()) { + zeroIsland(e.getIsland()); + } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onNewIsland(IslandResettedEvent e) { - if (addon.getSettings().isZeroNewIslandLevels()) { - zeroIsland(e.getIsland()); - } + if (addon.getSettings().isZeroNewIslandLevels()) { + zeroIsland(e.getIsland()); + } } private void zeroIsland(final Island island) { - // Clear the island setting - if (island.getOwner() != null && island.getWorld() != null) { - addon.getPipeliner().zeroIsland(island).thenAccept(results -> - addon.getManager().setInitialIslandLevel(island, results.getLevel())); - } + // Clear the island setting + if (island.getOwner() != null && island.getWorld() != null) { + addon.getPipeliner().zeroIsland(island) + .thenAccept(results -> addon.getManager().setInitialIslandLevel(island, results.getLevel())); + } } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onIslandDelete(IslandPreclearEvent e) { - - // Remove player from the top ten and level - UUID uuid = e.getIsland().getOwner(); - World world = e.getIsland().getWorld(); - remove(world, uuid); + remove(e.getIsland().getWorld(), e.getIsland().getUniqueId()); } @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onIslandDeleted(IslandDeleteEvent e) { - // Remove island - addon.getManager().deleteIsland(e.getIsland().getUniqueId()); + // Remove island + addon.getManager().deleteIsland(e.getIsland().getUniqueId()); } - private void remove(World world, UUID uuid) { - if (uuid != null && world != null) { - addon.getManager().removeEntry(world, uuid); - } + private void remove(World world, String uuid) { + if (uuid != null && world != null) { + addon.getManager().removeEntry(world, uuid); + } } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onNewIslandOwner(TeamSetownerEvent e) { - // Remove player from the top ten and level - remove(e.getIsland().getWorld(), e.getIsland().getOwner()); + // Remove island from the top ten and level + remove(e.getIsland().getWorld(), e.getIsland().getUniqueId()); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onIsland(TeamJoinedEvent e) { - - // Remove player from the top ten and level - remove(e.getIsland().getWorld(), e.getPlayerUUID()); + // TODO: anything to do here? + // Remove player from the top ten and level + // remove(e.getIsland().getWorld(), e.getPlayerUUID()); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onIsland(IslandUnregisteredEvent e) { - // Remove player from the top ten - remove(e.getIsland().getWorld(), e.getPlayerUUID()); + // Remove island from the top ten + remove(e.getIsland().getWorld(), e.getIsland().getUniqueId()); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onIsland(IslandRegisteredEvent e) { - - // Remove player from the top ten - remove(e.getIsland().getWorld(), e.getPlayerUUID()); + // TODO: anything to do here? + // Remove player from the top ten + // remove(e.getIsland().getWorld(), e.getPlayerUUID()); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onIsland(TeamLeaveEvent e) { - - // Remove player from the top ten and level - remove(e.getIsland().getWorld(), e.getPlayerUUID()); + // TODO: anything to do here? + // Remove player from the top ten and level + // remove(e.getIsland().getWorld(), e.getPlayerUUID()); } @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) public void onIsland(TeamKickEvent e) { - - // Remove player from the top ten and level - remove(e.getIsland().getWorld(), e.getPlayerUUID()); + //// TODO: anything to do here? + // Remove player from the top ten and level + // remove(e.getIsland().getWorld(), e.getPlayerUUID()); } } diff --git a/src/main/java/world/bentobox/level/objects/TopTenData.java b/src/main/java/world/bentobox/level/objects/TopTenData.java index e18e8bd..3d50b1f 100644 --- a/src/main/java/world/bentobox/level/objects/TopTenData.java +++ b/src/main/java/world/bentobox/level/objects/TopTenData.java @@ -3,56 +3,41 @@ package world.bentobox.level.objects; import java.util.LinkedHashMap; import java.util.Locale; import java.util.Map; -import java.util.UUID; import org.bukkit.World; import com.google.gson.annotations.Expose; -import world.bentobox.bentobox.database.objects.DataObject; -import world.bentobox.bentobox.database.objects.Table; - /** * This class stores the top ten. + * * @author tastybento * */ -@Table(name = "TopTenData") -public class TopTenData implements DataObject { +public class TopTenData { // UniqueId is the world name @Expose private String uniqueId = ""; @Expose - private Map topTen = new LinkedHashMap<>(); + private Map topTen = new LinkedHashMap<>(); public TopTenData(World k) { - uniqueId = k.getName().toLowerCase(Locale.ENGLISH); + uniqueId = k.getName().toLowerCase(Locale.ENGLISH); } - @Override - public String getUniqueId() { - // This is the world name - return uniqueId; - } - - @Override - public void setUniqueId(String uniqueId) { - // This is the world name - make it always lowercase - this.uniqueId = uniqueId.toLowerCase(Locale.ENGLISH); - } /** * @return the topTen */ - public Map getTopTen() { - return topTen; + public Map getTopTen() { + return topTen; } + /** * @param topTen the topTen to set */ - public void setTopTen(Map topTen) { - this.topTen = topTen; + public void setTopTen(Map topTen) { + this.topTen = topTen; } - } diff --git a/src/main/java/world/bentobox/level/panels/TopLevelPanel.java b/src/main/java/world/bentobox/level/panels/TopLevelPanel.java index e60d377..0254204 100644 --- a/src/main/java/world/bentobox/level/panels/TopLevelPanel.java +++ b/src/main/java/world/bentobox/level/panels/TopLevelPanel.java @@ -5,10 +5,11 @@ package world.bentobox.level.panels; - import java.io.File; import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.Optional; import java.util.UUID; import java.util.stream.Collectors; @@ -29,474 +30,390 @@ import world.bentobox.bentobox.managers.RanksManager; import world.bentobox.level.Level; import world.bentobox.level.util.Utils; - /** * This panel opens top likes panel */ -public class TopLevelPanel -{ - +public class TopLevelPanel { // --------------------------------------------------------------------- // Section: Internal Constructor // --------------------------------------------------------------------- - /** - * This is internal constructor. It is used internally in current class to avoid creating objects everywhere. + * This is internal constructor. It is used internally in current class to avoid + * creating objects everywhere. * - * @param addon Level object. - * @param user User who opens Panel. - * @param world World where gui is opened + * @param addon Level object. + * @param user User who opens Panel. + * @param world World where gui is opened * @param permissionPrefix Permission Prefix */ - private TopLevelPanel(Level addon, User user, World world, String permissionPrefix) - { - this.addon = addon; - this.user = user; - this.world = world; + private TopLevelPanel(Level addon, User user, World world, String permissionPrefix) { + this.addon = addon; + this.user = user; + this.world = world; - this.iconPermission = permissionPrefix + "level.icon"; - - this.topIslands = this.addon.getManager().getTopTen(this.world, 10).entrySet().stream(). - map(entry -> { - Island island = this.addon.getIslandsManager().getIsland(this.world, entry.getKey()); - return new IslandTopRecord(island, entry.getValue()); - }). - collect(Collectors.toList()); + this.iconPermission = permissionPrefix + "level.icon"; + topIslands = new ArrayList<>(); + for (Map.Entry en : addon.getManager().getTopTen(this.world, Level.TEN).entrySet()) { + Optional is = addon.getIslands().getIslandById(en.getKey()); + if (is.isPresent()) { + topIslands.add(new IslandTopRecord(is.get(), en.getValue())); + } + } } - /** - * Build method manages current panel opening. It uses BentoBox PanelAPI that is easy to use and users can get nice - * panels. + * Build method manages current panel opening. It uses BentoBox PanelAPI that is + * easy to use and users can get nice panels. */ - public void build() - { - TemplatedPanelBuilder panelBuilder = new TemplatedPanelBuilder(); + public void build() { + TemplatedPanelBuilder panelBuilder = new TemplatedPanelBuilder(); - panelBuilder.user(this.user); - panelBuilder.world(this.world); + panelBuilder.user(this.user); + panelBuilder.world(this.world); - panelBuilder.template("top_panel", new File(this.addon.getDataFolder(), "panels")); + panelBuilder.template("top_panel", new File(this.addon.getDataFolder(), "panels")); - panelBuilder.registerTypeBuilder("VIEW", this::createViewerButton); - panelBuilder.registerTypeBuilder("TOP", this::createPlayerButton); + panelBuilder.registerTypeBuilder("VIEW", this::createViewerButton); + panelBuilder.registerTypeBuilder("TOP", this::createPlayerButton); - // Register unknown type builder. - panelBuilder.build(); + // Register unknown type builder. + panelBuilder.build(); } - // --------------------------------------------------------------------- // Section: Methods // --------------------------------------------------------------------- - /** * Creates fallback based on template. + * * @param template Template record for fallback button. - * @param index Place of the fallback. + * @param index Place of the fallback. * @return Fallback panel item. */ - private PanelItem createFallback(ItemTemplateRecord template, long index) - { - if (template == null) - { - return null; - } + private PanelItem createFallback(ItemTemplateRecord template, long index) { + if (template == null) { + return null; + } - PanelItemBuilder builder = new PanelItemBuilder(); + PanelItemBuilder builder = new PanelItemBuilder(); - if (template.icon() != null) - { - builder.icon(template.icon().clone()); - } + if (template.icon() != null) { + builder.icon(template.icon().clone()); + } - if (template.title() != null) - { - builder.name(this.user.getTranslation(this.world, template.title(), - TextVariables.NAME, String.valueOf(index))); - } - else - { - builder.name(this.user.getTranslation(this.world, REFERENCE, - TextVariables.NAME, String.valueOf(index))); - } + if (template.title() != null) { + builder.name( + this.user.getTranslation(this.world, template.title(), TextVariables.NAME, String.valueOf(index))); + } else { + builder.name(this.user.getTranslation(this.world, REFERENCE, TextVariables.NAME, String.valueOf(index))); + } - if (template.description() != null) - { - builder.description(this.user.getTranslation(this.world, template.description(), - TextVariables.NUMBER, String.valueOf(index))); - } + if (template.description() != null) { + builder.description(this.user.getTranslation(this.world, template.description(), TextVariables.NUMBER, + String.valueOf(index))); + } - builder.amount(index != 0 ? (int) index : 1); + builder.amount(index != 0 ? (int) index : 1); - return builder.build(); + return builder.build(); } - /** * This method creates player icon with warp functionality. * * @return PanelItem for PanelBuilder. */ - private PanelItem createPlayerButton(ItemTemplateRecord template, TemplatedPanel.ItemSlot itemSlot) - { - int index = (int) template.dataMap().getOrDefault("index", 0); + private PanelItem createPlayerButton(ItemTemplateRecord template, TemplatedPanel.ItemSlot itemSlot) { + int index = (int) template.dataMap().getOrDefault("index", 0); - if (index < 1) - { - return this.createFallback(template.fallback(), index); - } + if (index < 1) { + return this.createFallback(template.fallback(), index); + } - IslandTopRecord islandTopRecord = this.topIslands.size() < index ? null : this.topIslands.get(index - 1); + IslandTopRecord islandTopRecord = this.topIslands.size() < index ? null : this.topIslands.get(index - 1); - if (islandTopRecord == null) - { - return this.createFallback(template.fallback(), index); - } + if (islandTopRecord == null) { + return this.createFallback(template.fallback(), index); + } - return this.createIslandIcon(template, islandTopRecord, index); + return this.createIslandIcon(template, islandTopRecord, index); } - /** * This method creates button from template for given island top record. - * @param template Icon Template. + * + * @param template Icon Template. * @param islandTopRecord Island Top Record. - * @param index Place Index. + * @param index Place Index. * @return PanelItem for PanelBuilder. */ - private PanelItem createIslandIcon(ItemTemplateRecord template, IslandTopRecord islandTopRecord, int index) - { - // Get player island. - Island island = islandTopRecord.island(); + private PanelItem createIslandIcon(ItemTemplateRecord template, IslandTopRecord islandTopRecord, int index) { + // Get player island. + Island island = islandTopRecord.island(); - if (island == null) - { - return this.createFallback(template.fallback(), index); - } + if (island == null) { + return this.createFallback(template.fallback(), index); + } - PanelItemBuilder builder = new PanelItemBuilder(); + PanelItemBuilder builder = new PanelItemBuilder(); - this.populateIslandIcon(builder, template, island); - this.populateIslandTitle(builder, template, island); - this.populateIslandDescription(builder, template, island, islandTopRecord, index); + this.populateIslandIcon(builder, template, island); + this.populateIslandTitle(builder, template, island); + this.populateIslandDescription(builder, template, island, islandTopRecord, index); - builder.amount(index); + builder.amount(index); - // Get only possible actions, by removing all inactive ones. - List activeActions = new ArrayList<>(template.actions()); + // Get only possible actions, by removing all inactive ones. + List activeActions = new ArrayList<>(template.actions()); - activeActions.removeIf(action -> - { - switch (action.actionType().toUpperCase()) - { - case "WARP" -> { - return island.getOwner() == null || - this.addon.getWarpHook() == null || - !this.addon.getWarpHook().getWarpSignsManager().hasWarp(this.world, island.getOwner()); - } - case "VISIT" -> { - return island.getOwner() == null || - this.addon.getVisitHook() == null || - !this.addon.getVisitHook().getAddonManager().preprocessTeleportation(this.user, island); - } - case "VIEW" -> { - return island.getOwner() == null || - !island.getMemberSet(RanksManager.MEMBER_RANK).contains(this.user.getUniqueId()); - } - default -> { - return false; - } - } - }); + activeActions.removeIf(action -> { + switch (action.actionType().toUpperCase()) { + case "WARP" -> { + return island.getOwner() == null || this.addon.getWarpHook() == null + || !this.addon.getWarpHook().getWarpSignsManager().hasWarp(this.world, island.getOwner()); + } + case "VISIT" -> { + return island.getOwner() == null || this.addon.getVisitHook() == null + || !this.addon.getVisitHook().getAddonManager().preprocessTeleportation(this.user, island); + } + case "VIEW" -> { + return island.getOwner() == null + || !island.getMemberSet(RanksManager.MEMBER_RANK).contains(this.user.getUniqueId()); + } + default -> { + return false; + } + } + }); - // Add Click handler - builder.clickHandler((panel, user, clickType, i) -> - { - for (ItemTemplateRecord.ActionRecords action : activeActions) - { - if (clickType == action.clickType() || action.clickType() == ClickType.UNKNOWN) - { - switch (action.actionType().toUpperCase()) - { - case "WARP" -> { - this.user.closeInventory(); - this.addon.getWarpHook().getWarpSignsManager().warpPlayer(this.world, this.user, island.getOwner()); - } - case "VISIT" -> - // The command call implementation solves necessity to check for all visits options, - // like cool down, confirmation and preprocess in single go. Would it be better to write - // all logic here? + // Add Click handler + builder.clickHandler((panel, user, clickType, i) -> { + for (ItemTemplateRecord.ActionRecords action : activeActions) { + if (clickType == action.clickType() || action.clickType() == ClickType.UNKNOWN) { + switch (action.actionType().toUpperCase()) { + case "WARP" -> { + this.user.closeInventory(); + this.addon.getWarpHook().getWarpSignsManager().warpPlayer(this.world, this.user, + island.getOwner()); + } + case "VISIT" -> + // The command call implementation solves necessity to check for all visits + // options, + // like cool down, confirmation and preprocess in single go. Would it be better + // to write + // all logic here? - this.addon.getPlugin().getIWM().getAddon(this.world). - flatMap(GameModeAddon::getPlayerCommand).ifPresent(command -> - { - String mainCommand = - this.addon.getVisitHook().getSettings().getPlayerMainCommand(); + this.addon.getPlugin().getIWM().getAddon(this.world).flatMap(GameModeAddon::getPlayerCommand) + .ifPresent(command -> { + String mainCommand = this.addon.getVisitHook().getSettings().getPlayerMainCommand(); - if (!mainCommand.isBlank()) - { - this.user.closeInventory(); - this.user.performCommand(command.getTopLabel() + " " + mainCommand + " " + island.getOwner()); - } - }); + if (!mainCommand.isBlank()) { + this.user.closeInventory(); + this.user.performCommand( + command.getTopLabel() + " " + mainCommand + " " + island.getOwner()); + } + }); - case "VIEW" -> { - this.user.closeInventory(); - // Open Detailed GUI. - DetailsPanel.openPanel(this.addon, this.world, this.user); - } - // Catch default - default -> { - this.user.closeInventory(); - addon.logError("Unknown action type " + action.actionType().toUpperCase()); - } - } - } - } + case "VIEW" -> { + this.user.closeInventory(); + // Open Detailed GUI. + DetailsPanel.openPanel(this.addon, this.world, this.user); + } + // Catch default + default -> { + this.user.closeInventory(); + addon.logError("Unknown action type " + action.actionType().toUpperCase()); + } + } + } + } - return true; - }); + return true; + }); - // Collect tooltips. - List tooltips = activeActions.stream(). - filter(action -> action.tooltip() != null). - map(action -> this.user.getTranslation(this.world, action.tooltip())). - filter(text -> !text.isBlank()). - collect(Collectors.toCollection(() -> new ArrayList<>(template.actions().size()))); + // Collect tooltips. + List tooltips = activeActions.stream().filter(action -> action.tooltip() != null) + .map(action -> this.user.getTranslation(this.world, action.tooltip())).filter(text -> !text.isBlank()) + .collect(Collectors.toCollection(() -> new ArrayList<>(template.actions().size()))); - // Add tooltips. - if (!tooltips.isEmpty()) - { - // Empty line and tooltips. - builder.description(""); - builder.description(tooltips); - } + // Add tooltips. + if (!tooltips.isEmpty()) { + // Empty line and tooltips. + builder.description(""); + builder.description(tooltips); + } - return builder.build(); + return builder.build(); } - /** - * Populate given panel item builder name with values from template and island objects. + * Populate given panel item builder name with values from template and island + * objects. * - * @param builder the builder + * @param builder the builder * @param template the template - * @param island the island + * @param island the island */ - private void populateIslandTitle(PanelItemBuilder builder, - ItemTemplateRecord template, - Island island) - { + private void populateIslandTitle(PanelItemBuilder builder, ItemTemplateRecord template, Island island) { - // Get Island Name - String nameText; + // Get Island Name + String nameText; - if (island.getName() == null || island.getName().isEmpty()) - { - nameText = this.user.getTranslation(REFERENCE + "owners-island", - PLAYER, - island.getOwner() == null ? - this.user.getTranslation(REFERENCE + "unknown") : - this.addon.getPlayers().getName(island.getOwner())); - } - else - { - nameText = island.getName(); - } + if (island.getName() == null || island.getName().isEmpty()) { + nameText = this.user.getTranslation(REFERENCE + "owners-island", PLAYER, + island.getOwner() == null ? this.user.getTranslation(REFERENCE + "unknown") + : this.addon.getPlayers().getName(island.getOwner())); + } else { + nameText = island.getName(); + } - // Template specific title is always more important than custom one. - if (template.title() != null && !template.title().isBlank()) - { - builder.name(this.user.getTranslation(this.world, template.title(), - TextVariables.NAME, nameText)); - } - else - { - builder.name(this.user.getTranslation(REFERENCE + "name", TextVariables.NAME, nameText)); - } + // Template specific title is always more important than custom one. + if (template.title() != null && !template.title().isBlank()) { + builder.name(this.user.getTranslation(this.world, template.title(), TextVariables.NAME, nameText)); + } else { + builder.name(this.user.getTranslation(REFERENCE + "name", TextVariables.NAME, nameText)); + } } - /** - * Populate given panel item builder icon with values from template and island objects. + * Populate given panel item builder icon with values from template and island + * objects. * - * @param builder the builder + * @param builder the builder * @param template the template - * @param island the island + * @param island the island */ - private void populateIslandIcon(PanelItemBuilder builder, - ItemTemplateRecord template, - Island island) - { - User owner = island.getOwner() == null ? null : User.getInstance(island.getOwner()); + private void populateIslandIcon(PanelItemBuilder builder, ItemTemplateRecord template, Island island) { + User owner = island.getOwner() == null ? null : User.getInstance(island.getOwner()); - // Get permission or island icon - String permissionIcon = owner == null ? null : - Utils.getPermissionValue(owner, this.iconPermission, null); + // Get permission or island icon + String permissionIcon = owner == null ? null : Utils.getPermissionValue(owner, this.iconPermission, null); - Material material; + Material material; - if (permissionIcon != null && !permissionIcon.equals("*")) - { - material = Material.matchMaterial(permissionIcon); - } - else - { - material = null; - } + if (permissionIcon != null && !permissionIcon.equals("*")) { + material = Material.matchMaterial(permissionIcon); + } else { + material = null; + } - if (material != null) - { - if (!material.equals(Material.PLAYER_HEAD)) - { - builder.icon(material); - } - else - { - builder.icon(owner.getName()); - } - } - else if (template.icon() != null) - { - builder.icon(template.icon().clone()); - } - else if (owner != null) - { - builder.icon(owner.getName()); - } - else - { - builder.icon(Material.PLAYER_HEAD); - } + if (material != null) { + if (!material.equals(Material.PLAYER_HEAD)) { + builder.icon(material); + } else { + builder.icon(owner.getName()); + } + } else if (template.icon() != null) { + builder.icon(template.icon().clone()); + } else if (owner != null) { + builder.icon(owner.getName()); + } else { + builder.icon(Material.PLAYER_HEAD); + } } - /** - * Populate given panel item builder description with values from template and island objects. + * Populate given panel item builder description with values from template and + * island objects. * - * @param builder the builder - * @param template the template - * @param island the island + * @param builder the builder + * @param template the template + * @param island the island * @param islandTopRecord the top record object - * @param index place index. + * @param index place index. */ - private void populateIslandDescription(PanelItemBuilder builder, - ItemTemplateRecord template, - Island island, - IslandTopRecord islandTopRecord, - int index) - { - // Get Owner Name - String ownerText = this.user.getTranslation(REFERENCE + "owner", - PLAYER, - island.getOwner() == null ? - this.user.getTranslation(REFERENCE + "unknown") : - this.addon.getPlayers().getName(island.getOwner())); + private void populateIslandDescription(PanelItemBuilder builder, ItemTemplateRecord template, Island island, + IslandTopRecord islandTopRecord, int index) { + // Get Owner Name + String ownerText = this.user.getTranslation(REFERENCE + "owner", PLAYER, + island.getOwner() == null ? this.user.getTranslation(REFERENCE + "unknown") + : this.addon.getPlayers().getName(island.getOwner())); - // Get Members Text - String memberText; + // Get Members Text + String memberText; - if (island.getMemberSet().size() > 1) - { - StringBuilder memberBuilder = new StringBuilder( - this.user.getTranslationOrNothing(REFERENCE + "members-title")); + if (island.getMemberSet().size() > 1) { + StringBuilder memberBuilder = new StringBuilder( + this.user.getTranslationOrNothing(REFERENCE + "members-title")); - for (UUID uuid : island.getMemberSet()) - { - User member = User.getInstance(uuid); + for (UUID uuid : island.getMemberSet()) { + User member = User.getInstance(uuid); - if (memberBuilder.length() > 0) - { - memberBuilder.append("\n"); - } + if (memberBuilder.length() > 0) { + memberBuilder.append("\n"); + } - memberBuilder.append( - this.user.getTranslationOrNothing(REFERENCE + "member", - PLAYER, member.getName())); - } + memberBuilder.append(this.user.getTranslationOrNothing(REFERENCE + "member", PLAYER, member.getName())); + } - memberText = memberBuilder.toString(); - } - else - { - memberText = ""; - } + memberText = memberBuilder.toString(); + } else { + memberText = ""; + } - String placeText = this.user.getTranslation(REFERENCE + "place", - TextVariables.NUMBER, String.valueOf(index)); + String placeText = this.user.getTranslation(REFERENCE + "place", TextVariables.NUMBER, String.valueOf(index)); - String levelText = this.user.getTranslation(REFERENCE + "level", - TextVariables.NUMBER, this.addon.getManager().formatLevel(islandTopRecord.level())); + String levelText = this.user.getTranslation(REFERENCE + "level", TextVariables.NUMBER, + this.addon.getManager().formatLevel(islandTopRecord.level())); - // Template specific description is always more important than custom one. - if (template.description() != null && !template.description().isBlank()) - { - builder.description(this.user.getTranslation(this.world, template.description(), - "[owner]", ownerText, - "[members]", memberText, - "[level]", levelText, - "[place]", placeText). - replaceAll("(?m)^[ \\t]*\\r?\\n", ""). - replaceAll("(? level to island -> level. + * + * @param island island + * @param level level */ - private record IslandTopRecord(Island island, Long level) {} - + private record IslandTopRecord(Island island, Long level) { + } // --------------------------------------------------------------------- // Section: Variables diff --git a/src/test/java/world/bentobox/level/LevelsManagerTest.java b/src/test/java/world/bentobox/level/LevelsManagerTest.java index e077de0..44b1b9b 100644 --- a/src/test/java/world/bentobox/level/LevelsManagerTest.java +++ b/src/test/java/world/bentobox/level/LevelsManagerTest.java @@ -73,60 +73,60 @@ import world.bentobox.level.objects.TopTenData; @PrepareForTest({ Bukkit.class, BentoBox.class, DatabaseSetup.class, PanelBuilder.class }) public class LevelsManagerTest { - @Mock - private static AbstractDatabaseHandler handler; - @Mock - Level addon; - @Mock - private BentoBox plugin; - @Mock - private Settings pluginSettings; + @Mock + private static AbstractDatabaseHandler handler; + @Mock + Level addon; + @Mock + private BentoBox plugin; + @Mock + private Settings pluginSettings; - // Class under test - private LevelsManager lm; - @Mock - private Island island; - @Mock - private Pipeliner pipeliner; - private CompletableFuture cf; - private UUID uuid; - @Mock - private World world; - @Mock - private Player player; - @Mock - private ConfigSettings settings; - @Mock - private User user; - @Mock - private PlayersManager pm; - @Mock - private Inventory inv; - @Mock - private IslandWorldManager iwm; - @Mock - private PluginManager pim; - @Mock - private IslandLevels levelsData; - @Mock - private IslandsManager im; - @Mock - private BukkitScheduler scheduler; + // Class under test + private LevelsManager lm; + @Mock + private Island island; + @Mock + private Pipeliner pipeliner; + private CompletableFuture cf; + private UUID uuid; + @Mock + private World world; + @Mock + private Player player; + @Mock + private ConfigSettings settings; + @Mock + private User user; + @Mock + private PlayersManager pm; + @Mock + private Inventory inv; + @Mock + private IslandWorldManager iwm; + @Mock + private PluginManager pim; + @Mock + private IslandLevels levelsData; + @Mock + private IslandsManager im; + @Mock + private BukkitScheduler scheduler; - @SuppressWarnings("unchecked") - @BeforeClass - public static void beforeClass() { - // This has to be done beforeClass otherwise the tests will interfere with each - // other - handler = mock(AbstractDatabaseHandler.class); - // Database - PowerMockito.mockStatic(DatabaseSetup.class); - DatabaseSetup dbSetup = mock(DatabaseSetup.class); - when(DatabaseSetup.getDatabase()).thenReturn(dbSetup); - when(dbSetup.getHandler(any())).thenReturn(handler); - } + @SuppressWarnings("unchecked") + @BeforeClass + public static void beforeClass() { + // This has to be done beforeClass otherwise the tests will interfere with each + // other + handler = mock(AbstractDatabaseHandler.class); + // Database + PowerMockito.mockStatic(DatabaseSetup.class); + DatabaseSetup dbSetup = mock(DatabaseSetup.class); + when(DatabaseSetup.getDatabase()).thenReturn(dbSetup); + when(dbSetup.getHandler(any())).thenReturn(handler); + } - /** + /** * @throws java.lang.Exception */ @SuppressWarnings("unchecked") @@ -160,7 +160,7 @@ public class LevelsManagerTest { when(island.getMemberSet()).thenReturn(iset); when(island.getOwner()).thenReturn(uuid); when(island.getWorld()).thenReturn(world); - when(island.getUniqueId()).thenReturn(UUID.randomUUID().toString()); + when(island.getUniqueId()).thenReturn(uuid.toString()); // Default to uuid's being island owners when(im.hasIsland(eq(world), any(UUID.class))).thenReturn(true); when(im.getIsland(world, uuid)).thenReturn(island); @@ -232,229 +232,218 @@ public class LevelsManagerTest { lm.migrate(); } - /** - * @throws java.lang.Exception - */ - @After - public void tearDown() throws Exception { - deleteAll(new File("database")); - User.clearUsers(); - Mockito.framework().clearInlineMocks(); - } - - private static void deleteAll(File file) throws IOException { - if (file.exists()) { - Files.walk(file.toPath()).sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete); - } - } - - /** - * Test method for - * {@link world.bentobox.level.LevelsManager#calculateLevel(UUID, world.bentobox.bentobox.database.objects.Island)}. - */ - @Test - public void testCalculateLevel() { - Results results = new Results(); - results.setLevel(10000); - results.setInitialLevel(3); - lm.calculateLevel(uuid, island); - // Complete the pipelined completable future - cf.complete(results); - - assertEquals(10000L, lm.getLevelsData(island).getLevel()); - // Map tt = lm.getTopTen(world, 10); - // assertEquals(1, tt.size()); - // assertTrue(tt.get(uuid) == 10000); - assertEquals(10000L, lm.getIslandMaxLevel(world, uuid)); - - results.setLevel(5000); - lm.calculateLevel(uuid, island); - // Complete the pipelined completable future - cf.complete(results); - assertEquals(5000L, lm.getLevelsData(island).getLevel()); - // Still should be 10000 - assertEquals(10000L, lm.getIslandMaxLevel(world, uuid)); - - } - - /** - * Test method for - * {@link world.bentobox.level.LevelsManager#getInitialLevel(world.bentobox.bentobox.database.objects.Island)}. - */ - @Test - public void testGetInitialLevel() { - assertEquals(0, lm.getInitialLevel(island)); - } - - /** - * Test method for - * {@link world.bentobox.level.LevelsManager#getIslandLevel(org.bukkit.World, java.util.UUID)}. - */ - @Test - public void testGetIslandLevel() { - assertEquals(-5, lm.getIslandLevel(world, uuid)); - } - - /** - * Test method for - * {@link world.bentobox.level.LevelsManager#getPointsToNextString(org.bukkit.World, java.util.UUID)}. - */ - @Test - public void testGetPointsToNextString() { - // No island player - assertEquals("", lm.getPointsToNextString(world, UUID.randomUUID())); - // Player has island - assertEquals("0", lm.getPointsToNextString(world, uuid)); - } - - /** - * Test method for - * {@link world.bentobox.level.LevelsManager#getIslandLevelString(org.bukkit.World, java.util.UUID)}. - */ - @Test - public void testGetIslandLevelString() { - assertEquals("-5", lm.getIslandLevelString(world, uuid)); - } - - /** - * Test method for - * {@link world.bentobox.level.LevelsManager#getLevelsData(java.util.UUID)}. - */ - @Test - public void testGetLevelsData() { - assertEquals(levelsData, lm.getLevelsData(island)); - - } - - /** - * Test method for {@link world.bentobox.level.LevelsManager#formatLevel(long)}. - */ - @Test - public void testFormatLevel() { - assertEquals("123456789", lm.formatLevel(123456789L)); - when(settings.isShorthand()).thenReturn(true); - assertEquals("123.5M", lm.formatLevel(123456789L)); - assertEquals("1.2k", lm.formatLevel(1234L)); - assertEquals("123.5G", lm.formatLevel(123456789352L)); - assertEquals("1.2T", lm.formatLevel(1234567893524L)); - assertEquals("12345.7T", lm.formatLevel(12345678345345349L)); - - } - - /** - * Test method for - * {@link world.bentobox.level.LevelsManager#getTopTen(org.bukkit.World, int)}. - */ - @Test - public void testGetTopTenEmpty() { - Map tt = lm.getTopTen(world, Level.TEN); - assertTrue(tt.isEmpty()); - } - - /** - * Test method for - * {@link world.bentobox.level.LevelsManager#getTopTen(org.bukkit.World, int)}. - */ - @Test - public void testGetTopTen() { - testLoadTopTens(); - Map tt = lm.getTopTen(world, Level.TEN); - assertFalse(tt.isEmpty()); - assertEquals(1, tt.size()); - assertEquals(1, lm.getTopTen(world, 1).size()); - } - - /** - * Test method for {@link world.bentobox.level.LevelsManager#getTopTen(org.bukkit.World, int)}. + /** + * @throws java.lang.Exception */ - @Test - public void testGetTopTenNoOwners() { - when(im.hasIsland(eq(world), any(UUID.class))).thenReturn(false); - testLoadTopTens(); - Map tt = lm.getTopTen(world, Level.TEN); - assertTrue(tt.isEmpty()); + @After + public void tearDown() throws Exception { + deleteAll(new File("database")); + User.clearUsers(); + Mockito.framework().clearInlineMocks(); } - /** - * Test method for - * {@link world.bentobox.level.LevelsManager#hasTopTenPerm(org.bukkit.World, java.util.UUID)}. - */ - @Test - public void testHasTopTenPerm() { - assertTrue(lm.hasTopTenPerm(world, uuid)); + private static void deleteAll(File file) throws IOException { + if (file.exists()) { + Files.walk(file.toPath()).sorted(Comparator.reverseOrder()).map(Path::toFile).forEach(File::delete); } + } - /** - * Test method for {@link world.bentobox.level.LevelsManager#loadTopTens()}. - */ - @Test - public void testLoadTopTens() { - ArgumentCaptor task = ArgumentCaptor.forClass(Runnable.class); - lm.loadTopTens(); - PowerMockito.verifyStatic(Bukkit.class); // 1 - Bukkit.getScheduler(); - verify(scheduler).runTaskAsynchronously(eq(plugin), task.capture()); - task.getValue().run(); - verify(addon).log("Generating rankings"); - verify(addon).log("Generated rankings for bskyblock-world"); + /** + * Test method for + * {@link world.bentobox.level.LevelsManager#calculateLevel(UUID, world.bentobox.bentobox.database.objects.Island)}. + */ + @Test + public void testCalculateLevel() { + Results results = new Results(); + results.setLevel(10000); + results.setInitialLevel(3); + lm.calculateLevel(uuid, island); + // Complete the pipelined completable future + cf.complete(results); + assertEquals(10000L, lm.getLevelsData(island).getLevel()); + // Map tt = lm.getTopTen(world, 10); + // assertEquals(1, tt.size()); + // assertTrue(tt.get(uuid) == 10000); + assertEquals(10000L, lm.getIslandMaxLevel(world, uuid)); + + results.setLevel(5000); + lm.calculateLevel(uuid, island); + // Complete the pipelined completable future + cf.complete(results); + assertEquals(5000L, lm.getLevelsData(island).getLevel()); + // Still should be 10000 + assertEquals(10000L, lm.getIslandMaxLevel(world, uuid)); + + } + + /** + * Test method for + * {@link world.bentobox.level.LevelsManager#getInitialLevel(world.bentobox.bentobox.database.objects.Island)}. + */ + @Test + public void testGetInitialLevel() { + assertEquals(0, lm.getInitialLevel(island)); + } + + /** + * Test method for + * {@link world.bentobox.level.LevelsManager#getIslandLevel(org.bukkit.World, java.util.UUID)}. + */ + @Test + public void testGetIslandLevel() { + assertEquals(-5, lm.getIslandLevel(world, uuid)); + } + + /** + * Test method for + * {@link world.bentobox.level.LevelsManager#getPointsToNextString(org.bukkit.World, java.util.UUID)}. + */ + @Test + public void testGetPointsToNextString() { + // No island player + assertEquals("", lm.getPointsToNextString(world, UUID.randomUUID())); + // Player has island + assertEquals("0", lm.getPointsToNextString(world, uuid)); + } + + /** + * Test method for + * {@link world.bentobox.level.LevelsManager#getIslandLevelString(org.bukkit.World, java.util.UUID)}. + */ + @Test + public void testGetIslandLevelString() { + assertEquals("-5", lm.getIslandLevelString(world, uuid)); + } + + /** + * Test method for + * {@link world.bentobox.level.LevelsManager#getLevelsData(java.util.UUID)}. + */ + @Test + public void testGetLevelsData() { + assertEquals(levelsData, lm.getLevelsData(island)); + + } + + /** + * Test method for {@link world.bentobox.level.LevelsManager#formatLevel(long)}. + */ + @Test + public void testFormatLevel() { + assertEquals("123456789", lm.formatLevel(123456789L)); + when(settings.isShorthand()).thenReturn(true); + assertEquals("123.5M", lm.formatLevel(123456789L)); + assertEquals("1.2k", lm.formatLevel(1234L)); + assertEquals("123.5G", lm.formatLevel(123456789352L)); + assertEquals("1.2T", lm.formatLevel(1234567893524L)); + assertEquals("12345.7T", lm.formatLevel(12345678345345349L)); + + } + + /** + * Test method for + * {@link world.bentobox.level.LevelsManager#getTopTen(org.bukkit.World, int)}. + */ + @Test + public void testGetTopTenEmpty() { + Map tt = lm.getTopTen(world, Level.TEN); + assertTrue(tt.isEmpty()); + } + + /** + * Test method for + * {@link world.bentobox.level.LevelsManager#getTopTen(org.bukkit.World, int)}. + */ + @Test + public void testGetTopTen() { + testLoadTopTens(); + Map tt = lm.getTopTen(world, Level.TEN); + assertFalse(tt.isEmpty()); + assertEquals(1, tt.size()); + assertEquals(1, lm.getTopTen(world, 1).size()); + } + + /** + * Test method for + * {@link world.bentobox.level.LevelsManager#hasTopTenPerm(org.bukkit.World, java.util.UUID)}. + */ + @Test + public void testHasTopTenPerm() { + assertTrue(lm.hasTopTenPerm(world, uuid)); + } + + /** + * Test method for {@link world.bentobox.level.LevelsManager#loadTopTens()}. + */ + @Test + public void testLoadTopTens() { + ArgumentCaptor task = ArgumentCaptor.forClass(Runnable.class); + lm.loadTopTens(); + PowerMockito.verifyStatic(Bukkit.class); // 1 + Bukkit.getScheduler(); + verify(scheduler).runTaskAsynchronously(eq(plugin), task.capture()); + task.getValue().run(); + verify(addon).log("Generating rankings"); + verify(addon).log("Generated rankings for bskyblock-world"); + + } + + /** + * Test method for + * {@link world.bentobox.level.LevelsManager#removeEntry(org.bukkit.World, java.util.UUID)}. + */ + @Test + public void testRemoveEntry() { + testLoadTopTens(); + Map tt = lm.getTopTen(world, Level.TEN); + assertTrue(tt.containsKey(uuid.toString())); + lm.removeEntry(world, uuid.toString()); + tt = lm.getTopTen(world, Level.TEN); + assertFalse(tt.containsKey(uuid.toString())); + } + + /** + * Test method for + * {@link world.bentobox.level.LevelsManager#setInitialIslandLevel(world.bentobox.bentobox.database.objects.Island, long)}. + */ + @Test + public void testSetInitialIslandLevel() { + lm.setInitialIslandLevel(island, Level.TEN); + assertEquals(Level.TEN, lm.getInitialLevel(island)); + } + + /** + * Test method for + * {@link world.bentobox.level.LevelsManager#setIslandLevel(org.bukkit.World, java.util.UUID, long)}. + */ + @Test + public void testSetIslandLevel() { + lm.setIslandLevel(world, uuid, 1234); + assertEquals(1234, lm.getIslandLevel(world, uuid)); + + } + + /** + * Test method for + * {@link world.bentobox.level.LevelsManager#getRank(World, UUID)} + */ + @Test + public void testGetRank() { + lm.createAndCleanRankings(world); + Map ttl = lm.getTopTenLists(); + Map tt = ttl.get(world).getTopTen(); + for (long i = 100; i < 150; i++) { + tt.put(UUID.randomUUID().toString(), i); } - - /** - * Test method for - * {@link world.bentobox.level.LevelsManager#removeEntry(org.bukkit.World, java.util.UUID)}. - */ - @Test - public void testRemoveEntry() { - testLoadTopTens(); - Map tt = lm.getTopTen(world, Level.TEN); - assertTrue(tt.containsKey(uuid)); - lm.removeEntry(world, uuid); - tt = lm.getTopTen(world, Level.TEN); - assertFalse(tt.containsKey(uuid)); - } - - /** - * Test method for - * {@link world.bentobox.level.LevelsManager#setInitialIslandLevel(world.bentobox.bentobox.database.objects.Island, long)}. - */ - @Test - public void testSetInitialIslandLevel() { - lm.setInitialIslandLevel(island, Level.TEN); - assertEquals(Level.TEN, lm.getInitialLevel(island)); - } - - /** - * Test method for - * {@link world.bentobox.level.LevelsManager#setIslandLevel(org.bukkit.World, java.util.UUID, long)}. - */ - @Test - public void testSetIslandLevel() { - lm.setIslandLevel(world, uuid, 1234); - assertEquals(1234, lm.getIslandLevel(world, uuid)); - - } - - /** - * Test method for - * {@link world.bentobox.level.LevelsManager#getRank(World, UUID)} - */ - @Test - public void testGetRank() { - lm.createAndCleanRankings(world); - Map ttl = lm.getTopTenLists(); - Map tt = ttl.get(world).getTopTen(); - for (long i = 100; i < 150; i++) { - tt.put(UUID.randomUUID(), i); - } - // Put player as lowest rank - tt.put(uuid, 10L); - assertEquals(51, lm.getRank(world, uuid)); - // Put player as highest rank - tt.put(uuid, 1000L); - assertEquals(1, lm.getRank(world, uuid)); - // Unknown UUID - lowest rank + 1 - assertEquals(52, lm.getRank(world, UUID.randomUUID())); - } + // Put island as lowest rank + tt.put(uuid.toString(), 10L); + assertEquals(51, lm.getRank(world, uuid)); + // Put island as highest rank + tt.put(uuid.toString(), 1000L); + assertEquals(1, lm.getRank(world, uuid)); + // Unknown UUID - lowest rank + 1 + assertEquals(52, lm.getRank(world, UUID.randomUUID())); + } } diff --git a/src/test/java/world/bentobox/level/PlaceholderManagerTest.java b/src/test/java/world/bentobox/level/PlaceholderManagerTest.java index b780b8e..63cc597 100644 --- a/src/test/java/world/bentobox/level/PlaceholderManagerTest.java +++ b/src/test/java/world/bentobox/level/PlaceholderManagerTest.java @@ -3,6 +3,7 @@ package world.bentobox.level; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -10,9 +11,10 @@ import static org.mockito.Mockito.when; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedHashMap; -import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Optional; import java.util.UUID; import java.util.stream.Collectors; @@ -44,7 +46,7 @@ import world.bentobox.level.objects.IslandLevels; * */ @RunWith(PowerMockRunner.class) -@PrepareForTest({BentoBox.class}) +@PrepareForTest({ BentoBox.class }) public class PlaceholderManagerTest { @Mock @@ -54,7 +56,7 @@ public class PlaceholderManagerTest { @Mock private BentoBox plugin; - private PlaceholderManager pm; + private PlaceholderManager phm; @Mock private PlaceholdersManager bpm; @Mock @@ -67,13 +69,24 @@ public class PlaceholderManagerTest { private Island island; @Mock private User user; - private Map names = new HashMap<>(); - private static final List NAMES = List.of("tasty", "bento", "fred", "bonne", "cyprien", "mael", "joe", "horacio", "steph", "vicky"); - private Map islands = new HashMap<>(); - private Map map = new HashMap<>(); + private static final Map names = new LinkedHashMap<>(); + static { + names.put(UUID.randomUUID(), "tasty"); + names.put(UUID.randomUUID(), "bento"); + names.put(UUID.randomUUID(), "fred"); + names.put(UUID.randomUUID(), "bonne"); + names.put(UUID.randomUUID(), "cyprien"); + names.put(UUID.randomUUID(), "mael"); + names.put(UUID.randomUUID(), "joe"); + names.put(UUID.randomUUID(), "horacio"); + names.put(UUID.randomUUID(), "steph"); + names.put(UUID.randomUUID(), "vicky"); + } + private Map islands = new HashMap<>(); + private Map map = new HashMap<>(); private @NonNull IslandLevels data; @Mock - private PlayersManager players; + private PlayersManager pm; /** * @throws java.lang.Exception @@ -83,29 +96,31 @@ public class PlaceholderManagerTest { when(addon.getPlugin()).thenReturn(plugin); // Users - when(addon.getPlayers()).thenReturn(players); + when(addon.getPlayers()).thenReturn(pm); + // Users when(user.getWorld()).thenReturn(world); when(user.getLocation()).thenReturn(mock(Location.class)); - for (int i = 0; i < Level.TEN; i++) { - UUID uuid = UUID.randomUUID(); - names.put(uuid, NAMES.get(i)); - map.put(uuid, (long)(100 - i)); + int i = 0; + for (Entry n : names.entrySet()) { + UUID uuid = UUID.randomUUID(); // Random island ID + map.put(uuid.toString(), (long)(100 - i++)); // level Island is = new Island(); - is.setOwner(uuid); - is.setName(NAMES.get(i) + "'s island"); - islands.put(uuid, is); + is.setUniqueId(uuid.toString()); + is.setOwner(n.getKey()); + is.setName(n.getValue() + "'s island"); + islands.put(uuid.toString(), is); } // Sort map = map.entrySet().stream() .sorted(Collections.reverseOrder(Map.Entry.comparingByValue())) .collect(Collectors.toMap( Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new)); - when(players.getName(any())).thenAnswer((Answer) invocation -> names.getOrDefault(invocation.getArgument(0, UUID.class), "unknown")); + when(pm.getName(any())).thenAnswer((Answer) invocation -> names.getOrDefault(invocation.getArgument(0, UUID.class), "unknown")); Map members = new HashMap<>(); - map.forEach((uuid, l) -> members.put(uuid, RanksManager.MEMBER_RANK)); - islands.values().forEach(i -> i.setMembers(members)); + names.forEach((uuid, l) -> members.put(uuid, RanksManager.MEMBER_RANK)); + islands.values().forEach(is -> is.setMembers(members)); // Placeholders manager for plugin @@ -120,7 +135,8 @@ public class PlaceholderManagerTest { // Islands when(im.getIsland(any(World.class), any(User.class))).thenReturn(island); when(im.getIslandAt(any(Location.class))).thenReturn(Optional.of(island)); - when(im.getIsland(any(World.class), any(UUID.class))).thenAnswer((Answer) invocation -> islands.get(invocation.getArgument(1, UUID.class))); + when(im.getIslandById(anyString())).thenAnswer((Answer>) invocation -> Optional.of(islands.get(invocation.getArgument(0, String.class)))); + when(im.getIslands(any(), any(UUID.class))).thenReturn(new HashSet<>(islands.values())); when(addon.getIslands()).thenReturn(im); // Levels Manager @@ -136,127 +152,134 @@ public class PlaceholderManagerTest { when(lm.getLevelsData(island)).thenReturn(data); when(addon.getManager()).thenReturn(lm); - pm = new PlaceholderManager(addon); + phm = new PlaceholderManager(addon); } /** - * Test method for {@link world.bentobox.level.PlaceholderManager#PlaceholderManager(world.bentobox.level.Level)}. + * Test method for + * {@link world.bentobox.level.PlaceholderManager#PlaceholderManager(world.bentobox.level.Level)}. */ @Test public void testPlaceholderManager() { - verify(addon).getPlugin(); + verify(addon).getPlugin(); } /** - * Test method for {@link world.bentobox.level.PlaceholderManager#registerPlaceholders(world.bentobox.bentobox.api.addons.GameModeAddon)}. + * Test method for + * {@link world.bentobox.level.PlaceholderManager#registerPlaceholders(world.bentobox.bentobox.api.addons.GameModeAddon)}. */ @Test public void testRegisterPlaceholders() { - pm.registerPlaceholders(gm); - // Island Level - verify(bpm).registerPlaceholder(eq(addon), eq("aoneblock_island_level"), any()); - verify(bpm).registerPlaceholder(eq(addon), eq("aoneblock_island_level_raw"), any()); - verify(bpm).registerPlaceholder(eq(addon), eq("aoneblock_island_total_points"), any()); + phm.registerPlaceholders(gm); + // Island Level + verify(bpm).registerPlaceholder(eq(addon), eq("aoneblock_island_level"), any()); + verify(bpm).registerPlaceholder(eq(addon), eq("aoneblock_island_level_raw"), any()); + verify(bpm).registerPlaceholder(eq(addon), eq("aoneblock_island_total_points"), any()); - verify(bpm).registerPlaceholder(eq(addon), eq("aoneblock_points_to_next_level"), any()); - verify(bpm).registerPlaceholder(eq(addon), eq("aoneblock_island_level_max"), any()); + verify(bpm).registerPlaceholder(eq(addon), eq("aoneblock_points_to_next_level"), any()); + verify(bpm).registerPlaceholder(eq(addon), eq("aoneblock_island_level_max"), any()); - // Visited Island Level - verify(bpm).registerPlaceholder(eq(addon), eq("aoneblock_visited_island_level"), any()); + // Visited Island Level + verify(bpm).registerPlaceholder(eq(addon), eq("aoneblock_visited_island_level"), any()); - // Register Top Ten Placeholders - for (int i = 1; i < 11; i++) { - // Name - verify(bpm).registerPlaceholder(eq(addon), eq("aoneblock_top_name_" + i), any()); - // Island Name - verify(bpm).registerPlaceholder(eq(addon), eq("aoneblock_top_island_name_" + i), any()); - // Members - verify(bpm).registerPlaceholder(eq(addon), eq("aoneblock_top_members_" + i), any()); - // Level - verify(bpm).registerPlaceholder(eq(addon), eq("aoneblock_top_value_" + i), any()); - } + // Register Top Ten Placeholders + for (int i = 1; i < 11; i++) { + // Name + verify(bpm).registerPlaceholder(eq(addon), eq("aoneblock_top_name_" + i), any()); + // Island Name + verify(bpm).registerPlaceholder(eq(addon), eq("aoneblock_top_island_name_" + i), any()); + // Members + verify(bpm).registerPlaceholder(eq(addon), eq("aoneblock_top_members_" + i), any()); + // Level + verify(bpm).registerPlaceholder(eq(addon), eq("aoneblock_top_value_" + i), any()); + } + + // Personal rank + verify(bpm).registerPlaceholder(eq(addon), eq("aoneblock_rank_value"), any()); - // Personal rank - verify(bpm).registerPlaceholder(eq(addon), eq("aoneblock_rank_value"), any()); - } /** - * Test method for {@link world.bentobox.level.PlaceholderManager#getRankName(org.bukkit.World, int)}. + * Test method for + * {@link world.bentobox.level.PlaceholderManager#getRankName(org.bukkit.World, int)}. */ @Test public void testGetRankName() { - // Test extremes - assertEquals("tasty", pm.getRankName(world, 0)); - assertEquals("vicky", pm.getRankName(world, 100)); - // Test the ranks - int rank = 1; - for (String name : NAMES) { - assertEquals(name, pm.getRankName(world, rank++)); - } - + // Test extremes + assertEquals("tasty", phm.getRankName(world, 0)); + assertEquals("vicky", phm.getRankName(world, 100)); + // Test the ranks + int rank = 1; + for (String name : names.values()) { + assertEquals(name, phm.getRankName(world, rank++)); + } + } /** - * Test method for {@link world.bentobox.level.PlaceholderManager#getRankIslandName(org.bukkit.World, int)}. + * Test method for + * {@link world.bentobox.level.PlaceholderManager#getRankIslandName(org.bukkit.World, int)}. */ @Test public void testGetRankIslandName() { - // Test extremes - assertEquals("tasty's island", pm.getRankIslandName(world, 0)); - assertEquals("vicky's island", pm.getRankIslandName(world, 100)); - // Test the ranks - int rank = 1; - for (String name : NAMES) { - assertEquals(name + "'s island", pm.getRankIslandName(world, rank++)); - } - + // Test extremes + assertEquals("tasty's island", phm.getRankIslandName(world, 0)); + assertEquals("vicky's island", phm.getRankIslandName(world, 100)); + // Test the ranks + int rank = 1; + for (String name : names.values()) { + assertEquals(name + "'s island", phm.getRankIslandName(world, rank++)); + } + } /** - * Test method for {@link world.bentobox.level.PlaceholderManager#getRankMembers(org.bukkit.World, int)}. + * Test method for + * {@link world.bentobox.level.PlaceholderManager#getRankMembers(org.bukkit.World, int)}. */ @Test public void testGetRankMembers() { - // Test extremes - check(1, pm.getRankMembers(world, 0)); - check(2, pm.getRankMembers(world, 100)); - // Test the ranks - for (int rank = 1; rank < 11; rank++) { - check(3, pm.getRankMembers(world, rank)); - } + // Test extremes + check(1, phm.getRankMembers(world, 0)); + check(2, phm.getRankMembers(world, 100)); + // Test the ranks + for (int rank = 1; rank < 11; rank++) { + check(3, phm.getRankMembers(world, rank)); + } } - + void check(int indicator, String list) { - for (String n : NAMES) { - assertTrue(n + " is missing for twst " + indicator, list.contains(n)); - } + for (String n : names.values()) { + assertTrue(n + " is missing for test " + indicator, list.contains(n)); + } } /** - * Test method for {@link world.bentobox.level.PlaceholderManager#getRankLevel(org.bukkit.World, int)}. + * Test method for + * {@link world.bentobox.level.PlaceholderManager#getRankLevel(org.bukkit.World, int)}. */ @Test public void testGetRankLevel() { - // Test extremes - assertEquals("100", pm.getRankLevel(world, 0)); - assertEquals("91", pm.getRankLevel(world, 100)); - // Test the ranks - for (int rank = 1; rank < 11; rank++) { - assertEquals(String.valueOf(101 - rank), pm.getRankLevel(world, rank)); - } - + // Test extremes + assertEquals("100", phm.getRankLevel(world, 0)); + assertEquals("91", phm.getRankLevel(world, 100)); + // Test the ranks + for (int rank = 1; rank < 11; rank++) { + assertEquals(String.valueOf(101 - rank), phm.getRankLevel(world, rank)); + } + } /** - * Test method for {@link world.bentobox.level.PlaceholderManager#getVisitedIslandLevel(world.bentobox.bentobox.api.addons.GameModeAddon, world.bentobox.bentobox.api.user.User)}. + * Test method for + * {@link world.bentobox.level.PlaceholderManager#getVisitedIslandLevel(world.bentobox.bentobox.api.addons.GameModeAddon, world.bentobox.bentobox.api.user.User)}. */ @Test public void testGetVisitedIslandLevelNullUser() { - assertEquals("", pm.getVisitedIslandLevel(gm, null)); - + assertEquals("", phm.getVisitedIslandLevel(gm, null)); + } - + /** * Test method for {@link world.bentobox.level.PlaceholderManager#getVisitedIslandLevel(world.bentobox.bentobox.api.addons.GameModeAddon, world.bentobox.bentobox.api.user.User)}. */ @@ -264,26 +287,27 @@ public class PlaceholderManagerTest { public void testGetVisitedIslandLevelUserNotInWorld() { // Another world when(user.getWorld()).thenReturn(mock(World.class)); - assertEquals("", pm.getVisitedIslandLevel(gm, user)); + assertEquals("", phm.getVisitedIslandLevel(gm, user)); } - + /** - * Test method for {@link world.bentobox.level.PlaceholderManager#getVisitedIslandLevel(world.bentobox.bentobox.api.addons.GameModeAddon, world.bentobox.bentobox.api.user.User)}. + * Test method for + * {@link world.bentobox.level.PlaceholderManager#getVisitedIslandLevel(world.bentobox.bentobox.api.addons.GameModeAddon, world.bentobox.bentobox.api.user.User)}. */ @Test public void testGetVisitedIslandLevel() { - assertEquals("1234567", pm.getVisitedIslandLevel(gm, user)); - + assertEquals("1234567", phm.getVisitedIslandLevel(gm, user)); + } - + /** * Test method for {@link world.bentobox.level.PlaceholderManager#getVisitedIslandLevel(world.bentobox.bentobox.api.addons.GameModeAddon, world.bentobox.bentobox.api.user.User)}. */ @Test public void testGetVisitedIslandLevelNoIsland() { when(im.getIslandAt(any(Location.class))).thenReturn(Optional.empty()); - assertEquals("0", pm.getVisitedIslandLevel(gm, user)); + assertEquals("0", phm.getVisitedIslandLevel(gm, user)); } diff --git a/src/test/java/world/bentobox/level/commands/AdminStatsCommandTest.java b/src/test/java/world/bentobox/level/commands/AdminStatsCommandTest.java index f00cd24..21d26d0 100644 --- a/src/test/java/world/bentobox/level/commands/AdminStatsCommandTest.java +++ b/src/test/java/world/bentobox/level/commands/AdminStatsCommandTest.java @@ -52,132 +52,132 @@ import world.bentobox.level.objects.TopTenData; @PrepareForTest({ Bukkit.class, BentoBox.class }) public class AdminStatsCommandTest { - @Mock - private CompositeCommand ic; - private UUID uuid; - @Mock - private User user; - @Mock - private IslandsManager im; - @Mock - private Island island; - @Mock - private Level addon; - @Mock - private World world; - @Mock - private IslandWorldManager iwm; - @Mock - private GameModeAddon gameModeAddon; - @Mock - private Player p; - @Mock - private LocalesManager lm; - @Mock - private PlayersManager pm; + @Mock + private CompositeCommand ic; + private UUID uuid; + @Mock + private User user; + @Mock + private IslandsManager im; + @Mock + private Island island; + @Mock + private Level addon; + @Mock + private World world; + @Mock + private IslandWorldManager iwm; + @Mock + private GameModeAddon gameModeAddon; + @Mock + private Player p; + @Mock + private LocalesManager lm; + @Mock + private PlayersManager pm; - private AdminStatsCommand asc; - private TopTenData ttd; - @Mock - private LevelsManager manager; - @Mock - private Server server; + private AdminStatsCommand asc; + private TopTenData ttd; + @Mock + private LevelsManager manager; + @Mock + private Server server; - @Before - public void setUp() { - // Set up plugin - BentoBox plugin = mock(BentoBox.class); - Whitebox.setInternalState(BentoBox.class, "instance", plugin); - User.setPlugin(plugin); - when(addon.getPlugin()).thenReturn(plugin); + @Before + public void setUp() { + // Set up plugin + BentoBox plugin = mock(BentoBox.class); + Whitebox.setInternalState(BentoBox.class, "instance", plugin); + User.setPlugin(plugin); + when(addon.getPlugin()).thenReturn(plugin); - // Addon - when(ic.getAddon()).thenReturn(addon); - when(ic.getPermissionPrefix()).thenReturn("bskyblock."); - when(ic.getLabel()).thenReturn("island"); - when(ic.getTopLabel()).thenReturn("island"); - when(ic.getWorld()).thenReturn(world); - when(ic.getTopLabel()).thenReturn("bsb"); + // Addon + when(ic.getAddon()).thenReturn(addon); + when(ic.getPermissionPrefix()).thenReturn("bskyblock."); + when(ic.getLabel()).thenReturn("island"); + when(ic.getTopLabel()).thenReturn("island"); + when(ic.getWorld()).thenReturn(world); + when(ic.getTopLabel()).thenReturn("bsb"); - // IWM friendly name - when(plugin.getIWM()).thenReturn(iwm); - when(iwm.getFriendlyName(any())).thenReturn("BSkyBlock"); + // IWM friendly name + when(plugin.getIWM()).thenReturn(iwm); + when(iwm.getFriendlyName(any())).thenReturn("BSkyBlock"); - // World - when(world.toString()).thenReturn("world"); - when(world.getName()).thenReturn("BSkyBlock_world"); + // World + when(world.toString()).thenReturn("world"); + when(world.getName()).thenReturn("BSkyBlock_world"); - // Player manager - when(plugin.getPlayers()).thenReturn(pm); - when(pm.getUser(anyString())).thenReturn(user); - // topTen - when(addon.getManager()).thenReturn(manager); - // User - uuid = UUID.randomUUID(); - when(user.getUniqueId()).thenReturn(uuid); - when(user.getTranslation(any())).thenAnswer(invocation -> invocation.getArgument(0, String.class)); + // Player manager + when(plugin.getPlayers()).thenReturn(pm); + when(pm.getUser(anyString())).thenReturn(user); + // topTen + when(addon.getManager()).thenReturn(manager); + // User + uuid = UUID.randomUUID(); + when(user.getUniqueId()).thenReturn(uuid); + when(user.getTranslation(any())).thenAnswer(invocation -> invocation.getArgument(0, String.class)); - // Bukkit - PowerMockito.mockStatic(Bukkit.class); - when(Bukkit.getServer()).thenReturn(server); - // Mock item factory (for itemstacks) - ItemFactory itemFactory = mock(ItemFactory.class); - ItemMeta itemMeta = mock(ItemMeta.class); - when(itemFactory.getItemMeta(any())).thenReturn(itemMeta); - when(server.getItemFactory()).thenReturn(itemFactory); - when(Bukkit.getItemFactory()).thenReturn(itemFactory); + // Bukkit + PowerMockito.mockStatic(Bukkit.class); + when(Bukkit.getServer()).thenReturn(server); + // Mock item factory (for itemstacks) + ItemFactory itemFactory = mock(ItemFactory.class); + ItemMeta itemMeta = mock(ItemMeta.class); + when(itemFactory.getItemMeta(any())).thenReturn(itemMeta); + when(server.getItemFactory()).thenReturn(itemFactory); + when(Bukkit.getItemFactory()).thenReturn(itemFactory); - // Top ten - ttd = new TopTenData(world); - Map topten = new HashMap<>(); - Random r = new Random(); - for (int i = 0; i < 1000; i++) { - topten.put(UUID.randomUUID(), r.nextLong(20000)); - } - ttd.setTopTen(topten); - asc = new AdminStatsCommand(addon, ic); + // Top ten + ttd = new TopTenData(world); + Map topten = new HashMap<>(); + Random r = new Random(); + for (int i = 0; i < 1000; i++) { + topten.put(UUID.randomUUID().toString(), r.nextLong(20000)); } + ttd.setTopTen(topten); + asc = new AdminStatsCommand(addon, ic); + } - @After - public void tearDown() { - User.clearUsers(); - } + @After + public void tearDown() { + User.clearUsers(); + } - /** - * Test method for - * {@link world.bentobox.level.commands.AdminStatsCommand#setup()}. - */ - @Test - public void testSetup() { - assertEquals("bskyblock.admin.stats", asc.getPermission()); - assertFalse(asc.isOnlyPlayer()); - assertEquals("admin.stats.description", asc.getDescription()); + /** + * Test method for + * {@link world.bentobox.level.commands.AdminStatsCommand#setup()}. + */ + @Test + public void testSetup() { + assertEquals("bskyblock.admin.stats", asc.getPermission()); + assertFalse(asc.isOnlyPlayer()); + assertEquals("admin.stats.description", asc.getDescription()); - } + } - /** - * Test method for - * {@link world.bentobox.level.commands.AdminStatsCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. - */ - @Test - public void testExecuteUserStringListOfString() { - assertFalse(asc.execute(user, "", List.of())); - verify(user).sendMessage("admin.stats.title"); - verify(user).sendMessage("admin.stats.no-data"); - } + /** + * Test method for + * {@link world.bentobox.level.commands.AdminStatsCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testExecuteUserStringListOfString() { + assertFalse(asc.execute(user, "", List.of())); + verify(user).sendMessage("admin.stats.title"); + verify(user).sendMessage("admin.stats.no-data"); + } - /** - * Test method for - * {@link world.bentobox.level.commands.AdminStatsCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. - */ - @Test - public void testExecuteUserStringListOfStringLevels() { - Map map = new HashMap<>(); - map.put(world, ttd); - when(manager.getTopTenLists()).thenReturn(map); - assertTrue(asc.execute(user, "", List.of())); - verify(user).sendMessage("admin.stats.title"); - verify(user, never()).sendMessage("admin.stats.no-data"); - } + /** + * Test method for + * {@link world.bentobox.level.commands.AdminStatsCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testExecuteUserStringListOfStringLevels() { + Map map = new HashMap<>(); + map.put(world, ttd); + when(manager.getTopTenLists()).thenReturn(map); + assertTrue(asc.execute(user, "", List.of())); + verify(user).sendMessage("admin.stats.title"); + verify(user, never()).sendMessage("admin.stats.no-data"); + } } diff --git a/src/test/java/world/bentobox/level/commands/AdminTopRemoveCommandTest.java b/src/test/java/world/bentobox/level/commands/AdminTopRemoveCommandTest.java index af38901..9e82384 100644 --- a/src/test/java/world/bentobox/level/commands/AdminTopRemoveCommandTest.java +++ b/src/test/java/world/bentobox/level/commands/AdminTopRemoveCommandTest.java @@ -5,12 +5,12 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.Collections; +import java.util.Set; import java.util.UUID; import org.bukkit.Bukkit; @@ -51,122 +51,130 @@ import world.bentobox.level.objects.TopTenData; @PrepareForTest({ Bukkit.class, BentoBox.class }) public class AdminTopRemoveCommandTest { - @Mock - private CompositeCommand ic; - private UUID uuid; - @Mock - private User user; - @Mock - private IslandsManager im; - @Mock - private Island island; - @Mock - private Level addon; - @Mock - private World world; - @Mock - private IslandWorldManager iwm; - @Mock - private GameModeAddon gameModeAddon; - @Mock - private Player p; - @Mock - private LocalesManager lm; - @Mock - private PlayersManager pm; + @Mock + private CompositeCommand ic; + private UUID uuid; + @Mock + private User user; + @Mock + private IslandsManager im; + @Mock + private Island island; + @Mock + private Level addon; + @Mock + private World world; + @Mock + private IslandWorldManager iwm; + @Mock + private GameModeAddon gameModeAddon; + @Mock + private Player p; + @Mock + private LocalesManager lm; + @Mock + private PlayersManager pm; - private AdminTopRemoveCommand atrc; - @Mock - private TopTenData ttd; - @Mock - private LevelsManager manager; - @Mock - private Server server; + private AdminTopRemoveCommand atrc; + @Mock + private TopTenData ttd; + @Mock + private LevelsManager manager; + @Mock + private Server server; - @Before - public void setUp() { - // Set up plugin - BentoBox plugin = mock(BentoBox.class); - Whitebox.setInternalState(BentoBox.class, "instance", plugin); - User.setPlugin(plugin); - // Addon - when(ic.getAddon()).thenReturn(addon); - when(ic.getPermissionPrefix()).thenReturn("bskyblock."); - when(ic.getLabel()).thenReturn("island"); - when(ic.getTopLabel()).thenReturn("island"); - when(ic.getWorld()).thenReturn(world); - when(ic.getTopLabel()).thenReturn("bsb"); + @Before + public void setUp() { + // Set up plugin + BentoBox plugin = mock(BentoBox.class); + Whitebox.setInternalState(BentoBox.class, "instance", plugin); + User.setPlugin(plugin); - // IWM friendly name - when(plugin.getIWM()).thenReturn(iwm); - when(iwm.getFriendlyName(any())).thenReturn("BSkyBlock"); + // Addon + when(ic.getAddon()).thenReturn(addon); + when(ic.getPermissionPrefix()).thenReturn("bskyblock."); + when(ic.getLabel()).thenReturn("island"); + when(ic.getTopLabel()).thenReturn("island"); + when(ic.getWorld()).thenReturn(world); + when(ic.getTopLabel()).thenReturn("bsb"); - // World - when(world.toString()).thenReturn("world"); - when(world.getName()).thenReturn("BSkyBlock_world"); + // IWM friendly name + when(plugin.getIWM()).thenReturn(iwm); + when(iwm.getFriendlyName(any())).thenReturn("BSkyBlock"); - // Player manager - when(plugin.getPlayers()).thenReturn(pm); - when(pm.getUser(anyString())).thenReturn(user); - // topTen - when(addon.getManager()).thenReturn(manager); - // User - uuid = UUID.randomUUID(); - when(user.getUniqueId()).thenReturn(uuid); - when(user.getTranslation(any())).thenAnswer(invocation -> invocation.getArgument(0, String.class)); + // World + when(world.toString()).thenReturn("world"); + when(world.getName()).thenReturn("BSkyBlock_world"); - // Bukkit - PowerMockito.mockStatic(Bukkit.class); - when(Bukkit.getServer()).thenReturn(server); - // Mock item factory (for itemstacks) - ItemFactory itemFactory = mock(ItemFactory.class); - ItemMeta itemMeta = mock(ItemMeta.class); - when(itemFactory.getItemMeta(any())).thenReturn(itemMeta); - when(server.getItemFactory()).thenReturn(itemFactory); - when(Bukkit.getItemFactory()).thenReturn(itemFactory); + // Player manager + when(plugin.getPlayers()).thenReturn(pm); + when(pm.getUser(anyString())).thenReturn(user); + // topTen + when(addon.getManager()).thenReturn(manager); + // User + uuid = UUID.randomUUID(); + when(user.getUniqueId()).thenReturn(uuid); + when(user.getTranslation(any())).thenAnswer(invocation -> invocation.getArgument(0, String.class)); + // Island + when(island.getUniqueId()).thenReturn(uuid.toString()); + when(island.getOwner()).thenReturn(uuid); + // Island Manager + when(plugin.getIslands()).thenReturn(im); + when(im.getIslands(any(), any(User.class))).thenReturn(Set.of(island)); + when(im.getIslands(any(), any(UUID.class))).thenReturn(Set.of(island)); - atrc = new AdminTopRemoveCommand(addon, ic); - } + // Bukkit + PowerMockito.mockStatic(Bukkit.class); + when(Bukkit.getServer()).thenReturn(server); + // Mock item factory (for itemstacks) + ItemFactory itemFactory = mock(ItemFactory.class); + ItemMeta itemMeta = mock(ItemMeta.class); + when(itemFactory.getItemMeta(any())).thenReturn(itemMeta); + when(server.getItemFactory()).thenReturn(itemFactory); + when(Bukkit.getItemFactory()).thenReturn(itemFactory); - @After - public void tearDown() { - User.clearUsers(); - } + atrc = new AdminTopRemoveCommand(addon, ic); + } - /** - * Test method for - * {@link world.bentobox.level.commands.admin.AdminTopRemoveCommand#AdminTopRemoveCommand(world.bentobox.level.Level, world.bentobox.bentobox.api.commands.CompositeCommand)}. - */ - @Test - public void testAdminTopRemoveCommand() { - assertEquals("remove", atrc.getLabel()); - assertEquals("delete", atrc.getAliases().get(0)); - } + @After + public void tearDown() { + User.clearUsers(); + } - /** - * Test method for - * {@link world.bentobox.level.commands.admin.AdminTopRemoveCommand#setup()}. - */ - @Test - public void testSetup() { - assertEquals("bskyblock.admin.top.remove", atrc.getPermission()); - assertEquals("admin.top.remove.parameters", atrc.getParameters()); - assertEquals("admin.top.remove.description", atrc.getDescription()); - assertFalse(atrc.isOnlyPlayer()); + /** + * Test method for + * {@link world.bentobox.level.commands.admin.AdminTopRemoveCommand#AdminTopRemoveCommand(world.bentobox.level.Level, world.bentobox.bentobox.api.commands.CompositeCommand)}. + */ + @Test + public void testAdminTopRemoveCommand() { + assertEquals("remove", atrc.getLabel()); + assertEquals("delete", atrc.getAliases().get(0)); + } - } + /** + * Test method for + * {@link world.bentobox.level.commands.admin.AdminTopRemoveCommand#setup()}. + */ + @Test + public void testSetup() { + assertEquals("bskyblock.admin.top.remove", atrc.getPermission()); + assertEquals("admin.top.remove.parameters", atrc.getParameters()); + assertEquals("admin.top.remove.description", atrc.getDescription()); + assertFalse(atrc.isOnlyPlayer()); - /** - * Test method for - * {@link world.bentobox.level.commands.admin.AdminTopRemoveCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. - */ - @Test - public void testCanExecuteWrongArgs() { - assertFalse(atrc.canExecute(user, "delete", Collections.emptyList())); - verify(user).sendMessage("commands.help.header", TextVariables.LABEL, "BSkyBlock"); - } + } - /** + /** + * Test method for + * {@link world.bentobox.level.commands.admin.AdminTopRemoveCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testCanExecuteWrongArgs() { + assertFalse(atrc.canExecute(user, "delete", Collections.emptyList())); + verify(user).sendMessage("commands.help.header", TextVariables.LABEL, "BSkyBlock"); + } + + /** * Test method for {@link world.bentobox.level.commands.admin.AdminTopRemoveCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. */ @Test @@ -176,25 +184,25 @@ public class AdminTopRemoveCommandTest { verify(user).sendMessage("general.errors.unknown-player", TextVariables.NAME, "tastybento"); } - /** - * Test method for - * {@link world.bentobox.level.commands.admin.AdminTopRemoveCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. - */ - @Test - public void testCanExecuteKnown() { - assertTrue(atrc.canExecute(user, "delete", Collections.singletonList("tastybento"))); - } + /** + * Test method for + * {@link world.bentobox.level.commands.admin.AdminTopRemoveCommand#canExecute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testCanExecuteKnown() { + assertTrue(atrc.canExecute(user, "delete", Collections.singletonList("tastybento"))); + } - /** - * Test method for - * {@link world.bentobox.level.commands.admin.AdminTopRemoveCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. - */ - @Test - public void testExecuteUserStringListOfString() { - testCanExecuteKnown(); - assertTrue(atrc.execute(user, "delete", Collections.singletonList("tastybento"))); - verify(manager).removeEntry(any(World.class), eq(uuid)); - verify(user).sendMessage("general.success"); - } + /** + * Test method for + * {@link world.bentobox.level.commands.admin.AdminTopRemoveCommand#execute(world.bentobox.bentobox.api.user.User, java.lang.String, java.util.List)}. + */ + @Test + public void testExecuteUserStringListOfString() { + testCanExecuteKnown(); + assertTrue(atrc.execute(user, "delete", Collections.singletonList("tastybento"))); + verify(manager).removeEntry(world, uuid.toString()); + verify(user).sendMessage("general.success"); + } }