Made EnumHandler not static, made update-settings-methods static to remove unnecessary classes in constructors

This commit is contained in:
Artemis-the-gr8 2022-07-26 16:13:11 +02:00
parent b361918ca3
commit 9bf4e25750
16 changed files with 187 additions and 170 deletions

View File

@ -11,6 +11,7 @@ import com.gmail.artemis.the.gr8.playerstats.listeners.JoinListener;
import com.gmail.artemis.the.gr8.playerstats.msg.OutputManager;
import com.gmail.artemis.the.gr8.playerstats.statistic.RequestManager;
import com.gmail.artemis.the.gr8.playerstats.statistic.StatManager;
import com.gmail.artemis.the.gr8.playerstats.utils.EnumHandler;
import com.gmail.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import org.bstats.bukkit.Metrics;
@ -33,20 +34,21 @@ public final class Main extends JavaPlugin {
@Override
public void onEnable() {
//TODO fix (move these two into initializeMainClasses also, and remove all the Main.get... methods)
Metrics metrics = new Metrics(this, 15923);
new Metrics(this, 15923);
//first get an instance of all the classes that need to be passed along to different classes
ConfigHandler config = new ConfigHandler(this);
EnumHandler enumHandler = new EnumHandler();
OfflinePlayerHandler offlinePlayerHandler = new OfflinePlayerHandler();
//initialize all the Managers and the API
initializeMainClasses(config, offlinePlayerHandler);
initializeMainClasses(config, enumHandler, offlinePlayerHandler);
//register all commands and the tabCompleter
PluginCommand statcmd = this.getCommand("statistic");
if (statcmd != null) {
statcmd.setExecutor(new StatCommand(outputManager, threadManager, requestManager));
statcmd.setTabCompleter(new TabCompleter(offlinePlayerHandler));
statcmd.setTabCompleter(new TabCompleter(enumHandler, offlinePlayerHandler));
}
PluginCommand reloadcmd = this.getCommand("statisticreload");
if (reloadcmd != null) reloadcmd.setExecutor(new ReloadCommand(threadManager));
@ -83,42 +85,14 @@ public final class Main extends JavaPlugin {
return playerStatsAPI;
}
public static @NotNull OutputManager getOutputManager() throws IllegalStateException {
if (outputManager == null) {
throw new IllegalStateException("The OutputManager is not loaded! Is PlayerStats enabled?");
}
return outputManager;
}
public static @NotNull ShareManager getShareManager() throws IllegalStateException {
if (shareManager == null) {
throw new IllegalStateException("The ShareManager is not loaded! Is PlayerStats enabled?");
}
return shareManager;
}
public static @NotNull StatManager getStatManager() throws IllegalStateException {
if (statManager == null) {
throw new IllegalStateException("The StatManager is not loaded! Is PlayerStats enabled?");
}
return statManager;
}
public static @NotNull ThreadManager getThreadManager() throws IllegalStateException {
if (threadManager == null) {
throw new IllegalStateException("The ThreadManager is not loaded! Is PlayerStats enabled?");
}
return threadManager;
}
private void initializeMainClasses(ConfigHandler config, OfflinePlayerHandler offlinePlayerHandler) {
private void initializeMainClasses(ConfigHandler config, EnumHandler enumHandler, OfflinePlayerHandler offlinePlayerHandler) {
adventure = BukkitAudiences.create(this);
shareManager = new ShareManager(config);
statManager = new StatManager(offlinePlayerHandler, config.getTopListMaxSize());
outputManager = new OutputManager(getAdventure(), config, shareManager);
requestManager = new RequestManager(offlinePlayerHandler, outputManager);
threadManager = new ThreadManager(config, statManager, outputManager, offlinePlayerHandler);
requestManager = new RequestManager(enumHandler, offlinePlayerHandler, outputManager);
threadManager = new ThreadManager(config, statManager, outputManager);
playerStatsAPI = new PlayerStatsAPI(requestManager, statManager, outputManager);
}

View File

@ -27,10 +27,10 @@ public final class ShareManager {
private static boolean isEnabled;
private static int waitingTime;
private volatile AtomicInteger resultID;
private ConcurrentHashMap<UUID, StatResult> statResultQueue;
private ConcurrentHashMap<String, Instant> shareTimeStamp;
private ArrayBlockingQueue<UUID> sharedResults;
private static volatile AtomicInteger resultID;
private static ConcurrentHashMap<UUID, StatResult> statResultQueue;
private static ConcurrentHashMap<String, Instant> shareTimeStamp;
private static ArrayBlockingQueue<UUID> sharedResults;
public ShareManager(ConfigHandler config) {
updateSettings(config);
@ -40,7 +40,7 @@ public final class ShareManager {
return isEnabled;
}
public synchronized void updateSettings(ConfigHandler config) {
public static synchronized void updateSettings(ConfigHandler config) {
isEnabled = config.allowStatSharing() && config.useHoverText();
waitingTime = config.getStatShareWaitingTime();

View File

@ -27,18 +27,16 @@ public final class ThreadManager {
private static ConfigHandler config;
private static OutputManager outputManager;
private static StatManager statManager;
private final OfflinePlayerHandler offlinePlayerHandler;
private ReloadThread lastActiveReloadThread;
private StatThread lastActiveStatThread;
private final HashMap<String, Thread> statThreads;
private static long lastRecordedCalcTime;
public ThreadManager(ConfigHandler config, StatManager statManager, OutputManager outputManager, OfflinePlayerHandler offlinePlayerHandler) {
public ThreadManager(ConfigHandler config, StatManager statManager, OutputManager outputManager) {
ThreadManager.config = config;
ThreadManager.outputManager = outputManager;
ThreadManager.statManager = statManager;
this.offlinePlayerHandler = offlinePlayerHandler;
statThreads = new HashMap<>();
statThreadID = 0;
@ -56,7 +54,7 @@ public final class ThreadManager {
if (lastActiveReloadThread == null || !lastActiveReloadThread.isAlive()) {
reloadThreadID += 1;
lastActiveReloadThread = new ReloadThread(config, outputManager, offlinePlayerHandler, reloadThreadID, lastActiveStatThread, sender);
lastActiveReloadThread = new ReloadThread(config, outputManager, reloadThreadID, lastActiveStatThread, sender);
lastActiveReloadThread.start();
}
else {

View File

@ -1,14 +1,16 @@
package com.gmail.artemis.the.gr8.playerstats.api;
import com.gmail.artemis.the.gr8.playerstats.Main;
import com.gmail.artemis.the.gr8.playerstats.msg.msgutils.LanguageKeyHandler;
import com.gmail.artemis.the.gr8.playerstats.msg.msgutils.StringUtils;
import com.gmail.artemis.the.gr8.playerstats.utils.MyLogger;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.ComponentIteratorType;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.TranslatableComponent;
import net.kyori.adventure.text.renderer.TranslatableComponentRenderer;
import net.kyori.adventure.text.*;
import net.kyori.adventure.text.flattener.ComponentFlattener;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import net.kyori.adventure.translation.GlobalTranslator;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.Statistic;
import org.bukkit.entity.EntityType;
import org.jetbrains.annotations.Contract;
@ -16,8 +18,6 @@ import org.jetbrains.annotations.NotNull;
import java.util.Locale;
import static net.kyori.adventure.translation.GlobalTranslator.renderer;
/** This is the outgoing API that you can use to access the core functionality of PlayerStats.
To work with it, you need to call PlayerStats.{@link #getAPI()} to get an instance of {@link PlayerStatsAPI}.
You can then use this object to access any of the further methods.
@ -48,48 +48,60 @@ public interface PlayerStats {
/** Turns a TextComponent into its String representation. If you don't want to work with
Adventure's TextComponents, you can call this method to turn any stat-result into a String.
@return a String representation of this TextComponent, without color and style, but with line-breaks*/
@return a String representation of this TextComponent, without hover/click events, but with color, style and formatting */
default String statResultComponentToString(TextComponent statResult) {
return LegacyComponentSerializer.builder().hexColors().useUnusualXRepeatedCharacterHexFormat().build().serialize(statResult);
ComponentFlattener flattener = ComponentFlattener.basic().toBuilder()
.mapper(TranslatableComponent.class, trans ->
StringUtils.prettify(
LanguageKeyHandler.extractName(
trans.key())))
.build();
return LegacyComponentSerializer.builder()
.hexColors()
.useUnusualXRepeatedCharacterHexFormat()
.flattener(flattener)
.build()
.serialize(statResult);
}
/** Get a formatted player-statistic of Statistic.Type UNTYPED.
/** Get a formatted player-statistic of Statistic.Type Untyped.
@return a TextComponent with the following parts:
<br>[player-name]: [number] [stat-name]
@throws NullPointerException if statistic or playerName is null*/
TextComponent getPlayerStat(@NotNull Statistic statistic, @NotNull String playerName) throws NullPointerException;
/** Get a formatted player-statistic of Statistic.Type BLOCK or ITEM.
/** Get a formatted player-statistic of Statistic.Type Block or Item.
@return a TextComponent with the following parts:
<br>[player-name]: [number] [stat-name] [sub-stat-name]
@throws NullPointerException if statistic, material or playerName is null*/
TextComponent getPlayerStat(@NotNull Statistic statistic, @NotNull Material material, @NotNull String playerName) throws NullPointerException;
/** Get a formatted player-statistic of Statistic.Type ENTITY.
/** Get a formatted player-statistic of Statistic.Type Entity.
@return a TextComponent with the following parts:
<br>[player-name]: [number] [stat-name] [sub-stat-name]
@throws NullPointerException if statistic, entity or playerName is null*/
TextComponent getPlayerStat(@NotNull Statistic statistic, @NotNull EntityType entity, @NotNull String playerName) throws NullPointerException;
/** Get a formatted server-statistic of Statistic.Type UNTYPED. Not recommended to call this from the main Thread (see class description).
/** Get a formatted server-statistic of Statistic.Type Untyped. Don't call this from the main Thread (see class description)!
@return a TextComponent with the following parts:
<br>[Total on] [server-name]: [number] [stat-name]
@throws NullPointerException if statistic is null*/
TextComponent getServerStat(@NotNull Statistic statistic) throws NullPointerException;
/** Get a formatted server-statistic of Statistic.Type BLOCK or ITEM. Not recommended to call this from the main Thread (see class description).
/** Get a formatted server-statistic of Statistic.Type Block or Item. Don't call this from the main Thread (see class description)!
@return a TextComponent with the following parts:
<br>[Total on] [server-name]: [number] [stat-name] [sub-stat-name]
@throws NullPointerException if statistic or material is null*/
TextComponent getServerStat(@NotNull Statistic statistic, @NotNull Material material) throws NullPointerException;
/** Get a formatted server-statistic of Statistic.Type ENTITY. Not recommended to call this from the main Thread (see class description).
/** Get a formatted server-statistic of Statistic.Type Entity. Don't call this from the main Thread (see class description)!
@return a TextComponent with the following parts:
<br>[Total on] [server-name]: [number] [stat-name] [sub-stat-name]
@throws NullPointerException if statistic or entity is null*/
TextComponent getServerStat(@NotNull Statistic statistic, @NotNull EntityType entity) throws NullPointerException;
/** Get a formatted top-statistic of Statistic.Type UNTYPED. Not recommended to call this from the main Thread (see class description).
/** Get a formatted top-statistic of Statistic.Type Untyped. Don't call this from the main Thread (see class description)!
@return a TextComponent with the following parts:
<br>[PlayerStats] [Top 10] [stat-name]
<br> [1.] [player-name] [number]
@ -98,7 +110,7 @@ public interface PlayerStats {
@throws NullPointerException if statistic is null*/
TextComponent getTopStats(@NotNull Statistic statistic) throws NullPointerException;
/** Get a formatted top-statistic of Statistic.Type BLOCK or ITEM. Not recommended to call this from the main Thread (see class description).
/** Get a formatted top-statistic of Statistic.Type Block or Item. Don't call this from the main Thread (see class description)!
@return a TextComponent with the following parts:
<br>[PlayerStats] [Top 10] [stat-name] [sub-stat-name]
<br> [1.] [player-name] [number]
@ -107,7 +119,7 @@ public interface PlayerStats {
@throws NullPointerException if statistic or material is null*/
TextComponent getTopStats(@NotNull Statistic statistic, @NotNull Material material) throws NullPointerException;
/** Get a formatted top-statistic of Statistic.Type ENTITY. Not recommended to call this from the main Thread (see class description).
/** Get a formatted top-statistic of Statistic.Type Entity. Don't call this from the main Thread (see class description)!
@return a TextComponent with the following parts:
<br>[PlayerStats] [Top 10] [stat-name] [sub-stat-name]
<br> [1.] [player-name] [number]

View File

@ -1,13 +1,17 @@
package com.gmail.artemis.the.gr8.playerstats.commands;
import com.gmail.artemis.the.gr8.playerstats.Main;
import com.gmail.artemis.the.gr8.playerstats.ThreadManager;
import com.gmail.artemis.the.gr8.playerstats.msg.OutputManager;
import com.gmail.artemis.the.gr8.playerstats.statistic.RequestManager;
import com.gmail.artemis.the.gr8.playerstats.models.StatRequest;
import com.gmail.artemis.the.gr8.playerstats.utils.MyLogger;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TranslatableComponent;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.Material;
import org.bukkit.Statistic;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
@ -36,16 +40,6 @@ public class StatCommand implements CommandExecutor {
outputManager.sendExamples(sender);
}
else if (args[0].equalsIgnoreCase(">:(")) {
java.awt.Color color = new java.awt.Color(178, 102, 255);
// ChatColor one = ChatColor.of(color);
// TextComponent msg = new TextComponent(">:(((((");
// msg.setColor(one);
// sender.spigot().sendMessage(msg);
// sender.sendMessage("regular msg with ChatColor: " + one + ">:((((((");
// sender.sendMessage("regular msg Component.toLegacyText: " + msg.toLegacyText());
// sender.sendMessage("regular msg Component.toString: " + msg);
}
else if (args[0].equalsIgnoreCase(">:((")) {
Component msg = MiniMessage.miniMessage().deserialize("<gradient:#f74040:#FF6600:#f74040>fire demon</gradient>");
String msgString = LegacyComponentSerializer.builder().hexColors().build().serialize(msg);
sender.sendMessage("LCS.hexColors(): " + msgString);
@ -60,6 +54,16 @@ public class StatCommand implements CommandExecutor {
sender.sendMessage("LCS.hexColors().spigotformat...: " + msgString3);
MyLogger.logMsg(msgString3);
}
else if (args[0].equalsIgnoreCase("test")) {
TranslatableComponent msg = Component.translatable(Statistic.ANIMALS_BRED.getKey().getNamespace() + "." + Statistic.ANIMALS_BRED.getKey().getKey());
TranslatableComponent msg2 = Component.translatable("stat." + Statistic.ANIMALS_BRED.getKey().getNamespace() + "." + Statistic.ANIMALS_BRED.getKey().getKey());
Main.getAdventure().console().sendMessage(msg);
Main.getAdventure().console().sendMessage(msg2);
MyLogger.logMsg("key to String: " + Statistic.KILL_ENTITY.getKey());
MyLogger.logMsg("key.getNamespace(): " + Statistic.KILL_ENTITY.getKey().getNamespace());
MyLogger.logMsg("key.getKey(): " + Statistic.KILL_ENTITY.getKey().getKey());
}
else {
StatRequest request = requestManager.generateRequest(sender, args);
if (requestManager.validateRequest(request)) {

View File

@ -14,14 +14,16 @@ import java.util.stream.Collectors;
public class TabCompleter implements org.bukkit.command.TabCompleter {
private final EnumHandler enumHandler;
private final OfflinePlayerHandler offlinePlayerHandler;
private final TabCompleteHelper tabCompleteHelper;
private final List<String> commandOptions;
public TabCompleter(OfflinePlayerHandler o) {
offlinePlayerHandler = o;
tabCompleteHelper = new TabCompleteHelper();
public TabCompleter(EnumHandler enumHandler, OfflinePlayerHandler offlinePlayerHandler) {
this.enumHandler = enumHandler;
this.offlinePlayerHandler = offlinePlayerHandler;
tabCompleteHelper = new TabCompleteHelper(enumHandler);
commandOptions = new ArrayList<>();
commandOptions.add("top");
@ -50,7 +52,7 @@ public class TabCompleter implements org.bukkit.command.TabCompleter {
else { //after checking if args[0] is a viable statistic, suggest substatistic OR commandOptions
String previousArg = args[args.length -2];
if (EnumHandler.isStatistic(previousArg)) {
if (enumHandler.isStatistic(previousArg)) {
Statistic stat = EnumHandler.getStatEnum(previousArg);
if (stat != null) {
tabSuggestions = getTabSuggestions(getRelevantList(stat), currentArg);
@ -60,7 +62,7 @@ public class TabCompleter implements org.bukkit.command.TabCompleter {
//if previous arg = "player"
else if (previousArg.equalsIgnoreCase("player")) {
if (args.length >= 3 && EnumHandler.isEntityStatistic(args[args.length-3])) {
if (args.length >= 3 && enumHandler.isEntityStatistic(args[args.length-3])) {
tabSuggestions = commandOptions; //if arg before "player" was entity-stat, suggest commandOptions
}
else { //otherwise "player" is target-flag: suggest playerNames
@ -69,7 +71,7 @@ public class TabCompleter implements org.bukkit.command.TabCompleter {
}
//after a substatistic, suggest commandOptions
else if (EnumHandler.isSubStatEntry(previousArg)) {
else if (enumHandler.isSubStatEntry(previousArg)) {
tabSuggestions = commandOptions;
}
}
@ -78,7 +80,7 @@ public class TabCompleter implements org.bukkit.command.TabCompleter {
}
private List<String> getFirstArgSuggestions(String currentArg) {
List<String> suggestions = EnumHandler.getStatNames();
List<String> suggestions = enumHandler.getStatNames();
suggestions.add("examples");
suggestions.add("help");
return getTabSuggestions(suggestions, currentArg);

View File

@ -10,15 +10,17 @@ import java.util.stream.Collectors;
public final class TabCompleteHelper {
private final EnumHandler enumHandler;
private static List<String> itemBrokenSuggestions;
private static List<String> entitySuggestions;
public TabCompleteHelper() {
public TabCompleteHelper(EnumHandler enumHandler) {
this.enumHandler = enumHandler;
prepareLists();
}
public List<String> getAllItemNames() {
return EnumHandler.getItemNames();
return enumHandler.getItemNames();
}
public List<String> getItemBrokenSuggestions() {
@ -26,7 +28,7 @@ public final class TabCompleteHelper {
}
public List<String> getAllBlockNames() {
return EnumHandler.getBlockNames();
return enumHandler.getBlockNames();
}
public List<String> getEntitySuggestions() {
@ -52,4 +54,4 @@ public final class TabCompleteHelper {
.map(String::toLowerCase)
.collect(Collectors.toList());
}
}
}

View File

@ -10,7 +10,6 @@ import com.gmail.artemis.the.gr8.playerstats.msg.components.ExampleMessage;
import com.gmail.artemis.the.gr8.playerstats.msg.components.HelpMessage;
import com.gmail.artemis.the.gr8.playerstats.msg.msgutils.*;
import com.gmail.artemis.the.gr8.playerstats.models.StatRequest;
import com.gmail.artemis.the.gr8.playerstats.utils.EnumHandler;
import com.gmail.artemis.the.gr8.playerstats.utils.MyLogger;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
@ -90,7 +89,7 @@ public class MessageBuilder {
return componentFactory.pluginPrefix()
.append(space())
.append(componentFactory.message().content(
"Please add a valid " + EnumHandler.getSubStatTypeName(statType) + " to look up this statistic!"));
"Please add a valid " + getSubStatTypeName(statType) + " to look up this statistic!"));
}
public TextComponent missingPlayerName() {
@ -106,7 +105,7 @@ public class MessageBuilder {
.append(componentFactory.messageAccent().content("\"" + subStatName + "\""))
.append(space())
.append(componentFactory.message().content(
"is not a valid " + EnumHandler.getSubStatTypeName(statType) + "!"));
"is not a valid " + getSubStatTypeName(statType) + "!"));
}
public TextComponent requestAlreadyRunning() {
@ -483,4 +482,16 @@ public class MessageBuilder {
return Component.space()
.append(componentFactory.statUnit(statName, null, selection));
}
/** Returns "block", "entity", "item", or "sub-statistic" if the provided Type is null. */
public static String getSubStatTypeName(Statistic.Type statType) {
String subStat = "sub-statistic";
if (statType == null) return subStat;
switch (statType) {
case BLOCK -> subStat = "block";
case ENTITY -> subStat = "entity";
case ITEM -> subStat = "item";
}
return subStat;
}
}

View File

@ -46,7 +46,7 @@ public final class OutputManager implements StatFormatter {
prepareFunctions();
}
public void updateMessageWriters(ConfigHandler config) {
public static void updateMessageWriters(ConfigHandler config) {
getMessageWriters(config);
}
@ -145,7 +145,7 @@ public final class OutputManager implements StatFormatter {
}
}
private void getMessageWriters(ConfigHandler config) {
private static void getMessageWriters(ConfigHandler config) {
boolean isBukkit = Bukkit.getName().equalsIgnoreCase("CraftBukkit");
if (config.useRainbowMode() ||
(config.useFestiveFormatting() && LocalDate.now().getMonth().equals(Month.JUNE))) {

View File

@ -5,6 +5,7 @@ import com.gmail.artemis.the.gr8.playerstats.enums.PluginColor;
import com.gmail.artemis.the.gr8.playerstats.enums.Target;
import com.gmail.artemis.the.gr8.playerstats.enums.Unit;
import com.gmail.artemis.the.gr8.playerstats.msg.MessageBuilder;
import com.gmail.artemis.the.gr8.playerstats.msg.msgutils.LanguageKeyHandler;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.TranslatableComponent;
@ -206,10 +207,10 @@ public class ComponentFactory {
getStyleFromString(config.getStatNameDecoration(selection, true)));
TextComponent subStat = subStatNameTranslatable(subStatKey, selection);
if (statKey.equalsIgnoreCase("stat_type.minecraft.killed")) {
if (LanguageKeyHandler.isKeyForKillEntity(statKey)) {
return totalStatNameBuilder.append(killEntityBuilder(subStat)).build();
}
else if (statKey.equalsIgnoreCase("stat_type.minecraft.killed_by")) {
else if (LanguageKeyHandler.isKeyForEntityKilledBy(statKey)) {
return totalStatNameBuilder.append(entityKilledByBuilder(subStat)).build();
}
else {

View File

@ -20,6 +20,36 @@ public final class LanguageKeyHandler {
statNameKeys = generateStatNameKeys();
}
public static boolean isKeyForKillEntity(String statKey) {
return statKey.equalsIgnoreCase("stat_type.minecraft.killed");
}
public static boolean isKeyForEntityKilledBy(String statKey) {
return statKey.equalsIgnoreCase("stat_type.minecraft.killed_by");
}
public static String extractName(String nameSpacedKey) {
if (nameSpacedKey.equalsIgnoreCase("soundCategory.block")) {
return Unit.BLOCK.getLabel();
}
String toReplace = "";
if (nameSpacedKey.contains("stat")) {
if (nameSpacedKey.contains("type")) {
toReplace = "stat_type";
} else {
toReplace = "stat";
}
} else if (nameSpacedKey.contains("entity")) {
toReplace = "entity";
} else if (nameSpacedKey.contains("block")) {
toReplace = "block";
} else if (nameSpacedKey.contains("item")) {
toReplace = "item";
}
toReplace = toReplace + ".minecraft.";
return nameSpacedKey.replace(toReplace, "");
}
public String getStatKey(@NotNull Statistic statistic) {
if (statistic.getType() == Statistic.Type.UNTYPED) {
return "stat.minecraft." + statNameKeys.get(statistic);

View File

@ -1,6 +1,5 @@
package com.gmail.artemis.the.gr8.playerstats.reload;
import com.gmail.artemis.the.gr8.playerstats.Main;
import com.gmail.artemis.the.gr8.playerstats.ShareManager;
import com.gmail.artemis.the.gr8.playerstats.ThreadManager;
import com.gmail.artemis.the.gr8.playerstats.config.ConfigHandler;
@ -27,21 +26,15 @@ public class ReloadThread extends Thread {
private static ConfigHandler config;
private static OutputManager outputManager;
private static ShareManager shareManager;
private final OfflinePlayerHandler offlinePlayerHandler;
private final int reloadThreadID;
private final StatThread statThread;
private final CommandSender sender;
public ReloadThread(ConfigHandler c, OutputManager m, OfflinePlayerHandler o, int ID, @Nullable StatThread s, @Nullable CommandSender se) {
public ReloadThread(ConfigHandler c, OutputManager m, int ID, @Nullable StatThread s, @Nullable CommandSender se) {
config = c;
outputManager = m;
offlinePlayerHandler = o;
shareManager = Main.getShareManager();
reloadThreadID = ID;
statThread = s;
@ -81,16 +74,16 @@ public class ReloadThread extends Thread {
}
else { //during first start-up
MyLogger.setDebugLevel(config.getDebugLevel());
offlinePlayerHandler.updateOfflinePlayerList(loadOfflinePlayers());
OfflinePlayerHandler.updateOfflinePlayerList(loadOfflinePlayers());
ThreadManager.recordCalcTime(System.currentTimeMillis() - time);
}
}
private void reloadEverything() {
MyLogger.setDebugLevel(config.getDebugLevel());
outputManager.updateMessageWriters(config);
offlinePlayerHandler.updateOfflinePlayerList(loadOfflinePlayers());
shareManager.updateSettings(config);
OutputManager.updateMessageWriters(config);
OfflinePlayerHandler.updateOfflinePlayerList(loadOfflinePlayers());
ShareManager.updateSettings(config);
StatManager.updateSettings(config.getTopListMaxSize());
}

View File

@ -18,10 +18,12 @@ import org.jetbrains.annotations.NotNull;
public class RequestManager implements RequestGenerator {
private final EnumHandler enumHandler;
private final OfflinePlayerHandler offlinePlayerHandler;
private static OutputManager outputManager;
public RequestManager(OfflinePlayerHandler offlinePlayerHandler, OutputManager outputManager) {
public RequestManager(EnumHandler enumHandler, OfflinePlayerHandler offlinePlayerHandler, OutputManager outputManager) {
this.enumHandler = enumHandler;
this.offlinePlayerHandler = offlinePlayerHandler;
RequestManager.outputManager = outputManager;
}
@ -30,11 +32,11 @@ public class RequestManager implements RequestGenerator {
StatRequest request = new StatRequest(sender);
for (String arg : args) {
//check for statName
if (EnumHandler.isStatistic(arg) && request.getStatistic() == null) {
if (enumHandler.isStatistic(arg) && request.getStatistic() == null) {
request.setStatistic(EnumHandler.getStatEnum(arg));
}
//check for subStatEntry and playerFlag
else if (EnumHandler.isSubStatEntry(arg)) {
else if (enumHandler.isSubStatEntry(arg)) {
if (arg.equalsIgnoreCase("player") && !request.getPlayerFlag()) {
request.setPlayerFlag(true);
}

View File

@ -1,5 +1,6 @@
package com.gmail.artemis.the.gr8.playerstats.statistic;
import com.gmail.artemis.the.gr8.playerstats.api.PlayerStats;
import com.gmail.artemis.the.gr8.playerstats.enums.StandardMessage;
import com.gmail.artemis.the.gr8.playerstats.enums.Target;
import com.gmail.artemis.the.gr8.playerstats.models.StatRequest;
@ -8,8 +9,6 @@ import com.gmail.artemis.the.gr8.playerstats.reload.ReloadThread;
import com.gmail.artemis.the.gr8.playerstats.ThreadManager;
import com.gmail.artemis.the.gr8.playerstats.utils.MyLogger;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import net.md_5.bungee.api.chat.BaseComponent;
import org.jetbrains.annotations.Nullable;
import java.util.*;
@ -66,11 +65,8 @@ public class StatThread extends Thread {
case SERVER -> outputManager.formatServerStat(request, statManager.getServerStat(request));
};
if (request.isAPIRequest()) {
String msg = LegacyComponentSerializer.builder().hexColors().build().serialize(statResult);
String msg = PlayerStats.getAPI().statResultComponentToString(statResult);
request.getCommandSender().sendMessage(msg);
String msg2 = LegacyComponentSerializer.builder().hexColors().useUnusualXRepeatedCharacterHexFormat().build().serialize(statResult);
request.getCommandSender().sendMessage(msg2);
}
else {
outputManager.sendToCommandSender(request.getCommandSender(), statResult);

View File

@ -19,54 +19,27 @@ import java.util.stream.Stream;
and turn a name into its corresponding enum constant. */
public final class EnumHandler {
private final static List<String> blockNames;
private final static List<String> entityNames;
private final static List<String> itemNames;
private final static List<String> statNames;
private final static List<String> subStatNames;
private static List<String> blockNames;
private static List<String> itemNames;
private static List<String> statNames;
private static List<String> subStatNames;
static {
blockNames = Arrays.stream(Material.values())
.filter(Material::isBlock)
.map(Material::toString)
.map(String::toLowerCase)
.collect(Collectors.toList());
entityNames = Arrays.stream(EntityType.values())
.map(EntityType::toString)
.map(String::toLowerCase)
.filter(entityName -> !entityName.equalsIgnoreCase("unknown"))
.collect(Collectors.toList());
itemNames = Arrays.stream(Material.values())
.filter(Material::isItem)
.map(Material::toString)
.map(String::toLowerCase)
.collect(Collectors.toList());
subStatNames = Stream.of(blockNames, entityNames, itemNames)
.flatMap(Collection::stream)
.distinct()
.collect(Collectors.toList());
statNames = Arrays.stream(Statistic.values())
.map(Statistic::toString)
.map(String::toLowerCase)
.collect(Collectors.toList());
public EnumHandler() {
prepareLists();
}
/** Returns all block-names in lowercase */
public static List<String> getBlockNames() {
public List<String> getBlockNames() {
return blockNames;
}
/** Returns all item-names in lowercase*/
public static List<String> getItemNames() {
public List<String> getItemNames() {
return itemNames;
}
/** Returns all statistic-names in lowercase */
public static List<String> getStatNames() {
public List<String> getStatNames() {
return statNames;
}
@ -115,31 +88,50 @@ public final class EnumHandler {
/** Checks if string is a valid statistic
@param statName String, case-insensitive */
public static boolean isStatistic(@NotNull String statName) {
public boolean isStatistic(@NotNull String statName) {
return statNames.contains(statName.toLowerCase());
}
/** Checks whether the given String equals the name of an entity-type statistic. */
public static boolean isEntityStatistic(String statName) {
public boolean isEntityStatistic(String statName) {
return statName.equalsIgnoreCase(Statistic.ENTITY_KILLED_BY.toString()) ||
statName.equalsIgnoreCase(Statistic.KILL_ENTITY.toString());
}
/** Checks if this statistic is a subStatEntry, meaning it is a block, item or entity
@param statName String, case-insensitive*/
public static boolean isSubStatEntry(@NotNull String statName) {
public boolean isSubStatEntry(@NotNull String statName) {
return subStatNames.contains(statName.toLowerCase());
}
/** Returns "block", "entity", "item", or "sub-statistic" if the provided Type is null. */
public static String getSubStatTypeName(Statistic.Type statType) {
String subStat = "sub-statistic";
if (statType == null) return subStat;
switch (statType) {
case BLOCK -> subStat = "block";
case ENTITY -> subStat = "entity";
case ITEM -> subStat = "item";
}
return subStat;
private void prepareLists() {
List<String> entityNames = Arrays.stream(EntityType.values())
.map(EntityType::toString)
.map(String::toLowerCase)
.filter(entityName -> !entityName.equalsIgnoreCase("unknown"))
.collect(Collectors.toList());
blockNames = Arrays.stream(Material.values())
.filter(Material::isBlock)
.map(Material::toString)
.map(String::toLowerCase)
.collect(Collectors.toList());
itemNames = Arrays.stream(Material.values())
.filter(Material::isItem)
.map(Material::toString)
.map(String::toLowerCase)
.collect(Collectors.toList());
subStatNames = Stream.of(blockNames, entityNames, itemNames)
.flatMap(Collection::stream)
.distinct()
.collect(Collectors.toList());
statNames = Arrays.stream(Statistic.values())
.map(Statistic::toString)
.map(String::toLowerCase)
.collect(Collectors.toList());
}
}

View File

@ -10,7 +10,7 @@ import java.util.concurrent.ConcurrentHashMap;
/** A utility class that deals with OfflinePlayers. It stores a list of all OfflinePlayer-names
that need to be included in statistic calculations, and can retrieve the corresponding OfflinePlayer
object for a given player-name.*/
public class OfflinePlayerHandler {
public final class OfflinePlayerHandler {
private static ConcurrentHashMap<String, UUID> offlinePlayerUUIDs;
private static ArrayList<String> playerNames;
@ -20,6 +20,16 @@ public class OfflinePlayerHandler {
playerNames = new ArrayList<>();
}
/**
* Get a new HashMap that stores the players to include in stat calculations.
* This HashMap is stored as a private variable in OfflinePlayerHandler.
* @param playerList ConcurrentHashMap with keys: playerNames and values: UUIDs
*/
public static void updateOfflinePlayerList(ConcurrentHashMap<String, UUID> playerList) {
offlinePlayerUUIDs = playerList;
playerNames = Collections.list(offlinePlayerUUIDs.keys());
}
/** Checks if a given playerName is on the private HashMap of players that should be included in statistic calculations
@param playerName String, case-sensitive */
public boolean isRelevantPlayer(String playerName) {
@ -36,16 +46,6 @@ public class OfflinePlayerHandler {
return playerNames;
}
/**
* Get a new HashMap that stores the players to include in stat calculations.
* This HashMap is stored as a private variable in OfflinePlayerHandler.
* @param playerList ConcurrentHashMap with keys: playerNames and values: UUIDs
*/
public void updateOfflinePlayerList(ConcurrentHashMap<String, UUID> playerList) {
offlinePlayerUUIDs = playerList;
playerNames = Collections.list(offlinePlayerUUIDs.keys());
}
/**
* Uses the playerName to get the player's UUID from a private HashMap, and uses the UUID to get the corresponding OfflinePlayer Object.
* @param playerName name of the target player