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<>();