/**
* (c) 2014 dmulloy2
*/
package net.t7seven7t.swornguard.commands;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Level;
import net.dmulloy2.util.FormatUtil;
import net.dmulloy2.util.Util;
import net.t7seven7t.swornguard.SwornGuard;
import net.t7seven7t.swornguard.types.Permission;
import net.t7seven7t.swornguard.types.PlayerData;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
/**
* @author dmulloy2
*/
public class CmdLeaderboard extends SwornGuardCommand {
protected boolean updating;
protected long lastUpdateTime;
protected List<String> leaderboard;
public CmdLeaderboard(SwornGuard plugin) {
super(plugin);
this.name = "lb";
this.aliases.add("leaderboard");
this.description = "Display kills leaderboard";
this.permission = Permission.CMD_LEADERBOARD;
this.mustBePlayer = true;
}
@Override
public void perform() {
if (updating) {
err("Leaderboard is already updating!");
return;
}
if (leaderboard == null) {
this.leaderboard = new ArrayList<>();
}
if (System.currentTimeMillis() - lastUpdateTime > 600000L) {
sendMessage(plugin.getMessage("leaderboard_wait"));
this.updating = true;
new BuildLeaderboardThread();
}
new DisplayLeaderboardThread(sender.getName());
}
public void displayLeaderboard(String playerName) {
Player player = Util.matchPlayer(playerName);
if (player == null)
return;
// Header
sendMessage(player, plugin.getMessage("leaderboard_header"));
// Body
for (String line : leaderboard) {
sendMessage(player, line);
}
// Footer
sendMessage(player, "&eTo see your most recent stats, type &b/p &3info");
sendMessage(player, "&eLeaderboard is updated every 10 minutes.");
}
public class BuildLeaderboardThread extends Thread {
public BuildLeaderboardThread() {
super("SwornGuard-BuildLeaderboard");
this.setPriority(MIN_PRIORITY);
this.start();
}
@Override
public void run() {
plugin.getLogHandler().log("Updating leaderboard...");
long start = System.currentTimeMillis();
Map<String, PlayerData> allData = plugin.getPlayerDataCache().getAllPlayerData();
Map<PlayerData, Integer> experienceMap = new HashMap<>();
for (Entry<String, PlayerData> entry : allData.entrySet()) {
PlayerData value = entry.getValue();
if (value != null && value.getPlayerKills() > 0) {
experienceMap.put(value, value.getPlayerKills());
}
}
if (experienceMap.isEmpty()) {
err("No players with kills found!");
return;
}
List<Entry<PlayerData, Integer>> sortedEntries = new ArrayList<>(experienceMap.entrySet());
Collections.sort(sortedEntries, new Comparator<Entry<PlayerData, Integer>>() {
@Override
public int compare(Entry<PlayerData, Integer> entry1, Entry<PlayerData, Integer> entry2) {
return -entry1.getValue().compareTo(entry2.getValue());
}
});
// Clear the map
experienceMap.clear();
// Reinitialize the leaderboard
leaderboard = new ArrayList<>();
String format = plugin.getMessage("leaderboard_format");
for (int i = 0; i < sortedEntries.size() && i < 10; i++) {
try {
PlayerData data = sortedEntries.get(i).getKey();
String space = "";
String name = data.getLastKnownBy();
for (int ii = name.length(); ii < 19; ii++)
space = space + " ";
name = name + space;
int kills = data.getPlayerKills();
int deaths = data.getDeaths();
leaderboard.add(FormatUtil.format(format, i + 1, name, kills, deaths, formatKDR(kills, deaths)));
} catch (Throwable ex) {
continue;
}
}
sortedEntries.clear();
lastUpdateTime = System.currentTimeMillis();
updating = false;
plugin.getLogHandler().log("Leaderboard updated! [{0}ms]", System.currentTimeMillis() - start);
// Save the data
plugin.getPlayerDataCache().save();
// Clean up the data
new BukkitRunnable() {
@Override
public void run() {
plugin.getPlayerDataCache().cleanupData();
}
}.runTaskLater(plugin, 2L);
}
}
public final String formatKDR(int kills, int deaths) {
if (deaths > 0) {
DecimalFormat format = new DecimalFormat("#.##");
return format.format((double) kills / (double) deaths);
}
return String.valueOf(kills);
}
public class DisplayLeaderboardThread extends Thread {
private String playerName;
public DisplayLeaderboardThread(String playerName) {
super("SwornGuard-DisplayLeaderboard");
this.setPriority(MIN_PRIORITY);
this.playerName = playerName;
this.start();
}
@Override
public void run() {
try {
while (updating) {
sleep(500L);
}
displayLeaderboard(playerName);
} catch (Throwable ex) {
Player player = Util.matchPlayer(playerName);
if (player != null)
sendMessage(player, "&cError: &4Failed to update leaderboard: &c{0}", ex);
plugin.getLogHandler().log(Level.WARNING, Util.getUsefulStack(ex, "updating leaderboard"));
}
}
}
}