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:
Artemis-the-gr8 2022-06-29 17:11:43 +02:00
parent 82a0196214
commit 9ca234975b
13 changed files with 217 additions and 134 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -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();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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