mirror of
https://github.com/itHotL/PlayerStats.git
synced 2024-11-26 12:36:16 +01:00
Made LanguageKeyHandler static, improved MyLogger, added a while statement in StatThread in an attempt to enable ReloadThread to kill it (#64), Re-enabled PrideComponentFactory
This commit is contained in:
parent
82a0196214
commit
9ca234975b
@ -31,12 +31,11 @@ public class Main extends JavaPlugin {
|
||||
//initialize the Adventure library
|
||||
adventure = BukkitAudiences.create(this);
|
||||
|
||||
//first get an instance of the ConfigHandler and LanguageKeyHandler
|
||||
//first get an instance of the ConfigHandler
|
||||
ConfigHandler config = new ConfigHandler(this);
|
||||
LanguageKeyHandler language = new LanguageKeyHandler();
|
||||
|
||||
//for now always use the PrideComponentFactory (it'll use the regular formatting when needed)
|
||||
MessageWriter messageWriter = new MessageWriter(config, language);
|
||||
MessageWriter messageWriter = new MessageWriter(config);
|
||||
|
||||
//initialize the threadManager
|
||||
ThreadManager threadManager = new ThreadManager(adventure(), config, messageWriter, this);
|
||||
|
@ -41,7 +41,7 @@ public class ThreadManager {
|
||||
if (reloadThread == null || !reloadThread.isAlive()) {
|
||||
reloadThreadID += 1;
|
||||
|
||||
reloadThread = new ReloadThread(adventure, config, messageWriter, plugin, threshold, reloadThreadID, statThread, sender);
|
||||
reloadThread = new ReloadThread(adventure, config, messageWriter, threshold, reloadThreadID, statThread, sender);
|
||||
reloadThread.start();
|
||||
}
|
||||
else {
|
||||
|
@ -26,7 +26,7 @@ public class ConfigHandler {
|
||||
configVersion = 4;
|
||||
checkConfigVersion();
|
||||
|
||||
MyLogger.setDebugLevel(debugLevel());
|
||||
MyLogger.setDebugLevel(getDebugLevel());
|
||||
}
|
||||
|
||||
/** Checks the number that "config-version" returns to see if the config needs updating, and if so, send it to the Updater.
|
||||
@ -56,13 +56,14 @@ public class ConfigHandler {
|
||||
}
|
||||
try {
|
||||
config = YamlConfiguration.loadConfiguration(configFile);
|
||||
MyLogger.setDebugLevel(debugLevel());
|
||||
return true;
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
MyLogger.logException(e, "ConfigHandler", "reloadConfig");
|
||||
return false;
|
||||
}
|
||||
//TODO Move this to ReloadThread
|
||||
MyLogger.setDebugLevel(getDebugLevel());
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Returns the desired debugging level.
|
||||
@ -70,7 +71,7 @@ public class ConfigHandler {
|
||||
<p>2 = medium (detail all encountered exceptions, log main tasks and show time taken)</p>
|
||||
<p>3 = high (log all tasks and time taken)</p>
|
||||
<p>Default: 1</p>*/
|
||||
public int debugLevel() {
|
||||
public int getDebugLevel() {
|
||||
return config.getInt("debug-level", 1);
|
||||
}
|
||||
|
||||
@ -88,7 +89,7 @@ public class ConfigHandler {
|
||||
|
||||
/** Returns the number of maximum days since a player has last been online.
|
||||
<p>Default: 0 (which signals not to use this limit)</p>*/
|
||||
public int lastPlayedLimit() {
|
||||
public int getLastPlayedLimit() {
|
||||
return config.getInt("number-of-days-since-last-joined", 0);
|
||||
}
|
||||
|
||||
@ -112,7 +113,7 @@ public class ConfigHandler {
|
||||
|
||||
/** Whether to use rainbow colors for the [PlayerStats] prefix rather than the default gold/purple.
|
||||
<p>Default: false</p> */
|
||||
public boolean useRainbowPrefix() {
|
||||
public boolean useRainbowMode() {
|
||||
return config.getBoolean("rainbow-mode", false);
|
||||
}
|
||||
|
||||
|
@ -21,15 +21,15 @@ import org.jetbrains.annotations.Nullable;
|
||||
import static net.kyori.adventure.text.Component.*;
|
||||
import static net.kyori.adventure.text.Component.text;
|
||||
|
||||
/** Constructs Components with */
|
||||
/** Creates Components with the desired formatting. This class can put Strings
|
||||
into formatted Components with TextColor and TextDecoration, and turn
|
||||
certain Strings into appropriate LanguageKeys to return a TranslatableComponent.*/
|
||||
public class ComponentFactory {
|
||||
|
||||
private static ConfigHandler config;
|
||||
private final LanguageKeyHandler language;
|
||||
|
||||
public ComponentFactory(ConfigHandler c, LanguageKeyHandler l) {
|
||||
public ComponentFactory(ConfigHandler c) {
|
||||
config = c;
|
||||
language = l;
|
||||
}
|
||||
|
||||
/** Returns [PlayerStats] followed by a single space. */
|
||||
@ -188,11 +188,11 @@ public class ComponentFactory {
|
||||
subStatName = getPrettyName(subStatName);
|
||||
}
|
||||
else {
|
||||
statName = language.getStatKey(request.getStatistic());
|
||||
statName = LanguageKeyHandler.getStatKey(request.getStatistic());
|
||||
switch (request.getStatistic().getType()) {
|
||||
case BLOCK -> subStatName = language.getBlockKey(request.getBlock());
|
||||
case ENTITY -> subStatName = language.getEntityKey(request.getEntity());
|
||||
case ITEM -> subStatName = language.getItemKey(request.getItem());
|
||||
case BLOCK -> subStatName = LanguageKeyHandler.getBlockKey(request.getBlock());
|
||||
case ENTITY -> subStatName = LanguageKeyHandler.getEntityKey(request.getEntity());
|
||||
case ITEM -> subStatName = LanguageKeyHandler.getItemKey(request.getItem());
|
||||
case UNTYPED -> {
|
||||
}
|
||||
}
|
||||
|
@ -12,14 +12,17 @@ import java.util.HashMap;
|
||||
|
||||
public class LanguageKeyHandler {
|
||||
|
||||
private final HashMap<Statistic, String> statNameKeys;
|
||||
private final static HashMap<Statistic, String> statNameKeys;
|
||||
|
||||
public LanguageKeyHandler() {
|
||||
static {
|
||||
statNameKeys = new HashMap<>();
|
||||
generateStatNameKeys();
|
||||
}
|
||||
|
||||
public String getStatKey(@NotNull Statistic statistic) {
|
||||
private LanguageKeyHandler() {
|
||||
}
|
||||
|
||||
public static String getStatKey(@NotNull Statistic statistic) {
|
||||
if (statistic.getType() == Statistic.Type.UNTYPED) {
|
||||
return "stat.minecraft." + statNameKeys.get(statistic);
|
||||
}
|
||||
@ -30,7 +33,7 @@ public class LanguageKeyHandler {
|
||||
|
||||
/** Get the official Key from the NameSpacedKey for this entityType,
|
||||
or return null if no enum constant can be retrieved or entityType is UNKNOWN.*/
|
||||
public @Nullable String getEntityKey(EntityType entity) {
|
||||
public static @Nullable String getEntityKey(EntityType entity) {
|
||||
if (entity == null || entity == EntityType.UNKNOWN) return null;
|
||||
else {
|
||||
return "entity.minecraft." + entity.getKey().getKey();
|
||||
@ -39,7 +42,7 @@ public class LanguageKeyHandler {
|
||||
|
||||
/** Get the official Key from the NameSpacedKey for this item Material,
|
||||
or return null if no enum constant can be retrieved.*/
|
||||
public @Nullable String getItemKey(Material item) {
|
||||
public static @Nullable String getItemKey(Material item) {
|
||||
if (item == null) return null;
|
||||
else if (item.isBlock()) {
|
||||
return getBlockKey(item);
|
||||
@ -51,7 +54,7 @@ public class LanguageKeyHandler {
|
||||
|
||||
/** Returns the official Key from the NameSpacedKey for the block Material provided,
|
||||
or return null if no enum constant can be retrieved.*/
|
||||
public @Nullable String getBlockKey(Material block) {
|
||||
public static @Nullable String getBlockKey(Material block) {
|
||||
if (block == null) return null;
|
||||
else if (block.toString().toLowerCase().contains("wall_banner")) { //replace wall_banner with regular banner, since there is no key for wall banners
|
||||
String blockName = block.toString().toLowerCase().replace("wall_", "");
|
||||
@ -63,11 +66,11 @@ public class LanguageKeyHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private void generateDefaultKeys() {
|
||||
private static void generateDefaultKeys() {
|
||||
Arrays.stream(Statistic.values()).forEach(statistic -> statNameKeys.put(statistic, statistic.toString().toLowerCase()));
|
||||
}
|
||||
|
||||
private void generateStatNameKeys() {
|
||||
private static void generateStatNameKeys() {
|
||||
//get the enum names for all statistics first
|
||||
generateDefaultKeys();
|
||||
|
||||
|
@ -25,9 +25,23 @@ public class MessageWriter {
|
||||
private static ConfigHandler config;
|
||||
private static ComponentFactory componentFactory;
|
||||
|
||||
public MessageWriter(ConfigHandler c, LanguageKeyHandler l) {
|
||||
public MessageWriter(ConfigHandler c) {
|
||||
config = c;
|
||||
componentFactory = new ComponentFactory(c, l);
|
||||
getComponentFactory();
|
||||
}
|
||||
|
||||
//TODO Make ReloadThread do an update
|
||||
public static void updateComponentFactory() {
|
||||
getComponentFactory();
|
||||
}
|
||||
|
||||
private static void getComponentFactory() {
|
||||
if (config.useFestiveFormatting() || config.useRainbowMode()) {
|
||||
componentFactory = new PrideComponentFactory(config);
|
||||
}
|
||||
else {
|
||||
componentFactory = new ComponentFactory(config);
|
||||
}
|
||||
}
|
||||
|
||||
public TextComponent reloadedConfig(boolean isBukkitConsole) {
|
||||
@ -37,7 +51,7 @@ public class MessageWriter {
|
||||
|
||||
public TextComponent stillReloading(boolean isBukkitConsole) {
|
||||
return componentFactory.msg(
|
||||
"The plugin is still (re)loading, " +
|
||||
"The plugin is (re)loading, " +
|
||||
"your request will be processed when it is done!", isBukkitConsole);
|
||||
}
|
||||
|
||||
@ -48,6 +62,10 @@ public class MessageWriter {
|
||||
"please reload PlayerStats again to fix it!", isBukkitConsole);
|
||||
}
|
||||
|
||||
public TextComponent interruptedRequest() {
|
||||
return componentFactory.msg("Your request was interrupted, please try again in a moment!", false);
|
||||
}
|
||||
|
||||
public TextComponent waitAMoment(boolean longWait, boolean isBukkitConsole) {
|
||||
String msg = longWait ? "Calculating statistics, this may take a minute..." :
|
||||
"Calculating statistics, this may take a few moments...";
|
||||
|
@ -4,7 +4,6 @@ import com.gmail.artemis.the.gr8.playerstats.config.ConfigHandler;
|
||||
|
||||
import net.kyori.adventure.text.TextComponent;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.Month;
|
||||
@ -16,8 +15,8 @@ public class PrideComponentFactory extends ComponentFactory {
|
||||
|
||||
private static ConfigHandler config;
|
||||
|
||||
public PrideComponentFactory(ConfigHandler c, LanguageKeyHandler l) {
|
||||
super(c, l);
|
||||
public PrideComponentFactory(ConfigHandler c) {
|
||||
super(c);
|
||||
config = c;
|
||||
}
|
||||
|
||||
@ -62,7 +61,7 @@ public class PrideComponentFactory extends ComponentFactory {
|
||||
if festive formatting is disabled or it is not pride month,
|
||||
or the commandsender is a Bukkit or Spigot console.*/
|
||||
private boolean cancelRainbow(boolean isBukkitConsole) {
|
||||
return !(config.useRainbowPrefix() || (config.useFestiveFormatting() && LocalDate.now().getMonth().equals(Month.JUNE))) ||
|
||||
return !(config.useRainbowMode() || (config.useFestiveFormatting() && LocalDate.now().getMonth().equals(Month.JUNE))) ||
|
||||
(isBukkitConsole);
|
||||
}
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
package com.gmail.artemis.the.gr8.playerstats.reload;
|
||||
|
||||
import com.gmail.artemis.the.gr8.playerstats.Main;
|
||||
import com.gmail.artemis.the.gr8.playerstats.ThreadManager;
|
||||
import com.gmail.artemis.the.gr8.playerstats.config.ConfigHandler;
|
||||
import com.gmail.artemis.the.gr8.playerstats.enums.DebugLevel;
|
||||
import com.gmail.artemis.the.gr8.playerstats.msg.MessageWriter;
|
||||
import com.gmail.artemis.the.gr8.playerstats.statistic.StatThread;
|
||||
import com.gmail.artemis.the.gr8.playerstats.utils.MyLogger;
|
||||
@ -30,19 +30,17 @@ public class ReloadThread extends Thread {
|
||||
private final BukkitAudiences adventure;
|
||||
private static ConfigHandler config;
|
||||
private static MessageWriter messageWriter;
|
||||
private final Main plugin;
|
||||
|
||||
private final StatThread statThread;
|
||||
private final CommandSender sender;
|
||||
|
||||
public ReloadThread(BukkitAudiences a, ConfigHandler c, MessageWriter m, Main p, int threshold, int ID, @Nullable StatThread s, @Nullable CommandSender se) {
|
||||
public ReloadThread(BukkitAudiences a, ConfigHandler c, MessageWriter m, int threshold, int ID, @Nullable StatThread s, @Nullable CommandSender se) {
|
||||
this.threshold = threshold;
|
||||
reloadThreadID = ID;
|
||||
|
||||
adventure = a;
|
||||
config = c;
|
||||
messageWriter = m;
|
||||
plugin = p;
|
||||
|
||||
statThread = s;
|
||||
sender = se;
|
||||
@ -59,6 +57,10 @@ public class ReloadThread extends Thread {
|
||||
//if reload is triggered by /statreload (aka this thread does not have ID number 1)...
|
||||
if (reloadThreadID != 1) {
|
||||
if (statThread != null && statThread.isAlive()) {
|
||||
statThread.stopThread();
|
||||
return;
|
||||
|
||||
/*
|
||||
try {
|
||||
MyLogger.waitingForOtherThread(this.getName(), statThread.getName());
|
||||
statThread.join();
|
||||
@ -66,8 +68,9 @@ public class ReloadThread extends Thread {
|
||||
MyLogger.logException(e, "ReloadThread", "run(), trying to join" + statThread.getName());
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
*/
|
||||
}
|
||||
plugin.getLogger().info("Reloading!");
|
||||
MyLogger.logMsg("Reloading!", false);
|
||||
if (config.reloadConfig()) {
|
||||
boolean isBukkitConsole = sender instanceof ConsoleCommandSender && Bukkit.getName().equalsIgnoreCase("CraftBukkit");
|
||||
|
||||
@ -81,7 +84,7 @@ public class ReloadThread extends Thread {
|
||||
}
|
||||
}
|
||||
|
||||
MyLogger.logTimeTakenDefault("ReloadThread", ("loaded " + OfflinePlayerHandler.getOfflinePlayerCount() + " offline players"), time);
|
||||
MyLogger.logTimeTaken("ReloadThread", ("loaded " + OfflinePlayerHandler.getOfflinePlayerCount() + " offline players"), time);
|
||||
if (sender != null) {
|
||||
adventure.sender(sender).sendMessage(messageWriter.reloadedConfig(isBukkitConsole));
|
||||
}
|
||||
@ -92,7 +95,7 @@ public class ReloadThread extends Thread {
|
||||
try {
|
||||
OfflinePlayerHandler.updateOfflinePlayerList(getPlayerMap());
|
||||
ThreadManager.recordCalcTime(System.currentTimeMillis() - time);
|
||||
MyLogger.logTimeTakenDefault("ReloadThread",
|
||||
MyLogger.logTimeTaken("ReloadThread",
|
||||
("loaded " + OfflinePlayerHandler.getOfflinePlayerCount() + " offline players"), time);
|
||||
}
|
||||
catch (ConcurrentModificationException e) {
|
||||
@ -107,29 +110,42 @@ public class ReloadThread extends Thread {
|
||||
OfflinePlayer[] offlinePlayers;
|
||||
if (config.whitelistOnly()) {
|
||||
offlinePlayers = Bukkit.getWhitelistedPlayers().toArray(OfflinePlayer[]::new);
|
||||
MyLogger.logTimeTaken("ReloadThread", "retrieved whitelist", time);
|
||||
MyLogger.logTimeTaken("ReloadThread", "retrieved whitelist", time, DebugLevel.MEDIUM);
|
||||
}
|
||||
else if (config.excludeBanned()) {
|
||||
Set<OfflinePlayer> bannedPlayers = Bukkit.getBannedPlayers();
|
||||
offlinePlayers = Arrays.stream(Bukkit.getOfflinePlayers())
|
||||
.parallel()
|
||||
.filter(offlinePlayer -> !bannedPlayers.contains(offlinePlayer)).toArray(OfflinePlayer[]::new);
|
||||
MyLogger.logTimeTaken("ReloadThread", "retrieved banlist", time);
|
||||
MyLogger.logTimeTaken("ReloadThread", "retrieved banlist", time, DebugLevel.MEDIUM);
|
||||
}
|
||||
else {
|
||||
offlinePlayers = Bukkit.getOfflinePlayers();
|
||||
MyLogger.logTimeTaken("ReloadThread", "retrieved list of Offline Players", time);
|
||||
MyLogger.logTimeTaken("ReloadThread", "retrieved list of Offline Players", time, DebugLevel.MEDIUM);
|
||||
}
|
||||
|
||||
int size = offlinePlayers != null ? offlinePlayers.length : 16;
|
||||
ConcurrentHashMap<String, UUID> playerMap = new ConcurrentHashMap<>(size);
|
||||
|
||||
ReloadAction task = new ReloadAction(threshold, offlinePlayers, config.lastPlayedLimit(), playerMap);
|
||||
ReloadAction task = new ReloadAction(threshold, offlinePlayers, config.getLastPlayedLimit(), playerMap);
|
||||
MyLogger.actionCreated((offlinePlayers != null) ? offlinePlayers.length : 0);
|
||||
|
||||
ForkJoinPool.commonPool().invoke(task);
|
||||
MyLogger.actionFinished(1);
|
||||
|
||||
return playerMap;
|
||||
return generateFakeExtraPlayers(playerMap, 10);
|
||||
}
|
||||
|
||||
//generate fake extra players for PlayerStats, by looping over the real offlinePlayers multiple times
|
||||
private @NotNull ConcurrentHashMap<String, UUID> generateFakeExtraPlayers(@NotNull ConcurrentHashMap<String, UUID> realPlayers, int loops) {
|
||||
if (loops == 0 || loops == 1) return realPlayers;
|
||||
|
||||
ConcurrentHashMap<String, UUID> newPlayerMap = new ConcurrentHashMap<>(realPlayers.size() * loops);
|
||||
for (int i = 0; i < loops; i++) {
|
||||
for (String key : realPlayers.keySet()) {
|
||||
newPlayerMap.put(key + i, realPlayers.get(key));
|
||||
}
|
||||
}
|
||||
return newPlayerMap;
|
||||
}
|
||||
}
|
@ -24,6 +24,7 @@ import java.util.stream.Collectors;
|
||||
|
||||
public class StatThread extends Thread {
|
||||
|
||||
private volatile boolean keepRunning = true;
|
||||
private final int threshold;
|
||||
|
||||
private final StatRequest request;
|
||||
@ -50,6 +51,12 @@ public class StatThread extends Thread {
|
||||
MyLogger.threadCreated(this.getName());
|
||||
}
|
||||
|
||||
public void stopThread() {
|
||||
MyLogger.logMsg("stopThread() is being executed by: " + Thread.currentThread().getName(), false);
|
||||
keepRunning = false;
|
||||
MyLogger.logMsg("StatThread has been forced to stop!", true);
|
||||
}
|
||||
|
||||
//what the thread will do once started
|
||||
@Override
|
||||
public void run() throws IllegalStateException, NullPointerException {
|
||||
@ -71,52 +78,48 @@ public class StatThread extends Thread {
|
||||
.sendMessage(messageWriter
|
||||
.stillReloading(isBukkitConsole));
|
||||
reloadThread.join();
|
||||
|
||||
//TODO Add timeout after which it checks again and potentially aborts mission
|
||||
} catch (InterruptedException e) {
|
||||
plugin.getLogger().warning(e.toString());
|
||||
MyLogger.logException(e, "StatThread", "Trying to join" + reloadThread.getName());
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
Target selection = request.getSelection();
|
||||
|
||||
if (selection == Target.TOP || selection == Target.SERVER) {
|
||||
if (ThreadManager.getLastRecordedCalcTime() > 20000) {
|
||||
adventure.sender(sender).sendMessage(messageWriter.waitAMoment(true, isBukkitConsole));
|
||||
}
|
||||
else if (ThreadManager.getLastRecordedCalcTime() > 2000) {
|
||||
adventure.sender(sender).sendMessage(messageWriter.waitAMoment(false, isBukkitConsole));
|
||||
}
|
||||
|
||||
try {
|
||||
if (selection == Target.TOP) {
|
||||
adventure.sender(sender).sendMessage(messageWriter.formatTopStats(getTopStats(), request));
|
||||
}
|
||||
else {
|
||||
adventure.sender(sender).sendMessage(messageWriter.formatServerStat(getServerTotal(), request));
|
||||
}
|
||||
|
||||
} catch (ConcurrentModificationException e) {
|
||||
if (!isBukkitConsole) {
|
||||
adventure.sender(sender).sendMessage(messageWriter.unknownError(false));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
adventure.sender(sender).sendMessage(messageWriter.formatExceptions(e.toString(), isBukkitConsole));
|
||||
MyLogger.logException(e, "StatThread", "run(), trying to calculate or format a top or server statistic");
|
||||
}
|
||||
}
|
||||
|
||||
else if (selection == Target.PLAYER) {
|
||||
try {
|
||||
//TODO Evaluate if this really does something
|
||||
while (keepRunning) {
|
||||
Target selection = request.getSelection();
|
||||
if (selection == Target.PLAYER) {
|
||||
adventure.sender(sender).sendMessage(
|
||||
messageWriter.formatPlayerStat(getIndividualStat(), request));
|
||||
|
||||
} catch (UnsupportedOperationException | NullPointerException e) {
|
||||
adventure.sender(sender).sendMessage(messageWriter.formatExceptions(e.toString(), isBukkitConsole));
|
||||
}
|
||||
else {
|
||||
if (ThreadManager.getLastRecordedCalcTime() > 2000) {
|
||||
adventure.sender(sender).sendMessage(
|
||||
messageWriter.waitAMoment(ThreadManager.getLastRecordedCalcTime() > 20000, isBukkitConsole));
|
||||
}
|
||||
try {
|
||||
if (selection == Target.TOP) {
|
||||
adventure.sender(sender).sendMessage(
|
||||
messageWriter.formatTopStats(getTopStats(), request));
|
||||
} else {
|
||||
adventure.sender(sender).sendMessage(
|
||||
messageWriter.formatServerStat(getServerTotal(), request));
|
||||
}
|
||||
} catch (ConcurrentModificationException e) {
|
||||
if (!isBukkitConsole) {
|
||||
adventure.sender(sender).sendMessage(
|
||||
messageWriter.unknownError(false));
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
MyLogger.logMsg("(" + Thread.currentThread().getName() + ") shutting down...", false);
|
||||
adventure.sender(sender).sendMessage(messageWriter.interruptedRequest());
|
||||
}
|
||||
|
||||
private LinkedHashMap<String, Integer> getTopStats() throws ConcurrentModificationException, NullPointerException {
|
||||
private LinkedHashMap<String, Integer> getTopStats() throws ConcurrentModificationException {
|
||||
return getAllStats().entrySet().stream()
|
||||
.sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
|
||||
.limit(config.getTopListMaxSize()).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
|
||||
@ -128,7 +131,7 @@ public class StatThread extends Thread {
|
||||
}
|
||||
|
||||
//invokes a bunch of worker pool threads to divide and conquer (get the statistics for all players in the list)
|
||||
private @NotNull ConcurrentHashMap<String, Integer> getAllStats() throws ConcurrentModificationException, NullPointerException {
|
||||
private @NotNull ConcurrentHashMap<String, Integer> getAllStats() throws ConcurrentModificationException {
|
||||
long time = System.currentTimeMillis();
|
||||
|
||||
int size = OfflinePlayerHandler.getOfflinePlayerCount() != 0 ? (int) (OfflinePlayerHandler.getOfflinePlayerCount() * 1.05) : 16;
|
||||
@ -142,20 +145,21 @@ public class StatThread extends Thread {
|
||||
try {
|
||||
commonPool.invoke(task);
|
||||
} catch (ConcurrentModificationException e) {
|
||||
plugin.getLogger().warning("The request could not be executed due to a ConcurrentModificationException. " +
|
||||
"This likely happened because Bukkit hasn't fully initialized all player-data yet. Try again and it should be fine!");
|
||||
MyLogger.logMsg("The request could not be executed due to a ConcurrentModificationException. " +
|
||||
"This likely happened because Bukkit hasn't fully initialized all player-data yet. Try again and it should be fine!", true);
|
||||
throw new ConcurrentModificationException(e.toString());
|
||||
}
|
||||
|
||||
MyLogger.actionFinished(2);
|
||||
ThreadManager.recordCalcTime(System.currentTimeMillis() - time);
|
||||
MyLogger.logTimeTakenDefault("StatThread", "calculated all stats", time);
|
||||
MyLogger.logTimeTaken("StatThread", "calculated all stats", time);
|
||||
|
||||
return playerStats;
|
||||
}
|
||||
|
||||
//gets the actual statistic data for an individual player
|
||||
private int getIndividualStat() throws UnsupportedOperationException, NullPointerException {
|
||||
/** Gets the statistic data for an individual player. If somehow the player
|
||||
cannot be found, this returns 0.*/
|
||||
private int getIndividualStat() {
|
||||
OfflinePlayer player = OfflinePlayerHandler.getOfflinePlayer(request.getPlayerName());
|
||||
if (player != null) {
|
||||
switch (request.getStatistic().getType()) {
|
||||
@ -173,6 +177,6 @@ public class StatThread extends Thread {
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new NullPointerException("The player you are trying to request either does not exist, or is not on the list for statistic lookups!");
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -50,29 +50,26 @@ public class TopStatAction extends RecursiveAction {
|
||||
}
|
||||
}
|
||||
|
||||
private void getStatsDirectly() throws UnsupportedOperationException {
|
||||
try {
|
||||
Iterator<String> iterator = playerNames.iterator();
|
||||
if (iterator.hasNext()) {
|
||||
do {
|
||||
String playerName = iterator.next();
|
||||
MyLogger.actionRunning(Thread.currentThread().getName(), playerName, 2);
|
||||
OfflinePlayer player = OfflinePlayerHandler.getOfflinePlayer(playerName);
|
||||
if (player != null) {
|
||||
int statistic = 0;
|
||||
switch (request.getStatistic().getType()) {
|
||||
case UNTYPED -> statistic = player.getStatistic(request.getStatistic());
|
||||
case ENTITY -> statistic = player.getStatistic(request.getStatistic(), request.getEntity());
|
||||
case BLOCK -> statistic = player.getStatistic(request.getStatistic(), request.getBlock());
|
||||
case ITEM -> statistic = player.getStatistic(request.getStatistic(), request.getItem());
|
||||
}
|
||||
if (statistic > 0) {
|
||||
playerStats.put(playerName, statistic);
|
||||
}
|
||||
private void getStatsDirectly() {
|
||||
Iterator<String> iterator = playerNames.iterator();
|
||||
if (iterator.hasNext()) {
|
||||
do {
|
||||
String playerName = iterator.next();
|
||||
MyLogger.actionRunning(Thread.currentThread().getName(), playerName, 2);
|
||||
OfflinePlayer player = OfflinePlayerHandler.getOfflinePlayer(playerName);
|
||||
if (player != null) {
|
||||
int statistic = 0;
|
||||
switch (request.getStatistic().getType()) {
|
||||
case UNTYPED -> statistic = player.getStatistic(request.getStatistic());
|
||||
case ENTITY -> statistic = player.getStatistic(request.getStatistic(), request.getEntity());
|
||||
case BLOCK -> statistic = player.getStatistic(request.getStatistic(), request.getBlock());
|
||||
case ITEM -> statistic = player.getStatistic(request.getStatistic(), request.getItem());
|
||||
}
|
||||
} while (iterator.hasNext());
|
||||
}
|
||||
} catch (NoSuchElementException ignored) {
|
||||
if (statistic > 0) {
|
||||
playerStats.put(playerName, statistic);
|
||||
}
|
||||
}
|
||||
} while (iterator.hasNext());
|
||||
}
|
||||
}
|
||||
}
|
@ -21,7 +21,7 @@ public class EnumHandler {
|
||||
private final static List<String> entitySubStatNames;
|
||||
private final static List<String> subStatNames;
|
||||
|
||||
static{
|
||||
static {
|
||||
blockNames = Arrays.stream(Material.values())
|
||||
.filter(Material::isBlock)
|
||||
.map(Material::toString)
|
||||
|
@ -22,7 +22,7 @@ public class MyLogger {
|
||||
private static final AtomicInteger playersIndex;
|
||||
private static ConcurrentHashMap<String, Integer> threadNames;
|
||||
|
||||
static{
|
||||
static {
|
||||
Plugin plugin = Bukkit.getPluginManager().getPlugin("PlayerStats");
|
||||
logger = (plugin != null) ? plugin.getLogger() : Bukkit.getLogger();
|
||||
debugLevel = DebugLevel.LOW;
|
||||
@ -35,17 +35,6 @@ public class MyLogger {
|
||||
private MyLogger() {
|
||||
}
|
||||
|
||||
|
||||
/** Accesses the playersIndex to up it by 1 and return its previous value. */
|
||||
private static int nextPlayersIndex() {
|
||||
return playersIndex.getAndIncrement();
|
||||
}
|
||||
|
||||
/** Returns true if the playersIndex is 10, or any subsequent increment of 10. */
|
||||
private static boolean incrementOfTen() {
|
||||
return (playersIndex.get() == 10 || (playersIndex.get() > 10 && playersIndex.get() % 10 == 0));
|
||||
}
|
||||
|
||||
/** Sets the desired debugging level.
|
||||
<p>1 = low (only show unexpected errors)</p>
|
||||
<p>2 = medium (detail all encountered exceptions, log main tasks and show time taken)</p>
|
||||
@ -63,6 +52,30 @@ public class MyLogger {
|
||||
}
|
||||
}
|
||||
|
||||
public static void logMsg(String content, boolean logAsWarning) {
|
||||
logMsg(content, DebugLevel.LOW, logAsWarning);
|
||||
}
|
||||
|
||||
public static void logMsg(String content, DebugLevel logThreshold) {
|
||||
logMsg(content, logThreshold, false);
|
||||
}
|
||||
|
||||
public static void logMsg(String content, DebugLevel logThreshold, boolean logAsWarning) {
|
||||
switch (logThreshold) {
|
||||
case LOW -> log(content, logAsWarning);
|
||||
case MEDIUM -> {
|
||||
if (debugLevel != DebugLevel.LOW) {
|
||||
log(content, logAsWarning);
|
||||
}
|
||||
}
|
||||
case HIGH -> {
|
||||
if (debugLevel == DebugLevel.HIGH) {
|
||||
log(content, logAsWarning);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Log the encountered exception as a warning to console,
|
||||
with some information about which class/method caught it
|
||||
and with a printStackTrace if DebugLevel is HIGH.
|
||||
@ -171,21 +184,54 @@ public class MyLogger {
|
||||
}
|
||||
}
|
||||
|
||||
/** Output to console how long a certain task has taken if DebugLevel is MEDIUM or HIGH.
|
||||
@param className Name of the class executing the task
|
||||
@param methodName Name or description of the task
|
||||
@param startTime Timestamp marking the beginning of the task */
|
||||
public static void logTimeTaken(String className, String methodName, long startTime) {
|
||||
if (debugLevel != DebugLevel.LOW) {
|
||||
logger.info(className + " " + methodName + ": " + (System.currentTimeMillis() - startTime) + "ms");
|
||||
}
|
||||
}
|
||||
|
||||
/** Output to console how long a certain task has taken (regardless of DebugLevel).
|
||||
@param className Name of the class executing the task
|
||||
@param methodName Name or description of the task
|
||||
@param startTime Timestamp marking the beginning of the task */
|
||||
public static void logTimeTakenDefault(String className, String methodName, long startTime) {
|
||||
public static void logTimeTaken(String className, String methodName, long startTime) {
|
||||
logTimeTaken(className, methodName, startTime, DebugLevel.LOW);
|
||||
}
|
||||
|
||||
/** Output to console how long a certain task has taken if DebugLevel is equal to or higher than the specified threshold.
|
||||
@param className Name of the class executing the task
|
||||
@param methodName Name or description of the task
|
||||
@param startTime Timestamp marking the beginning of the task
|
||||
@param logThreshold the DebugLevel threshold */
|
||||
public static void logTimeTaken(String className, String methodName, long startTime, DebugLevel logThreshold) {
|
||||
switch (logThreshold) {
|
||||
case LOW -> printTime(className, methodName, startTime);
|
||||
case MEDIUM -> {
|
||||
if (debugLevel != DebugLevel.LOW) {
|
||||
printTime(className, methodName, startTime);
|
||||
}
|
||||
}
|
||||
case HIGH -> {
|
||||
if (debugLevel == DebugLevel.HIGH) {
|
||||
printTime(className, methodName, startTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void log(String content, boolean logAsWarning) {
|
||||
if (logAsWarning) {
|
||||
logger.warning(content);
|
||||
} else {
|
||||
logger.info(content);
|
||||
}
|
||||
}
|
||||
|
||||
private static void printTime(String className, String methodName, long startTime) {
|
||||
logger.info(className + " " + methodName + ": " + (System.currentTimeMillis() - startTime) + "ms");
|
||||
}
|
||||
|
||||
/** Accesses the playersIndex to up it by 1 and return its previous value. */
|
||||
private static int nextPlayersIndex() {
|
||||
return playersIndex.getAndIncrement();
|
||||
}
|
||||
|
||||
/** Returns true if the playersIndex is 10, or any subsequent increment of 10. */
|
||||
private static boolean incrementOfTen() {
|
||||
return (playersIndex.get() == 10 || (playersIndex.get() > 10 && playersIndex.get() % 10 == 0));
|
||||
}
|
||||
}
|
@ -12,7 +12,7 @@ public class OfflinePlayerHandler {
|
||||
private static ConcurrentHashMap<String, UUID> offlinePlayerUUIDs;
|
||||
private static ArrayList<String> playerNames;
|
||||
|
||||
static{
|
||||
static {
|
||||
offlinePlayerUUIDs = new ConcurrentHashMap<>();
|
||||
playerNames = new ArrayList<>();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user