Improved MyLogger, added more formatting methods to the API

This commit is contained in:
Artemis-the-gr8 2022-08-11 17:23:02 +02:00
parent 9c1298794d
commit d7285f71de
16 changed files with 198 additions and 261 deletions

View File

@ -1,7 +1,6 @@
package com.gmail.artemis.the.gr8.playerstats;
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.statistic.result.InternalStatResult;
import com.gmail.artemis.the.gr8.playerstats.utils.MyLogger;
import net.kyori.adventure.text.TextComponent;
@ -58,8 +57,8 @@ public final class ShareManager {
sharedResults = null;
}
if (config.allowStatSharing() && !config.useHoverText()) {
MyLogger.logMsg("Stat-sharing does not work without hover-text enabled! " +
"Enable hover-text, or disable stat-sharing to stop seeing this message.", true);
MyLogger.logWarning("Stat-sharing does not work without hover-text enabled! " +
"Enable hover-text, or disable stat-sharing to stop seeing this message.");
}
}
}
@ -76,7 +75,7 @@ public final class ShareManager {
InternalStatResult result = new InternalStatResult(playerName, statResult, ID);
int shareCode = result.hashCode();
statResultQueue.put(shareCode, result);
MyLogger.logMsg("Saving statResults with no. " + ID, DebugLevel.MEDIUM);
MyLogger.logMediumLevelMsg("Saving statResults with no. " + ID);
return shareCode;
}
@ -102,8 +101,8 @@ public final class ShareManager {
shareTimeStamp.put(playerName, Instant.now());
if (!sharedResults.offer(shareCode)) { //create a new ArrayBlockingQueue if our queue is full
MyLogger.logMsg("500 stat-results have been shared, " +
"creating a new internal queue with the most recent 50 share-code-values and discarding the rest...", DebugLevel.MEDIUM);
MyLogger.logMediumLevelMsg("500 stat-results have been shared, " +
"creating a new internal queue with the most recent 50 share-code-values and discarding the rest...");
ArrayBlockingQueue<Integer> newQueue = new ArrayBlockingQueue<>(500);
synchronized (this) { //put the last 50 values in the new Queue
@ -136,7 +135,7 @@ public final class ShareManager {
.parallelStream()
.min(Comparator.comparing(InternalStatResult::ID))
.orElseThrow().hashCode();
MyLogger.logMsg("Removing old stat no. " + statResultQueue.get(hashCode).ID() + " for player " + playerName, DebugLevel.MEDIUM);
MyLogger.logMediumLevelMsg("Removing old stat no. " + statResultQueue.get(hashCode).ID() + " for player " + playerName);
statResultQueue.remove(hashCode);
}
}

View File

@ -57,7 +57,7 @@ public final class ThreadManager {
lastActiveReloadThread.start();
}
else {
MyLogger.threadAlreadyRunning(lastActiveReloadThread.getName());
MyLogger.logLowLevelMsg("Another reloadThread is already running! (" + lastActiveReloadThread.getName() + ")");
}
}

View File

@ -69,21 +69,37 @@ public interface ApiFormatter {
@return Top [topStatSize] [stat-name] [unit-name] */
TextComponent getTopStatTitle(int topStatSize, Statistic statistic, Unit unit);
/** Formats the input into a single top-statistic line.
/** Formats the input into a single top-statistic line. The stat-number
is formatted into the most suitable {@link Unit} based on the provided Unit.Type.
For Type.Time, the result will have one additional Unit, unless
<code>getTopStatLineForTypeTime()</code> is used.
@return a single line from a top-x statistic:
* <br> [positionInTopList]. [player-name] ......... [stat-number] */
TextComponent getFormattedTopStatLine(int positionInTopList, String playerName, long statNumber, Statistic statistic);
* <br> [positionInTopList]. [player-name] ......... [stat-number] */
TextComponent getTopStatLine(int positionInTopList, String playerName, long statNumber, Unit.Type unitType);
/** Formats the input into a single top-statistic line. The stat-number is formatted
into the provided {@link Unit}. For Type.Time, the result will have one additional Unit, unless
<code>getTopStatLineForTypeTime()</code> is used.
@return a single line from a top-x statistic:
* <br> [positionInTopList]. [player-name] ......... [stat-number] */
TextComponent getTopStatLine(int positionInTopList, String playerName, long statNumber, Unit unit);
/** Formats the input into a single top-statistic line for a time-based statistic.
The stat-number is formatted with the provided units.
@return a single line from a stop-x statistic:
<br>[positionInTopList]. [player-name] ......... [1D 2H 3M 4S]*/
TextComponent getTopStatLineForTypeTime(int positionInList, String playerName, long statNumber, Unit bigUnit, Unit smallUnit);
/** Formats the input into a server statistic message.
@return [Total on this server]: [stat-number] [stat-name] */
TextComponent getFormattedServerStat(long statNumber, Statistic statistic);
TextComponent getServerStat(long statNumber, Statistic statistic);
/** Formats the input into a server statistic message for a statistic that has a
sub-statistic (block, item or entity).
@return [Total on this server]: [stat-number] [stat-name] [sub-stat-name]*/
TextComponent getFormattedServerStat(long statNumber, Statistic statistic, String subStatName);
TextComponent getServerStat(long statNumber, Statistic statistic, String subStatName);
/** Formats the input into a server statistic message with the specified {@link Unit}.
@return [Total on this server]: [stat-number] [stat-name] [unit-name]*/
TextComponent getFormattedServerStat(long statNumber, Statistic statistic, Unit unit);
TextComponent getServerStat(long statNumber, Statistic statistic, Unit unit);
}

View File

@ -64,66 +64,6 @@ public class ApiOutputManager implements ApiFormatter {
return getTopStatTitle(topListSize, statistic, null, unit);
}
@Override
public TextComponent getFormattedTopStatLine(int positionInTopList, String playerName, long statNumber, Statistic statistic) {
TextComponent.Builder topStatLineBuilder = Component.text()
.append(space())
.append(componentFactory.rankNumber(positionInTopList))
.append(space())
.append(componentFactory.playerName(playerName, Target.TOP))
.append(space());
int dots = FontUtils.getNumberOfDotsToAlign(positionInTopList + ". " + playerName);
if (dots >= 1) {
topStatLineBuilder.append(componentFactory.dots(".".repeat(dots)));
}
Unit.Type statUnitType = Unit.getTypeFromStatistic(statistic);
TextComponent numberComponent = getStatNumberComponent(statNumber, statUnitType, Target.TOP);
return topStatLineBuilder
.append(space())
.append(numberComponent)
.build();
}
@Override
public TextComponent getFormattedServerStat(long statNumber, Statistic statistic) {
return getFormattedServerStat(statNumber, statistic, null, null);
}
@Override
public TextComponent getFormattedServerStat(long statNumber, Statistic statistic, String subStatName) {
return getFormattedServerStat(statNumber, statistic, subStatName, null);
}
@Override
public TextComponent getFormattedServerStat(long statNumber, Statistic statistic, Unit unit) {
return getFormattedServerStat(statNumber, statistic, null, unit);
}
private TextComponent getFormattedServerStat(long statNumber, Statistic statistic, @Nullable String subStatName, @Nullable Unit unit) {
String serverTitle = config.getServerTitle();
String serverName = config.getServerName();
String prettyStatName = StringUtils.prettify(statistic.toString());
Unit.Type unitType = Unit.getTypeFromStatistic(statistic);
TextComponent.Builder serverStatBuilder = Component.text()
.append(componentFactory.title(serverTitle, Target.SERVER))
.append(space())
.append(componentFactory.serverName(serverName))
.append(space())
.append(getStatNumberComponent(statNumber, unitType, Target.SERVER))
.append(space())
.append(componentFactory.statAndSubStatName(prettyStatName, subStatName, Target.SERVER));
if (unit != null) {
serverStatBuilder.append(space())
.append(componentFactory.statUnit(unit.getLabel(), Target.SERVER));
}
return serverStatBuilder.build();
}
private TextComponent getTopStatTitle(int topListSize, Statistic statistic, @Nullable String subStatName, @Nullable Unit unit) {
String prettyStatName = StringUtils.prettify(statistic.toString());
TextComponent.Builder titleBuilder = Component.text()
@ -140,22 +80,105 @@ public class ApiOutputManager implements ApiFormatter {
return titleBuilder.build();
}
private TextComponent getStatNumberComponent(long statNumber, Unit.Type unitType, Target target) {
return switch (unitType) {
case DISTANCE -> {
Unit unit = Unit.getMostSuitableUnit(Unit.Type.DISTANCE, statNumber);
yield componentFactory.distanceNumber(numberFormatter.formatDistanceNumber(statNumber, unit), target);
}
case DAMAGE -> {
Unit unit = Unit.getMostSuitableUnit(Unit.Type.DAMAGE, statNumber);
yield componentFactory.damageNumber(numberFormatter.formatDamageNumber(statNumber, unit), target);
}
case TIME -> {
Unit bigUnit = Unit.getMostSuitableUnit(Unit.Type.TIME, statNumber);
Unit smallUnit = bigUnit.getSmallerUnit(1);
yield componentFactory.timeNumber(numberFormatter.formatTimeNumber(statNumber, bigUnit, smallUnit), target);
}
@Override
public TextComponent getTopStatLine(int positionInTopList, String playerName, long statNumber, Unit.Type unitType) {
Unit unit = Unit.getMostSuitableUnit(unitType, statNumber);
TextComponent statNumberComponent = getStatNumberComponent(statNumber, Target.TOP, unit);
return getTopStatLine(positionInTopList, playerName, statNumberComponent);
}
@Override
public TextComponent getTopStatLine(int positionInTopList, String playerName, long statNumber, Unit unit) {
TextComponent statNumberComponent = getStatNumberComponent(statNumber, Target.TOP, unit);
return getTopStatLine(positionInTopList, playerName, statNumberComponent);
}
@Override
public TextComponent getTopStatLineForTypeTime(int positionInList, String playerName, long statNumber, Unit bigUnit, Unit smallUnit) {
TextComponent statNumberComponent = getTimeNumberComponent(statNumber, Target.TOP, bigUnit, smallUnit);
return getTopStatLine(positionInList, playerName, statNumberComponent);
}
private TextComponent getTopStatLine(int positionInTopList, String playerName, TextComponent statNumberComponent) {
TextComponent.Builder topStatLineBuilder = Component.text()
.append(space())
.append(componentFactory.rankNumber(positionInTopList))
.append(space())
.append(componentFactory.playerName(playerName, Target.TOP))
.append(space());
int dots = FontUtils.getNumberOfDotsToAlign(positionInTopList + ". " + playerName);
if (dots >= 1) {
topStatLineBuilder.append(componentFactory.dots(".".repeat(dots)));
}
return topStatLineBuilder
.append(space())
.append(statNumberComponent)
.build();
}
@Override
public TextComponent getServerStat(long statNumber, Statistic statistic) {
Unit.Type unitType = Unit.getTypeFromStatistic(statistic);
Unit unit = Unit.getMostSuitableUnit(unitType, statNumber);
return getServerStat(statNumber, statistic, null, unit);
}
@Override
public TextComponent getServerStat(long statNumber, Statistic statistic, String subStatName) {
return getServerStat(statNumber, statistic, subStatName, Unit.NUMBER);
}
@Override
public TextComponent getServerStat(long statNumber, Statistic statistic, Unit unit) {
return getServerStat(statNumber, statistic, null, unit);
}
private TextComponent getServerStat(long statNumber, Statistic statistic, @Nullable String subStatName, Unit unit) {
String serverTitle = config.getServerTitle();
String serverName = config.getServerName();
String prettyStatName = StringUtils.prettify(statistic.toString());
Unit.Type unitType = unit.getType();
TextComponent.Builder serverStatBuilder = Component.text()
.append(componentFactory.title(serverTitle, Target.SERVER))
.append(space())
.append(componentFactory.serverName(serverName))
.append(space())
.append(getStatNumberComponent(statNumber, Target.SERVER, unit))
.append(space())
.append(componentFactory.statAndSubStatName(prettyStatName, subStatName, Target.SERVER));
if (unitType== Unit.Type.DAMAGE || unitType == Unit.Type.DISTANCE) {
serverStatBuilder
.append(space())
.append(componentFactory.statUnit(unit.getLabel(), Target.SERVER));
}
return serverStatBuilder.build();
}
private TextComponent getStatNumberComponent(long statNumber, Target target, Unit unit) {
return switch (unit.getType()) {
case TIME -> getTimeNumberComponent(statNumber, target, unit, null);
case DAMAGE -> getDamageNumberComponent(statNumber, target, unit);
case DISTANCE -> getDistanceNumberComponent(statNumber, target, unit);
default -> componentFactory.statNumber(numberFormatter.formatNumber(statNumber), target);
};
}
private TextComponent getTimeNumberComponent(long statNumber, Target target, Unit bigUnit, @Nullable Unit smallUnit) {
if (smallUnit == null) {
smallUnit = bigUnit.getSmallerUnit(1);
}
return componentFactory.timeNumber(numberFormatter.formatTimeNumber(statNumber, bigUnit, smallUnit), target);
}
private TextComponent getDamageNumberComponent(long statNumber, Target target, Unit unit) {
return componentFactory.damageNumber(numberFormatter.formatDamageNumber(statNumber, unit), target);
}
private TextComponent getDistanceNumberComponent(long statNumber, Target target, Unit unit) {
return componentFactory.distanceNumber(numberFormatter.formatDistanceNumber(statNumber, unit), target);
}
}

View File

@ -153,9 +153,9 @@ public final class ConfigHandler {
};
return section.getBoolean(path, def);
}
MyLogger.logMsg("Config settings for use-enters could not be retrieved! " +
MyLogger.logWarning("Config settings for use-enters could not be retrieved! " +
"Please check your file if you want to use custom settings. " +
"Using default values...", true);
"Using default values...");
return def;
}

View File

@ -20,7 +20,7 @@ public final class ConfigUpdateHandler {
try {
configuration.save(configFile);
ConfigUpdater.update(plugin, configFile.getName(), configFile);
MyLogger.logMsg("Your config has been updated to version " + configVersion +
MyLogger.logLowLevelMsg("Your config has been updated to version " + configVersion +
", but all of your custom settings should still be there!");
} catch (IOException e) {
e.printStackTrace();

View File

@ -6,17 +6,17 @@ import org.jetbrains.annotations.NotNull;
/** All the units PlayerStats can display statistics in, separated by Type.*/
public enum Unit {
NUMBER (Type.UNTYPED, "Times"),
KM (Type.DISTANCE, "km"),
KM (Type.DISTANCE, "KM"),
MILE (Type.DISTANCE, "Miles"),
BLOCK (Type.DISTANCE, "Blocks"),
CM (Type.DISTANCE, "cm"),
CM (Type.DISTANCE, "CM"),
HP (Type.DAMAGE, "HP"),
HEART (Type.DAMAGE, "Hearts"),
DAY (Type.TIME, "days"),
HOUR (Type.TIME, "hours"),
MINUTE (Type.TIME, "minutes"),
SECOND (Type.TIME, "seconds"),
TICK (Type.TIME, "ticks");
DAY (Type.TIME, "Days"),
HOUR (Type.TIME, "Hours"),
MINUTE (Type.TIME, "Minutes"),
SECOND (Type.TIME, "Seconds"),
TICK (Type.TIME, "Ticks");
private final Type type;
private final String label;

View File

@ -1,6 +1,5 @@
package com.gmail.artemis.the.gr8.playerstats.msg;
import com.gmail.artemis.the.gr8.playerstats.enums.DebugLevel;
import com.gmail.artemis.the.gr8.playerstats.enums.Target;
import com.gmail.artemis.the.gr8.playerstats.config.ConfigHandler;
import com.gmail.artemis.the.gr8.playerstats.enums.Unit;
@ -49,7 +48,7 @@ public final class MessageBuilder {
formatter = new NumberFormatter();
languageKeyHandler = new LanguageKeyHandler();
MyLogger.logMsg("MessageBuilder created with factory: " + componentFactory.getClass().getSimpleName(), DebugLevel.MEDIUM);
MyLogger.logMediumLevelMsg("MessageBuilder created with factory: " + componentFactory.getClass().getSimpleName());
}
public static MessageBuilder defaultBuilder(ConfigHandler config) {
@ -413,9 +412,7 @@ public final class MessageBuilder {
private TextComponent getTimeNumberComponent(long statNumber, Target target) {
ArrayList<Unit> unitRange = getTimeUnitRange(statNumber);
if (unitRange.size() <= 1 || (useHoverText && unitRange.size() <= 3)) {
MyLogger.logMsg(
"There is something wrong with the time-units you specified, please check your config!",
true);
MyLogger.logWarning("There is something wrong with the time-units you specified, please check your config!");
return componentFactory.timeNumber(formatter.formatNumber(statNumber), target);
}
else {
@ -424,7 +421,7 @@ public final class MessageBuilder {
return componentFactory.timeNumber(mainNumber, target);
} else {
String hoverNumber = formatter.formatTimeNumber(statNumber, unitRange.get(2), unitRange.get(3));
MyLogger.logMsg("mainNumber: " + mainNumber + ", hoverNumber: " + hoverNumber, DebugLevel.HIGH);
MyLogger.logHighLevelMsg("mainNumber: " + mainNumber + ", hoverNumber: " + hoverNumber);
return componentFactory.timeNumberWithHoverText(mainNumber, hoverNumber, target);
}
}
@ -541,7 +538,7 @@ public final class MessageBuilder {
unitRange.add(bigHoverUnit.getSmallerUnit(config.getNumberOfExtraTimeUnits(true)));
}
}
MyLogger.logMsg("total selected unitRange for this statistic: " + unitRange, DebugLevel.MEDIUM);
MyLogger.logMediumLevelMsg("total selected unitRange for this statistic: " + unitRange);
return unitRange;
}

View File

@ -15,7 +15,7 @@ public final class StringUtils {
StringBuilder capitals = new StringBuilder(input.toLowerCase());
capitals.setCharAt(0, Character.toUpperCase(capitals.charAt(0)));
while (capitals.indexOf("_") != -1) {
MyLogger.replacingUnderscores();
MyLogger.logHighLevelMsg("Replacing underscores and capitalizing names...");
int index = capitals.indexOf("_");
capitals.setCharAt(index + 1, Character.toUpperCase(capitals.charAt(index + 1)));

View File

@ -68,7 +68,7 @@ final class ReloadAction extends RecursiveAction {
for (int i = start; i < end; i++) {
OfflinePlayer player = players[i];
String playerName = player.getName();
MyLogger.actionRunning(Thread.currentThread().getName(), playerName, 1);
MyLogger.actionRunning(Thread.currentThread().getName());
if (playerName != null &&
(lastPlayedLimit == 0 || UnixTimeHandler.hasPlayedSince(lastPlayedLimit, player.getLastPlayed()))) {
offlinePlayerUUIDs.put(playerName, player.getUniqueId());

View File

@ -41,7 +41,7 @@ public final class ReloadThread extends Thread {
sender = se;
this.setName("ReloadThread-" + reloadThreadID);
MyLogger.threadCreated(this.getName());
MyLogger.logHighLevelMsg(this.getName() + " created!");
}
/** This method will perform a series of tasks. If a {@link StatThread} is still running,
@ -52,11 +52,11 @@ public final class ReloadThread extends Thread {
@Override
public void run() {
long time = System.currentTimeMillis();
MyLogger.threadStart(this.getName());
MyLogger.logHighLevelMsg(this.getName() + " started!");
if (statThread != null && statThread.isAlive()) {
try {
MyLogger.waitingForOtherThread(this.getName(), statThread.getName());
MyLogger.logLowLevelMsg(this.getName() + ": Waiting for " + statThread.getName() + " to finish up...");
statThread.join();
} catch (InterruptedException e) {
MyLogger.logException(e, "ReloadThread", "run(), trying to join " + statThread.getName());
@ -65,7 +65,7 @@ public final class ReloadThread extends Thread {
}
if (reloadThreadID != 1 && config.reloadConfig()) { //during a reload
MyLogger.logMsg("Reloading!", false);
MyLogger.logLowLevelMsg("Reloading!");
reloadEverything();
if (sender != null) {
@ -92,8 +92,8 @@ public final class ReloadThread extends Thread {
OfflinePlayer[] offlinePlayers;
if (config.whitelistOnly()) {
offlinePlayers = Bukkit.getWhitelistedPlayers().toArray(OfflinePlayer[]::new);
MyLogger.logTimeTaken("ReloadThread",
"retrieved whitelist", time, DebugLevel.MEDIUM);
MyLogger.logMediumLevelTask("ReloadThread",
"retrieved whitelist", time);
}
else if (config.excludeBanned()) {
if (Bukkit.getPluginManager().getPlugin("LiteBans") != null) {
@ -107,13 +107,13 @@ public final class ReloadThread extends Thread {
.parallel()
.filter(offlinePlayer -> !bannedPlayers.contains(offlinePlayer)).toArray(OfflinePlayer[]::new);
}
MyLogger.logTimeTaken("ReloadThread",
"retrieved banlist", time, DebugLevel.MEDIUM);
MyLogger.logMediumLevelTask("ReloadThread",
"retrieved banlist", time);
}
else {
offlinePlayers = Bukkit.getOfflinePlayers();
MyLogger.logTimeTaken("ReloadThread",
"retrieved list of Offline Players", time, DebugLevel.MEDIUM);
MyLogger.logMediumLevelTask("ReloadThread",
"retrieved list of Offline Players", time);
}
int size = offlinePlayers != null ? offlinePlayers.length : 16;
@ -122,10 +122,10 @@ public final class ReloadThread extends Thread {
ReloadAction task = new ReloadAction(offlinePlayers, config.getLastPlayedLimit(), playerMap);
MyLogger.actionCreated((offlinePlayers != null) ? offlinePlayers.length : 0);
ForkJoinPool.commonPool().invoke(task);
MyLogger.actionFinished(1);
MyLogger.actionFinished();
MyLogger.logTimeTaken("ReloadThread",
("loaded " + playerMap.size() + " offline players"), time, DebugLevel.LOW);
MyLogger.logLowLevelTask("ReloadThread",
("loaded " + playerMap.size() + " offline players"), time);
return playerMap;
}
}

View File

@ -61,7 +61,7 @@ final class StatAction extends RecursiveTask<ConcurrentHashMap<String, Integer>>
if (iterator.hasNext()) {
do {
String playerName = iterator.next();
MyLogger.actionRunning(Thread.currentThread().getName(), playerName, 2);
MyLogger.actionRunning(Thread.currentThread().getName());
OfflinePlayer player = offlinePlayerHandler.getOfflinePlayer(playerName);
int statistic = 0;
switch (requestSettings.getStatistic().getType()) {

View File

@ -1,7 +1,6 @@
package com.gmail.artemis.the.gr8.playerstats.statistic;
import com.gmail.artemis.the.gr8.playerstats.ThreadManager;
import com.gmail.artemis.the.gr8.playerstats.enums.DebugLevel;
import com.gmail.artemis.the.gr8.playerstats.statistic.request.RequestSettings;
import com.gmail.artemis.the.gr8.playerstats.utils.MyLogger;
import com.gmail.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler;
@ -58,15 +57,15 @@ public final class StatCalculator {
try {
allStats = commonPool.invoke(getStatTask(requestSettings));
} catch (ConcurrentModificationException e) {
MyLogger.logMsg("The requestSettings could not be executed due to a ConcurrentModificationException. " +
MyLogger.logWarning("The requestSettings 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);
"Try again and it should be fine!");
throw new ConcurrentModificationException(e.toString());
}
MyLogger.actionFinished(2);
MyLogger.actionFinished();
ThreadManager.recordCalcTime(System.currentTimeMillis() - time);
MyLogger.logTimeTaken("StatThread", "calculated all stats", time, DebugLevel.MEDIUM);
MyLogger.logMediumLevelTask("StatThread", "calculated all stats", time);
return allStats;
}

View File

@ -30,19 +30,19 @@ public final class StatThread extends Thread {
requestSettings = s;
this.setName("StatThread-" + requestSettings.getCommandSender().getName() + "-" + ID);
MyLogger.threadCreated(this.getName());
MyLogger.logHighLevelMsg(this.getName() + " created!");
}
@Override
public void run() throws IllegalStateException, NullPointerException {
MyLogger.threadStart(this.getName());
MyLogger.logHighLevelMsg(this.getName() + " started!");
if (requestSettings == null) {
throw new NullPointerException("No statistic requestSettings was found!");
}
if (reloadThread != null && reloadThread.isAlive()) {
try {
MyLogger.waitingForOtherThread(this.getName(), reloadThread.getName());
MyLogger.logLowLevelMsg(this.getName() + ": Waiting for " + reloadThread.getName() + " to finish up...");
outputManager.sendFeedbackMsg(requestSettings.getCommandSender(), StandardMessage.STILL_RELOADING);
reloadThread.join();

View File

@ -6,11 +6,8 @@ import org.bukkit.plugin.Plugin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Logger;
/** The PlayerStats Logger*/
@ -19,17 +16,12 @@ public final class MyLogger {
private static final Logger logger;
private static DebugLevel debugLevel;
private static final String[] processedPlayers;
private static final AtomicInteger playersIndex;
private static ConcurrentHashMap<String, Integer> threadNames;
static {
Plugin plugin = Bukkit.getPluginManager().getPlugin("PlayerStats");
logger = (plugin != null) ? plugin.getLogger() : Bukkit.getLogger();
debugLevel = DebugLevel.LOW;
processedPlayers = new String[10];
playersIndex = new AtomicInteger(0);
threadNames = new ConcurrentHashMap<>();
}
@ -53,36 +45,24 @@ public final class MyLogger {
}
}
public static void logMsg(String content) {
logMsg(content, DebugLevel.LOW, false);
public static void logLowLevelMsg(String content) {
logger.info(content);
}
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);
}
}
public static void logMediumLevelMsg(String content) {
if (debugLevel != DebugLevel.LOW) {
logger.info(content);
}
}
public static void logException(@NotNull Exception exception, String caughtBy) {
logException(exception, caughtBy, null);
public static void logHighLevelMsg(String content) {
if (debugLevel == DebugLevel.HIGH) {
logger.info(content);
}
}
public static void logWarning(String content) {
logger.warning(content);
}
/** Log the encountered exception as a warning to console,
@ -101,43 +81,11 @@ public final class MyLogger {
}
}
/** If DebugLevel is HIGH, logs when the while loop in MessageBuilder, getLanguageKey is being run. */
public static void replacingUnderscores() {
if (debugLevel == DebugLevel.HIGH) {
logger.info("Replacing underscores and capitalizing names...");
}
}
/** Output to console that the given thread has been created (but not started yet).*/
public static void threadCreated(String threadName) {
if (debugLevel == DebugLevel.HIGH) {
logger.info(threadName + " created!");
}
}
/** Output to console that the given thread has been started. */
public static void threadStart(String threadName) {
if (debugLevel == DebugLevel.HIGH) {
logger.info(threadName + " started!");
}
}
/** Output to console that another reloadThread is already running. */
public static void threadAlreadyRunning(String threadName) {
logger.info("Another reloadThread is already running! (" + threadName + ")");
}
/** Output to console that the executingThread is waiting for otherThread to finish up. */
public static void waitingForOtherThread(String executingThread, String otherThread) {
logger.info(executingThread + ": Waiting for " + otherThread + " to finish up...");
}
/** If DebugLevel is MEDIUM or HIGH, output to console that an action has started.
@param taskLength Length of the action (in terms of units-to-process)*/
public static void actionCreated(int taskLength) {
if (debugLevel != DebugLevel.LOW) {
threadNames = new ConcurrentHashMap<>();
playersIndex.set(0);
logger.info("Initial Action created for " + taskLength + " Players. Processing...");
}
}
@ -153,88 +101,43 @@ public final class MyLogger {
}
}
/** Internally save the name of the executing thread and processed player for logging,
and for the ReloadThread, if DebugLevel is HIGH, output the last 10 processed players once
there have been 10 names saved in MyLogger. This method is synchronized.
@param threadName Name of the executing thread
@param playerName Name of the player that was processed in this action
@param thread 1 for ReloadThread, 2 for StatThread */
public static synchronized void actionRunning(String threadName, String playerName, int thread) {
/** Internally save the name of the executing thread for logging.
@param threadName Name of the executing thread */
public static void actionRunning(String threadName) {
if (debugLevel != DebugLevel.LOW) {
if (!threadNames.containsKey(threadName)) {
threadNames.put(threadName, threadNames.size());
}
if (thread == 1 && debugLevel == DebugLevel.HIGH) {
if (incrementOfTen()) {
logger.info(Arrays.asList(processedPlayers).toString());
}
processedPlayers[nextPlayersIndex() % 10] = playerName;
}
else if (debugLevel == DebugLevel.MEDIUM || debugLevel == DebugLevel.HIGH && thread == 2) {
nextPlayersIndex();
}
}
}
/** Output to console that an action has finished.
<p>For the ReloadThread, if DebugLevel is HIGH, output the left-over processed players.
For both threads, if DebugLevel is MEDIUM or HIGH, output the names of the threads that were used.</p>
@param thread 1 for ReloadThread, 2 for StatThread */
public static void actionFinished(int thread) {
if (thread == 1 && debugLevel == DebugLevel.HIGH) {
ArrayList<String> leftOvers = new ArrayList<>(Arrays.asList(processedPlayers).subList(playersIndex.intValue() % 10, 10));
logger.info(leftOvers.toString());
}
/** Output to console that an action has finished if DebugLevel is MEDIUM or higher.
If DebugLevel is HIGH, also output the names of the threads that were used. */
public static void actionFinished() {
if (debugLevel != DebugLevel.LOW) {
logger.info("Finished Recursive Action! In total " +
threadNames.size() + " Threads were used to process " +
playersIndex.get() + " Players.");
threadNames.size() + " Threads were used");
}
if (debugLevel == DebugLevel.HIGH) {
logger.info(Collections.list(threadNames.keys()).toString());
}
}
/** Output to console how long a certain task has taken if DebugLevel is equal to or higher than the specified threshold.
public static void logMediumLevelTask(String className, String methodName, long startTime) {
if (debugLevel != DebugLevel.LOW) {
printTime(className, methodName, startTime);
}
}
public static void logLowLevelTask(String className, String methodName, long startTime) {
printTime(className, methodName, startTime);
}
/** Output to console how long a certain task has taken.
@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);
}
}
@param startTime Timestamp marking the beginning of the task */
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

@ -56,9 +56,9 @@ public final class OfflinePlayerHandler {
return Bukkit.getOfflinePlayer(offlinePlayerUUIDs.get(playerName));
}
else {
MyLogger.logMsg("Cannot calculate statistics for player-name: " + playerName +
MyLogger.logWarning("Cannot calculate statistics for player-name: " + playerName +
"! Double-check if the name is spelled correctly (including capital letters), " +
"or if any of your config settings exclude them", true);
"or if any of your config settings exclude them");
throw new IllegalArgumentException("Cannot convert this player-name into a valid Player to calculate statistics for");
}
}