mirror of
https://github.com/itHotL/PlayerStats.git
synced 2025-01-22 21:41:19 +01:00
Started using multi-threading to improve performance (#24)
This commit is contained in:
parent
a9dca1db83
commit
2709232e67
@ -3,8 +3,10 @@ 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;
|
||||
import com.gmail.artemis.the.gr8.playerstats.utils.OutputFormatter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
@ -14,14 +16,14 @@ 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));
|
||||
//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);
|
||||
|
@ -1,250 +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 org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
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;
|
||||
|
||||
private final String className;
|
||||
|
||||
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());
|
||||
|
||||
className = "StatManger";
|
||||
}
|
||||
|
||||
//returns the integer associated with a certain statistic for a player
|
||||
public int getStatistic(String statName, String subStatEntryName, String playerName) throws IllegalArgumentException, NullPointerException {
|
||||
OfflinePlayer player = offlinePlayerHandler.getOfflinePlayer(playerName);
|
||||
if (player != null) {
|
||||
Statistic stat = getStatisticEnum(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!");
|
||||
}
|
||||
|
||||
public LinkedHashMap<String, Integer> getTopStatistics(String statName, String subStatEntry) throws IllegalArgumentException, NullPointerException {
|
||||
String methodName = "getTopStatistic";
|
||||
long time = System.currentTimeMillis();
|
||||
|
||||
Statistic stat = getStatisticEnum(statName);
|
||||
time = plugin.logTimeTaken(className, methodName, time, 106);
|
||||
|
||||
if (stat != null) {
|
||||
if (stat.getType().equals(Statistic.Type.UNTYPED) || isMatchingSubStatEntry(stat, subStatEntry)) {
|
||||
HashMap<String, Integer> playerStats = new HashMap<>((int) (offlinePlayerHandler.getOfflinePlayerCount() * 1.05));
|
||||
time = plugin.logTimeTaken(className, methodName, time, 111);
|
||||
|
||||
for (String playerName : offlinePlayerHandler.getAllOfflinePlayerNames()) {
|
||||
OfflinePlayer player = offlinePlayerHandler.getOfflinePlayer(playerName);
|
||||
if (player != null) {
|
||||
try {
|
||||
int statistic = getPlayerStat(player, stat, subStatEntry);
|
||||
if (statistic > 0) {
|
||||
playerStats.put(playerName, getPlayerStat(player, stat, subStatEntry));
|
||||
}
|
||||
}
|
||||
catch (IllegalArgumentException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
time = plugin.logTimeTaken(className, methodName, time, 123);
|
||||
|
||||
LinkedHashMap<String, Integer> topStats = 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));
|
||||
time = plugin.logTimeTaken(className, methodName, time, 128);
|
||||
|
||||
plugin.getLogger().info("Top 10: " + topStats);
|
||||
plugin.logTimeTaken(className, methodName, time, 131);
|
||||
return topStats;
|
||||
}
|
||||
throw new IllegalArgumentException(subStatEntry + " is not a valid substatistic entry for this statistic!");
|
||||
}
|
||||
throw new NullPointerException("Statistic " + statName + " could not be retrieved!");
|
||||
}
|
||||
|
||||
public LinkedHashMap<String, Integer> getTopStatistics2(String statName, String subStatEntry) {
|
||||
String methodName = "getTopStatistics2";
|
||||
long time = System.currentTimeMillis();
|
||||
|
||||
Statistic stat = getStatisticEnum(statName);
|
||||
time = plugin.logTimeTaken(className, methodName, time, 144);
|
||||
|
||||
if (stat != null) {
|
||||
if (stat.getType().equals(Statistic.Type.UNTYPED) || isMatchingSubStatEntry(stat, subStatEntry)) {
|
||||
HashMap<String, Integer> playerStats = new HashMap<>((int) (offlinePlayerHandler.getOfflinePlayerCount() * 1.05));
|
||||
time = plugin.logTimeTaken(className, methodName, time, 149);
|
||||
|
||||
offlinePlayerHandler.getAllOfflinePlayerNames().forEach(playerName -> {
|
||||
OfflinePlayer player = offlinePlayerHandler.getOfflinePlayer(playerName);
|
||||
if (player != null)
|
||||
try {
|
||||
playerStats.put(playerName, getPlayerStat(player, stat, subStatEntry));
|
||||
}
|
||||
catch (IllegalArgumentException ignored) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
time = plugin.logTimeTaken(className, methodName, time, 162);
|
||||
|
||||
LinkedHashMap<String, Integer> topStats = 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));
|
||||
time = plugin.logTimeTaken(className, methodName, time, 167);
|
||||
|
||||
plugin.getLogger().info("Top 10: " + topStats);
|
||||
plugin.logTimeTaken(className, methodName, time, 170);
|
||||
return topStats;
|
||||
}
|
||||
throw new IllegalArgumentException(subStatEntry + " is not a valid substatistic entry for this statistic!");
|
||||
}
|
||||
throw new NullPointerException("Statistic " + statName + " could not be retrieved!");
|
||||
}
|
||||
|
||||
//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;
|
||||
}
|
||||
}
|
||||
|
||||
//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 string is a valid statistic (param: statName, not case sensitive)
|
||||
public boolean isStatistic(String statName) {
|
||||
return statNames.contains(statName.toLowerCase());
|
||||
}
|
||||
|
||||
//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 whether a subStatEntry is of the type that the statistic requires
|
||||
public boolean isMatchingSubStatEntry(String statName, String subStatEntry) {
|
||||
Statistic stat = getStatisticEnum(statName);
|
||||
return (stat != null && isMatchingSubStatEntry(stat, subStatEntry));
|
||||
}
|
||||
|
||||
private boolean isMatchingSubStatEntry(@NotNull Statistic stat, String subStatEntry) {
|
||||
switch (stat.getType()) {
|
||||
case ENTITY -> {
|
||||
return subStatEntry != null && enumHandler.isEntityType(subStatEntry);
|
||||
}
|
||||
case ITEM -> {
|
||||
return subStatEntry != null && enumHandler.isItem(subStatEntry);
|
||||
}
|
||||
case BLOCK -> {
|
||||
return subStatEntry != null && enumHandler.isBlock(subStatEntry);
|
||||
}
|
||||
case UNTYPED -> {
|
||||
return subStatEntry==null;
|
||||
}
|
||||
default -> {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
//returns the statistic enum constant, or null if non-existent (param: statName, not case sensitive)
|
||||
private Statistic getStatisticEnum(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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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,193 @@
|
||||
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)));
|
||||
} catch (Exception e) {
|
||||
sender.sendMessage(outputFormatter.formatExceptions(e.toString()));
|
||||
}
|
||||
|
||||
} else if (topFlag) {
|
||||
try {
|
||||
LinkedHashMap<String, Integer> topStats = getTopStatisticsForLoop(statName, subStatEntry);
|
||||
time = plugin.logTimeTaken(className, "run(): for loop", time, 67);
|
||||
|
||||
LinkedHashMap<String, Integer> topStats2 = getTopStatisticsForEach(statName, subStatEntry);
|
||||
time = plugin.logTimeTaken(className, "run(): for each loop", time, 70);
|
||||
|
||||
String top2 = outputFormatter.formatTopStats(topStats2, statName, subStatEntry);
|
||||
sender.sendMessage(top2);
|
||||
plugin.logTimeTaken(className, "run(): format output", time, 74);
|
||||
|
||||
} 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> getTopStatisticsForLoop(String statName, String subStatEntry) throws NullPointerException {
|
||||
long time = System.currentTimeMillis();
|
||||
|
||||
Statistic stat = enumHandler.getStatEnum(statName);
|
||||
|
||||
if (stat != null) {
|
||||
HashMap<String, Integer> playerStats = new HashMap<>((int) (OfflinePlayerHandler.getOfflinePlayerCount() * 1.05));
|
||||
for (String playerName : OfflinePlayerHandler.getAllOfflinePlayerNames()) {
|
||||
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) {
|
||||
}
|
||||
}
|
||||
}
|
||||
time = plugin.logTimeTaken(className, "for loop", time, 116);
|
||||
|
||||
LinkedHashMap<String, Integer> topStats = 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));
|
||||
|
||||
plugin.logTimeTaken(className, "for loop, sorting", time, 122);
|
||||
return topStats;
|
||||
|
||||
}
|
||||
throw new NullPointerException("Statistic " + statName + " could not be retrieved!");
|
||||
}
|
||||
|
||||
private LinkedHashMap<String, Integer> getTopStatisticsForEach(String statName, String subStatEntry) {
|
||||
long time = System.currentTimeMillis();
|
||||
|
||||
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 {
|
||||
playerStats.put(playerName, getPlayerStat(player, stat, subStatEntry));
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
}
|
||||
});
|
||||
|
||||
time = plugin.logTimeTaken(className, "for each loop", time, 145);
|
||||
|
||||
LinkedHashMap<String, Integer> topStats = 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));
|
||||
|
||||
plugin.logTimeTaken(className, "for each loop, sorting", time, 151);
|
||||
return topStats;
|
||||
}
|
||||
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,6 @@
|
||||
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;
|
||||
@ -13,13 +13,11 @@ import org.jetbrains.annotations.NotNull;
|
||||
public class ReloadCommand implements CommandExecutor {
|
||||
|
||||
private final ConfigHandler config;
|
||||
private final OfflinePlayerHandler offlinePlayerHandler;
|
||||
private final OutputFormatter outputFormatter;
|
||||
private final Main plugin;
|
||||
|
||||
public ReloadCommand(ConfigHandler c, OutputFormatter o, Main p) {
|
||||
outputFormatter = o;
|
||||
offlinePlayerHandler = OfflinePlayerHandler.getInstance();
|
||||
config = c;
|
||||
plugin = p;
|
||||
}
|
||||
@ -32,11 +30,11 @@ public class ReloadCommand implements CommandExecutor {
|
||||
outputFormatter.updateOutputColors();
|
||||
time = plugin.logTimeTaken("ReloadCommand", "onCommand", time, 33);
|
||||
|
||||
offlinePlayerHandler.updateOfflinePlayers();
|
||||
OfflinePlayerHandler.updateOfflinePlayers();
|
||||
time = plugin.logTimeTaken("ReloadCommand", "onCommand", time, 36);
|
||||
|
||||
sender.sendMessage(ChatColor.GREEN + "Config reloaded!");
|
||||
time = plugin.logTimeTaken("ReloadCommand", "onCommand", time, 39);
|
||||
plugin.logTimeTaken("ReloadCommand", "onCommand", time, 39);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -1,36 +1,28 @@
|
||||
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 net.md_5.bungee.api.ChatColor;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
import net.md_5.bungee.api.chat.ComponentBuilder;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
|
||||
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
|
||||
@ -39,84 +31,65 @@ public class StatCommand implements CommandExecutor {
|
||||
|
||||
//part 1: collecting all relevant information from the args
|
||||
if (args.length >= 2) {
|
||||
String statName = null;
|
||||
String subStatEntry = null;
|
||||
String playerName = null;
|
||||
boolean playerFlag = false;
|
||||
boolean topFlag = false;
|
||||
StatRequest request = new StatRequest(sender);
|
||||
|
||||
for (String arg : args) {
|
||||
if (statManager.isStatistic(arg)) {
|
||||
statName = (statName == null) ? arg : statName;
|
||||
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;
|
||||
if (request.playerFlag()) {
|
||||
if (request.getSubStatEntry() == null) request.setSubStatEntry(arg);
|
||||
}
|
||||
else {
|
||||
request.setPlayerFlag(true);
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
subStatEntry = (subStatEntry == null || playerFlag) ? arg : subStatEntry;
|
||||
if (request.getSubStatEntry() == null) request.setSubStatEntry(arg);
|
||||
}
|
||||
}
|
||||
|
||||
else if (arg.equalsIgnoreCase("top")) {
|
||||
topFlag = true;
|
||||
request.setTopFlag(true);
|
||||
}
|
||||
else if (arg.equalsIgnoreCase("me") && sender instanceof Player) {
|
||||
playerName = sender.getName();
|
||||
request.setPlayerName(sender.getName());
|
||||
}
|
||||
else if (offlinePlayerHandler.isOfflinePlayerName(arg)) {
|
||||
playerName = (playerName == null) ? arg : playerName;
|
||||
else if (OfflinePlayerHandler.isOfflinePlayerName(arg) && request.getPlayerName() == null) {
|
||||
request.setPlayerName(arg);
|
||||
}
|
||||
}
|
||||
|
||||
//part 2: sending the information to the StatManager
|
||||
if (statName != null) {
|
||||
subStatEntry = statManager.isMatchingSubStatEntry(statName, subStatEntry) ? subStatEntry : null;
|
||||
//part 2: sending the information to the StatThread
|
||||
if (isValidStatRequest(request)) {
|
||||
StatThread statThread = new StatThread(request, enumHandler, outputFormatter, plugin);
|
||||
statThread.start();
|
||||
|
||||
if (topFlag) {
|
||||
try {
|
||||
time = plugin.logTimeTaken("StatCommand", "onCommand", time, 76);
|
||||
LinkedHashMap<String, Integer> topStats = statManager.getTopStatistics(statName, subStatEntry);
|
||||
|
||||
time = plugin.logTimeTaken("StatCommand", "onCommand", time, 79);
|
||||
|
||||
LinkedHashMap<String, Integer> topStats2 = statManager.getTopStatistics2(statName, subStatEntry);
|
||||
time = plugin.logTimeTaken("StatCommand", "onCommand", time, 82);
|
||||
|
||||
String top = outputFormatter.formatTopStats(topStats, statName, subStatEntry);
|
||||
String top2 = outputFormatter.formatTopStats(topStats2, statName, subStatEntry);
|
||||
sender.sendMessage(top);
|
||||
sender.sendMessage(top2);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (Exception e) {
|
||||
sender.sendMessage(outputFormatter.formatExceptions(e.toString()));
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else if (playerName != null) {
|
||||
try {
|
||||
BaseComponent[] component = new ComponentBuilder("hi?").color(ChatColor.of("#4a32a8")).create();
|
||||
sender.spigot().sendMessage(component);
|
||||
String msg = ChatColor.of("#f27d07") + "... hi";
|
||||
sender.sendMessage(msg);
|
||||
sender.sendMessage(outputFormatter.formatPlayerStat(playerName, statName, subStatEntry, statManager.getStatistic
|
||||
(statName, subStatEntry, playerName)));
|
||||
}
|
||||
catch (Exception e) {
|
||||
sender.sendMessage(outputFormatter.formatExceptions(e.toString()));
|
||||
}
|
||||
}
|
||||
plugin.logTimeTaken("StatCommand", "onCommand", time, 71);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
plugin.logTimeTaken("StatCommand", "onCommand", time, 90);
|
||||
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.getEntityStatNames().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;
|
@ -8,16 +8,13 @@ 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,28 +1,51 @@
|
||||
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());
|
||||
}
|
||||
@ -38,6 +61,7 @@ public class EnumHandler {
|
||||
return itemNames;
|
||||
}
|
||||
|
||||
//checks whether the provided string is a valid entity
|
||||
public boolean isEntityType(String entityName) {
|
||||
return entityTypeNames.contains(entityName.toLowerCase());
|
||||
}
|
||||
@ -49,7 +73,12 @@ public class EnumHandler {
|
||||
try {
|
||||
entityType = EntityType.valueOf(entityName.toUpperCase());
|
||||
}
|
||||
catch (IllegalArgumentException | NullPointerException exception) {
|
||||
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;
|
||||
@ -60,6 +89,7 @@ public class EnumHandler {
|
||||
return entityTypeNames;
|
||||
}
|
||||
|
||||
//checks whether the provided string is a valid block
|
||||
public boolean isBlock(String materialName) {
|
||||
return blockNames.contains(materialName.toLowerCase());
|
||||
}
|
||||
@ -75,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,41 +7,31 @@ import java.util.*;
|
||||
|
||||
public class OfflinePlayerHandler {
|
||||
|
||||
private static OfflinePlayerHandler instance;
|
||||
private HashMap<String, OfflinePlayer> offlinePlayerMap;
|
||||
private List<String> offlinePlayerNames;
|
||||
private int totalOfflinePlayers;
|
||||
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();
|
||||
public static OfflinePlayer getOfflinePlayer(String playerName) {
|
||||
return offlinePlayerMap.get(playerName);
|
||||
}
|
||||
|
||||
public int getOfflinePlayerCount() {
|
||||
public static int getOfflinePlayerCount() {
|
||||
return totalOfflinePlayers > 0 ? totalOfflinePlayers : 1;
|
||||
}
|
||||
|
||||
public List<String> getAllOfflinePlayerNames() {
|
||||
public static List<String> getAllOfflinePlayerNames() {
|
||||
return offlinePlayerNames;
|
||||
}
|
||||
|
||||
//stores a private HashMap with keys:playerName and values:OfflinePlayer, and a private list of the names for easy access
|
||||
public void updateOfflinePlayers() {
|
||||
public static void updateOfflinePlayers() {
|
||||
long totalTime = System.currentTimeMillis();
|
||||
long time = System.currentTimeMillis();
|
||||
if (offlinePlayerMap == null) offlinePlayerMap = new HashMap<>();
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.gmail.artemis.the.gr8.playerstats.utils;
|
||||
|
||||
import com.gmail.artemis.the.gr8.playerstats.ConfigHandler;
|
||||
import com.gmail.artemis.the.gr8.playerstats.filehandlers.ConfigHandler;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.map.MinecraftFont;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user