mirror of
https://github.com/itHotL/PlayerStats.git
synced 2024-11-23 12:05:47 +01:00
commit
0c93fa85c9
2
pom.xml
2
pom.xml
@ -19,7 +19,7 @@
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.18-R0.1-SNAPSHOT</version>
|
||||
<version>1.18.2-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
@ -3,6 +3,7 @@ package com.gmail.artemis.the.gr8.playerstats;
|
||||
import com.gmail.artemis.the.gr8.playerstats.commands.ReloadCommand;
|
||||
import com.gmail.artemis.the.gr8.playerstats.commands.StatCommand;
|
||||
import com.gmail.artemis.the.gr8.playerstats.commands.TabCompleter;
|
||||
import com.gmail.artemis.the.gr8.playerstats.filehandlers.ConfigHandler;
|
||||
import com.gmail.artemis.the.gr8.playerstats.listeners.JoinListener;
|
||||
import com.gmail.artemis.the.gr8.playerstats.utils.EnumHandler;
|
||||
import com.gmail.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler;
|
||||
@ -14,17 +15,16 @@ public class Main extends JavaPlugin {
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
|
||||
ConfigHandler config = new ConfigHandler(this);
|
||||
EnumHandler enumHandler = new EnumHandler();
|
||||
|
||||
EnumHandler enumHandler = new EnumHandler(this);
|
||||
OutputFormatter outputFormatter = new OutputFormatter(config);
|
||||
StatManager statManager = new StatManager(enumHandler, this);
|
||||
|
||||
this.getCommand("statistic").setExecutor(new StatCommand(outputFormatter, statManager, this));
|
||||
this.getCommand("statistic").setTabCompleter(new TabCompleter(
|
||||
enumHandler, statManager,this));
|
||||
this.getCommand("statisticreload").setExecutor(new ReloadCommand(config, outputFormatter));
|
||||
//prepare private hashMap of offline players
|
||||
OfflinePlayerHandler.updateOfflinePlayers();
|
||||
|
||||
this.getCommand("statistic").setExecutor(new StatCommand(outputFormatter, enumHandler, this));
|
||||
this.getCommand("statistic").setTabCompleter(new TabCompleter(enumHandler, this));
|
||||
this.getCommand("statisticreload").setExecutor(new ReloadCommand(config, outputFormatter, this));
|
||||
|
||||
Bukkit.getPluginManager().registerEvents(new JoinListener(), this);
|
||||
this.getLogger().info("Enabled PlayerStats!");
|
||||
@ -35,14 +35,8 @@ public class Main extends JavaPlugin {
|
||||
this.getLogger().info("Disabled PlayerStats!");
|
||||
}
|
||||
|
||||
|
||||
public void logStatRelatedExceptions(Exception exception) {
|
||||
if (exception instanceof IllegalArgumentException) {
|
||||
getLogger().warning("IllegalArgumentException - this is probably not a valid statistic name!");
|
||||
public long logTimeTaken(String className, String methodName, long previousTime, int lineNumber) {
|
||||
getLogger().info(className + " " + methodName + " " + lineNumber + ": " + (System.currentTimeMillis() - previousTime));
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
else if (exception instanceof NullPointerException) {
|
||||
getLogger().warning("NullPointerException - no statistic name was provided");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,165 +0,0 @@
|
||||
package com.gmail.artemis.the.gr8.playerstats;
|
||||
|
||||
import com.gmail.artemis.the.gr8.playerstats.utils.EnumHandler;
|
||||
import com.gmail.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.Statistic;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class StatManager {
|
||||
|
||||
private final Main plugin;
|
||||
private final EnumHandler enumHandler;
|
||||
private final OfflinePlayerHandler offlinePlayerHandler;
|
||||
private final List<String> statNames;
|
||||
private final List<String> entityStatNames;
|
||||
private final List<String> subStatEntryNames;
|
||||
|
||||
public StatManager(EnumHandler e, Main p) {
|
||||
plugin = p;
|
||||
enumHandler = e;
|
||||
offlinePlayerHandler = OfflinePlayerHandler.getInstance();
|
||||
|
||||
statNames = Arrays.stream(Statistic.values()).map(
|
||||
Statistic::toString).map(String::toLowerCase).toList();
|
||||
entityStatNames = Arrays.stream(Statistic.values()).filter(statistic ->
|
||||
statistic.getType().equals(Statistic.Type.ENTITY)).map(
|
||||
Statistic::toString).map(String::toLowerCase).collect(Collectors.toList());
|
||||
|
||||
subStatEntryNames = new ArrayList<>();
|
||||
subStatEntryNames.addAll(enumHandler.getBlockNames());
|
||||
subStatEntryNames.addAll(enumHandler.getEntityTypeNames());
|
||||
subStatEntryNames.addAll(enumHandler.getItemNames());
|
||||
}
|
||||
|
||||
public int getStatistic(String statName, String playerName) throws IllegalArgumentException, NullPointerException {
|
||||
return getStatistic(statName, null, playerName);
|
||||
}
|
||||
|
||||
//returns the integer associated with a certain statistic for a player
|
||||
public int getStatistic(String statName, String subStatEntryName, String playerName) throws IllegalArgumentException, NullPointerException {
|
||||
long time = System.currentTimeMillis();
|
||||
|
||||
OfflinePlayer player = offlinePlayerHandler.getOfflinePlayer(playerName);
|
||||
|
||||
plugin.getLogger().info("StatManager 51: " + (System.currentTimeMillis() - time));
|
||||
time = System.currentTimeMillis();
|
||||
if (player == null) throw new NullPointerException("No player called " + playerName + " was found!");
|
||||
|
||||
Statistic stat = getStatistic(statName);
|
||||
plugin.getLogger().info("StatManager 56: " + (System.currentTimeMillis() - time));
|
||||
time = System.currentTimeMillis();
|
||||
|
||||
if (stat != null) {
|
||||
switch (stat.getType()) {
|
||||
case UNTYPED -> {
|
||||
plugin.getLogger().info("StatManager 62: " + (System.currentTimeMillis() - time));
|
||||
time = System.currentTimeMillis();
|
||||
return player.getStatistic(stat);
|
||||
}
|
||||
case BLOCK -> {
|
||||
plugin.getLogger().info("StatManager 67: " + (System.currentTimeMillis() - time));
|
||||
time = System.currentTimeMillis();
|
||||
Material block = enumHandler.getBlock(subStatEntryName);
|
||||
if (block == null) throw new NullPointerException(subStatEntryName + " is not a valid block name!");
|
||||
return player.getStatistic(stat, block);
|
||||
}
|
||||
case ENTITY -> {
|
||||
plugin.getLogger().info("StatManager 74: " + (System.currentTimeMillis() - time));
|
||||
time = System.currentTimeMillis();
|
||||
EntityType entity = enumHandler.getEntityType(subStatEntryName);
|
||||
if (entity == null) throw new NullPointerException(subStatEntryName + " is not a valid entity name!");
|
||||
return player.getStatistic(stat, entity);
|
||||
}
|
||||
case ITEM -> {
|
||||
plugin.getLogger().info("StatManager 81: " + (System.currentTimeMillis() - time));
|
||||
time = System.currentTimeMillis();
|
||||
Material item = enumHandler.getItem(subStatEntryName);
|
||||
if (item == null) throw new NullPointerException(subStatEntryName + " is not a valid item name!");
|
||||
return player.getStatistic(stat, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new NullPointerException(statName + " is not a valid statistic name!");
|
||||
}
|
||||
|
||||
//returns the statistic enum constant, or null if non-existent (param: statName, not case sensitive)
|
||||
private Statistic getStatistic(String statName) {
|
||||
try {
|
||||
return Statistic.valueOf(statName.toUpperCase());
|
||||
}
|
||||
catch (IllegalArgumentException | NullPointerException exception) {
|
||||
plugin.logStatRelatedExceptions(exception);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
//gets the type of the statistic from the string, otherwise returns null (param: statName, not case sensitive)
|
||||
public Statistic.Type getStatType(String statName) {
|
||||
try {
|
||||
return Statistic.valueOf(statName.toUpperCase()).getType();
|
||||
}
|
||||
catch (IllegalArgumentException | NullPointerException exception) {
|
||||
plugin.logStatRelatedExceptions(exception);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
//checks if string is a valid statistic (param: statName, not case sensitive)
|
||||
public boolean isStatistic(String statName) {
|
||||
return statNames.contains(statName.toLowerCase());
|
||||
}
|
||||
|
||||
//checks if string is a valid substatistic dealing with entities (param: statName, not case sensitive)
|
||||
public boolean isStatEntityType(String statName) {
|
||||
return entityStatNames.contains(statName.toLowerCase());
|
||||
}
|
||||
|
||||
//checks in the most general sense if this statistic is a substatistic (param: statName, not case sensitive)
|
||||
public boolean isSubStatEntry(String statName) {
|
||||
return subStatEntryNames.contains(statName.toLowerCase());
|
||||
}
|
||||
|
||||
//checks whether a subStatEntry is of the type that the statistic requires
|
||||
public boolean isMatchingSubStatEntry(String statName, String subStatEntry) {
|
||||
Statistic.Type type = getStatType(statName);
|
||||
if (type != null && subStatEntry != null) {
|
||||
switch (type) {
|
||||
case ENTITY -> {
|
||||
return enumHandler.isEntityType(subStatEntry);
|
||||
}
|
||||
case ITEM -> {
|
||||
return enumHandler.isItem(subStatEntry);
|
||||
}
|
||||
case BLOCK -> {
|
||||
return enumHandler.isBlock(subStatEntry);
|
||||
}
|
||||
case UNTYPED -> {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//returns the names of all general statistics in lowercase
|
||||
public List<String> getStatNames() {
|
||||
return statNames;
|
||||
}
|
||||
|
||||
//returns all statistics that have type entities, in lowercase
|
||||
public List<String> getEntityTypeNames() {
|
||||
return entityStatNames;
|
||||
}
|
||||
|
||||
//returns all substatnames in lowercase
|
||||
public List<String> getSubStatEntryNames() {
|
||||
return subStatEntryNames;
|
||||
}
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
package com.gmail.artemis.the.gr8.playerstats;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class StatRequest {
|
||||
|
||||
private final CommandSender sender;
|
||||
private String statName;
|
||||
private String subStatEntry;
|
||||
private String playerName;
|
||||
private boolean playerFlag;
|
||||
private boolean topFlag;
|
||||
|
||||
//playerFlag and topFlag are false by default, will be set to true if "player" or "top" is in the args
|
||||
public StatRequest(@NotNull CommandSender s) {
|
||||
sender = s;
|
||||
playerFlag = false;
|
||||
topFlag = false;
|
||||
}
|
||||
|
||||
public CommandSender getCommandSender() {
|
||||
return sender;
|
||||
}
|
||||
|
||||
public String getStatName() {
|
||||
return statName;
|
||||
}
|
||||
|
||||
public void setStatName(String statName) {
|
||||
this.statName = statName;
|
||||
}
|
||||
|
||||
public String getSubStatEntry() {
|
||||
return subStatEntry;
|
||||
}
|
||||
|
||||
public void setSubStatEntry(String subStatEntry) {
|
||||
this.subStatEntry = subStatEntry;
|
||||
}
|
||||
|
||||
public String getPlayerName() {
|
||||
return playerName;
|
||||
}
|
||||
|
||||
public void setPlayerName(String playerName) {
|
||||
this.playerName = playerName;
|
||||
}
|
||||
|
||||
//the "player" arg in the statCommand is a special case, because it could either be a valid subStatEntry, or indicate that the lookup action should target a specific player
|
||||
//this is why the playerFlag exists - if this is true, and playerName is null, subStatEntry will be "player"
|
||||
public boolean playerFlag() {
|
||||
return playerFlag;
|
||||
}
|
||||
|
||||
public void setPlayerFlag(boolean playerFlag) {
|
||||
this.playerFlag = playerFlag;
|
||||
}
|
||||
|
||||
public boolean topFlag() {
|
||||
return topFlag;
|
||||
}
|
||||
|
||||
public void setTopFlag(boolean topFlag) {
|
||||
this.topFlag = topFlag;
|
||||
}
|
||||
}
|
@ -0,0 +1,154 @@
|
||||
package com.gmail.artemis.the.gr8.playerstats;
|
||||
|
||||
import com.gmail.artemis.the.gr8.playerstats.utils.EnumHandler;
|
||||
import com.gmail.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler;
|
||||
import com.gmail.artemis.the.gr8.playerstats.utils.OutputFormatter;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.Statistic;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class StatThread extends Thread {
|
||||
|
||||
private final StatRequest request;
|
||||
private final EnumHandler enumHandler;
|
||||
private final OutputFormatter outputFormatter;
|
||||
private final Main plugin;
|
||||
private String className = "StatThread";
|
||||
|
||||
//constructor (called on thread creation)
|
||||
public StatThread(StatRequest s, EnumHandler e, OutputFormatter o, Main p) {
|
||||
request = s;
|
||||
|
||||
enumHandler = e;
|
||||
outputFormatter = o;
|
||||
plugin = p;
|
||||
}
|
||||
|
||||
//what the thread will do once started
|
||||
@Override
|
||||
public void run() throws IllegalStateException, NullPointerException {
|
||||
long time = System.currentTimeMillis();
|
||||
|
||||
if (outputFormatter == null || plugin == null) {
|
||||
throw new IllegalStateException("Not all classes off the plugin are running!");
|
||||
}
|
||||
if (request == null) {
|
||||
throw new NullPointerException("No statistic request was found!");
|
||||
}
|
||||
|
||||
CommandSender sender = request.getCommandSender();
|
||||
String playerName = request.getPlayerName();
|
||||
String statName = request.getStatName();
|
||||
String subStatEntry = request.getSubStatEntry();
|
||||
boolean topFlag = request.topFlag();
|
||||
|
||||
if (playerName != null) {
|
||||
try {
|
||||
sender.sendMessage(
|
||||
outputFormatter.formatPlayerStat(
|
||||
playerName, statName, subStatEntry, getStatistic(
|
||||
statName, subStatEntry, playerName)));
|
||||
plugin.logTimeTaken(className, "run(): individual stat", time, 60);
|
||||
|
||||
} catch (Exception e) {
|
||||
sender.sendMessage(outputFormatter.formatExceptions(e.toString()));
|
||||
}
|
||||
|
||||
} else if (topFlag) {
|
||||
try {
|
||||
LinkedHashMap<String, Integer> topStats = getTopStatistics(statName, subStatEntry);
|
||||
plugin.logTimeTaken(className, "run(): for each loop", time, 69);
|
||||
|
||||
String top = outputFormatter.formatTopStats(topStats, statName, subStatEntry);
|
||||
sender.sendMessage(top);
|
||||
plugin.logTimeTaken(className, "run(): format output", time, 73);
|
||||
|
||||
} catch (Exception e) {
|
||||
sender.sendMessage(outputFormatter.formatExceptions(e.toString()));
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//returns the integer associated with a certain statistic for a player
|
||||
private int getStatistic(String statName, String subStatEntryName, String playerName) throws IllegalArgumentException, NullPointerException {
|
||||
OfflinePlayer player = OfflinePlayerHandler.getOfflinePlayer(playerName);
|
||||
if (player != null) {
|
||||
Statistic stat = enumHandler.getStatEnum(statName);
|
||||
if (stat != null) {
|
||||
return getPlayerStat(player, stat, subStatEntryName);
|
||||
}
|
||||
throw new IllegalArgumentException("Statistic " + statName + " could not be retrieved!");
|
||||
}
|
||||
throw new IllegalArgumentException("Player object for " + playerName + " could not be retrieved!");
|
||||
}
|
||||
|
||||
private LinkedHashMap<String, Integer> getTopStatistics(String statName, String subStatEntry) {
|
||||
Statistic stat = enumHandler.getStatEnum(statName);
|
||||
|
||||
if (stat != null) {
|
||||
HashMap<String, Integer> playerStats = new HashMap<>((int) (OfflinePlayerHandler.getOfflinePlayerCount() * 1.05));
|
||||
OfflinePlayerHandler.getAllOfflinePlayerNames().forEach(playerName -> {
|
||||
OfflinePlayer player = OfflinePlayerHandler.getOfflinePlayer(playerName);
|
||||
if (player != null)
|
||||
try {
|
||||
int statistic = getPlayerStat(player, stat, subStatEntry);
|
||||
if (statistic > 0) {
|
||||
playerStats.put(playerName, statistic);
|
||||
}
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
}
|
||||
});
|
||||
return playerStats.entrySet().stream()
|
||||
.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
|
||||
.limit(10).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
|
||||
}
|
||||
throw new NullPointerException("Statistic " + statName + " could not be retrieved!");
|
||||
}
|
||||
|
||||
private int getPlayerStat(@NotNull OfflinePlayer player, @NotNull Statistic stat, String subStatEntryName) throws IllegalArgumentException {
|
||||
switch (stat.getType()) {
|
||||
case UNTYPED -> {
|
||||
return player.getStatistic(stat);
|
||||
}
|
||||
case BLOCK -> {
|
||||
Material block = enumHandler.getBlock(subStatEntryName);
|
||||
if (block != null) {
|
||||
return player.getStatistic(stat, block);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException(subStatEntryName + " is not a valid block name!");
|
||||
}
|
||||
}
|
||||
case ENTITY -> {
|
||||
EntityType entity = enumHandler.getEntityType(subStatEntryName);
|
||||
if (entity != null) {
|
||||
return player.getStatistic(stat, entity);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException(subStatEntryName + " is not a valid entity name!");
|
||||
}
|
||||
}
|
||||
case ITEM -> {
|
||||
Material item = enumHandler.getItem(subStatEntryName);
|
||||
if (item != null) {
|
||||
return player.getStatistic(stat, item);
|
||||
}
|
||||
else {
|
||||
throw new IllegalArgumentException(subStatEntryName + " is not a valid item name!");
|
||||
}
|
||||
}
|
||||
default ->
|
||||
throw new IllegalArgumentException("This statistic does not seem to be of type:untyped/block/entity/item, I think we should panic");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
package com.gmail.artemis.the.gr8.playerstats.commands;
|
||||
|
||||
import com.gmail.artemis.the.gr8.playerstats.ConfigHandler;
|
||||
import com.gmail.artemis.the.gr8.playerstats.filehandlers.ConfigHandler;
|
||||
import com.gmail.artemis.the.gr8.playerstats.Main;
|
||||
import com.gmail.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler;
|
||||
import com.gmail.artemis.the.gr8.playerstats.utils.OutputFormatter;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.Command;
|
||||
@ -12,17 +14,27 @@ public class ReloadCommand implements CommandExecutor {
|
||||
|
||||
private final ConfigHandler config;
|
||||
private final OutputFormatter outputFormatter;
|
||||
private final Main plugin;
|
||||
|
||||
public ReloadCommand(ConfigHandler c, OutputFormatter o) {
|
||||
public ReloadCommand(ConfigHandler c, OutputFormatter o, Main p) {
|
||||
outputFormatter = o;
|
||||
config = c;
|
||||
plugin = p;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
|
||||
if (config.reloadConfig()) {
|
||||
long time = System.currentTimeMillis();
|
||||
|
||||
outputFormatter.updateOutputColors();
|
||||
time = plugin.logTimeTaken("ReloadCommand", "onCommand", time, 33);
|
||||
|
||||
OfflinePlayerHandler.updateOfflinePlayers();
|
||||
time = plugin.logTimeTaken("ReloadCommand", "onCommand", time, 36);
|
||||
|
||||
sender.sendMessage(ChatColor.GREEN + "Config reloaded!");
|
||||
plugin.logTimeTaken("ReloadCommand", "onCommand", time, 39);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -1,7 +1,9 @@
|
||||
package com.gmail.artemis.the.gr8.playerstats.commands;
|
||||
|
||||
import com.gmail.artemis.the.gr8.playerstats.Main;
|
||||
import com.gmail.artemis.the.gr8.playerstats.StatManager;
|
||||
import com.gmail.artemis.the.gr8.playerstats.utils.EnumHandler;
|
||||
import com.gmail.artemis.the.gr8.playerstats.StatRequest;
|
||||
import com.gmail.artemis.the.gr8.playerstats.StatThread;
|
||||
import com.gmail.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler;
|
||||
import com.gmail.artemis.the.gr8.playerstats.utils.OutputFormatter;
|
||||
import org.bukkit.command.Command;
|
||||
@ -13,98 +15,81 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class StatCommand implements CommandExecutor {
|
||||
|
||||
private final OfflinePlayerHandler offlinePlayerHandler;
|
||||
private final OutputFormatter outputFormatter;
|
||||
private final StatManager statManager;
|
||||
private final EnumHandler enumHandler;
|
||||
private final Main plugin;
|
||||
|
||||
public StatCommand(OutputFormatter o, StatManager s, Main p) {
|
||||
public StatCommand(OutputFormatter o, EnumHandler e, Main p) {
|
||||
outputFormatter = o;
|
||||
statManager = s;
|
||||
enumHandler = e;
|
||||
plugin = p;
|
||||
|
||||
offlinePlayerHandler = OfflinePlayerHandler.getInstance();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
|
||||
long time = System.currentTimeMillis();
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
//part 1: collecting all relevant information from the args
|
||||
if (args.length >= 2) {
|
||||
StatRequest request = new StatRequest(sender);
|
||||
|
||||
String statName = null;
|
||||
String subStatEntry = null;
|
||||
String playerName = null;
|
||||
boolean playerFlag = false;
|
||||
|
||||
plugin.getLogger().info("onCommand 40: " + (System.currentTimeMillis() - time));
|
||||
time = System.currentTimeMillis();
|
||||
|
||||
//all args are in lowercase
|
||||
for (String arg : args) {
|
||||
if (statManager.isStatistic(arg)) {
|
||||
statName = (statName == null) ? arg : statName;
|
||||
plugin.getLogger().info("onCommand 48: " + (System.currentTimeMillis() - time));
|
||||
time = System.currentTimeMillis();
|
||||
if (enumHandler.isStatistic(arg) && request.getStatName() == null) {
|
||||
request.setStatName(arg);
|
||||
}
|
||||
else if (statManager.isSubStatEntry(arg)) {
|
||||
else if (enumHandler.isSubStatEntry(arg)) {
|
||||
if (arg.equalsIgnoreCase("player")) {
|
||||
if (!playerFlag) {
|
||||
subStatEntry = (subStatEntry == null) ? arg : subStatEntry;
|
||||
playerFlag = true;
|
||||
plugin.getLogger().info("onCommand 56: " + (System.currentTimeMillis() - time));
|
||||
time = System.currentTimeMillis();
|
||||
}
|
||||
if (request.playerFlag()) {
|
||||
if (request.getSubStatEntry() == null) request.setSubStatEntry(arg);
|
||||
}
|
||||
else {
|
||||
subStatEntry = (subStatEntry == null || playerFlag) ? arg : subStatEntry;
|
||||
plugin.getLogger().info("onCommand 62: " + (System.currentTimeMillis() - time));
|
||||
time = System.currentTimeMillis();
|
||||
request.setPlayerFlag(true);
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
if (request.getSubStatEntry() == null) request.setSubStatEntry(arg);
|
||||
}
|
||||
}
|
||||
|
||||
else if (arg.equalsIgnoreCase("top")) {
|
||||
request.setTopFlag(true);
|
||||
}
|
||||
else if (arg.equalsIgnoreCase("me") && sender instanceof Player) {
|
||||
playerName = sender.getName();
|
||||
plugin.getLogger().info("onCommand 69: " + (System.currentTimeMillis() - time));
|
||||
time = System.currentTimeMillis();
|
||||
request.setPlayerName(sender.getName());
|
||||
}
|
||||
else if (offlinePlayerHandler.isOfflinePlayerName(arg)) {
|
||||
playerName = (playerName == null) ? arg : playerName;
|
||||
plugin.getLogger().info("onCommand 74: " + (System.currentTimeMillis() - time));
|
||||
time = System.currentTimeMillis();
|
||||
else if (OfflinePlayerHandler.isOfflinePlayerName(arg) && request.getPlayerName() == null) {
|
||||
request.setPlayerName(arg);
|
||||
}
|
||||
}
|
||||
if (playerName != null && statName != null) {
|
||||
plugin.getLogger().info("onCommand 79: " + (System.currentTimeMillis() - time));
|
||||
time = System.currentTimeMillis();
|
||||
subStatEntry = statManager.isMatchingSubStatEntry(statName, subStatEntry) ? subStatEntry : null;
|
||||
plugin.getLogger().info("onCommand 82: " + (System.currentTimeMillis() - time));
|
||||
time = System.currentTimeMillis();
|
||||
try {
|
||||
plugin.getLogger().info("onCommand 85: " + (System.currentTimeMillis() - time));
|
||||
time = System.currentTimeMillis();
|
||||
|
||||
int stat = statManager.getStatistic(statName, subStatEntry, playerName);
|
||||
plugin.getLogger().info("onCommand 89: " + (System.currentTimeMillis() - time));
|
||||
time = System.currentTimeMillis();
|
||||
|
||||
String msg = outputFormatter.formatPlayerStat(playerName, statName, subStatEntry, stat);
|
||||
plugin.getLogger().info("onCommand 93: " + (System.currentTimeMillis() - time));
|
||||
time = System.currentTimeMillis();
|
||||
|
||||
sender.sendMessage(msg);
|
||||
plugin.getLogger().info("onCommand 97: " + (System.currentTimeMillis() - time));
|
||||
time = System.currentTimeMillis();
|
||||
}
|
||||
catch (Exception e) {
|
||||
sender.sendMessage(e.toString());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
plugin.getLogger().info("onCommand 106: " + (System.currentTimeMillis() - time));
|
||||
plugin.getLogger().info("Total time elapsed: " + (System.currentTimeMillis() - startTime));
|
||||
//part 2: sending the information to the StatThread
|
||||
if (isValidStatRequest(request)) {
|
||||
StatThread statThread = new StatThread(request, enumHandler, outputFormatter, plugin);
|
||||
statThread.start();
|
||||
|
||||
plugin.logTimeTaken("StatCommand", "onCommand", time, 71);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//check whether all necessary ingredients are present to proceed with a lookup
|
||||
private boolean isValidStatRequest(StatRequest request) {
|
||||
if (request.getStatName() != null) {
|
||||
if (request.topFlag() || request.getPlayerName() != null) {
|
||||
validatePlayerFlag(request);
|
||||
return enumHandler.isValidStatEntry(request.getStatName(), request.getSubStatEntry());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//account for the fact that "player" could be either a subStatEntry or a flag to indicate the target for the lookup, and correct the request if necessary
|
||||
private void validatePlayerFlag(StatRequest request) {
|
||||
if (!enumHandler.isValidStatEntry(request.getStatName(), request.getSubStatEntry()) && request.playerFlag()) {
|
||||
request.setSubStatEntry("player");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package com.gmail.artemis.the.gr8.playerstats.commands;
|
||||
|
||||
import com.gmail.artemis.the.gr8.playerstats.Main;
|
||||
import com.gmail.artemis.the.gr8.playerstats.StatManager;
|
||||
import com.gmail.artemis.the.gr8.playerstats.utils.EnumHandler;
|
||||
import com.gmail.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler;
|
||||
import org.bukkit.command.Command;
|
||||
@ -15,16 +14,12 @@ import java.util.stream.Collectors;
|
||||
public class TabCompleter implements org.bukkit.command.TabCompleter {
|
||||
|
||||
private final EnumHandler enumHandler;
|
||||
private final OfflinePlayerHandler offlinePlayerHandler;
|
||||
private final StatManager statManager;
|
||||
private final Main plugin;
|
||||
private final List<String> commandOptions;
|
||||
|
||||
|
||||
public TabCompleter(EnumHandler e, StatManager s, Main p) {
|
||||
public TabCompleter(EnumHandler e, Main p) {
|
||||
enumHandler = e;
|
||||
offlinePlayerHandler = OfflinePlayerHandler.getInstance();
|
||||
statManager = s;
|
||||
plugin = p;
|
||||
|
||||
commandOptions = new ArrayList<>();
|
||||
@ -45,14 +40,14 @@ public class TabCompleter implements org.bukkit.command.TabCompleter {
|
||||
//after typing "stat", suggest a list of viable statistics
|
||||
if (args.length >= 1) {
|
||||
if (args.length == 1) {
|
||||
tabSuggestions = statManager.getStatNames().stream().filter(stat ->
|
||||
tabSuggestions = enumHandler.getStatNames().stream().filter(stat ->
|
||||
stat.contains(args[0].toLowerCase())).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
//after checking if args[0] is a viable statistic, suggest substatistic OR commandOptions
|
||||
else {
|
||||
if (statManager.isStatistic(args[args.length-2])) {
|
||||
tabSuggestions = switch (statManager.getStatType(args[args.length-2])) {
|
||||
if (enumHandler.isStatistic(args[args.length-2])) {
|
||||
tabSuggestions = switch (enumHandler.getStatType(args[args.length-2])) {
|
||||
case UNTYPED -> commandOptions;
|
||||
case BLOCK -> enumHandler.getBlockNames().stream().filter(block ->
|
||||
block.contains(args[args.length - 1])).collect(Collectors.toList());
|
||||
@ -61,23 +56,22 @@ public class TabCompleter implements org.bukkit.command.TabCompleter {
|
||||
case ENTITY -> enumHandler.getEntityTypeNames().stream().filter(entity ->
|
||||
entity.contains(args[args.length - 1])).collect(Collectors.toList());
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
//if previous arg = "player", suggest playerNames
|
||||
else if (args[args.length-2].equalsIgnoreCase("player")) {
|
||||
if (args.length >= 3 && statManager.getEntityTypeNames().contains(args[args.length-3].toLowerCase())) {
|
||||
if (args.length >= 3 && enumHandler.getEntityStatNames().contains(args[args.length-3].toLowerCase())) {
|
||||
tabSuggestions = commandOptions;
|
||||
|
||||
}
|
||||
else {
|
||||
tabSuggestions = offlinePlayerHandler.getAllOfflinePlayerNames().stream().filter(player ->
|
||||
tabSuggestions = OfflinePlayerHandler.getAllOfflinePlayerNames().stream().filter(player ->
|
||||
player.toLowerCase().contains(args[args.length-1].toLowerCase())).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
||||
//after a substatistic, suggest commandOptions
|
||||
else if (statManager.isSubStatEntry(args[args.length-2])) {
|
||||
else if (enumHandler.isSubStatEntry(args[args.length-2])) {
|
||||
tabSuggestions = commandOptions;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.gmail.artemis.the.gr8.playerstats;
|
||||
package com.gmail.artemis.the.gr8.playerstats.filehandlers;
|
||||
|
||||
import com.gmail.artemis.the.gr8.playerstats.Main;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
@ -19,24 +20,53 @@ public class ConfigHandler {
|
||||
saveDefaultConfig();
|
||||
}
|
||||
|
||||
//returns the config setting for use-dots, or the default value "true" if no value can be retrieved
|
||||
public boolean getUseDots() {
|
||||
ConfigurationSection ranked = config.getConfigurationSection("ranked-list");
|
||||
try {
|
||||
return ranked == null || ranked.getBoolean("use-dots");
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//returns a HashMap with all the available color choices, or a ChatColor.RESET if no colors were found
|
||||
public HashMap<String, ChatColor> getChatColors() {
|
||||
HashMap<String, ChatColor> chatColors = new HashMap<>();
|
||||
|
||||
ConfigurationSection individual = config.getConfigurationSection("individual-statistics");
|
||||
chatColors.put("playerNames", getChatColor(individual, "player-names"));
|
||||
chatColors.put("statNames", getChatColor(individual, "stat-names"));
|
||||
chatColors.put("subStatNames", getChatColor(individual, "sub-stat-names"));
|
||||
chatColors.put("numbers", getChatColor(individual, "numbers"));
|
||||
chatColors.put("player-names", getChatColor(individual, "player-names"));
|
||||
chatColors.put("stat-names", getChatColor(individual, "stat-names"));
|
||||
chatColors.put("sub-stat-names", getChatColor(individual, "sub-stat-names"));
|
||||
chatColors.put("stat-numbers", getChatColor(individual, "stat-numbers"));
|
||||
|
||||
ConfigurationSection ranked = config.getConfigurationSection("ranked-list");
|
||||
chatColors.put("playerNamesRanked", getChatColor(ranked, "player-names"));
|
||||
chatColors.put("statNamesRanked", getChatColor(ranked, "stat-names"));
|
||||
chatColors.put("subStatNamesRanked", getChatColor(ranked, "sub-stat-names"));
|
||||
chatColors.put("numbersRanked", getChatColor(ranked, "numbers"));
|
||||
chatColors.put("player-names-ranked", getChatColor(ranked, "player-names"));
|
||||
chatColors.put("list-title", getChatColor(ranked, "list-title"));
|
||||
chatColors.put("sub-stat-names-ranked", getChatColor(ranked, "sub-stat-names"));
|
||||
chatColors.put("stat-numbers-ranked", getChatColor(ranked, "stat-numbers"));
|
||||
chatColors.put("list-numbers", getChatColor(ranked, "list-numbers"));
|
||||
chatColors.put("dots", getChatColor(ranked, "dots"));
|
||||
return chatColors;
|
||||
}
|
||||
|
||||
//reload the config after changes have been made to it
|
||||
public boolean reloadConfig() {
|
||||
try {
|
||||
if (!configFile.exists()) {
|
||||
saveDefaultConfig();
|
||||
}
|
||||
config = YamlConfiguration.loadConfiguration(configFile);
|
||||
return true;
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//returns the requested entry from the provided configuration section, null if section does not exist, and ChatColor.RESET if there is no entry
|
||||
private ChatColor getChatColor(ConfigurationSection section, String path) {
|
||||
ChatColor color;
|
||||
@ -56,21 +86,6 @@ public class ConfigHandler {
|
||||
return color;
|
||||
}
|
||||
|
||||
//reload the config after changes have been made to it
|
||||
public boolean reloadConfig() {
|
||||
try {
|
||||
if (!configFile.exists()) {
|
||||
saveDefaultConfig();
|
||||
}
|
||||
config = YamlConfiguration.loadConfiguration(configFile);
|
||||
return true;
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//create a config file if none exists yet (from the config.yml in the plugin's resources)
|
||||
private void saveDefaultConfig() {
|
||||
config = plugin.getConfig();
|
@ -1,21 +1,20 @@
|
||||
package com.gmail.artemis.the.gr8.playerstats.listeners;
|
||||
|
||||
import com.gmail.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
|
||||
|
||||
public class JoinListener implements Listener {
|
||||
|
||||
private final OfflinePlayerHandler offlinePlayerHandler;
|
||||
|
||||
public JoinListener() {
|
||||
offlinePlayerHandler = OfflinePlayerHandler.getInstance();
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerJoin(PlayerJoinEvent joinEvent) {
|
||||
if (!joinEvent.getPlayer().hasPlayedBefore()) {
|
||||
offlinePlayerHandler.updateOfflinePlayers();
|
||||
OfflinePlayerHandler.updateOfflinePlayers();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,32 +1,57 @@
|
||||
package com.gmail.artemis.the.gr8.playerstats.utils;
|
||||
|
||||
import com.gmail.artemis.the.gr8.playerstats.Main;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Statistic;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class EnumHandler {
|
||||
|
||||
private final List<String> blockNames;
|
||||
private final List<String> entityTypeNames;
|
||||
private final List<String> itemNames;
|
||||
private final List<String> statNames;
|
||||
private final List<String> entityStatNames;
|
||||
private final List<String> subStatEntryNames;
|
||||
private final Main plugin;
|
||||
|
||||
|
||||
public EnumHandler() {
|
||||
public EnumHandler(Main p) {
|
||||
plugin = p;
|
||||
|
||||
blockNames = Arrays.stream(Material.values()).filter(
|
||||
Material::isBlock).map(Material::toString).map(String::toLowerCase).toList();
|
||||
entityTypeNames = Arrays.stream(EntityType.values()).map(
|
||||
EntityType::toString).map(String::toLowerCase).toList();
|
||||
itemNames = Arrays.stream(Material.values()).filter(
|
||||
Material::isItem).map(Material::toString).map(String::toLowerCase).toList();
|
||||
statNames = Arrays.stream(Statistic.values()).map(
|
||||
Statistic::toString).map(String::toLowerCase).toList();
|
||||
|
||||
entityStatNames = Arrays.stream(Statistic.values()).filter(statistic ->
|
||||
statistic.getType().equals(Statistic.Type.ENTITY)).map(
|
||||
Statistic::toString).map(String::toLowerCase).collect(Collectors.toList());
|
||||
|
||||
subStatEntryNames = new ArrayList<>();
|
||||
subStatEntryNames.addAll(getBlockNames());
|
||||
subStatEntryNames.addAll(getEntityTypeNames());
|
||||
subStatEntryNames.addAll(getItemNames());
|
||||
}
|
||||
|
||||
//checks whether the provided string is a valid item
|
||||
public boolean isItem(String itemName) {
|
||||
return itemNames.contains(itemName.toLowerCase());
|
||||
}
|
||||
|
||||
//returns corresponding item enum constant (uppercase), otherwise null (param: itemName, not case sensitive)
|
||||
@Nullable
|
||||
public Material getItem(String itemName) {
|
||||
return Material.matchMaterial(itemName);
|
||||
}
|
||||
@ -36,18 +61,25 @@ public class EnumHandler {
|
||||
return itemNames;
|
||||
}
|
||||
|
||||
//checks whether the provided string is a valid entity
|
||||
public boolean isEntityType(String entityName) {
|
||||
return entityTypeNames.contains(entityName.toLowerCase());
|
||||
}
|
||||
|
||||
//returns EntityType enum constant (uppercase) if the input name is valid, otherwise null (param: entityName, not case sensitive)
|
||||
@Nullable
|
||||
public EntityType getEntityType(String entityName) {
|
||||
EntityType entityType = null;
|
||||
EntityType entityType;
|
||||
try {
|
||||
entityType = EntityType.valueOf(entityName.toUpperCase());
|
||||
}
|
||||
catch (IllegalArgumentException | NullPointerException exception) {
|
||||
exception.printStackTrace();
|
||||
catch (IllegalArgumentException e) {
|
||||
plugin.getLogger().warning("IllegalArgumentException: " + entityName + " is not a valid statistic name!");
|
||||
return null;
|
||||
}
|
||||
catch (NullPointerException e) {
|
||||
plugin.getLogger().warning("NullPointerException: please provide a statistic name!");
|
||||
return null;
|
||||
}
|
||||
return entityType;
|
||||
}
|
||||
@ -57,11 +89,13 @@ public class EnumHandler {
|
||||
return entityTypeNames;
|
||||
}
|
||||
|
||||
//checks whether the provided string is a valid block
|
||||
public boolean isBlock(String materialName) {
|
||||
return blockNames.contains(materialName.toLowerCase());
|
||||
}
|
||||
|
||||
//returns corresponding block enum constant (uppercase), otherwise null (param: materialName, not case sensitive)
|
||||
@Nullable
|
||||
public Material getBlock(String materialName) {
|
||||
return Material.matchMaterial(materialName);
|
||||
}
|
||||
@ -71,4 +105,85 @@ public class EnumHandler {
|
||||
return blockNames;
|
||||
}
|
||||
|
||||
//returns the statistic enum constant, or null if non-existent (param: statName, not case sensitive)
|
||||
public Statistic getStatEnum(String statName) {
|
||||
try {
|
||||
return Statistic.valueOf(statName.toUpperCase());
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
plugin.getLogger().warning("IllegalArgumentException: " + statName + " is not a valid statistic name!");
|
||||
return null;
|
||||
}
|
||||
catch (NullPointerException e) {
|
||||
plugin.getLogger().warning("NullPointerException: please provide a statistic name!");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
//gets the type of the statistic from the string, otherwise returns null (param: statName, not case sensitive)
|
||||
public Statistic.Type getStatType(String statName) {
|
||||
try {
|
||||
return Statistic.valueOf(statName.toUpperCase()).getType();
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
plugin.getLogger().warning("IllegalArgumentException: " + statName + " is not a valid statistic name!");
|
||||
return null;
|
||||
}
|
||||
catch (NullPointerException e) {
|
||||
plugin.getLogger().warning("NullPointerException: please provide a statistic name!");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
//checks if string is a valid statistic (param: statName, not case sensitive)
|
||||
public boolean isStatistic(String statName) {
|
||||
return statNames.contains(statName.toLowerCase());
|
||||
}
|
||||
|
||||
//returns the names of all general statistics in lowercase
|
||||
public List<String> getStatNames() {
|
||||
return statNames;
|
||||
}
|
||||
|
||||
//returns all statistics that have type entities, in lowercase
|
||||
public List<String> getEntityStatNames() {
|
||||
return entityStatNames;
|
||||
}
|
||||
|
||||
//checks if this statistic is a subStatEntry, meaning it is a block, item or entity (param: statName, not case sensitive)
|
||||
public boolean isSubStatEntry(String statName) {
|
||||
return subStatEntryNames.contains(statName.toLowerCase());
|
||||
}
|
||||
|
||||
//checks if string is a valid statistic (param: statName, not case sensitive)
|
||||
public boolean isValidStatEntry(String statName) {
|
||||
return isValidStatEntry(statName, null);
|
||||
}
|
||||
|
||||
//checks whether a subStatEntry is of the type that the statistic requires
|
||||
public boolean isValidStatEntry(String statName, String subStatEntry) {
|
||||
Statistic stat = getStatEnum(statName);
|
||||
return (stat != null && isMatchingSubStatEntry(stat, subStatEntry));
|
||||
}
|
||||
|
||||
//returns true if subStatEntry matches the type the stat requires, or if stat is untyped and subStatEntry is null
|
||||
private boolean isMatchingSubStatEntry(@NotNull Statistic stat, String subStatEntry) {
|
||||
switch (stat.getType()) {
|
||||
case ENTITY -> {
|
||||
return subStatEntry != null && isEntityType(subStatEntry);
|
||||
}
|
||||
case ITEM -> {
|
||||
return subStatEntry != null && isItem(subStatEntry);
|
||||
}
|
||||
case BLOCK -> {
|
||||
return subStatEntry != null && isBlock(subStatEntry);
|
||||
}
|
||||
case UNTYPED -> {
|
||||
return subStatEntry==null;
|
||||
}
|
||||
default -> {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,51 +4,60 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class OfflinePlayerHandler {
|
||||
|
||||
private static OfflinePlayerHandler instance;
|
||||
private List<OfflinePlayer> offlinePlayers;
|
||||
private List<String> offlinePlayerNames;
|
||||
private HashMap<String, OfflinePlayer> offlinePlayerMap;
|
||||
private static HashMap<String, OfflinePlayer> offlinePlayerMap;
|
||||
private static List<String> offlinePlayerNames;
|
||||
private static int totalOfflinePlayers;
|
||||
|
||||
private OfflinePlayerHandler() {
|
||||
updateOfflinePlayers();
|
||||
}
|
||||
|
||||
public static OfflinePlayerHandler getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new OfflinePlayerHandler();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public boolean isOfflinePlayerName(String playerName) {
|
||||
public static boolean isOfflinePlayerName(String playerName) {
|
||||
return offlinePlayerNames.contains(playerName);
|
||||
}
|
||||
|
||||
public OfflinePlayer getOfflinePlayer(String playerName) {
|
||||
long time = System.currentTimeMillis();
|
||||
|
||||
OfflinePlayer player = offlinePlayerMap.get(playerName);
|
||||
System.out.println(("OfflinePlayerHandler 35: " + (System.currentTimeMillis() - time)));
|
||||
return player;
|
||||
public static OfflinePlayer getOfflinePlayer(String playerName) {
|
||||
return offlinePlayerMap.get(playerName);
|
||||
}
|
||||
|
||||
public List<OfflinePlayer> getAllOfflinePlayers() {
|
||||
return offlinePlayers;
|
||||
public static int getOfflinePlayerCount() {
|
||||
return totalOfflinePlayers > 0 ? totalOfflinePlayers : 1;
|
||||
}
|
||||
|
||||
public List<String> getAllOfflinePlayerNames() {
|
||||
public static List<String> getAllOfflinePlayerNames() {
|
||||
return offlinePlayerNames;
|
||||
}
|
||||
|
||||
public void updateOfflinePlayers() {
|
||||
offlinePlayerMap = new HashMap<>();
|
||||
offlinePlayers = Arrays.stream(Bukkit.getOfflinePlayers()).filter(offlinePlayer ->
|
||||
offlinePlayer.getName() != null && offlinePlayer.hasPlayedBefore()).collect(Collectors.toList());
|
||||
offlinePlayerNames = offlinePlayers.stream().map(OfflinePlayer::getName).collect(Collectors.toList());
|
||||
offlinePlayers.forEach(offlinePlayer -> offlinePlayerMap.put(offlinePlayer.getName(), offlinePlayer));
|
||||
//stores a private HashMap with keys:playerName and values:OfflinePlayer, and a private list of the names for easy access
|
||||
public static void updateOfflinePlayers() {
|
||||
long totalTime = System.currentTimeMillis();
|
||||
long time = System.currentTimeMillis();
|
||||
if (offlinePlayerMap == null) offlinePlayerMap = new HashMap<>();
|
||||
else if (!offlinePlayerMap.isEmpty()) {
|
||||
offlinePlayerMap.clear();
|
||||
}
|
||||
|
||||
if (offlinePlayerNames == null) offlinePlayerNames = new ArrayList<>();
|
||||
else if (!offlinePlayerNames.isEmpty()) {
|
||||
offlinePlayerNames.clear();
|
||||
}
|
||||
|
||||
Arrays.stream(Bukkit.getOfflinePlayers()).filter(offlinePlayer ->
|
||||
offlinePlayer.getName() != null && offlinePlayer.hasPlayedBefore()).forEach(offlinePlayer -> {
|
||||
offlinePlayerNames.add(offlinePlayer.getName());
|
||||
offlinePlayerMap.put(offlinePlayer.getName(), offlinePlayer);
|
||||
});
|
||||
System.out.println("OfflinePlayerHandler, making the HashMap and ArrayList: " + (System.currentTimeMillis() - time));
|
||||
time = System.currentTimeMillis();
|
||||
|
||||
totalOfflinePlayers = offlinePlayerMap.size();
|
||||
System.out.println("OfflinePlayerHandler, counting the HashMap: " + (System.currentTimeMillis() - time));
|
||||
time = System.currentTimeMillis();
|
||||
|
||||
totalOfflinePlayers = offlinePlayerNames.size();
|
||||
System.out.println("OfflinePlayerHandler, counting the ArrayList: " + (System.currentTimeMillis() - time));
|
||||
System.out.println("updateOfflinePlayers total time: " + (System.currentTimeMillis() - totalTime));
|
||||
}
|
||||
}
|
||||
|
@ -1,51 +1,72 @@
|
||||
package com.gmail.artemis.the.gr8.playerstats.utils;
|
||||
|
||||
import com.gmail.artemis.the.gr8.playerstats.ConfigHandler;
|
||||
import com.gmail.artemis.the.gr8.playerstats.Main;
|
||||
import com.gmail.artemis.the.gr8.playerstats.filehandlers.ConfigHandler;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.map.MinecraftFont;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.*;
|
||||
|
||||
public class OutputFormatter {
|
||||
|
||||
//keys for the HashMap are:
|
||||
//playerNames(Ranked)
|
||||
//statNames(Ranked)
|
||||
//subStatNames(Ranked)
|
||||
//numbers(Ranked)
|
||||
//keys for the HashMap are the same as the config options (so e.g. player-names/player-names-ranked)
|
||||
|
||||
private final ConfigHandler config;
|
||||
private HashMap<String, ChatColor> chatColors;
|
||||
private final String pluginPrefix;
|
||||
|
||||
public OutputFormatter(ConfigHandler c) {
|
||||
config = c;
|
||||
pluginPrefix = ChatColor.GRAY + "[" + ChatColor.GOLD + "PlayerStats" + ChatColor.GRAY + "] " + ChatColor.RESET;
|
||||
updateOutputColors();
|
||||
}
|
||||
|
||||
public String formatTopStats(LinkedHashMap<String, Integer> topStats) {
|
||||
return "";
|
||||
}
|
||||
|
||||
public String formatPlayerStat(String playerName, String statName, int stat) {
|
||||
return formatPlayerStat(playerName, statName, null, stat);
|
||||
public String formatExceptions(String exception) {
|
||||
return pluginPrefix + exception;
|
||||
}
|
||||
|
||||
public String formatPlayerStat(String playerName, String statName, String subStatEntryName, int stat) {
|
||||
long time = System.currentTimeMillis();
|
||||
System.out.println("OutputFormatter 33: " + (System.currentTimeMillis() - time));
|
||||
time = System.currentTimeMillis();
|
||||
|
||||
String subStat = subStatEntryName != null ?
|
||||
chatColors.get("subStatNames") + " (" + subStatEntryName.toLowerCase().replace("_", " ") + ")" : "";
|
||||
chatColors.get("sub-stat-names") + " (" + subStatEntryName.toLowerCase().replace("_", " ") + ")" : "";
|
||||
|
||||
System.out.println("OutputFormatter 39: " + (System.currentTimeMillis() - time));
|
||||
time = System.currentTimeMillis();
|
||||
return chatColors.get("player-names") + playerName + chatColors.get("stat-numbers") + ": " + stat + " " +
|
||||
chatColors.get("stat-names") + statName.toLowerCase().replace("_", " ") + subStat;
|
||||
}
|
||||
|
||||
String msg = chatColors.get("playerNames") + playerName + chatColors.get("numbers") + ": " + stat + " " +
|
||||
chatColors.get("statNames") + statName.toLowerCase().replace("_", " ") + subStat;
|
||||
public String formatTopStats(LinkedHashMap<String, Integer> topStats, String statName, String subStatEntryName) {
|
||||
String subStat = subStatEntryName != null ?
|
||||
chatColors.get("sub-stat-names-ranked") + " (" + subStatEntryName.toLowerCase().replace("_", " ") + ")" : "";
|
||||
String topCount = chatColors.get("list-numbers") + " " + topStats.size();
|
||||
String title = "\n" + pluginPrefix + chatColors.get("list-title") + "Top" + topCount + chatColors.get("list-title") + " " +
|
||||
statName.toLowerCase().replace("_", " ") + subStat;
|
||||
|
||||
System.out.println("OutputFormatter 45: " + (System.currentTimeMillis() - time));
|
||||
return msg;
|
||||
boolean useDots = config.getUseDots();
|
||||
int count = 0;
|
||||
Set<String> playerNames = topStats.keySet();
|
||||
MinecraftFont font = new MinecraftFont();
|
||||
|
||||
StringBuilder rankList = new StringBuilder();
|
||||
for (String playerName : playerNames) {
|
||||
count = count+1;
|
||||
|
||||
rankList.append("\n")
|
||||
.append(chatColors.get("list-numbers")).append(count).append(". ")
|
||||
.append(chatColors.get("player-names-ranked")).append(playerName)
|
||||
.append(chatColors.get("dots"));
|
||||
|
||||
if (useDots) {
|
||||
rankList.append(" ");
|
||||
int dots = (int) Math.round((125.0 - font.getWidth(count + ". " + playerName))/2);
|
||||
if (dots >= 1) {
|
||||
rankList.append(".".repeat(dots));
|
||||
}
|
||||
}
|
||||
else {
|
||||
rankList.append(":");
|
||||
}
|
||||
|
||||
rankList.append(" ").append(chatColors.get("stat-numbers-ranked")).append(topStats.get(playerName).toString());
|
||||
}
|
||||
return title + rankList;
|
||||
}
|
||||
|
||||
public void updateOutputColors() {
|
||||
|
@ -1,15 +1,23 @@
|
||||
# PlayerStats Configuration
|
||||
|
||||
# --- Color Options ---
|
||||
# supports: all default Minecraft colors
|
||||
# --- General Options ---
|
||||
|
||||
|
||||
# --- Format & Color Options ---
|
||||
individual-statistics:
|
||||
player-names: gold
|
||||
stat-names: yellow
|
||||
sub-stat-names: yellow
|
||||
numbers: white
|
||||
stat-numbers: white
|
||||
|
||||
ranked-list:
|
||||
player-names: gold
|
||||
stat-names: yellow
|
||||
player-names: green
|
||||
list-title: yellow
|
||||
sub-stat-names: yellow
|
||||
numbers: white
|
||||
stat-numbers: white
|
||||
list-numbers: gold
|
||||
|
||||
# If true, the statistics will be aligned so that they are all underneath each other
|
||||
use-dots: true
|
||||
dots: dark_gray
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user