Finished version (for now).

Adds top ten and integration with welcome warps addon.
This commit is contained in:
Tastybento 2018-02-19 13:06:58 -08:00
parent 01d2bba4c5
commit ab39dd4ac5
8 changed files with 345 additions and 255 deletions

View File

@ -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"

17
pom.xml
View File

@ -43,14 +43,18 @@
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>1.12.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>us.tastybento</groupId>
<artifactId>bskyblock</artifactId>
<version>LATEST</version>
<version>alpha-0.0.1</version>
</dependency>
<dependency>
<groupId>bskyblock.addon</groupId>
<artifactId>WelcomeWarpSigns</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
<repositories>
<repository>
@ -59,4 +63,13 @@
</repository>
</repositories>
<groupId>bskyblock.addon</groupId>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>1.12.2-R0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>

View File

@ -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<LevelsData> 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<UUID, Long> levelsCache;
private Map<UUID, Long> 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<LevelsData> 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<LevelsData> getHandler() {
return handler;
}
public TopTen getTopTen() {
return topTen;
}
public void calculateIslandLevel(User user, UUID playerUUID, boolean b) {
levelCalc.calculateIslandLevel(user, playerUUID, b);
}
}

View File

@ -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<Pair<Integer, Integer>> chunksToScan;
private Island island;
private World world;
private User asker;
private UUID targetPlayer;
private Results result;
// Copy the limits hashmap
HashMap<MaterialData, Integer> 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<Integer, Integer> 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> chunkSnapshot) {
private void checkChunksAsync(final Set<ChunkSnapshot> 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<Pair<Integer, Integer>> getChunksToScan(Island island) {
// Get the chunks coords
Set<Pair<Integer, Integer>> 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<Integer, Integer> 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<String> 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<Multiset.Entry<MaterialData>> entriesSortedByCount =
Multisets.copyHighestCountFirst(result.uwCount).entrySet();
Iterator<Entry<MaterialData>> it = entriesSortedByCount.iterator();
while (it.hasNext()) {
Entry<MaterialData> 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<Multiset.Entry<MaterialData>> entriesSortedByCount =
result.mdCount.entrySet();
Iterator<Entry<MaterialData>> it = entriesSortedByCount.iterator();
while (it.hasNext()) {
Entry<MaterialData> 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<Multiset.Entry<MaterialData>> entriesSortedByCount = result.ofCount.entrySet();
Iterator<Entry<MaterialData>> it = entriesSortedByCount.iterator();
while (it.hasNext()) {
Entry<MaterialData> type = it.next();
Integer limit = addon.getSettings().getBlockLimits().get(type.getElement());
@ -300,9 +367,35 @@ public class Scanner {
}
}
private Collection<String> sortedReport(int total, Multiset<MaterialData> materialDataCount) {
Collection<String> result = new ArrayList<>();
Iterable<Multiset.Entry<MaterialData>> entriesSortedByCount = Multisets.copyHighestCountFirst(materialDataCount).entrySet();
Iterator<Entry<MaterialData>> it = entriesSortedByCount.iterator();
while (it.hasNext()) {
Entry<MaterialData> 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 {

View File

@ -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;
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*******************************************************************************/
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<TopTenData> 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<LevelsData> levelHandler = plugin.getHandler();
AbstractDatabaseHandler<LevelsData> 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<UUID, Long> 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<String> 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<String> 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
*

View File

@ -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 {

View File

@ -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<MaterialData, Integer> blockLimits = new HashMap<>();