diff --git a/locales/en-US.yml b/locales/en-US.yml index 82bb311..fc9b772 100755 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -13,14 +13,17 @@ admin: island: level: parameters: "[player]" - description: "calculate your island level or show the level of [player]" - island-level-is: "Island level is [level]" - required-points-to-next-level: "[points] points required until the next level" - deaths: "([number] deaths)" + description: "calculate your island level or show the level of [player]" + calculating: "&aCalculating level..." + island-level-is: "&aIsland level is &b[level]" + required-points-to-next-level: "&a[points] points required until the next level" + deaths: "&c([number] deaths)" + cooldown: "&cYou must wait &b[time] &cseconds until you can do that again" top: description: "show the Top Ten" - gui-title: "Top Ten" - gui-heading: "[name]:[rank]" - island-level: "Level [level]" + gui-title: "&aTop Ten" + gui-heading: "&6[name]: &B[rank]" + island-level: "&BLevel [level]" + warp-to: "&AWarping to [name]'s island" \ No newline at end of file diff --git a/pom.xml b/pom.xml index 0451a67..f3e650b 100644 --- a/pom.xml +++ b/pom.xml @@ -43,14 +43,18 @@ org.bukkit bukkit - 1.12.2-R0.1-SNAPSHOT provided us.tastybento bskyblock - LATEST + alpha-0.0.1 + + bskyblock.addon + WelcomeWarpSigns + 0.0.1-SNAPSHOT + @@ -59,4 +63,13 @@ bskyblock.addon + + + + org.bukkit + bukkit + 1.12.2-R0.1-SNAPSHOT + + + \ No newline at end of file diff --git a/src/main/java/bskyblock/addon/level/Level.java b/src/main/java/bskyblock/addon/level/Level.java index 8382b39..8d85ccf 100644 --- a/src/main/java/bskyblock/addon/level/Level.java +++ b/src/main/java/bskyblock/addon/level/Level.java @@ -4,18 +4,16 @@ import java.beans.IntrospectionException; import java.lang.reflect.InvocationTargetException; import java.sql.SQLException; import java.util.HashMap; +import java.util.Map; import java.util.Map.Entry; import java.util.UUID; -import org.bukkit.scheduler.BukkitTask; - import bskyblock.addon.level.commands.AdminLevel; import bskyblock.addon.level.commands.AdminTop; import bskyblock.addon.level.commands.IslandLevel; import bskyblock.addon.level.commands.IslandTop; import bskyblock.addon.level.config.Settings; import bskyblock.addon.level.database.object.LevelsData; -import us.tastybento.bskyblock.BSkyBlock; import us.tastybento.bskyblock.Constants; import us.tastybento.bskyblock.api.addons.Addon; import us.tastybento.bskyblock.api.commands.CompositeCommand; @@ -24,22 +22,15 @@ import us.tastybento.bskyblock.database.BSBDatabase; import us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler; /** - * Addin to BSkyBlock that enables island level scoring and top ten functionality + * Addon to BSkyBlock that enables island level scoring and top ten functionality * @author tastybento * */ public class Level extends Addon { - - - // The BSkyBlock plugin instance. - private BSkyBlock bSkyBlock; // Settings private Settings settings; - // Level calc checker - BukkitTask checker = null; - // Database handler for level data private AbstractDatabaseHandler handler; @@ -49,7 +40,7 @@ public class Level extends Addon { // A cache of island levels. Island levels are not kept in memory unless required. // The cache is saved when the server shuts down and the plugin is disabled. // TODO: Save regularly to avoid crash issues. - private HashMap levelsCache; + private Map levelsCache; // The Top Ten object private TopTen topTen; @@ -57,18 +48,87 @@ public class Level extends Addon { // Level calculator private LevelPresenter levelCalc; + /** + * Calculates a user's island + * @param user + * @param playerUUID - the player's UUID + * @param b + */ + public void calculateIslandLevel(User user, UUID playerUUID, boolean b) { + levelCalc.calculateIslandLevel(user, playerUUID, b); + } + + public AbstractDatabaseHandler getHandler() { + return handler; + } + + /** + * Get level from cache for a player + * @param targetPlayer + * @return Level of player + */ + public long getIslandLevel(UUID targetPlayer) { + if (levelsCache.containsKey(targetPlayer)) { + return levelsCache.get(targetPlayer); + } + // Get from database + LevelsData level; + try { + level = handler.loadObject(targetPlayer.toString()); + if (level == null) { + // We do not know this player, set to zero + return 0; + } + levelsCache.put(targetPlayer, level.getLevel()); + return level.getLevel(); + } catch (InstantiationException | IllegalAccessException | InvocationTargetException + | ClassNotFoundException | IntrospectionException | SQLException e) { + getLogger().severe("Could not load player's level! " + e.getMessage()); + } + return 0; + } + + /** + * @return the settings + */ + public final Settings getSettings() { + return settings; + } + + public TopTen getTopTen() { + return topTen; + } + + private void load() { + try { + for (LevelsData level : handler.loadObjects()) { + levelsCache.put(UUID.fromString(level.getUniqueId()), level.getLevel()); + } + } catch (InstantiationException | IllegalAccessException | InvocationTargetException + | ClassNotFoundException | IntrospectionException | SQLException e) { + getLogger().severe("Could not load levels cache data! " + e.getMessage()); + } + } + + @Override + public void onDisable(){ + // Save the cache + if (levelsCache != null) { + save(false); + } + } + @SuppressWarnings("unchecked") @Override public void onEnable() { - // Load the plugin's config - settings = new Settings(this); - // Get the BSkyBlock plugin. This will be available because this plugin depends on it in plugin.yml. - bSkyBlock = BSkyBlock.getInstance(); // Check if it is enabled - it might be loaded, but not enabled. - if (!bSkyBlock.isEnabled()) { + if (getBSkyBlock() == null || !getBSkyBlock().isEnabled()) { + getLogger().severe("BSkyBlock does not exist or is not enabled. Stopping."); this.setEnabled(false); return; } + // Load the plugin's config + settings = new Settings(this); // Get the BSkyBlock database database = BSBDatabase.getDatabase(); // Set up the database handler to store and retrieve Island classes @@ -83,45 +143,16 @@ public class Level extends Addon { // Start the top ten and register it for clicks topTen = new TopTen(this); registerListener(topTen); - // Local locales - //localeManager = new LocaleManager(this); // Register commands - CompositeCommand bsbIslandCmd = (CompositeCommand) BSkyBlock.getInstance().getCommandsManager().getCommand(Constants.ISLANDCOMMAND); + CompositeCommand bsbIslandCmd = getBSkyBlock().getCommandsManager().getCommand(Constants.ISLANDCOMMAND); new IslandLevel(this, bsbIslandCmd); new IslandTop(this, bsbIslandCmd); - CompositeCommand bsbAdminCmd = (CompositeCommand) BSkyBlock.getInstance().getCommandsManager().getCommand(Constants.ADMINCOMMAND); + CompositeCommand bsbAdminCmd = getBSkyBlock().getCommandsManager().getCommand(Constants.ADMINCOMMAND); new AdminLevel(this, bsbAdminCmd); new AdminTop(this, bsbAdminCmd); // Done } - @Override - public void onDisable(){ - // Save the cache - if (levelsCache != null) { - save(false); - } - } - - /** - * @return the settings - */ - public final Settings getSettings() { - return settings; - } - - public void load() { - try { - for (LevelsData level : handler.loadObjects()) { - levelsCache.put(UUID.fromString(level.getUniqueId()), level.getLevel()); - } - } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException - | SecurityException | ClassNotFoundException | IntrospectionException | SQLException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - /** * Save the levels to the database * @param async - if true, saving will be done async @@ -135,10 +166,9 @@ public class Level extends Addon { lv.setUniqueId(en.getKey().toString()); handler.saveObject(lv); } - } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | SecurityException + } catch (IllegalAccessException | InvocationTargetException | InstantiationException | NoSuchMethodException | IntrospectionException | SQLException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + getLogger().severe("Could not save levels async! " + e.getMessage()); } }; if(async){ @@ -149,55 +179,14 @@ public class Level extends Addon { } /** - * Get level from cache for a player - * @param targetPlayer - * @return Level of player - */ - public long getIslandLevel(UUID targetPlayer) { - //getLogger().info("DEBUG: getting island level for " + bSkyBlock.getPlayers().getName(targetPlayer)); - if (levelsCache.containsKey(targetPlayer)) { - return levelsCache.get(targetPlayer); - } - // Get from database - LevelsData level; - try { - level = handler.loadObject(targetPlayer.toString()); - if (level == null) { - // We do not know this player, set to zero - return 0; - } - levelsCache.put(targetPlayer, level.getLevel()); - return level.getLevel(); - } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException - | SecurityException | ClassNotFoundException | IntrospectionException | SQLException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return 0; - } - - /** - * Save the player's level + * Sets the player's level to a value * @param targetPlayer * @param level */ - public void setIslandLevel(UUID targetPlayer, long level) { - //getLogger().info("DEBUG: set island level to " + level + " for " + bSkyBlock.getPlayers().getName(targetPlayer)); + protected void setIslandLevel(UUID targetPlayer, long level) { // Add to cache levelsCache.put(targetPlayer, level); topTen.addEntry(targetPlayer, level); } - public AbstractDatabaseHandler getHandler() { - return handler; - } - - public TopTen getTopTen() { - return topTen; - } - - public void calculateIslandLevel(User user, UUID playerUUID, boolean b) { - levelCalc.calculateIslandLevel(user, playerUUID, b); - } - } diff --git a/src/main/java/bskyblock/addon/level/Scanner.java b/src/main/java/bskyblock/addon/level/LevelCalcByChunk.java similarity index 57% rename from src/main/java/bskyblock/addon/level/Scanner.java rename to src/main/java/bskyblock/addon/level/LevelCalcByChunk.java index 7f33af9..ee3822e 100644 --- a/src/main/java/bskyblock/addon/level/Scanner.java +++ b/src/main/java/bskyblock/addon/level/LevelCalcByChunk.java @@ -1,15 +1,21 @@ package bskyblock.addon.level; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; +import java.util.UUID; +import org.apache.commons.lang.math.NumberUtils; import org.bukkit.ChunkSnapshot; import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.entity.Player; import org.bukkit.material.MaterialData; +import org.bukkit.permissions.PermissionAttachmentInfo; import org.bukkit.scheduler.BukkitTask; import com.google.common.collect.HashMultiset; @@ -17,15 +23,18 @@ import com.google.common.collect.Multiset; import com.google.common.collect.Multiset.Entry; import com.google.common.collect.Multisets; -import us.tastybento.bskyblock.BSkyBlock; +import bskyblock.addon.level.event.IslandPostLevelEvent; +import bskyblock.addon.level.event.IslandPreLevelEvent; +import us.tastybento.bskyblock.Constants; import us.tastybento.bskyblock.api.commands.User; import us.tastybento.bskyblock.database.objects.Island; import us.tastybento.bskyblock.util.Pair; -public class Scanner { - private static final int MAX_CHUNKS = 50; - private static final long SPEED = 5; +public class LevelCalcByChunk { + + private static final int MAX_CHUNKS = 200; + private static final long SPEED = 1; private boolean checking = true; private BukkitTask task; @@ -33,18 +42,27 @@ public class Scanner { private Set> chunksToScan; private Island island; + private World world; private User asker; + private UUID targetPlayer; private Results result; // Copy the limits hashmap HashMap limitCount; + private boolean report; + private long oldLevel; - public Scanner(Level addon, Island island, User asker) { + public LevelCalcByChunk(final Level addon, final Island island, final UUID targetPlayer, final User asker, final boolean report) { this.addon = addon; this.island = island; + this.world = island != null ? island.getCenter().getWorld() : null; this.asker = asker; + this.targetPlayer = targetPlayer; this.limitCount = new HashMap<>(addon.getSettings().getBlockLimits()); + this.report = report; + this.oldLevel = addon.getIslandLevel(targetPlayer); + // Results go here result = new Results(); @@ -67,7 +85,13 @@ public class Scanner { // Add chunk snapshots to the list while (it.hasNext() && chunkSnapshot.size() < MAX_CHUNKS) { Pair pair = it.next(); - chunkSnapshot.add(island.getWorld().getChunkAt(pair.x, pair.z).getChunkSnapshot()); + if (!world.isChunkLoaded(pair.x, pair.z)) { + world.loadChunk(pair.x, pair.z); + chunkSnapshot.add(world.getChunkAt(pair.x, pair.z).getChunkSnapshot()); + world.unloadChunk(pair.x, pair.z); + } else { + chunkSnapshot.add(world.getChunkAt(pair.x, pair.z).getChunkSnapshot()); + } it.remove(); } // Move to next step @@ -77,10 +101,9 @@ public class Scanner { }, 0L, SPEED); } - private void checkChunksAsync(Set chunkSnapshot) { + private void checkChunksAsync(final Set chunkSnapshot) { // Run async task to scan chunks addon.getServer().getScheduler().runTaskAsynchronously(addon.getBSkyBlock(), () -> { - for (ChunkSnapshot chunk: chunkSnapshot) { scanChunk(chunk); } @@ -94,16 +117,16 @@ public class Scanner { private void scanChunk(ChunkSnapshot chunk) { for (int x = 0; x< 16; x++) { // Check if the block coord is inside the protection zone and if not, don't count it - if (chunk.getX() * 16 + x < island.getMinProtectedX() || chunk.getX() * 16 + x >= island.getMinProtectedX() + (island.getProtectionRange() * 2)) { + if (chunk.getX() * 16 + x < island.getMinProtectedX() || chunk.getX() * 16 + x >= island.getMinProtectedX() + island.getProtectionRange()) { continue; } for (int z = 0; z < 16; z++) { // Check if the block coord is inside the protection zone and if not, don't count it - if (chunk.getZ() * 16 + z < island.getMinProtectedZ() || chunk.getZ() * 16 + z >= island.getMinProtectedZ() + (island.getProtectionRange() * 2)) { + if (chunk.getZ() * 16 + z < island.getMinProtectedZ() || chunk.getZ() * 16 + z >= island.getMinProtectedZ() + island.getProtectionRange()) { continue; } - for (int y = 0; y < island.getWorld().getMaxHeight(); y++) { + for (int y = 0; y < island.getCenter().getWorld().getMaxHeight(); y++) { Material blockType = chunk.getBlockType(x, y, z); boolean belowSeaLevel = (addon.getSettings().getSeaHeight() > 0 && y<=addon.getSettings().getSeaHeight()) ? true : false; // Air is free @@ -172,11 +195,11 @@ public class Scanner { * @return */ private Set> getChunksToScan(Island island) { - // Get the chunks coords Set> chunkSnapshot = new HashSet<>(); - for (int x = island.getMinProtectedX(); x < (island.getMinProtectedX() + (island.getProtectionRange() *2) + 16); x += 16) { - for (int z = island.getMinProtectedZ(); z < (island.getMinProtectedZ() + (island.getProtectionRange() * 2) + 16); z += 16) { - chunkSnapshot.add(new Pair<>(x/16,z/16)); + for (int x = island.getMinProtectedX(); x < (island.getMinProtectedX() + island.getProtectionRange() + 16); x += 16) { + for (int z = island.getMinProtectedZ(); z < (island.getMinProtectedZ() + island.getProtectionRange() + 16); z += 16) { + Pair pair = new Pair<>(world.getBlockAt(x, 0, z).getChunk().getX(), world.getBlockAt(x, 0, z).getChunk().getZ()); + chunkSnapshot.add(pair); } } return chunkSnapshot; @@ -188,23 +211,109 @@ public class Scanner { // Finalize calculations result.rawBlockCount += (long)((double)result.underWaterBlockCount * addon.getSettings().getUnderWaterMultiplier()); // Set the death penalty - result.deathHandicap = BSkyBlock.getInstance().getPlayers().getDeaths(island.getOwner()) * addon.getSettings().getDeathPenalty(); + result.deathHandicap = addon.getPlayers().getDeaths(island.getOwner()); // Set final score - result.score = (result.rawBlockCount / addon.getSettings().getLevelCost()) - result.deathHandicap; + result.score = (result.rawBlockCount / addon.getSettings().getLevelCost()) - result.deathHandicap - island.getLevelHandicap(); // Run any modifications - // Save the value - addon.setIslandLevel(island.getOwner(), result.score); + // Get the permission multiplier if it is available + int levelMultiplier = 1; + Player player = addon.getServer().getPlayer(targetPlayer); + if (player != null) { + // Get permission multiplier + for (PermissionAttachmentInfo perms : player.getEffectivePermissions()) { + if (perms.getPermission().startsWith(Constants.PERMPREFIX + "island.multiplier.")) { + String spl[] = perms.getPermission().split(Constants.PERMPREFIX + "island.multiplier."); + if (spl.length > 1) { + if (!NumberUtils.isDigits(spl[1])) { + addon.getLogger().severe("Player " + player.getName() + " has permission: " + perms.getPermission() + " <-- the last part MUST be a number! Ignoring..."); + } else { + // Get the max value should there be more than one + levelMultiplier = Math.max(levelMultiplier, Integer.valueOf(spl[1])); + } + } + } + // Do some sanity checking + if (levelMultiplier < 1) { + levelMultiplier = 1; + } + } + } + // Calculate how many points are required to get to the next level + long pointsToNextLevel = (addon.getSettings().getLevelCost() * (result.score + 1 + island.getLevelHandicap())) - ((result.rawBlockCount * levelMultiplier) - (result.deathHandicap * addon.getSettings().getDeathPenalty())); + // Sometimes it will return 0, so calculate again to make sure it will display a good value + if(pointsToNextLevel == 0) pointsToNextLevel = (addon.getSettings().getLevelCost() * (result.score + 2 + island.getLevelHandicap()) - ((result.rawBlockCount * levelMultiplier) - (result.deathHandicap * addon.getSettings().getDeathPenalty()))); + // All done. - // Tell the asker the result - if (asker.isPlayer() && asker.isOnline()) { - asker.sendMessage("island.level.island-level-is", "[level]", String.valueOf(result.score)); - } else { - // Console - sendConsoleReport(asker, island); + informPlayers(saveLevel(island, targetPlayer, pointsToNextLevel)); + + } + + private void informPlayers(IslandPreLevelEvent event) { + // Fire the island post level calculation event + final IslandPostLevelEvent event3 = new IslandPostLevelEvent(targetPlayer, island, event.getLevel(), event.getPointsToNextLevel()); + addon.getServer().getPluginManager().callEvent(event3); + + if(event3.isCancelled() || asker == null) { + return; + } + // Tell the asker + asker.sendMessage("island.level.island-level-is", "[level]", String.valueOf(addon.getIslandLevel(targetPlayer))); + // Console + if (report) { + sendConsoleReport(asker); + } + // Check if player - if so show some more info + if (!(asker instanceof Player)) { + return; + } + // Player + if (addon.getSettings().getDeathPenalty() != 0) { + asker.sendMessage("island.level.deaths", "[number]", String.valueOf(result.deathHandicap)); + } + // Send player how many points are required to reach next island level + if (event.getPointsToNextLevel() >= 0) { + asker.sendMessage("island.level.required-points-to-next-level", "[points]", String.valueOf(event.getPointsToNextLevel())); + } + // Tell other team members + if (addon.getIslandLevel(targetPlayer) != oldLevel) { + for (UUID member : island.getMemberSet()) { + if (!member.equals(asker.getUniqueId())) { + User.getInstance(member).sendMessage("island.level.island-level-is", "[level]", String.valueOf(addon.getIslandLevel(targetPlayer))); + } + } } } - private void sendConsoleReport(User asker, Island island) { + private IslandPreLevelEvent saveLevel(Island island, UUID targetPlayer, long pointsToNextLevel) { + // Fire the pre-level event + final IslandPreLevelEvent event = new IslandPreLevelEvent(targetPlayer, island, result.score); + event.setPointsToNextLevel(pointsToNextLevel); + addon.getServer().getPluginManager().callEvent(event); + if (!event.isCancelled()) { + // Save the value + addon.setIslandLevel(island.getOwner(), event.getLevel()); + if (addon.getPlayers().inTeam(targetPlayer)) { + //plugin.getLogger().info("DEBUG: player is in team"); + for (UUID member : addon.getIslands().getMembers(targetPlayer)) { + //plugin.getLogger().info("DEBUG: updating team member level too"); + if (addon.getIslandLevel(member) != event.getLevel()) { + addon.setIslandLevel(member, event.getLevel()); + } + } + if (addon.getPlayers().inTeam(targetPlayer)) { + UUID leader = addon.getIslands().getTeamLeader(targetPlayer); + if (leader != null) { + addon.getTopTen().addEntry(leader, event.getLevel()); + } + } else { + addon.getTopTen().addEntry(targetPlayer, event.getLevel()); + } + } + } + return event; + } + + private void sendConsoleReport(User asker) { List reportLines = new ArrayList<>(); // provide counts reportLines.add("Level Log for island at " + island.getCenter()); @@ -220,58 +329,16 @@ public class Scanner { if (!result.uwCount.isEmpty()) { reportLines.add("Underwater block count (Multiplier = x" + addon.getSettings().getUnderWaterMultiplier() + ") value"); reportLines.add("Total number of underwater blocks = " + String.format("%,d",result.uwCount.size())); - Iterable> entriesSortedByCount = - Multisets.copyHighestCountFirst(result.uwCount).entrySet(); - Iterator> it = entriesSortedByCount.iterator(); - while (it.hasNext()) { - Entry en = it.next(); - MaterialData type = en.getElement(); - - int value = 0; - if (addon.getSettings().getBlockValues().containsKey(type)) { - // Specific - value = addon.getSettings().getBlockValues().get(type); - } else if (addon.getSettings().getBlockValues().containsKey(new MaterialData(type.getItemType()))) { - // Generic - value = addon.getSettings().getBlockValues().get(new MaterialData(type.getItemType())); - } - if (value > 0) { - reportLines.add(type.toString() + ":" - + String.format("%,d",en.getCount()) + " blocks x " + value + " = " + (value * en.getCount())); - total += (value * en.getCount()); - } - } - reportLines.add("Subtotal = " + total); - reportLines.add("=================================="); + reportLines.addAll(sortedReport(total, result.uwCount)); } reportLines.add("Regular block count"); reportLines.add("Total number of blocks = " + String.format("%,d",result.mdCount.size())); - Iterable> entriesSortedByCount = - result.mdCount.entrySet(); - Iterator> it = entriesSortedByCount.iterator(); - while (it.hasNext()) { - Entry en = it.next(); - MaterialData type = en.getElement(); - int value = 0; - if (addon.getSettings().getBlockValues().containsKey(type)) { - // Specific - value = addon.getSettings().getBlockValues().get(type); - } else if (addon.getSettings().getBlockValues().containsKey(new MaterialData(type.getItemType()))) { - // Generic - value = addon.getSettings().getBlockValues().get(new MaterialData(type.getItemType())); - } - if (value > 0) { - reportLines.add(type.toString() + ":" - + String.format("%,d",en.getCount()) + " blocks x " + value + " = " + (value * en.getCount())); - total += (value * en.getCount()); - } - } - reportLines.add("Total = " + total); - reportLines.add("=================================="); + reportLines.addAll(sortedReport(total, result.mdCount)); + reportLines.add("Blocks not counted because they exceeded limits: " + String.format("%,d",result.ofCount.size())); //entriesSortedByCount = Multisets.copyHighestCountFirst(ofCount).entrySet(); - entriesSortedByCount = result.ofCount.entrySet(); - it = entriesSortedByCount.iterator(); + Iterable> entriesSortedByCount = result.ofCount.entrySet(); + Iterator> it = entriesSortedByCount.iterator(); while (it.hasNext()) { Entry type = it.next(); Integer limit = addon.getSettings().getBlockLimits().get(type.getElement()); @@ -300,9 +367,35 @@ public class Scanner { } } + private Collection sortedReport(int total, Multiset materialDataCount) { + Collection result = new ArrayList<>(); + Iterable> entriesSortedByCount = Multisets.copyHighestCountFirst(materialDataCount).entrySet(); + Iterator> it = entriesSortedByCount.iterator(); + while (it.hasNext()) { + Entry en = it.next(); + MaterialData type = en.getElement(); + + int value = 0; + if (addon.getSettings().getBlockValues().containsKey(type)) { + // Specific + value = addon.getSettings().getBlockValues().get(type); + } else if (addon.getSettings().getBlockValues().containsKey(new MaterialData(type.getItemType()))) { + // Generic + value = addon.getSettings().getBlockValues().get(new MaterialData(type.getItemType())); + } + if (value > 0) { + result.add(type.toString() + ":" + + String.format("%,d",en.getCount()) + " blocks x " + value + " = " + (value * en.getCount())); + total += (value * en.getCount()); + } + } + result.add("Subtotal = " + total); + result.add("=================================="); + return result; + } + /** * Results class - * @author ben * */ public class Results { diff --git a/src/main/java/bskyblock/addon/level/LevelPresenter.java b/src/main/java/bskyblock/addon/level/LevelPresenter.java index 6fb23fa..230fd1c 100644 --- a/src/main/java/bskyblock/addon/level/LevelPresenter.java +++ b/src/main/java/bskyblock/addon/level/LevelPresenter.java @@ -4,8 +4,6 @@ import java.util.Calendar; import java.util.HashMap; import java.util.UUID; -import org.bukkit.ChatColor; - import us.tastybento.bskyblock.Constants; import us.tastybento.bskyblock.api.commands.User; @@ -42,23 +40,24 @@ public class LevelPresenter extends LevelPlugin { public boolean calculateIslandLevel(final User sender, final UUID targetPlayer, boolean report) { // Check if sender has island if (!bSkyBlock.getIslands().hasIsland(targetPlayer)) { - sender.sendRawMessage("Target does not have an island"); + sender.sendMessage("general.errors.player-has-no-island"); return false; } // Player asking for their own island calc if (!sender.isPlayer() || sender.getUniqueId().equals(targetPlayer) || sender.isOp() || sender.hasPermission(Constants.PERMPREFIX + "mod.info")) { // Newer better system - uses chunks if (!onLevelWaitTime(sender) || levelWait <= 0 || sender.isOp() || sender.hasPermission(Constants.PERMPREFIX + "mod.info")) { - sender.sendRawMessage(ChatColor.GREEN + "Calculating level, please wait..."); + sender.sendMessage("island.level.calculating"); setLevelWaitTime(sender); - new Scanner(plugin, bSkyBlock.getIslands().getIsland(targetPlayer), sender); + new LevelCalcByChunk(plugin, bSkyBlock.getIslands().getIsland(targetPlayer), targetPlayer, sender, report); } else { - sender.sendRawMessage( ChatColor.YELLOW + String.valueOf(getLevelWaitTime(sender))); + // Cooldown + sender.sendMessage("island.level.cooldown", "[time]", String.valueOf(getLevelWaitTime(sender))); } } else { // Asking for the level of another player - sender.sendMessage("island.islandLevelIs","[level]", String.valueOf(plugin.getIslandLevel(targetPlayer))); + sender.sendMessage("island.level.island-level-is","[level]", String.valueOf(plugin.getIslandLevel(targetPlayer))); } return true; } diff --git a/src/main/java/bskyblock/addon/level/TopTen.java b/src/main/java/bskyblock/addon/level/TopTen.java index 606c4f2..d1c37f6 100644 --- a/src/main/java/bskyblock/addon/level/TopTen.java +++ b/src/main/java/bskyblock/addon/level/TopTen.java @@ -1,20 +1,3 @@ -/******************************************************************************* - * This file is part of ASkyBlock. - * - * ASkyBlock is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ASkyBlock is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with ASkyBlock. If not, see . - *******************************************************************************/ - package bskyblock.addon.level; import java.beans.IntrospectionException; @@ -25,27 +8,21 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Optional; import java.util.UUID; +import java.util.function.Consumer; import org.bukkit.ChatColor; -import org.bukkit.Material; import org.bukkit.entity.Player; -import org.bukkit.event.EventHandler; -import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.event.inventory.InventoryClickEvent; -import org.bukkit.event.inventory.InventoryType.SlotType; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.SkullMeta; +import bskyblock.addin.warps.Warp; import bskyblock.addon.level.database.object.LevelsData; import bskyblock.addon.level.database.object.TopTenData; -import bskyblock.addon.level.event.TopTenClick; -import us.tastybento.bskyblock.BSkyBlock; import us.tastybento.bskyblock.Constants; +import us.tastybento.bskyblock.api.addons.Addon; import us.tastybento.bskyblock.api.commands.User; +import us.tastybento.bskyblock.api.panels.ClickType; import us.tastybento.bskyblock.api.panels.PanelItem; import us.tastybento.bskyblock.api.panels.PanelItem.ClickHandler; import us.tastybento.bskyblock.api.panels.builders.PanelBuilder; @@ -60,20 +37,17 @@ import us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler; * */ public class TopTen implements Listener { - private Level plugin; + private Level addon; // Top ten list of players private TopTenData topTenList; - private final int GUISIZE = 27; // Must be a multiple of 9 private final int[] SLOTS = new int[] {4, 12, 14, 19, 20, 21, 22, 23, 24, 25}; private final boolean DEBUG = false; - // Store this as a because it's the same for everyone and saves memory cleanup - private Inventory gui; private BSBDatabase database; private AbstractDatabaseHandler handler; @SuppressWarnings("unchecked") - public TopTen(Level plugin) { - this.plugin = plugin; + public TopTen(Level addon) { + this.addon = addon; // Set up database database = BSBDatabase.getDatabase(); // Set up the database handler to store and retrieve the TopTenList class @@ -90,7 +64,7 @@ public class TopTen implements Listener { */ public void addEntry(UUID ownerUUID, long l) { // Try and see if the player is online - Player player = plugin.getServer().getPlayer(ownerUUID); + Player player = addon.getServer().getPlayer(ownerUUID); if (player != null) { // Online if (!player.hasPermission(Constants.PERMPREFIX + "intopten")) { @@ -109,17 +83,17 @@ public class TopTen implements Listener { */ public void create() { // Obtain all the levels for each known player - AbstractDatabaseHandler levelHandler = plugin.getHandler(); + AbstractDatabaseHandler levelHandler = addon.getHandler(); try { long index = 0; for (LevelsData lv : levelHandler.loadObjects()) { if (index++ % 1000 == 0) { - plugin.getLogger().info("Processed " + index + " players for top ten"); + addon.getLogger().info("Processed " + index + " players for top ten"); } // Convert to UUID UUID playerUUID = UUID.fromString(lv.getUniqueId()); // Check if the player is an owner or team leader - if (BSkyBlock.getInstance().getIslands().isOwner(playerUUID)) { + if (addon.getIslands().isOwner(playerUUID)) { topTenList.addLevel(playerUUID, lv.getLevel()); } } @@ -132,7 +106,7 @@ public class TopTen implements Listener { } /** - * Displays the Top Ten list if it exists in chat + * Displays the Top Ten list * * @param user * - the requesting player @@ -140,12 +114,12 @@ public class TopTen implements Listener { */ public boolean getGUI(final User user) { if (DEBUG) - plugin.getLogger().info("DEBUG: GUI display"); + addon.getLogger().info("DEBUG: GUI display"); // New GUI display (shown by default) if (topTenList == null) create(); PanelBuilder panel = new PanelBuilder() - .setName("island.top.guiTitle") + .setName(user.getTranslation("island.top.gui-title")) .setUser(user); int i = 1; @@ -154,9 +128,9 @@ public class TopTen implements Listener { Map.Entry m = it.next(); UUID topTenUUID = m.getKey(); if (DEBUG) - plugin.getLogger().info("DEBUG: " + i + ": " + topTenUUID); + addon.getLogger().info("DEBUG: " + i + ": " + topTenUUID); // Remove from TopTen if the player is online and has the permission - Player entry = plugin.getServer().getPlayer(topTenUUID); + Player entry = addon.getServer().getPlayer(topTenUUID); boolean show = true; if (entry != null) { if (!entry.hasPermission(Constants.PERMPREFIX + "intopten")) { @@ -165,11 +139,11 @@ public class TopTen implements Listener { } } else { if (DEBUG) - plugin.getLogger().info("DEBUG: player not online, so no per check"); + addon.getLogger().info("DEBUG: player not online, so no per check"); } if (show) { - panel.addItem(SLOTS[i-1], getSkulls(i, m.getValue(), topTenUUID, user)); + panel.addItem(SLOTS[i-1], getHead(i, m.getValue(), topTenUUID, user)); if (i++ == 10) break; } } @@ -177,36 +151,55 @@ public class TopTen implements Listener { return true; } - private PanelItem getSkulls(int rank, Long value, UUID topTenUUID, User user) { - final String name = BSkyBlock.getInstance().getPlayers().getName(topTenUUID); - ItemStack playerSkull = new ItemStack(Material.SKULL_ITEM, 1, (short) 3); + /** + * Get the head panel item + * @param rank - the top ten rank of this player/team. Can be used in the name of the island for vanity. + * @param level - the level of the island + * @param playerUUID - the UUID of the top ten player + * @param asker - the asker of the top ten + * @return PanelItem + */ + private PanelItem getHead(int rank, Long level, UUID playerUUID, User asker) { + final String name = addon.getPlayers().getName(playerUUID); List description = new ArrayList<>(); if (name != null) { - SkullMeta meta = (SkullMeta) playerSkull.getItemMeta(); - meta.setOwner(name); - playerSkull.setItemMeta(meta); - description.add(user.getTranslation("island.top.guiHeading", "[name]", BSkyBlock.getInstance().getIslands().getIslandName(topTenUUID), "[rank]", String.valueOf(rank))); - description.add(user.getTranslation("island.top.islandLevel","[level]", String.valueOf(value))); - if (BSkyBlock.getInstance().getPlayers().inTeam(topTenUUID)) { + description.add(asker.getTranslation("island.top.gui-heading", "[name]", addon.getIslands().getIslandName(playerUUID), "[rank]", String.valueOf(rank))); + description.add(asker.getTranslation("island.top.island-level","[level]", String.valueOf(level))); + if (addon.getPlayers().inTeam(playerUUID)) { List memberList = new ArrayList<>(); - for (UUID members : BSkyBlock.getInstance().getIslands().getMembers(topTenUUID)) { - memberList.add(ChatColor.AQUA + BSkyBlock.getInstance().getPlayers().getName(members)); + for (UUID members : addon.getIslands().getMembers(playerUUID)) { + memberList.add(ChatColor.AQUA + addon.getPlayers().getName(members)); } description.addAll(memberList); } } - return new PanelItemBuilder() - .icon(playerSkull) + PanelItemBuilder builder = new PanelItemBuilder() + .icon(name) .name(name) - .description(description) - .clickHandler(new ClickHandler() { + .description(description); + + // If welcome warps is present then add warping + addon.getAddonByName("BSkyBlock-WelcomeWarps").ifPresent(warp -> { + + if (((Warp)warp).getWarpSignsManager().hasWarp(playerUUID)) { + + builder.clickHandler(new ClickHandler() { @Override - public boolean onClick(User user, us.tastybento.bskyblock.api.panels.ClickType click) { - user.sendRawMessage("Warp to " + name); - return false; - }}) - .build(); + public boolean onClick(User user, ClickType click) { + if (click.equals(ClickType.LEFT)) { + user.sendMessage("island.top.warp-to", "[name]", name); + + + ((Warp)warp).getWarpSignsManager().warpPlayer(user, playerUUID); + } + return true; + } + }); + + } + }); + return builder.build(); } public TopTenData getTopTenList() { @@ -227,7 +220,7 @@ public class TopTen implements Listener { e.printStackTrace(); } } - + /* @SuppressWarnings("deprecation") @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled=true) public void onInventoryClick(InventoryClickEvent event) { @@ -246,7 +239,7 @@ public class TopTen implements Listener { player.closeInventory(); // Fire click event TopTenClick clickEvent = new TopTenClick(((SkullMeta)event.getCurrentItem().getItemMeta()).getOwningPlayer().getName()); - plugin.getServer().getPluginManager().callEvent(clickEvent); + addon.getServer().getPluginManager().callEvent(clickEvent); return; } if (event.getSlotType().equals(SlotType.OUTSIDE)) { @@ -258,7 +251,7 @@ public class TopTen implements Listener { return; } } - + */ /** * Removes ownerUUID from the top ten list * diff --git a/src/main/java/bskyblock/addon/level/commands/IslandLevel.java b/src/main/java/bskyblock/addon/level/commands/IslandLevel.java index f8b49a4..e0d8cd9 100644 --- a/src/main/java/bskyblock/addon/level/commands/IslandLevel.java +++ b/src/main/java/bskyblock/addon/level/commands/IslandLevel.java @@ -25,13 +25,13 @@ public class IslandLevel extends CompositeCommand { final UUID playerUUID = getPlugin().getPlayers().getUUID(args.get(0)); //getLogger().info("DEBUG: console player info UUID = " + playerUUID); if (playerUUID == null) { - user.sendMessage("error.UnknownPlayer"); + user.sendMessage("general.errors.unknown-player"); return true; } else if (user.getUniqueId().equals(playerUUID) ) { // Self level request levelPlugin.calculateIslandLevel(user, user.getUniqueId(), false); } else { - user.sendMessage("island.level.islandLevelIs", "[level]", String.valueOf(levelPlugin.getIslandLevel(playerUUID))); + user.sendMessage("island.level.island-level-is", "[level]", String.valueOf(levelPlugin.getIslandLevel(playerUUID))); return true; } } else { diff --git a/src/main/java/bskyblock/addon/level/config/Settings.java b/src/main/java/bskyblock/addon/level/config/Settings.java index aca4329..c678206 100644 --- a/src/main/java/bskyblock/addon/level/config/Settings.java +++ b/src/main/java/bskyblock/addon/level/config/Settings.java @@ -10,7 +10,7 @@ import bskyblock.addon.level.Level; public class Settings { - private static final boolean DEBUG = true; + private static final boolean DEBUG = false; private boolean sumTeamDeaths; private int seaHeight; private HashMap blockLimits = new HashMap<>();