From 3417233decbfbd1f7e96b7f8cb7104e27a5e29c5 Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Sun, 2 Oct 2022 15:19:51 +0200 Subject: [PATCH 01/43] Started working on exclude file (#88) and made file-reloading/updating more organized with an abstract FileHandler --- .../com/artemis/the/gr8/playerstats/Main.java | 24 ++++-- .../gr8/playerstats/config/ConfigHandler.java | 73 ++++++------------ .../config/ConfigUpdateHandler.java | 69 ----------------- .../config/DefaultValueGetter.java | 56 ++++++++++++++ .../msg/components/ComponentUtils.java | 5 +- .../msg/msgutils/LanguageKeyHandler.java | 45 ++--------- .../gr8/playerstats/reload/ReloadThread.java | 8 +- .../gr8/playerstats/utils/FileHandler.java | 77 +++++++++++++++++++ .../utils/OfflinePlayerHandler.java | 9 ++- src/main/resources/excluded_players.yml | 10 +++ 10 files changed, 210 insertions(+), 166 deletions(-) delete mode 100644 src/main/java/com/artemis/the/gr8/playerstats/config/ConfigUpdateHandler.java create mode 100644 src/main/java/com/artemis/the/gr8/playerstats/config/DefaultValueGetter.java create mode 100644 src/main/java/com/artemis/the/gr8/playerstats/utils/FileHandler.java create mode 100644 src/main/resources/excluded_players.yml diff --git a/src/main/java/com/artemis/the/gr8/playerstats/Main.java b/src/main/java/com/artemis/the/gr8/playerstats/Main.java index d821972..96a1be4 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/Main.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/Main.java @@ -32,7 +32,7 @@ import org.jetbrains.annotations.NotNull; */ public final class Main extends JavaPlugin { - private static Main instance; + private static JavaPlugin pluginInstance; private static BukkitAudiences adventure; private static ConfigHandler config; @@ -81,6 +81,18 @@ public final class Main extends JavaPlugin { this.getLogger().info("Disabled PlayerStats!"); } + /** + * + * @return the JavaPlugin instance associated with PlayerStats + * @throws IllegalStateException if PlayerStats is not enabled + */ + public static @NotNull JavaPlugin getPluginInstance() throws IllegalStateException { + if (pluginInstance == null) { + throw new IllegalStateException("PlayerStats is not loaded!"); + } + return pluginInstance; + } + /** * @return Adventure's BukkitAudiences object * @throws IllegalStateException if PlayerStats is not enabled @@ -112,7 +124,7 @@ public final class Main extends JavaPlugin { public static @NotNull LanguageKeyHandler getLanguageKeyHandler() { if (languageKeyHandler == null) { - languageKeyHandler = new LanguageKeyHandler(instance); + languageKeyHandler = new LanguageKeyHandler(); } return languageKeyHandler; } @@ -150,12 +162,12 @@ public final class Main extends JavaPlugin { } private void initializeMainClasses() { - instance = this; + pluginInstance = this; adventure = BukkitAudiences.create(this); - config = new ConfigHandler(this); + config = new ConfigHandler(); enumHandler = new EnumHandler(); - languageKeyHandler = new LanguageKeyHandler(instance); + languageKeyHandler = new LanguageKeyHandler(); offlinePlayerHandler = new OfflinePlayerHandler(); shareManager = new ShareManager(config); @@ -171,7 +183,7 @@ public final class Main extends JavaPlugin { new BukkitRunnable() { @Override public void run() { - final Metrics metrics = new Metrics(instance, 15923); + final Metrics metrics = new Metrics(pluginInstance, 15923); final boolean placeholderExpansionActive; if (Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI")) { PlaceholderExpansion expansion = PlaceholderAPIPlugin diff --git a/src/main/java/com/artemis/the/gr8/playerstats/config/ConfigHandler.java b/src/main/java/com/artemis/the/gr8/playerstats/config/ConfigHandler.java index c40010e..56c9085 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/config/ConfigHandler.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/config/ConfigHandler.java @@ -1,39 +1,39 @@ package com.artemis.the.gr8.playerstats.config; -import com.artemis.the.gr8.playerstats.Main; import com.artemis.the.gr8.playerstats.enums.Target; import com.artemis.the.gr8.playerstats.enums.Unit; +import com.artemis.the.gr8.playerstats.utils.FileHandler; import com.artemis.the.gr8.playerstats.utils.MyLogger; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; import org.jetbrains.annotations.Nullable; -import java.io.File; +import java.util.Map; /** Handles all PlayerStats' config-settings. */ -public final class ConfigHandler { +public final class ConfigHandler extends FileHandler { - private static Main plugin; - private static int configVersion; - - private File configFile; + private final int configVersion; private FileConfiguration config; - public ConfigHandler(Main plugin) { - ConfigHandler.plugin = plugin; + public ConfigHandler() { + super("config.yml"); + config = super.getFileConfiguration(); + configVersion = 6; - - saveDefaultConfig(); - config = YamlConfiguration.loadConfiguration(configFile); - checkConfigVersion(); - + checkAndUpdateConfigVersion(); MyLogger.setDebugLevel(getDebugLevel()); } + @Override + public void reload() { + super.reload(); + config = super.getFileConfiguration(); + } + /** * Checks the number that "config-version" returns to see if the - * config needs updating, and if so, send it to the {@link ConfigUpdateHandler}. + * config needs updating, and if so, updates it. *
*
PlayerStats 1.1: "config-version" doesn't exist. *
PlayerStats 1.2: "config-version" is 2. @@ -42,41 +42,18 @@ public final class ConfigHandler { *
PlayerStats 1.5: "config-version" is 5. *
PlayerStats 1.6 and up: "config-version" is 6. */ - private void checkConfigVersion() { + private void checkAndUpdateConfigVersion() { if (!config.contains("config-version") || config.getInt("config-version") != configVersion) { - new ConfigUpdateHandler(plugin, configFile, configVersion); - reloadConfig(); - } - } + DefaultValueGetter defaultValueGetter = new DefaultValueGetter(config); + Map defaultValues = defaultValueGetter.getValuesToAdjust(); + defaultValues.put("config-version", configVersion); - /** - * Create a config file if none exists yet - * (from the config.yml in the plugin's resources). - */ - private void saveDefaultConfig() { - config = plugin.getConfig(); - plugin.saveDefaultConfig(); - configFile = new File(plugin.getDataFolder(), "config.yml"); - } + super.addValues(defaultValues); + super.updateFile(); + reload(); - /** - * Reloads the config from file, or creates a new file with default values - * if there is none. Also reads the value for debug-level and passes it - * on to {@link MyLogger}. - * - * @return true if the config has been reloaded from disk, false if it failed - */ - public boolean reloadConfig() { - if (!configFile.exists()) { - saveDefaultConfig(); - } - try { - config = YamlConfiguration.loadConfiguration(configFile); - return true; - } - catch (IllegalArgumentException e) { - MyLogger.logException(e, "ConfigHandler", "reloadConfig"); - return false; + MyLogger.logLowLevelMsg("Your config has been updated to version " + configVersion + + ", but all of your custom settings should still be there!"); } } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/config/ConfigUpdateHandler.java b/src/main/java/com/artemis/the/gr8/playerstats/config/ConfigUpdateHandler.java deleted file mode 100644 index 905dc8e..0000000 --- a/src/main/java/com/artemis/the/gr8/playerstats/config/ConfigUpdateHandler.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.artemis.the.gr8.playerstats.config; - -import com.artemis.the.gr8.playerstats.Main; -import com.artemis.the.gr8.playerstats.utils.MyLogger; -import org.bukkit.configuration.file.YamlConfiguration; - -import java.io.File; -import java.io.IOException; - -import com.tchristofferson.configupdater.ConfigUpdater; - -public final class ConfigUpdateHandler { - - /** - * Add new key-value pairs to the config without losing comments, - * using tchristofferson's Config-Updater - */ - public ConfigUpdateHandler(Main plugin, File configFile, int configVersion) { - YamlConfiguration configuration = YamlConfiguration.loadConfiguration(configFile); - updateTopListDefault(configuration); - updateDefaultColors(configuration); - configuration.set("config-version", configVersion); - try { - configuration.save(configFile); - ConfigUpdater.update(plugin, configFile.getName(), configFile); - 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(); - } - } - - /** - * Adjusts the value for "top-list" to migrate the config file from - * versions 1 or 2 to version 3 and above. - */ - private void updateTopListDefault(YamlConfiguration configuration) { - String oldTitle = configuration.getString("top-list-title"); - if (oldTitle != null && oldTitle.equalsIgnoreCase("Top [x]")) { - configuration.set("top-list-title", "Top"); - } - } - - /** - * Adjusts some of the default colors to migrate from versions 2 - * or 3 to version 4 and above. - */ - private void updateDefaultColors(YamlConfiguration configuration) { - updateColor(configuration, "top-list.title", "yellow", "#FFD52B"); - updateColor(configuration, "top-list.title", "#FFEA40", "#FFD52B"); - updateColor(configuration, "top-list.stat-names", "yellow", "#FFD52B"); - updateColor(configuration, "top-list.stat-names", "#FFEA40", "#FFD52B"); - updateColor(configuration, "top-list.sub-stat-names", "#FFD52B", "yellow"); - - updateColor(configuration, "individual-statistics.stat-names", "yellow", "#FFD52B"); - updateColor(configuration, "individual-statistics.sub-stat-names", "#FFD52B", "yellow"); - updateColor(configuration, "total-server.title", "gold", "#55AAFF"); - updateColor(configuration, "total-server.server-name", "gold", "#55AAFF"); - updateColor(configuration, "total-server.stat-names", "yellow", "#FFD52B"); - updateColor(configuration, "total-server.sub-stat-names", "#FFD52B", "yellow"); - } - - private void updateColor(YamlConfiguration configuration, String path, String oldValue, String newValue) { - String configString = configuration.getString(path); - if (configString != null && configString.equalsIgnoreCase(oldValue)) { - configuration.set(path, newValue); - } - } -} \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/config/DefaultValueGetter.java b/src/main/java/com/artemis/the/gr8/playerstats/config/DefaultValueGetter.java new file mode 100644 index 0000000..b0038dd --- /dev/null +++ b/src/main/java/com/artemis/the/gr8/playerstats/config/DefaultValueGetter.java @@ -0,0 +1,56 @@ +package com.artemis.the.gr8.playerstats.config; + +import org.bukkit.configuration.file.FileConfiguration; + +import java.util.HashMap; +import java.util.Map; + +public class DefaultValueGetter { + + private final FileConfiguration config; + private final Map defaultValuesToAdjust; + + public DefaultValueGetter(FileConfiguration configuration) { + config = configuration; + defaultValuesToAdjust = new HashMap<>(); + } + + public Map getValuesToAdjust() { + checkTopListDefault(); + checkDefaultColors(); + return defaultValuesToAdjust; + } + + private void checkTopListDefault() { + String oldTitle = config.getString("top-list-title"); + if (oldTitle != null && oldTitle.equalsIgnoreCase("Top [x]")) { + defaultValuesToAdjust.put("top-list-title", "Top"); + } + } + + /** + * Adjusts some of the default colors to migrate from versions 2 + * or 3 to version 4 and above. + */ + private void checkDefaultColors() { + addValueIfNeeded("top-list.title", "yellow", "#FFD52B"); + addValueIfNeeded("top-list.title", "#FFEA40", "#FFD52B"); + addValueIfNeeded("top-list.stat-names", "yellow", "#FFD52B"); + addValueIfNeeded("top-list.stat-names", "#FFEA40", "#FFD52B"); + addValueIfNeeded("top-list.sub-stat-names", "#FFD52B", "yellow"); + + addValueIfNeeded("individual-statistics.stat-names", "yellow", "#FFD52B"); + addValueIfNeeded("individual-statistics.sub-stat-names", "#FFD52B", "yellow"); + addValueIfNeeded("total-server.title", "gold", "#55AAFF"); + addValueIfNeeded("total-server.server-name", "gold", "#55AAFF"); + addValueIfNeeded("total-server.stat-names", "yellow", "#FFD52B"); + addValueIfNeeded("total-server.sub-stat-names", "#FFD52B", "yellow"); + } + + private void addValueIfNeeded(String path, String oldValue, String newValue) { + String configString = config.getString(path); + if (configString != null && configString.equalsIgnoreCase(oldValue)) { + defaultValuesToAdjust.put(path, newValue); + } + } +} diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentUtils.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentUtils.java index c5fc688..590b706 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentUtils.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentUtils.java @@ -1,5 +1,6 @@ package com.artemis.the.gr8.playerstats.msg.components; +import com.artemis.the.gr8.playerstats.Main; import com.artemis.the.gr8.playerstats.msg.msgutils.LanguageKeyHandler; import com.artemis.the.gr8.playerstats.msg.msgutils.StringUtils; import net.kyori.adventure.text.*; @@ -61,14 +62,14 @@ public final class ComponentUtils { } else if (!LanguageKeyHandler.isKeyForEntityKilledByArg(translatable.key())) { totalPrettyName.append( - LanguageKeyHandler.getStatKeyTranslation( + Main.getLanguageKeyHandler().getStatKeyTranslation( translatable.key())); } } }); } else if (trans.key().startsWith("stat")) { - return LanguageKeyHandler.getStatKeyTranslation(trans.key()); + return Main.getLanguageKeyHandler().getStatKeyTranslation(trans.key()); } else { return StringUtils.prettify(LanguageKeyHandler.convertToName(trans.key())); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/LanguageKeyHandler.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/LanguageKeyHandler.java index 46afe4c..c40f3f7 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/LanguageKeyHandler.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/LanguageKeyHandler.java @@ -1,19 +1,14 @@ package com.artemis.the.gr8.playerstats.msg.msgutils; -import com.artemis.the.gr8.playerstats.Main; import com.artemis.the.gr8.playerstats.utils.EnumHandler; -import com.artemis.the.gr8.playerstats.utils.MyLogger; +import com.artemis.the.gr8.playerstats.utils.FileHandler; import com.artemis.the.gr8.playerstats.enums.Unit; import org.bukkit.Material; import org.bukkit.Statistic; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.EntityType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.ApiStatus.Internal; -import java.io.File; import java.util.Arrays; import java.util.HashMap; @@ -22,42 +17,18 @@ import java.util.HashMap; * A utility class that provides language keys to be * put in a TranslatableComponent. */ -public final class LanguageKeyHandler { +public final class LanguageKeyHandler extends FileHandler { - private static Main plugin; private static HashMap statNameKeys; - private static File languageKeyFile; - private static FileConfiguration languageKeys; /** - * Since this class uses a file to get the English translations - * of languageKeys, it needs an instance of the PlayerStats + * This class uses a file to get the English translations + * of languageKeys, and uses an instance of the PlayerStats * plugin to get access to this file. - * - * @param plugin an instance of PlayerStats' Main class */ - public LanguageKeyHandler(Main plugin) { - LanguageKeyHandler.plugin = plugin; + public LanguageKeyHandler() { + super("language.yml"); statNameKeys = generateStatNameKeys(); - loadFile(); - } - - private static void loadFile() { - languageKeyFile = new File(plugin.getDataFolder(), "language.yml"); - if (!languageKeyFile.exists()) { - plugin.saveResource("language.yml", false); - } - languageKeys = YamlConfiguration.loadConfiguration(languageKeyFile); - } - - @Internal - public static void reloadFile() { - if (!languageKeyFile.exists()) { - loadFile(); - } else { - languageKeys = YamlConfiguration.loadConfiguration(languageKeyFile); - MyLogger.logLowLevelMsg("Language file reloaded!"); - } } /** @@ -183,12 +154,12 @@ public final class LanguageKeyHandler { } } - public static String getStatKeyTranslation(String statKey) { + public String getStatKeyTranslation(String statKey) { String realKey = convertToNormalStatKey(statKey); if (realKey == null) { return ""; } - return languageKeys.getString(realKey); + return super.getFileConfiguration().getString(statKey); } /** diff --git a/src/main/java/com/artemis/the/gr8/playerstats/reload/ReloadThread.java b/src/main/java/com/artemis/the/gr8/playerstats/reload/ReloadThread.java index 69d3e7b..b45ab78 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/reload/ReloadThread.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/reload/ReloadThread.java @@ -1,10 +1,10 @@ package com.artemis.the.gr8.playerstats.reload; +import com.artemis.the.gr8.playerstats.Main; import com.artemis.the.gr8.playerstats.ShareManager; import com.artemis.the.gr8.playerstats.ThreadManager; import com.artemis.the.gr8.playerstats.enums.StandardMessage; import com.artemis.the.gr8.playerstats.msg.OutputManager; -import com.artemis.the.gr8.playerstats.msg.msgutils.LanguageKeyHandler; import com.artemis.the.gr8.playerstats.statistic.StatCalculator; import com.artemis.the.gr8.playerstats.statistic.StatThread; import com.artemis.the.gr8.playerstats.utils.MyLogger; @@ -69,7 +69,7 @@ public final class ReloadThread extends Thread { } } - if (reloadThreadID != 1 && config.reloadConfig()) { //during a reload + if (reloadThreadID != 1) { //during a reload MyLogger.logLowLevelMsg("Reloading!"); reloadEverything(); @@ -85,8 +85,10 @@ public final class ReloadThread extends Thread { } private void reloadEverything() { + config.reload(); MyLogger.setDebugLevel(config.getDebugLevel()); - LanguageKeyHandler.reloadFile(); + Main.getLanguageKeyHandler().reload(); + Main.getOfflinePlayerHandler().reload(); OutputManager.updateMessageBuilders(); OfflinePlayerHandler.updateOfflinePlayerList(loadOfflinePlayers()); ShareManager.updateSettings(config); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/utils/FileHandler.java b/src/main/java/com/artemis/the/gr8/playerstats/utils/FileHandler.java new file mode 100644 index 0000000..ebe26b3 --- /dev/null +++ b/src/main/java/com/artemis/the/gr8/playerstats/utils/FileHandler.java @@ -0,0 +1,77 @@ +package com.artemis.the.gr8.playerstats.utils; + +import com.artemis.the.gr8.playerstats.Main; +import com.tchristofferson.configupdater.ConfigUpdater; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.plugin.java.JavaPlugin; +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.io.IOException; +import java.util.Map; + +public abstract class FileHandler { + + private final String fileName; + private File file; + private FileConfiguration fileConfiguration; + + public FileHandler(String fileName) { + this.fileName = fileName; + loadFile(); + } + + public void loadFile() { + JavaPlugin plugin = Main.getPluginInstance(); + + file = new File(plugin.getDataFolder(), fileName); + if (!file.exists()) { + plugin.saveResource(fileName, false); + } + fileConfiguration = YamlConfiguration.loadConfiguration(file); + } + + public void reload() { + if (!file.exists()) { + loadFile(); + } else { + fileConfiguration = YamlConfiguration.loadConfiguration(file); + MyLogger.logLowLevelMsg(fileName + " reloaded!"); + } + } + + public FileConfiguration getFileConfiguration() { + return fileConfiguration; + } + + /** + * Add new key-value pairs to the config without losing comments, + * using tchristofferson's Config-Updater + */ + public void updateFile() { + JavaPlugin plugin = Main.getPluginInstance(); + try { + ConfigUpdater.update(plugin, fileName, file); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void addValues(@NotNull Map keyValuePairs) { + keyValuePairs.forEach(this::addValue); + save(); + } + + private void addValue(String key, Object value) { + fileConfiguration.set(key, value); + } + + private void save() { + try { + fileConfiguration.save(file); + } catch (IOException e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/utils/OfflinePlayerHandler.java b/src/main/java/com/artemis/the/gr8/playerstats/utils/OfflinePlayerHandler.java index 93d2e06..b889e03 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/utils/OfflinePlayerHandler.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/utils/OfflinePlayerHandler.java @@ -12,16 +12,23 @@ import java.util.concurrent.ConcurrentHashMap; * calculations, and can retrieve the corresponding OfflinePlayer * object for a given player-name. */ -public final class OfflinePlayerHandler { +public final class OfflinePlayerHandler extends FileHandler { private static ConcurrentHashMap offlinePlayerUUIDs; private static ArrayList playerNames; public OfflinePlayerHandler() { + super("excluded_players.yml"); offlinePlayerUUIDs = new ConcurrentHashMap<>(); playerNames = new ArrayList<>(); } + @Override + public void reload() { + super.reload(); + + } + /** * Get a new HashMap that stores the players to include in stat calculations. * This HashMap is stored as a private variable in OfflinePlayerHandler. diff --git a/src/main/resources/excluded_players.yml b/src/main/resources/excluded_players.yml new file mode 100644 index 0000000..081fa79 --- /dev/null +++ b/src/main/resources/excluded_players.yml @@ -0,0 +1,10 @@ +# ------------------------------------------------------------------------------------------------------ # +# PlayerStats Excluded Players # +# ------------------------------------------------------------------------------------------------------ # + +# Players whose UUIDs are stored in this file, will not be included in /statistic results. +# This can be used for more fine-grained filtering, for example to exclude alt accounts. +# For more general filtering settings, see the config.yml + +excluded: + - \ No newline at end of file From 9ac77a365b3f9799f4f17e9790e6116e7f3f3904 Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Mon, 3 Oct 2022 15:40:45 +0200 Subject: [PATCH 02/43] Separated initial plugin set-up from reloading and organized responsibilities better for the OfflinePlayerHandler, ThreadManager and the classes implementing FileHandler --- .../com/artemis/the/gr8/playerstats/Main.java | 2 +- .../the/gr8/playerstats/ThreadManager.java | 2 - .../gr8/playerstats/msg/MessageBuilder.java | 1 + ...eloadAction.java => PlayerLoadAction.java} | 14 ++-- .../gr8/playerstats/reload/ReloadThread.java | 80 +++---------------- .../playerstats/statistic/StatCalculator.java | 2 +- .../the/gr8/playerstats/utils/MyLogger.java | 27 +++---- .../utils/OfflinePlayerHandler.java | 76 ++++++++++++++---- src/main/resources/excluded_players.yml | 2 +- src/main/resources/language.yml | 3 + 10 files changed, 95 insertions(+), 114 deletions(-) rename src/main/java/com/artemis/the/gr8/playerstats/reload/{ReloadAction.java => PlayerLoadAction.java} (81%) diff --git a/src/main/java/com/artemis/the/gr8/playerstats/Main.java b/src/main/java/com/artemis/the/gr8/playerstats/Main.java index 96a1be4..9bbd89b 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/Main.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/Main.java @@ -168,7 +168,7 @@ public final class Main extends JavaPlugin { config = new ConfigHandler(); enumHandler = new EnumHandler(); languageKeyHandler = new LanguageKeyHandler(); - offlinePlayerHandler = new OfflinePlayerHandler(); + offlinePlayerHandler = new OfflinePlayerHandler(config); shareManager = new ShareManager(config); statCalculator = new StatCalculator(offlinePlayerHandler); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/ThreadManager.java b/src/main/java/com/artemis/the/gr8/playerstats/ThreadManager.java index 4ea77da..8561be0 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/ThreadManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/ThreadManager.java @@ -45,8 +45,6 @@ public final class ThreadManager { statThreadID = 0; reloadThreadID = 0; lastRecordedCalcTime = 0; - - startReloadThread(null); } public static int getTaskThreshold() { diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java index 3f73883..3607644 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java @@ -512,6 +512,7 @@ public final class MessageBuilder implements ApiFormatter { return componentFactory.statAndSubStatNameTranslatable(statKey, subStatKey, target); } + //TODO turn key into custom input from file String prettyStatName = StringUtils.prettify(statistic.toString()); String prettySubStatName = StringUtils.prettify(subStatName); return componentFactory.statAndSubStatName(prettyStatName, prettySubStatName, target); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/reload/ReloadAction.java b/src/main/java/com/artemis/the/gr8/playerstats/reload/PlayerLoadAction.java similarity index 81% rename from src/main/java/com/artemis/the/gr8/playerstats/reload/ReloadAction.java rename to src/main/java/com/artemis/the/gr8/playerstats/reload/PlayerLoadAction.java index 4ae0515..6d3dc4f 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/reload/ReloadAction.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/reload/PlayerLoadAction.java @@ -13,7 +13,7 @@ import java.util.concurrent.RecursiveAction; /** * The action that is executed when a reload-command is triggered. */ -final class ReloadAction extends RecursiveAction { +public final class PlayerLoadAction extends RecursiveAction { private static int threshold; @@ -33,14 +33,14 @@ final class ReloadAction extends RecursiveAction { * @param offlinePlayerUUIDs the ConcurrentHashMap to put playerNames and UUIDs in * @see OfflinePlayerHandler */ - public ReloadAction(OfflinePlayer[] players, - int lastPlayedLimit, ConcurrentHashMap offlinePlayerUUIDs) { + public PlayerLoadAction(OfflinePlayer[] players, + int lastPlayedLimit, ConcurrentHashMap offlinePlayerUUIDs) { this(players, 0, players.length, lastPlayedLimit, offlinePlayerUUIDs); } - private ReloadAction(OfflinePlayer[] players, int start, int end, - int lastPlayedLimit, ConcurrentHashMap offlinePlayerUUIDs) { + private PlayerLoadAction(OfflinePlayer[] players, int start, int end, + int lastPlayedLimit, ConcurrentHashMap offlinePlayerUUIDs) { threshold = ThreadManager.getTaskThreshold(); this.players = players; @@ -61,9 +61,9 @@ final class ReloadAction extends RecursiveAction { } else { final int split = length / 2; - final ReloadAction subTask1 = new ReloadAction(players, start, (start + split), + final PlayerLoadAction subTask1 = new PlayerLoadAction(players, start, (start + split), lastPlayedLimit, offlinePlayerUUIDs); - final ReloadAction subTask2 = new ReloadAction(players, (start + split), end, + final PlayerLoadAction subTask2 = new PlayerLoadAction(players, (start + split), end, lastPlayedLimit, offlinePlayerUUIDs); //queue and compute all subtasks in the right order diff --git a/src/main/java/com/artemis/the/gr8/playerstats/reload/ReloadThread.java b/src/main/java/com/artemis/the/gr8/playerstats/reload/ReloadThread.java index b45ab78..1ca1910 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/reload/ReloadThread.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/reload/ReloadThread.java @@ -2,25 +2,17 @@ package com.artemis.the.gr8.playerstats.reload; import com.artemis.the.gr8.playerstats.Main; import com.artemis.the.gr8.playerstats.ShareManager; -import com.artemis.the.gr8.playerstats.ThreadManager; import com.artemis.the.gr8.playerstats.enums.StandardMessage; import com.artemis.the.gr8.playerstats.msg.OutputManager; +import com.artemis.the.gr8.playerstats.msg.msgutils.LanguageKeyHandler; import com.artemis.the.gr8.playerstats.statistic.StatCalculator; import com.artemis.the.gr8.playerstats.statistic.StatThread; import com.artemis.the.gr8.playerstats.utils.MyLogger; import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; import com.artemis.the.gr8.playerstats.config.ConfigHandler; import com.artemis.the.gr8.playerstats.enums.DebugLevel; -import org.bukkit.Bukkit; -import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandSender; import org.jetbrains.annotations.Nullable; -import java.util.Arrays; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ForkJoinPool; -import java.util.function.Predicate; /** The Thread that is in charge of reloading PlayerStats. */ public final class ReloadThread extends Thread { @@ -28,35 +20,31 @@ public final class ReloadThread extends Thread { private static ConfigHandler config; private static OutputManager outputManager; - private final int reloadThreadID; private final StatThread statThread; - private final CommandSender sender; public ReloadThread(ConfigHandler c, OutputManager m, int ID, @Nullable StatThread s, @Nullable CommandSender se) { config = c; outputManager = m; - reloadThreadID = ID; statThread = s; sender = se; - this.setName("ReloadThread-" + reloadThreadID); + this.setName("ReloadThread-" + ID); MyLogger.logHighLevelMsg(this.getName() + " created!"); } /** * This method will perform a series of tasks. If a {@link StatThread} * is still running, it will join the statThread and wait for it to finish. - * Then, it will reload the config, update the offlinePlayerList in the - * {@link OfflinePlayerHandler}, update the {@link DebugLevel}, update + * Then, it will reload the config, update the {@link LanguageKeyHandler}, + * the {@link OfflinePlayerHandler}, the {@link DebugLevel}, update * the share-settings in {@link ShareManager} and topListSize-settings * in {@link StatCalculator}, and update the MessageBuilders in the * {@link OutputManager}. */ @Override public void run() { - long time = System.currentTimeMillis(); MyLogger.logHighLevelMsg(this.getName() + " started!"); if (statThread != null && statThread.isAlive()) { @@ -69,18 +57,11 @@ public final class ReloadThread extends Thread { } } - if (reloadThreadID != 1) { //during a reload - MyLogger.logLowLevelMsg("Reloading!"); - reloadEverything(); + MyLogger.logLowLevelMsg("Reloading!"); + reloadEverything(); - if (sender != null) { - outputManager.sendFeedbackMsg(sender, StandardMessage.RELOADED_CONFIG); - } - } - else { //during first start-up - MyLogger.setDebugLevel(config.getDebugLevel()); - OfflinePlayerHandler.updateOfflinePlayerList(loadOfflinePlayers()); - ThreadManager.recordCalcTime(System.currentTimeMillis() - time); + if (sender != null) { + outputManager.sendFeedbackMsg(sender, StandardMessage.RELOADED_CONFIG); } } @@ -89,51 +70,8 @@ public final class ReloadThread extends Thread { MyLogger.setDebugLevel(config.getDebugLevel()); Main.getLanguageKeyHandler().reload(); Main.getOfflinePlayerHandler().reload(); + OutputManager.updateMessageBuilders(); - OfflinePlayerHandler.updateOfflinePlayerList(loadOfflinePlayers()); ShareManager.updateSettings(config); } - - private ConcurrentHashMap loadOfflinePlayers() { - long time = System.currentTimeMillis(); - - OfflinePlayer[] offlinePlayers; - if (config.whitelistOnly()) { - offlinePlayers = Bukkit.getWhitelistedPlayers().toArray(OfflinePlayer[]::new); - MyLogger.logMediumLevelTask("ReloadThread", - "retrieved whitelist", time); - } - else if (config.excludeBanned()) { - if (Bukkit.getPluginManager().getPlugin("LiteBans") != null) { - offlinePlayers = Arrays.stream(Bukkit.getOfflinePlayers()) - .parallel() - .filter(Predicate.not(OfflinePlayer::isBanned)) - .toArray(OfflinePlayer[]::new); - } else { - Set bannedPlayers = Bukkit.getBannedPlayers(); - offlinePlayers = Arrays.stream(Bukkit.getOfflinePlayers()) - .parallel() - .filter(offlinePlayer -> !bannedPlayers.contains(offlinePlayer)).toArray(OfflinePlayer[]::new); - } - MyLogger.logMediumLevelTask("ReloadThread", - "retrieved banlist", time); - } - else { - offlinePlayers = Bukkit.getOfflinePlayers(); - MyLogger.logMediumLevelTask("ReloadThread", - "retrieved list of Offline Players", time); - } - - int size = offlinePlayers != null ? offlinePlayers.length : 16; - ConcurrentHashMap playerMap = new ConcurrentHashMap<>(size); - - ReloadAction task = new ReloadAction(offlinePlayers, config.getLastPlayedLimit(), playerMap); - MyLogger.actionCreated((offlinePlayers != null) ? offlinePlayers.length : 0); - ForkJoinPool.commonPool().invoke(task); - MyLogger.actionFinished(); - - MyLogger.logLowLevelTask("ReloadThread", - ("loaded " + playerMap.size() + " offline players"), time); - return playerMap; - } } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatCalculator.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatCalculator.java index 67e0a7a..78b4573 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatCalculator.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatCalculator.java @@ -67,7 +67,7 @@ public final class StatCalculator { MyLogger.actionFinished(); ThreadManager.recordCalcTime(System.currentTimeMillis() - time); - MyLogger.logMediumLevelTask("StatThread", "calculated all stats", time); + MyLogger.logMediumLevelTask("Calculated all stats", time); return allStats; } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/utils/MyLogger.java b/src/main/java/com/artemis/the/gr8/playerstats/utils/MyLogger.java index 0685903..4ab5838 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/utils/MyLogger.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/utils/MyLogger.java @@ -53,12 +53,22 @@ public final class MyLogger { logger.info(content); } + public static void logLowLevelTask(String taskName, long startTime) { + printTime(taskName, startTime); + } + public static void logMediumLevelMsg(String content) { if (debugLevel != DebugLevel.LOW) { logger.info(content); } } + public static void logMediumLevelTask(String taskName, long startTime) { + if (debugLevel != DebugLevel.LOW) { + printTime(taskName, startTime); + } + } + public static void logHighLevelMsg(String content) { if (debugLevel == DebugLevel.HIGH) { logger.info(content); @@ -146,24 +156,13 @@ public final class MyLogger { } } - 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 taskName name of the task that has been executed * @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"); + private static void printTime(String taskName, long startTime) { + logger.info(taskName + " (" + (System.currentTimeMillis() - startTime) + "ms)"); } } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/utils/OfflinePlayerHandler.java b/src/main/java/com/artemis/the/gr8/playerstats/utils/OfflinePlayerHandler.java index b889e03..f6765f7 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/utils/OfflinePlayerHandler.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/utils/OfflinePlayerHandler.java @@ -1,10 +1,15 @@ package com.artemis.the.gr8.playerstats.utils; +import com.artemis.the.gr8.playerstats.config.ConfigHandler; +import com.artemis.the.gr8.playerstats.reload.PlayerLoadAction; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ForkJoinPool; +import java.util.function.Predicate; /** * A utility class that deals with OfflinePlayers. It stores a list @@ -14,30 +19,20 @@ import java.util.concurrent.ConcurrentHashMap; */ public final class OfflinePlayerHandler extends FileHandler { - private static ConcurrentHashMap offlinePlayerUUIDs; - private static ArrayList playerNames; + private static ConfigHandler config; + private ConcurrentHashMap offlinePlayerUUIDs; + private ArrayList playerNames; - public OfflinePlayerHandler() { + public OfflinePlayerHandler(ConfigHandler configHandler) { super("excluded_players.yml"); - offlinePlayerUUIDs = new ConcurrentHashMap<>(); - playerNames = new ArrayList<>(); + config = configHandler; + loadOfflinePlayers(); } @Override public void reload() { super.reload(); - - } - - /** - * 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 playerList) { - offlinePlayerUUIDs = playerList; - playerNames = Collections.list(offlinePlayerUUIDs.keys()); + loadOfflinePlayers(); } /** @@ -91,4 +86,51 @@ public final class OfflinePlayerHandler extends FileHandler { throw new IllegalArgumentException("Cannot convert this player-name into a valid Player to calculate statistics for"); } } + + private void loadOfflinePlayers() { + Executors.newSingleThreadExecutor().execute(() -> { + long time = System.currentTimeMillis(); + + OfflinePlayer[] offlinePlayers; + if (config.whitelistOnly()) { + offlinePlayers = getWhitelistedPlayers(); + } + else if (config.excludeBanned()) { + offlinePlayers = getNonBannedPlayers(); + } + else { + offlinePlayers = Bukkit.getOfflinePlayers(); + } + + int size = offlinePlayerUUIDs != null ? offlinePlayerUUIDs.size() : 16; + offlinePlayerUUIDs = new ConcurrentHashMap<>(size); + + PlayerLoadAction task = new PlayerLoadAction(offlinePlayers, config.getLastPlayedLimit(), offlinePlayerUUIDs); + MyLogger.actionCreated(offlinePlayers != null ? offlinePlayers.length : 0); + ForkJoinPool.commonPool().invoke(task); + MyLogger.actionFinished(); + + playerNames = Collections.list(offlinePlayerUUIDs.keys()); + MyLogger.logLowLevelTask(("Loaded " + offlinePlayerUUIDs.size() + " offline players"), time); + }); + } + + private OfflinePlayer[] getWhitelistedPlayers() { + return Bukkit.getWhitelistedPlayers().toArray(OfflinePlayer[]::new); + } + + private OfflinePlayer[] getNonBannedPlayers() { + if (Bukkit.getPluginManager().isPluginEnabled("LiteBans")) { + return Arrays.stream(Bukkit.getOfflinePlayers()) + .parallel() + .filter(Predicate.not(OfflinePlayer::isBanned)) + .toArray(OfflinePlayer[]::new); + } + + Set banList = Bukkit.getBannedPlayers(); + return Arrays.stream(Bukkit.getOfflinePlayers()) + .parallel() + .filter(Predicate.not(banList::contains)) + .toArray(OfflinePlayer[]::new); + } } \ No newline at end of file diff --git a/src/main/resources/excluded_players.yml b/src/main/resources/excluded_players.yml index 081fa79..05cfef6 100644 --- a/src/main/resources/excluded_players.yml +++ b/src/main/resources/excluded_players.yml @@ -4,7 +4,7 @@ # Players whose UUIDs are stored in this file, will not be included in /statistic results. # This can be used for more fine-grained filtering, for example to exclude alt accounts. -# For more general filtering settings, see the config.yml +# For more general filtering settings, see the config.yml (section 'General') excluded: - \ No newline at end of file diff --git a/src/main/resources/language.yml b/src/main/resources/language.yml index 23ee04b..b6aee02 100644 --- a/src/main/resources/language.yml +++ b/src/main/resources/language.yml @@ -2,6 +2,9 @@ # PlayerStats Language File # # ------------------------------------------------------------------------------------------------------ # +# If "translate-to-client-language" in the config.yml is set to false (section 'Format & Display'), +# values from this file will be used instead + stat_type.minecraft.mined: "Times Mined" stat_type.minecraft.crafted: "Times Crafted" stat_type.minecraft.used: "Times Used" From 2c7717a20c28528bfa92f5ba291ad3f98a333f66 Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Tue, 4 Oct 2022 16:48:09 +0200 Subject: [PATCH 03/43] Fixed language bugs (#123), improved LanguageKeyHandler, ComponentUtils and StringUtils --- .../com/artemis/the/gr8/playerstats/Main.java | 65 ++++---- .../gr8/playerstats/msg/MessageBuilder.java | 118 +++++++------- .../msg/components/ComponentFactory.java | 10 +- .../msg/components/ComponentUtils.java | 32 ++-- .../msg/msgutils/LanguageKeyHandler.java | 149 ++++++++++-------- .../playerstats/msg/msgutils/StringUtils.java | 12 +- .../statistic/request/PlayerStatRequest.java | 2 +- .../statistic/request/ServerStatRequest.java | 2 +- .../statistic/request/TopStatRequest.java | 2 +- 9 files changed, 208 insertions(+), 184 deletions(-) diff --git a/src/main/java/com/artemis/the/gr8/playerstats/Main.java b/src/main/java/com/artemis/the/gr8/playerstats/Main.java index 9bbd89b..655f669 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/Main.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/Main.java @@ -81,18 +81,6 @@ public final class Main extends JavaPlugin { this.getLogger().info("Disabled PlayerStats!"); } - /** - * - * @return the JavaPlugin instance associated with PlayerStats - * @throws IllegalStateException if PlayerStats is not enabled - */ - public static @NotNull JavaPlugin getPluginInstance() throws IllegalStateException { - if (pluginInstance == null) { - throw new IllegalStateException("PlayerStats is not loaded!"); - } - return pluginInstance; - } - /** * @return Adventure's BukkitAudiences object * @throws IllegalStateException if PlayerStats is not enabled @@ -105,19 +93,44 @@ public final class Main extends JavaPlugin { } /** - * @return PlayerStats' ConfigHandler + * + * @return the JavaPlugin instance associated with PlayerStats * @throws IllegalStateException if PlayerStats is not enabled */ - public static @NotNull ConfigHandler getConfigHandler() throws IllegalStateException { - if (config == null) { + public static @NotNull JavaPlugin getPluginInstance() throws IllegalStateException { + if (pluginInstance == null) { + throw new IllegalStateException("PlayerStats is not loaded!"); + } + return pluginInstance; + } + + public static @NotNull PlayerStats getPlayerStatsAPI() throws IllegalStateException { + if (playerStatsAPI == null) { throw new IllegalStateException("PlayerStats does not seem to be loaded!"); } + return playerStatsAPI; + } + + public static @NotNull InternalFormatter getOutputManager() throws IllegalStateException { + if (outputManager == null) { + throw new IllegalStateException("PlayerStats does not seem to be loaded!"); + } + return outputManager; + } + + /** + * @return PlayerStats' ConfigHandler + */ + public static @NotNull ConfigHandler getConfigHandler() { + if (config == null) { + config = new ConfigHandler(); + } return config; } - public static @NotNull OfflinePlayerHandler getOfflinePlayerHandler() throws IllegalStateException { + public static @NotNull OfflinePlayerHandler getOfflinePlayerHandler() { if (offlinePlayerHandler == null) { - throw new IllegalStateException("PlayerStats does not seem to be loaded!"); + offlinePlayerHandler = new OfflinePlayerHandler(getConfigHandler()); } return offlinePlayerHandler; } @@ -140,27 +153,13 @@ public final class Main extends JavaPlugin { return enumHandler; } - public static @NotNull StatCalculator getStatCalculator() throws IllegalStateException { + public static @NotNull StatCalculator getStatCalculator() { if (statCalculator == null) { - throw new IllegalStateException("PlayerStats does not seem to be loaded!"); + statCalculator = new StatCalculator(getOfflinePlayerHandler()); } return statCalculator; } - public static @NotNull InternalFormatter getStatFormatter() throws IllegalStateException { - if (outputManager == null) { - throw new IllegalStateException("PlayerStats does not seem to be loaded!"); - } - return outputManager; - } - - public static @NotNull PlayerStats getPlayerStatsAPI() throws IllegalStateException { - if (playerStatsAPI == null) { - throw new IllegalStateException("PlayerStats does not seem to be loaded!"); - } - return playerStatsAPI; - } - private void initializeMainClasses() { pluginInstance = this; adventure = BukkitAudiences.create(this); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java index 3607644..8d31819 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java @@ -20,6 +20,7 @@ import net.kyori.adventure.text.TextComponent; import org.bukkit.Statistic; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -61,11 +62,13 @@ public final class MessageBuilder implements ApiFormatter { languageKeyHandler = Main.getLanguageKeyHandler(); } - public static MessageBuilder defaultBuilder(ConfigHandler config) { + @Contract("_ -> new") + public static @NotNull MessageBuilder defaultBuilder(ConfigHandler config) { return new MessageBuilder(config); } - public static MessageBuilder fromComponentFactory(ConfigHandler config, ComponentFactory factory) { + @Contract("_, _ -> new") + public static @NotNull MessageBuilder fromComponentFactory(ConfigHandler config, ComponentFactory factory) { return new MessageBuilder(config, factory); } @@ -103,20 +106,20 @@ public final class MessageBuilder implements ApiFormatter { return pride.pluginPrefixAsTitle(); } - public TextComponent reloadedConfig() { + public @NotNull TextComponent reloadedConfig() { return componentFactory.pluginPrefix() .append(space()) .append(componentFactory.message().content("Config reloaded!")); } - public TextComponent stillReloading() { + public @NotNull TextComponent stillReloading() { return componentFactory.pluginPrefix() .append(space()) .append(componentFactory.message().content( "The plugin is (re)loading, your request will be processed when it is done!")); } - public TextComponent waitAMoment(boolean longWait) { + public @NotNull TextComponent waitAMoment(boolean longWait) { String msg = longWait ? "Calculating statistics, this may take a minute..." : "Calculating statistics, this may take a few moments..."; return componentFactory.pluginPrefix() @@ -124,28 +127,28 @@ public final class MessageBuilder implements ApiFormatter { .append(componentFactory.message().content(msg)); } - public TextComponent missingStatName() { + public @NotNull TextComponent missingStatName() { return componentFactory.pluginPrefix() .append(space()) .append(componentFactory.message().content( "Please provide a valid statistic name!")); } - public TextComponent missingSubStatName(Statistic.Type statType) { + public @NotNull TextComponent missingSubStatName(Statistic.Type statType) { return componentFactory.pluginPrefix() .append(space()) .append(componentFactory.message().content( "Please add a valid " + EnumHandler.getSubStatTypeName(statType) + " to look up this statistic!")); } - public TextComponent missingPlayerName() { + public @NotNull TextComponent missingPlayerName() { return componentFactory.pluginPrefix() .append(space()) .append(componentFactory.message().content( "Please specify a valid player-name!")); } - public TextComponent wrongSubStatType(Statistic.Type statType, String subStatName) { + public @NotNull TextComponent wrongSubStatType(Statistic.Type statType, String subStatName) { return componentFactory.pluginPrefix() .append(space()) .append(componentFactory.messageAccent().content("\"" + subStatName + "\"")) @@ -154,14 +157,14 @@ public final class MessageBuilder implements ApiFormatter { "is not a valid " + EnumHandler.getSubStatTypeName(statType) + "!")); } - public TextComponent requestAlreadyRunning() { + public @NotNull TextComponent requestAlreadyRunning() { return componentFactory.pluginPrefix() .append(space()) .append(componentFactory.message().content( "Please wait for your previous lookup to finish!")); } - public TextComponent stillOnShareCoolDown() { + public @NotNull TextComponent stillOnShareCoolDown() { int waitTime = config.getStatShareWaitingTime(); String minutes = waitTime == 1 ? " minute" : " minutes"; @@ -175,20 +178,20 @@ public final class MessageBuilder implements ApiFormatter { .append(text("between sharing!"))); } - public TextComponent resultsAlreadyShared() { + public @NotNull TextComponent resultsAlreadyShared() { return componentFactory.pluginPrefix() .append(space()) .append(componentFactory.message().content("You already shared these results!")); } - public TextComponent statResultsTooOld() { + public @NotNull TextComponent statResultsTooOld() { return componentFactory.pluginPrefix() .append(space()) .append(componentFactory.message().content( "It has been too long since you looked up this statistic, please repeat the original command!")); } - public TextComponent unknownError() { + public @NotNull TextComponent unknownError() { return componentFactory.pluginPrefix() .append(space()) .append(componentFactory.message().content( @@ -196,7 +199,8 @@ public final class MessageBuilder implements ApiFormatter { "please try again or see /statistic for a usage explanation!")); } - public TextComponent usageExamples() { + @Contract(" -> new") + public @NotNull TextComponent usageExamples() { return ExampleMessage.construct(componentFactory); } @@ -210,33 +214,33 @@ public final class MessageBuilder implements ApiFormatter { } @Override - public TextComponent getStatTitle(Statistic statistic, @Nullable String subStatName) { + public @NotNull TextComponent getStatTitle(Statistic statistic, @Nullable String subStatName) { return getTopStatTitleComponent(0, statistic, subStatName, null); } @Override - public TextComponent getStatTitle(Statistic statistic, Unit unit) { + public @NotNull TextComponent getStatTitle(Statistic statistic, Unit unit) { return getTopStatTitleComponent(0, statistic, null, unit); } @Override - public TextComponent getTopStatTitle(int topListSize, Statistic statistic, @Nullable String subStatName) { + public @NotNull TextComponent getTopStatTitle(int topListSize, Statistic statistic, @Nullable String subStatName) { return getTopStatTitleComponent(topListSize, statistic, subStatName, null); } @Override - public TextComponent getTopStatTitle(int topStatSize, Statistic statistic, Unit unit) { + public @NotNull TextComponent getTopStatTitle(int topStatSize, Statistic statistic, Unit unit) { return getTopStatTitleComponent(topStatSize, statistic, null, unit); } @Override - public TextComponent formatTopStatLine(int positionInTopList, String playerName, long statNumber, Statistic statistic) { + public @NotNull TextComponent formatTopStatLine(int positionInTopList, String playerName, long statNumber, Statistic statistic) { TextComponent statNumberComponent = getStatNumberComponent(statNumber, Target.TOP, statistic); return getTopStatLineComponent(positionInTopList, playerName, statNumberComponent); } @Override - public TextComponent formatTopStatLine(int positionInTopList, String playerName, long statNumber, Unit unit) { + public @NotNull TextComponent formatTopStatLine(int positionInTopList, String playerName, long statNumber, Unit unit) { TextComponent statNumberComponent = getStatNumberComponent(statNumber, Target.TOP, unit); return getTopStatLineComponent(positionInTopList, playerName, statNumberComponent); } @@ -245,55 +249,55 @@ public final class MessageBuilder implements ApiFormatter { * Time-number does not hover */ @Override - public TextComponent formatTopStatLineForTypeTime(int positionInTopList, String playerName, long statNumber, Unit bigUnit, Unit smallUnit) { + public @NotNull TextComponent formatTopStatLineForTypeTime(int positionInTopList, String playerName, long statNumber, Unit bigUnit, Unit smallUnit) { TextComponent statNumberComponent = getBasicTimeNumberComponent(statNumber, Target.TOP, bigUnit, smallUnit); return getTopStatLineComponent(positionInTopList, playerName, statNumberComponent); } @Override - public TextComponent formatServerStat(long statNumber, Statistic statistic) { + public @NotNull TextComponent formatServerStat(long statNumber, Statistic statistic) { TextComponent statNumberComponent = getStatNumberComponent(statNumber, Target.SERVER, statistic); return getServerStatComponent(statNumberComponent, statistic, null, null); } @Override - public TextComponent formatServerStat(long statNumber, Statistic statistic, String subStatName) { + public @NotNull TextComponent formatServerStat(long statNumber, Statistic statistic, String subStatName) { TextComponent statNumberComponent = getStatNumberComponent(statNumber, Target.SERVER, statistic); return getServerStatComponent(statNumberComponent, statistic, subStatName, null); } @Override - public TextComponent formatServerStat(long statNumber, Statistic statistic, Unit unit) { + public @NotNull TextComponent formatServerStat(long statNumber, Statistic statistic, Unit unit) { TextComponent statNumberComponent = getStatNumberComponent(statNumber, Target.SERVER, unit); return getServerStatComponent(statNumberComponent, statistic, null, unit); } @Override - public TextComponent formatServerStatForTypeTime(long statNumber, Statistic statistic, Unit bigUnit, Unit smallUnit) { + public @NotNull TextComponent formatServerStatForTypeTime(long statNumber, Statistic statistic, Unit bigUnit, Unit smallUnit) { TextComponent statNumberComponent = getBasicTimeNumberComponent(statNumber, Target.SERVER, bigUnit, smallUnit); return getServerStatComponent(statNumberComponent, statistic, null, null); } @Override - public TextComponent formatPlayerStat(String playerName, int statNumber, Statistic statistic) { + public @NotNull TextComponent formatPlayerStat(String playerName, int statNumber, Statistic statistic) { TextComponent statNumberComponent = getStatNumberComponent(statNumber, Target.PLAYER, statistic); return getPlayerStatComponent(playerName, statNumberComponent, statistic, null, null); } @Override - public TextComponent formatPlayerStat(String playerName, int statNumber, Statistic statistic, Unit unit) { + public @NotNull TextComponent formatPlayerStat(String playerName, int statNumber, Statistic statistic, Unit unit) { TextComponent statNumberComponent = getStatNumberComponent(statNumber, Target.PLAYER, unit); return getPlayerStatComponent(playerName, statNumberComponent, statistic, null, unit); } @Override - public TextComponent formatPlayerStat(String playerName, int statNumber, Statistic statistic, String subStatName) { + public @NotNull TextComponent formatPlayerStat(String playerName, int statNumber, Statistic statistic, String subStatName) { TextComponent statNumberComponent = getStatNumberComponent(statNumber, Target.PLAYER, statistic); return getPlayerStatComponent(playerName, statNumberComponent, statistic, subStatName, null); } @Override - public TextComponent formatPlayerStatForTypeTime(String playerName, int statNumber, Statistic statistic, Unit bigUnit, Unit smallUnit) { + public @NotNull TextComponent formatPlayerStatForTypeTime(String playerName, int statNumber, Statistic statistic, Unit bigUnit, Unit smallUnit) { TextComponent statNumberComponent = getBasicTimeNumberComponent(statNumber, Target.PLAYER, bigUnit, smallUnit); return getPlayerStatComponent(playerName, statNumberComponent, statistic, null, null); } @@ -309,7 +313,7 @@ public final class MessageBuilder implements ApiFormatter { *
- If both parameters are null, the formattedComponent will be returned * as is. */ - public BiFunction formattedPlayerStatFunction(int stat, @NotNull RequestSettings request) { + public @NotNull BiFunction formattedPlayerStatFunction(int stat, @NotNull RequestSettings request) { TextComponent playerStat = formatPlayerStat(request.getPlayerName(), stat, request.getStatistic(), request.getSubStatEntryName()); return getFormattingFunction(playerStat, Target.PLAYER); } @@ -325,7 +329,7 @@ public final class MessageBuilder implements ApiFormatter { *
- If both parameters are null, the formattedComponent will be returned * as is. */ - public BiFunction formattedServerStatFunction(long stat, @NotNull RequestSettings request) { + public @NotNull BiFunction formattedServerStatFunction(long stat, @NotNull RequestSettings request) { TextComponent serverStat = formatServerStat(stat, request.getStatistic(), request.getSubStatEntryName()); return getFormattingFunction(serverStat, Target.SERVER); } @@ -341,7 +345,7 @@ public final class MessageBuilder implements ApiFormatter { *
- If both parameters are null, the formattedComponent will be returned * as is. */ - public BiFunction formattedTopStatFunction(@NotNull LinkedHashMap topStats, @NotNull RequestSettings request) { + public @NotNull BiFunction formattedTopStatFunction(@NotNull LinkedHashMap topStats, @NotNull RequestSettings request) { final TextComponent title = getTopStatTitle(topStats.size(), request.getStatistic(), request.getSubStatEntryName()); final TextComponent list = getTopStatListComponent(topStats, request.getStatistic()); final boolean useEnters = config.useEnters(Target.TOP, false); @@ -393,7 +397,7 @@ public final class MessageBuilder implements ApiFormatter { }; } - private TextComponent getPlayerStatComponent(String playerName, TextComponent statNumberComponent, Statistic statistic, @Nullable String subStatName, @Nullable Unit unit) { + private @NotNull TextComponent getPlayerStatComponent(String playerName, TextComponent statNumberComponent, Statistic statistic, @Nullable String subStatName, @Nullable Unit unit) { TextComponent statUnit = (unit == null) ? getStatUnitComponent(statistic, Target.PLAYER) : getStatUnitComponent(unit, Target.PLAYER); @@ -409,7 +413,7 @@ public final class MessageBuilder implements ApiFormatter { .build(); } - private TextComponent getServerStatComponent(TextComponent statNumber, Statistic statistic, @Nullable String subStatName, @Nullable Unit unit) { + private @NotNull TextComponent getServerStatComponent(TextComponent statNumber, Statistic statistic, @Nullable String subStatName, @Nullable Unit unit) { String serverTitle = config.getServerTitle(); String serverName = config.getServerName(); TextComponent statUnit = (unit == null) ? @@ -428,7 +432,7 @@ public final class MessageBuilder implements ApiFormatter { .build(); } - private TextComponent getTopStatTitleComponent(int topListSize, Statistic statistic, @Nullable String subStatName, @Nullable Unit unit) { + private @NotNull TextComponent getTopStatTitleComponent(int topListSize, Statistic statistic, @Nullable String subStatName, @Nullable Unit unit) { TextComponent statUnit = (unit == null) ? getStatUnitComponent(statistic, Target.TOP) : getStatUnitComponent(unit, Target.TOP); @@ -450,7 +454,7 @@ public final class MessageBuilder implements ApiFormatter { } } - private TextComponent getTopStatListComponent(LinkedHashMap topStats, Statistic statistic) { + private @NotNull TextComponent getTopStatListComponent(@NotNull LinkedHashMap topStats, Statistic statistic) { TextComponent.Builder topList = Component.text(); Set playerNames = topStats.keySet(); boolean useDots = config.useDots(); @@ -472,7 +476,7 @@ public final class MessageBuilder implements ApiFormatter { return topList.build(); } - private TextComponent getTopStatLineComponent(int positionInTopList, String playerName, TextComponent statNumberComponent) { + private @NotNull TextComponent getTopStatLineComponent(int positionInTopList, String playerName, TextComponent statNumberComponent) { boolean useDots = config.useDots(); String fullPlayerName = useDots ? playerName : playerName + ":"; @@ -498,27 +502,27 @@ public final class MessageBuilder implements ApiFormatter { } private TextComponent getStatAndSubStatNameComponent(Statistic statistic, @Nullable String subStatName, Target target) { + String statKey = languageKeyHandler.getStatKey(statistic); + String subStatKey = switch (statistic.getType()) { + case UNTYPED -> null; + case ENTITY -> languageKeyHandler.getEntityKey(EnumHandler.getEntityEnum(subStatName)); + case BLOCK -> languageKeyHandler.getBlockKey(EnumHandler.getBlockEnum(subStatName)); + case ITEM -> languageKeyHandler.getItemKey(EnumHandler.getItemEnum(subStatName)); + }; + if (subStatKey == null) { + subStatKey = StringUtils.prettify(subStatName); + } + if (config.useTranslatableComponents()) { - String statKey = languageKeyHandler.getStatKey(statistic); - String subStatKey = switch (statistic.getType()) { - case UNTYPED -> null; - case ENTITY -> languageKeyHandler.getEntityKey(EnumHandler.getEntityEnum(subStatName)); - case BLOCK -> languageKeyHandler.getBlockKey(EnumHandler.getBlockEnum(subStatName)); - case ITEM -> languageKeyHandler.getItemKey(EnumHandler.getItemEnum(subStatName)); - }; - if (subStatKey == null) { - subStatKey = StringUtils.prettify(subStatName); - } return componentFactory.statAndSubStatNameTranslatable(statKey, subStatKey, target); } - //TODO turn key into custom input from file - String prettyStatName = StringUtils.prettify(statistic.toString()); - String prettySubStatName = StringUtils.prettify(subStatName); + String prettyStatName = languageKeyHandler.convertLanguageKeyToDisplayName(statKey); + String prettySubStatName = languageKeyHandler.convertLanguageKeyToDisplayName(subStatKey); return componentFactory.statAndSubStatName(prettyStatName, prettySubStatName, target); } - private TextComponent getStatNumberComponent(long statNumber, Target target, Unit unit) { + private TextComponent getStatNumberComponent(long statNumber, Target target, @NotNull Unit unit) { return switch (unit.getType()) { case TIME -> getBasicTimeNumberComponent(statNumber, target, unit, null); case DAMAGE -> getDamageNumberComponent(statNumber, target, unit); @@ -619,7 +623,7 @@ public final class MessageBuilder implements ApiFormatter { return getStatUnitComponent(unit, target); } - private TextComponent getStatUnitComponent(Unit unit, Target target) { + private TextComponent getStatUnitComponent(@NotNull Unit unit, Target target) { return switch (unit.getType()) { case DAMAGE -> getDamageUnitComponent(unit, target); case DISTANCE -> getDistanceUnitComponent(unit, target); @@ -630,7 +634,7 @@ public final class MessageBuilder implements ApiFormatter { /** * Provides its own space in front of it! */ - private TextComponent getDistanceUnitComponent(Unit unit, Target target) { + private @NotNull TextComponent getDistanceUnitComponent(Unit unit, Target target) { if (config.useTranslatableComponents()) { String unitKey = languageKeyHandler.getUnitKey(unit); if (unitKey != null) { @@ -645,7 +649,7 @@ public final class MessageBuilder implements ApiFormatter { /** * Provides its own space in front of it! */ - private TextComponent getDamageUnitComponent(Unit unit, Target target) { + private @NotNull TextComponent getDamageUnitComponent(Unit unit, Target target) { if (unit == Unit.HEART) { TextComponent heartUnit; if (isConsoleBuilder) { @@ -672,7 +676,7 @@ public final class MessageBuilder implements ApiFormatter { return componentFactory.sharerName(sender.getName()); } - private BiFunction getFormattingFunction(@NotNull TextComponent statResult, Target target) { + private @NotNull BiFunction getFormattingFunction(@NotNull TextComponent statResult, Target target) { boolean useEnters = config.useEnters(target, false); boolean useEntersForShared = config.useEnters(target, true); @@ -726,7 +730,7 @@ public final class MessageBuilder implements ApiFormatter { *

2. maxHoverUnit

*

3. minHoverUnit

*/ - private ArrayList getTimeUnitRange(long statNumber) { + private @NotNull ArrayList getTimeUnitRange(long statNumber) { ArrayList unitRange = new ArrayList<>(); if (!config.autoDetectTimeUnit(false)) { unitRange.add(Unit.fromString(config.getTimeUnit(false))); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentFactory.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentFactory.java index f4c2506..2942544 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentFactory.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentFactory.java @@ -225,10 +225,10 @@ public class ComponentFactory { getStyleFromString(config.getStatNameDecoration(target, true))); TextComponent subStat = subStatNameTranslatable(subStatKey, target); - if (LanguageKeyHandler.isKeyForKillEntity(statKey)) { + if (LanguageKeyHandler.isNormalKeyForKillEntity(statKey)) { return totalStatNameBuilder.append(killEntityBuilder(subStat)).build(); } - else if (LanguageKeyHandler.isKeyForEntityKilledBy(statKey)) { + else if (LanguageKeyHandler.isNormalKeyForEntityKilledBy(statKey)) { return totalStatNameBuilder.append(entityKilledByBuilder(subStat)).build(); } else { @@ -370,7 +370,7 @@ public class ComponentFactory { */ private TranslatableComponent.Builder killEntityBuilder(@NotNull TextComponent subStat) { return translatable() - .key(LanguageKeyHandler.getAlternativeKeyForKillEntity()) //"Killed %s" + .key(LanguageKeyHandler.getCustomKeyForKillEntity()) //"Killed %s" .args(subStat); } @@ -384,10 +384,10 @@ public class ComponentFactory { */ private TranslatableComponent.Builder entityKilledByBuilder(@NotNull TextComponent subStat) { return translatable() - .key(LanguageKeyHandler.getAlternativeKeyForEntityKilledBy()) //"Number of Deaths" + .key(LanguageKeyHandler.getCustomKeyForEntityKilledBy()) //"Number of Deaths" .append(space()) .append(translatable() - .key(LanguageKeyHandler.getAlternativeKeyForEntityKilledByArg()) //"by %s" + .key(LanguageKeyHandler.getCustomKeyForEntityKilledByArg()) //"by %s" .args(subStat)); } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentUtils.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentUtils.java index 590b706..efdb20c 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentUtils.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentUtils.java @@ -2,10 +2,11 @@ package com.artemis.the.gr8.playerstats.msg.components; import com.artemis.the.gr8.playerstats.Main; import com.artemis.the.gr8.playerstats.msg.msgutils.LanguageKeyHandler; -import com.artemis.the.gr8.playerstats.msg.msgutils.StringUtils; import net.kyori.adventure.text.*; import net.kyori.adventure.text.flattener.ComponentFlattener; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; /** * A small utility class for turning PlayerStats' custom Components into String. @@ -22,19 +23,20 @@ public final class ComponentUtils { * @return the Serializer * @see LanguageKeyHandler */ - public static LegacyComponentSerializer getTranslatableComponentSerializer() { + public static @NotNull LegacyComponentSerializer getTranslatableComponentSerializer() { + LanguageKeyHandler languageKeyHandler = Main.getLanguageKeyHandler(); LegacyComponentSerializer serializer = getTextComponentSerializer(); ComponentFlattener flattener = ComponentFlattener.basic().toBuilder() .mapper(TranslatableComponent.class, trans -> { StringBuilder totalPrettyName = new StringBuilder(); - if (LanguageKeyHandler.isKeyForEntityKilledByArg(trans.key())) { + if (LanguageKeyHandler.isCustomKeyForEntityKilledByArg(trans.key())) { return ""; } - else if (LanguageKeyHandler.isKeyForEntityKilledBy(trans.key()) || - LanguageKeyHandler.isAlternativeKeyForEntityKilledBy(trans.key()) || - LanguageKeyHandler.isKeyForKillEntity(trans.key()) || - LanguageKeyHandler.isAlternativeKeyForKillEntity(trans.key())) { + else if (LanguageKeyHandler.isNormalKeyForEntityKilledBy(trans.key()) || + LanguageKeyHandler.isCustomKeyForEntityKilledBy(trans.key()) || + LanguageKeyHandler.isNormalKeyForKillEntity(trans.key()) || + LanguageKeyHandler.isCustomKeyForKillEntity(trans.key())) { TextComponent.Builder temp = Component.text(); trans.iterator(ComponentIteratorType.DEPTH_FIRST, ComponentIteratorFlag.INCLUDE_TRANSLATABLE_COMPONENT_ARGUMENTS) @@ -51,28 +53,25 @@ public final class ComponentUtils { } //isolate the translatable component with the entity inside else if (component instanceof TranslatableComponent translatable) { - if (translatable.key().contains("entity.")) { + if (LanguageKeyHandler.isEntityKey(translatable.key())) { temp.append(Component.space()) .append(Component.text("(") .append(Component.text( - StringUtils.prettify(LanguageKeyHandler.convertToName(translatable.key())))) + languageKeyHandler.convertLanguageKeyToDisplayName(translatable.key()))) .append(Component.text(")"))); totalPrettyName.append( serializer.serialize(temp.build())); } - else if (!LanguageKeyHandler.isKeyForEntityKilledByArg(translatable.key())) { + else if (!LanguageKeyHandler.isCustomKeyForEntityKilledByArg(translatable.key())) { totalPrettyName.append( - Main.getLanguageKeyHandler().getStatKeyTranslation( + languageKeyHandler.convertLanguageKeyToDisplayName( translatable.key())); } } }); } - else if (trans.key().startsWith("stat")) { - return Main.getLanguageKeyHandler().getStatKeyTranslation(trans.key()); - } else { - return StringUtils.prettify(LanguageKeyHandler.convertToName(trans.key())); + return languageKeyHandler.convertLanguageKeyToDisplayName(trans.key()); } return totalPrettyName.toString(); }) @@ -81,7 +80,8 @@ public final class ComponentUtils { return serializer.toBuilder().flattener(flattener).build(); } - private static LegacyComponentSerializer getTextComponentSerializer() { + @Contract(" -> new") + private static @NotNull LegacyComponentSerializer getTextComponentSerializer() { return LegacyComponentSerializer .builder() .hexColors() diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/LanguageKeyHandler.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/LanguageKeyHandler.java index c40f3f7..f0edb1e 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/LanguageKeyHandler.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/LanguageKeyHandler.java @@ -6,11 +6,14 @@ import com.artemis.the.gr8.playerstats.enums.Unit; import org.bukkit.Material; import org.bukkit.Statistic; import org.bukkit.entity.EntityType; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Arrays; import java.util.HashMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * @@ -19,7 +22,8 @@ import java.util.HashMap; */ public final class LanguageKeyHandler extends FileHandler { - private static HashMap statNameKeys; + private static HashMap statisticKeys; + private final Pattern subStatKey; /** * This class uses a file to get the English translations @@ -28,7 +32,18 @@ public final class LanguageKeyHandler extends FileHandler { */ public LanguageKeyHandler() { super("language.yml"); - statNameKeys = generateStatNameKeys(); + statisticKeys = generateStatisticKeys(); + subStatKey = Pattern.compile("(item|entity|block)\\.minecraft\\."); + } + + @Contract(pure = true) + public @NotNull String getKeyForBlockUnit() { + return "soundCategory.block"; + } + + @Contract(pure = true) + public static boolean isEntityKey(@NotNull String key) { + return key.contains("entity.minecraft"); } /** @@ -37,7 +52,8 @@ public final class LanguageKeyHandler extends FileHandler { * @param statKey the Key to check * @return true if this Key is key for kill-entity */ - public static boolean isKeyForKillEntity(String statKey) { + @Contract(pure = true) + public static boolean isNormalKeyForKillEntity(@NotNull String statKey) { return statKey.equalsIgnoreCase("stat_type.minecraft.killed"); } @@ -47,7 +63,8 @@ public final class LanguageKeyHandler extends FileHandler { * @param statKey the Key to check * @return true if this Key is key for commands.kill.success.single */ - public static boolean isAlternativeKeyForKillEntity(String statKey) { + @Contract(pure = true) + public static boolean isCustomKeyForKillEntity(@NotNull String statKey) { return statKey.equalsIgnoreCase("commands.kill.success.single"); } @@ -56,7 +73,8 @@ public final class LanguageKeyHandler extends FileHandler { * * @return the key "commands.kill.success.single", which results in "Killed %s" */ - public static String getAlternativeKeyForKillEntity() { + @Contract(pure = true) + public static @NotNull String getCustomKeyForKillEntity() { return "commands.kill.success.single"; } @@ -66,27 +84,19 @@ public final class LanguageKeyHandler extends FileHandler { * @param statKey the Key to check * @return true if this Key is a key for entity-killed-by */ - public static boolean isKeyForEntityKilledBy(String statKey) { + @Contract(pure = true) + public static boolean isNormalKeyForEntityKilledBy(@NotNull String statKey) { return statKey.equalsIgnoreCase("stat_type.minecraft.killed_by"); } /** - * Checks if a given Key is the language key "stat.minecraft.deaths". + * Checks if a given Key is the language key "subtitles.entity.generic.death". * @param statKey the Key to check - * @return true if this Key is key for stat.minecraft.deaths + * @return true if this Key is key for subtitles.entity.generic.death */ - public static boolean isAlternativeKeyForEntityKilledBy(String statKey) { - return statKey.equalsIgnoreCase("stat.minecraft.deaths"); - } - - /** - * Returns a language key to replace the default stat_type.minecraft.killed_by key. - * - * @return the key "stat.minecraft.deaths", which results in "Number of Deaths" - * (meant to be followed by {@link #getAlternativeKeyForEntityKilledByArg()}) - */ - public static String getAlternativeKeyForEntityKilledBy() { - return "stat.minecraft.deaths"; + @Contract(pure = true) + public static boolean isCustomKeyForEntityKilledBy(@NotNull String statKey) { + return statKey.equalsIgnoreCase("subtitles.entity.generic.death"); } /** @@ -96,70 +106,75 @@ public final class LanguageKeyHandler extends FileHandler { * @param statKey the Key to Check * @return true if this Key is the key for book.byAuthor */ - public static boolean isKeyForEntityKilledByArg(String statKey) { + @Contract(pure = true) + public static boolean isCustomKeyForEntityKilledByArg(@NotNull String statKey) { return statKey.equalsIgnoreCase("book.byAuthor"); } /** - * Returns a language key to complete the alternative key for Statistic.Entity_Killed_By. + * Returns a language key to replace the default stat_type.minecraft.killed_by key. * - * @return the key "book.byAuthor", which results in "by %". If used after - * {@link #getAlternativeKeyForEntityKilledBy()}, you will get "Number of Deaths" "by %s" + * @return the key "subtitles.entity.generic.death", which results in "Dying" + * (meant to be followed by {@link #getCustomKeyForEntityKilledByArg()}) */ - public static String getAlternativeKeyForEntityKilledByArg() { - return "book.byAuthor"; + @Contract(pure = true) + public static @NotNull String getCustomKeyForEntityKilledBy() { + return "subtitles.entity.generic.death"; } /** - * @param key the String to turn into a normal name - * @return a pretty name + * Returns a language key to complete the alternative key for statistic.entity_killed_by. + * + * @return the key "book.byAuthor", which results in "by %". If used after + * {@link #getCustomKeyForEntityKilledBy()}, you will get "Dying" "by %s" */ - public static String convertToName(String key) { - if (key.equalsIgnoreCase("soundCategory.block")) { + @Contract(pure = true) + public static @NotNull String getCustomKeyForEntityKilledByArg() { + return "book.byAuthor"; + } + + public String convertLanguageKeyToDisplayName(String key) { + if (key == null) return null; + if (isStatKey(key)) { + return getStatKeyTranslation(key); + } + else if (key.equalsIgnoreCase(getKeyForBlockUnit())) { return Unit.BLOCK.getLabel(); - } else if (isKeyForKillEntity(key)) { - return "times_killed"; - } else if (isKeyForEntityKilledBy(key)) { - return "number_of_times_killed_by"; - } else if (isKeyForEntityKilledByArg(key)) { //this one returns nothing, because it's an extra key I added - return ""; //to make the TranslatableComponent work } - String toReplace = ""; - if (key.contains("stat")) { - if (key.contains("type")) { - toReplace = "stat_type"; - } else { - toReplace = "stat"; - } - } else if (key.contains("entity")) { //for the two entity-related ones, put brackets around it to - toReplace = "entity"; //make up for the multiple-keys/args-serializer issues - } else if (key.contains("block")) { - toReplace = "block"; - } else if (key.contains("item")) { - toReplace = "item"; + + Matcher matcher = subStatKey.matcher(key); + if (matcher.find()) { + String rawName = matcher.replaceFirst(""); + return StringUtils.prettify(rawName); } - toReplace = toReplace + ".minecraft."; - return key.replace(toReplace, ""); + return key; } - private static @Nullable String convertToNormalStatKey(String statKey) { - if (isKeyForKillEntity(statKey)) { - return "stat_type.minecraft.killed"; - } else if (isKeyForEntityKilledBy(statKey)) { - return "stat_type.minecraft.killed_by"; - } else if (isKeyForEntityKilledByArg(statKey)) { - return null; - } else { - return statKey; - } + private boolean isStatKey(@NotNull String key) { + return (key.contains("stat") || + isCustomKeyForKillEntity(key) || + isCustomKeyForEntityKilledBy(key) || + isCustomKeyForEntityKilledByArg(key)); } - public String getStatKeyTranslation(String statKey) { + private String getStatKeyTranslation(String statKey) { String realKey = convertToNormalStatKey(statKey); if (realKey == null) { return ""; } - return super.getFileConfiguration().getString(statKey); + return super.getFileConfiguration().getString(realKey); + } + + private static @Nullable String convertToNormalStatKey(String statKey) { + if (isCustomKeyForKillEntity(statKey)) { + return "stat_type.minecraft.killed"; + } else if (isCustomKeyForEntityKilledBy(statKey)) { + return "stat_type.minecraft.killed_by"; + } else if (isCustomKeyForEntityKilledByArg(statKey)) { + return null; + } else { + return statKey; + } } /** @@ -167,12 +182,12 @@ public final class LanguageKeyHandler extends FileHandler { * @return the official Key from the NameSpacedKey for this Statistic, * or return null if no enum constant can be retrieved. */ - public String getStatKey(@NotNull Statistic statistic) { + public @NotNull String getStatKey(@NotNull Statistic statistic) { if (statistic.getType() == Statistic.Type.UNTYPED) { - return "stat.minecraft." + statNameKeys.get(statistic); + return "stat.minecraft." + statisticKeys.get(statistic); } else { - return "stat_type.minecraft." + statNameKeys.get(statistic); + return "stat_type.minecraft." + statisticKeys.get(statistic); } } @@ -232,7 +247,7 @@ public final class LanguageKeyHandler extends FileHandler { } } - private @NotNull HashMap generateStatNameKeys() { + private @NotNull HashMap generateStatisticKeys() { //get the enum names for all statistics first HashMap statNames = new HashMap<>(Statistic.values().length); Arrays.stream(Statistic.values()).forEach(statistic -> statNames.put(statistic, statistic.toString().toLowerCase())); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/StringUtils.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/StringUtils.java index 307dabc..ff62aec 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/StringUtils.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/StringUtils.java @@ -18,15 +18,21 @@ public final class StringUtils { */ public static String prettify(String input) { if (input == null) return null; + StringBuilder capitals = new StringBuilder(input.toLowerCase()); capitals.setCharAt(0, Character.toUpperCase(capitals.charAt(0))); - while (capitals.indexOf("_") != -1) { - MyLogger.logHighLevelMsg("Replacing underscores and capitalizing names..."); + while (capitals.indexOf("_") != -1) { + MyLogger.logHighLevelMsg("Replacing underscores..."); int index = capitals.indexOf("_"); - capitals.setCharAt(index + 1, Character.toUpperCase(capitals.charAt(index + 1))); capitals.setCharAt(index, ' '); } + + while (capitals.indexOf(" ") != -1) { + MyLogger.logHighLevelMsg("Capitalizing names..."); + int index = capitals.indexOf(" ") + 1; + capitals.setCharAt(index, Character.toUpperCase(capitals.charAt(index))); + } return capitals.toString(); } } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/PlayerStatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/PlayerStatRequest.java index 2162485..45739da 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/PlayerStatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/PlayerStatRequest.java @@ -48,7 +48,7 @@ public final class PlayerStatRequest extends StatRequest implements Req .getPlayerStat(completedRequest); TextComponent prettyComponent = Main - .getStatFormatter() + .getOutputManager() .formatAndSavePlayerStat(completedRequest, stat); String prettyString = ComponentUtils diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/ServerStatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/ServerStatRequest.java index 42916b0..15521a3 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/ServerStatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/ServerStatRequest.java @@ -48,7 +48,7 @@ public final class ServerStatRequest extends StatRequest implements Reques .getServerStat(completedRequest); TextComponent prettyComponent = Main - .getStatFormatter() + .getOutputManager() .formatAndSaveServerStat(completedRequest, stat); String prettyString = ComponentUtils diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/TopStatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/TopStatRequest.java index 8cf8f90..04c8f25 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/TopStatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/TopStatRequest.java @@ -50,7 +50,7 @@ public final class TopStatRequest extends StatRequest Date: Wed, 5 Oct 2022 14:20:12 +0200 Subject: [PATCH 04/43] Removed unnecessary method from BukkitConsoleComponentFactory, minor annotation improvements --- .../BukkitConsoleComponentFactory.java | 5 ----- .../msg/components/ComponentFactory.java | 21 +++++++++++-------- .../msg/msgutils/LanguageKeyHandler.java | 5 ----- 3 files changed, 12 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/BukkitConsoleComponentFactory.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/BukkitConsoleComponentFactory.java index 40c6697..8c51065 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/BukkitConsoleComponentFactory.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/BukkitConsoleComponentFactory.java @@ -41,11 +41,6 @@ public class BukkitConsoleComponentFactory extends ComponentFactory { MSG_HOVER_ACCENT = PluginColor.LIGHT_GOLD.getConsoleColor(); } - @Override - public TextColor getSharerNameColor() { - return PluginColor.NAME_5.getConsoleColor(); - } - @Override protected TextComponent getComponent(String content, @NotNull TextColor color, @Nullable TextDecoration style) { return getComponentBuilder(content, NamedTextColor.nearestTo(color), style).build(); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentFactory.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentFactory.java index 2942544..4f853ae 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentFactory.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentFactory.java @@ -17,6 +17,7 @@ import net.kyori.adventure.text.format.TextDecoration; import net.kyori.adventure.util.HSVLike; import net.kyori.adventure.util.Index; import org.bukkit.Bukkit; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -77,6 +78,7 @@ public class ComponentFactory { public TextColor getExampleNameColor() { return MSG_ACCENT_2B; } + public TextColor getSharerNameColor() { return getColorFromString(config.getSharerNameDecoration(false)); } @@ -321,7 +323,8 @@ public class ComponentFactory { } //console can do u2665, u2764 looks better in-game - private TextComponent basicHeartComponent(char heartChar) { + @Contract("_ -> new") + private @NotNull TextComponent basicHeartComponent(char heartChar) { return Component.text() .content(String.valueOf(heartChar)) .color(HEARTS) @@ -368,7 +371,7 @@ public class ComponentFactory { * * @return a TranslatableComponent Builder with the subStat Component as args. */ - private TranslatableComponent.Builder killEntityBuilder(@NotNull TextComponent subStat) { + private @NotNull TranslatableComponent.Builder killEntityBuilder(@NotNull TextComponent subStat) { return translatable() .key(LanguageKeyHandler.getCustomKeyForKillEntity()) //"Killed %s" .args(subStat); @@ -382,7 +385,7 @@ public class ComponentFactory { * @return a TranslatableComponent Builder with stat.minecraft.deaths as key, * with a ChildComponent with book.byAuthor as key and the subStat Component as args. */ - private TranslatableComponent.Builder entityKilledByBuilder(@NotNull TextComponent subStat) { + private @NotNull TranslatableComponent.Builder entityKilledByBuilder(@NotNull TextComponent subStat) { return translatable() .key(LanguageKeyHandler.getCustomKeyForEntityKilledBy()) //"Number of Deaths" .append(space()) @@ -391,10 +394,10 @@ public class ComponentFactory { .args(subStat)); } - private TextComponent statNumberWithHoverText(String mainNumber, String hoverNumber, - @Nullable String hoverUnitName, - @Nullable String hoverUnitKey, - @Nullable TextComponent heartComponent, Target target) { + private @NotNull TextComponent statNumberWithHoverText(String mainNumber, String hoverNumber, + @Nullable String hoverUnitName, + @Nullable String hoverUnitKey, + @Nullable TextComponent heartComponent, Target target) { TextColor baseColor = getColorFromString(config.getStatNumberDecoration(target, false)); TextDecoration style = getStyleFromString(config.getStatNumberDecoration(target, true)); @@ -415,7 +418,7 @@ public class ComponentFactory { return getComponent(mainNumber, baseColor, style).hoverEvent(HoverEvent.showText(hoverText)); } - private TextComponent surroundWithBrackets(TextComponent component) { + private @NotNull TextComponent surroundWithBrackets(TextComponent component) { return getComponent(null, BRACKETS, null) .append(text("[")) .append(component) @@ -465,7 +468,7 @@ public class ComponentFactory { return names.value(textColor); } - private TextColor getLighterColor(TextColor color) { + private @NotNull TextColor getLighterColor(@NotNull TextColor color) { float multiplier = (float) ((100 - config.getHoverTextAmountLighter()) / 100.0); HSVLike oldColor = HSVLike.fromRGB(color.red(), color.green(), color.blue()); HSVLike newColor = HSVLike.hsvLike(oldColor.h(), oldColor.s() * multiplier, oldColor.v()); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/LanguageKeyHandler.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/LanguageKeyHandler.java index f0edb1e..4c9de9c 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/LanguageKeyHandler.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/LanguageKeyHandler.java @@ -25,11 +25,6 @@ public final class LanguageKeyHandler extends FileHandler { private static HashMap statisticKeys; private final Pattern subStatKey; - /** - * This class uses a file to get the English translations - * of languageKeys, and uses an instance of the PlayerStats - * plugin to get access to this file. - */ public LanguageKeyHandler() { super("language.yml"); statisticKeys = generateStatisticKeys(); From 56dc30830aa648e6669807c23a753973eec3f756 Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Wed, 5 Oct 2022 17:24:51 +0200 Subject: [PATCH 05/43] Started a rewrite to make the request-business more clear and better organized --- .../the/gr8/playerstats/ThreadManager.java | 5 +- .../gr8/playerstats/api/PlayerStatsAPI.java | 9 +- .../playerstats/msg/InternalFormatter.java | 7 +- .../gr8/playerstats/msg/MessageBuilder.java | 8 +- .../gr8/playerstats/msg/OutputManager.java | 21 +- .../gr8/playerstats/statistic/StatAction.java | 6 +- .../playerstats/statistic/StatCalculator.java | 12 +- .../gr8/playerstats/statistic/StatThread.java | 5 +- .../statistic/request/PlayerStatRequest.java | 35 +-- .../statistic/request/ServerStatRequest.java | 35 +-- .../statistic/request/StatRequest.java | 238 ++++++++++++++---- .../statistic/request/TopStatRequest.java | 35 +-- 12 files changed, 282 insertions(+), 134 deletions(-) diff --git a/src/main/java/com/artemis/the/gr8/playerstats/ThreadManager.java b/src/main/java/com/artemis/the/gr8/playerstats/ThreadManager.java index 8561be0..6dbd29d 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/ThreadManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/ThreadManager.java @@ -7,6 +7,7 @@ import com.artemis.the.gr8.playerstats.statistic.request.RequestSettings; import com.artemis.the.gr8.playerstats.reload.ReloadThread; import com.artemis.the.gr8.playerstats.statistic.StatCalculator; import com.artemis.the.gr8.playerstats.statistic.StatThread; +import com.artemis.the.gr8.playerstats.statistic.request.StatRequest; import com.artemis.the.gr8.playerstats.utils.MyLogger; import org.bukkit.command.CommandSender; @@ -63,7 +64,7 @@ public final class ThreadManager { } } - public void startStatThread(RequestSettings requestSettings) { + public void startStatThread(StatRequest.Settings requestSettings) { statThreadID += 1; String cmdSender = requestSettings.getCommandSender().getName(); @@ -95,7 +96,7 @@ public final class ThreadManager { return lastRecordedCalcTime; } - private void startNewStatThread(RequestSettings requestSettings) { + private void startNewStatThread(StatRequest.Settings requestSettings) { lastActiveStatThread = new StatThread(outputManager, statCalculator, statThreadID, requestSettings, lastActiveReloadThread); statThreads.put(requestSettings.getCommandSender().getName(), lastActiveStatThread); lastActiveStatThread.start(); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStatsAPI.java b/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStatsAPI.java index 9fb62a4..b6a7636 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStatsAPI.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStatsAPI.java @@ -29,20 +29,17 @@ public final class PlayerStatsAPI implements PlayerStats, StatManager { @Override public PlayerStatRequest playerStatRequest(String playerName) { - RequestSettings request = RequestHandler.getBasicPlayerStatRequest(playerName); - return new PlayerStatRequest(request); + return new PlayerStatRequest(playerName); } @Override public ServerStatRequest serverStatRequest() { - RequestSettings request = RequestHandler.getBasicServerStatRequest(); - return new ServerStatRequest(request); + return new ServerStatRequest(); } @Override public TopStatRequest topStatRequest(int topListSize) { - RequestSettings request = RequestHandler.getBasicTopStatRequest(topListSize); - return new TopStatRequest(request); + return new TopStatRequest(topListSize); } @Override diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/InternalFormatter.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/InternalFormatter.java index 4041c7c..d63c8aa 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/InternalFormatter.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/InternalFormatter.java @@ -2,6 +2,7 @@ package com.artemis.the.gr8.playerstats.msg; import com.artemis.the.gr8.playerstats.statistic.request.RequestSettings; import com.artemis.the.gr8.playerstats.statistic.StatCalculator; +import com.artemis.the.gr8.playerstats.statistic.request.StatRequest; import net.kyori.adventure.text.*; import org.jetbrains.annotations.ApiStatus.Internal; @@ -19,12 +20,12 @@ public interface InternalFormatter { /** @return a TextComponent with the following parts: *
[player-name]: [number] [stat-name] {sub-stat-name} */ - TextComponent formatAndSavePlayerStat(RequestSettings requestSettings, int playerStat); + TextComponent formatAndSavePlayerStat(StatRequest.Settings requestSettings, int playerStat); /** @return a TextComponent with the following parts: *
[Total on] [server-name]: [number] [stat-name] [sub-stat-name] */ - TextComponent formatAndSaveServerStat(RequestSettings requestSettings, long serverStat); + TextComponent formatAndSaveServerStat(StatRequest.Settings requestSettings, long serverStat); /** @return a TextComponent with the following parts: *
[PlayerStats] [Top 10] [stat-name] [sub-stat-name] @@ -32,5 +33,5 @@ public interface InternalFormatter { *
[2.] [player-name] [number] *
[3.] etc... */ - TextComponent formatAndSaveTopStat(RequestSettings requestSettings, LinkedHashMap topStats); + TextComponent formatAndSaveTopStat(StatRequest.Settings requestSettings, LinkedHashMap topStats); } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java index 8d31819..5923ff1 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java @@ -8,13 +8,13 @@ import com.artemis.the.gr8.playerstats.msg.components.HelpMessage; import com.artemis.the.gr8.playerstats.msg.components.BukkitConsoleComponentFactory; import com.artemis.the.gr8.playerstats.msg.components.PrideComponentFactory; import com.artemis.the.gr8.playerstats.msg.msgutils.*; +import com.artemis.the.gr8.playerstats.statistic.request.StatRequest; import com.artemis.the.gr8.playerstats.utils.EnumHandler; import com.artemis.the.gr8.playerstats.utils.MyLogger; import com.artemis.the.gr8.playerstats.enums.Target; import com.artemis.the.gr8.playerstats.config.ConfigHandler; import com.artemis.the.gr8.playerstats.enums.Unit; -import com.artemis.the.gr8.playerstats.statistic.request.RequestSettings; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.TextComponent; import org.bukkit.Statistic; @@ -313,7 +313,7 @@ public final class MessageBuilder implements ApiFormatter { *
- If both parameters are null, the formattedComponent will be returned * as is. */ - public @NotNull BiFunction formattedPlayerStatFunction(int stat, @NotNull RequestSettings request) { + public @NotNull BiFunction formattedPlayerStatFunction(int stat, @NotNull StatRequest.Settings request) { TextComponent playerStat = formatPlayerStat(request.getPlayerName(), stat, request.getStatistic(), request.getSubStatEntryName()); return getFormattingFunction(playerStat, Target.PLAYER); } @@ -329,7 +329,7 @@ public final class MessageBuilder implements ApiFormatter { *
- If both parameters are null, the formattedComponent will be returned * as is. */ - public @NotNull BiFunction formattedServerStatFunction(long stat, @NotNull RequestSettings request) { + public @NotNull BiFunction formattedServerStatFunction(long stat, @NotNull StatRequest.Settings request) { TextComponent serverStat = formatServerStat(stat, request.getStatistic(), request.getSubStatEntryName()); return getFormattingFunction(serverStat, Target.SERVER); } @@ -345,7 +345,7 @@ public final class MessageBuilder implements ApiFormatter { *
- If both parameters are null, the formattedComponent will be returned * as is. */ - public @NotNull BiFunction formattedTopStatFunction(@NotNull LinkedHashMap topStats, @NotNull RequestSettings request) { + public @NotNull BiFunction formattedTopStatFunction(@NotNull LinkedHashMap topStats, @NotNull StatRequest.Settings request) { final TextComponent title = getTopStatTitle(topStats.size(), request.getStatistic(), request.getSubStatEntryName()); final TextComponent list = getTopStatListComponent(topStats, request.getStatistic()); final boolean useEnters = config.useEnters(Target.TOP, false); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java index 10f54fd..22bbc95 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java @@ -6,6 +6,7 @@ import com.artemis.the.gr8.playerstats.enums.StandardMessage; import com.artemis.the.gr8.playerstats.statistic.request.RequestSettings; import com.artemis.the.gr8.playerstats.msg.components.BukkitConsoleComponentFactory; import com.artemis.the.gr8.playerstats.msg.components.PrideComponentFactory; +import com.artemis.the.gr8.playerstats.statistic.request.StatRequest; import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.text.TextComponent; import org.bukkit.Bukkit; @@ -55,25 +56,25 @@ public final class OutputManager implements InternalFormatter { } @Override - public TextComponent formatAndSavePlayerStat(@NotNull RequestSettings requestSettings, int playerStat) { + public TextComponent formatAndSavePlayerStat(@NotNull StatRequest.Settings requestSettings, int playerStat) { BiFunction playerStatFunction = - getMessageBuilder(requestSettings).formattedPlayerStatFunction(playerStat, requestSettings); + getMessageBuilder(requestSettings.getCommandSender()).formattedPlayerStatFunction(playerStat, requestSettings); return processFunction(requestSettings.getCommandSender(), playerStatFunction); } @Override - public TextComponent formatAndSaveServerStat(@NotNull RequestSettings requestSettings, long serverStat) { + public TextComponent formatAndSaveServerStat(@NotNull StatRequest.Settings requestSettings, long serverStat) { BiFunction serverStatFunction = - getMessageBuilder(requestSettings).formattedServerStatFunction(serverStat, requestSettings); + getMessageBuilder(requestSettings.getCommandSender()).formattedServerStatFunction(serverStat, requestSettings); return processFunction(requestSettings.getCommandSender(), serverStatFunction); } @Override - public TextComponent formatAndSaveTopStat(@NotNull RequestSettings requestSettings, @NotNull LinkedHashMap topStats) { + public TextComponent formatAndSaveTopStat(@NotNull StatRequest.Settings requestSettings, @NotNull LinkedHashMap topStats) { BiFunction topStatFunction = - getMessageBuilder(requestSettings).formattedTopStatFunction(topStats, requestSettings); + getMessageBuilder(requestSettings.getCommandSender()).formattedTopStatFunction(topStats, requestSettings); return processFunction(requestSettings.getCommandSender(), topStatFunction); } @@ -141,14 +142,6 @@ public final class OutputManager implements InternalFormatter { return sender instanceof ConsoleCommandSender ? consoleMessageBuilder : messageBuilder; } - private MessageBuilder getMessageBuilder(RequestSettings requestSettings) { - if (!requestSettings.isConsoleSender()) { - return messageBuilder; - } else { - return consoleMessageBuilder; - } - } - private static void getMessageBuilders() { messageBuilder = getClientMessageBuilder(); consoleMessageBuilder = getConsoleMessageBuilder(); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatAction.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatAction.java index b11ce4f..7f1d598 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatAction.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatAction.java @@ -1,8 +1,8 @@ package com.artemis.the.gr8.playerstats.statistic; import com.artemis.the.gr8.playerstats.ThreadManager; +import com.artemis.the.gr8.playerstats.statistic.request.StatRequest; import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; -import com.artemis.the.gr8.playerstats.statistic.request.RequestSettings; import com.artemis.the.gr8.playerstats.utils.MyLogger; import com.google.common.collect.ImmutableList; import org.bukkit.OfflinePlayer; @@ -20,7 +20,7 @@ final class StatAction extends RecursiveTask> private final OfflinePlayerHandler offlinePlayerHandler; private final ImmutableList playerNames; - private final RequestSettings requestSettings; + private final StatRequest.Settings requestSettings; private final ConcurrentHashMap allStats; /** @@ -34,7 +34,7 @@ final class StatAction extends RecursiveTask> * @param requestSettings a validated requestSettings object * @param allStats the ConcurrentHashMap to put the results on */ - public StatAction(OfflinePlayerHandler offlinePlayerHandler, ImmutableList playerNames, RequestSettings requestSettings, ConcurrentHashMap allStats) { + public StatAction(OfflinePlayerHandler offlinePlayerHandler, ImmutableList playerNames, StatRequest.Settings requestSettings, ConcurrentHashMap allStats) { threshold = ThreadManager.getTaskThreshold(); this.offlinePlayerHandler = offlinePlayerHandler; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatCalculator.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatCalculator.java index 78b4573..573df7d 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatCalculator.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatCalculator.java @@ -1,8 +1,8 @@ package com.artemis.the.gr8.playerstats.statistic; import com.artemis.the.gr8.playerstats.ThreadManager; +import com.artemis.the.gr8.playerstats.statistic.request.StatRequest; import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; -import com.artemis.the.gr8.playerstats.statistic.request.RequestSettings; import com.artemis.the.gr8.playerstats.utils.MyLogger; import com.google.common.collect.ImmutableList; import org.bukkit.OfflinePlayer; @@ -21,7 +21,7 @@ public final class StatCalculator { this.offlinePlayerHandler = offlinePlayerHandler; } - public int getPlayerStat(RequestSettings requestSettings) { + public int getPlayerStat(StatRequest.Settings requestSettings) { OfflinePlayer player = offlinePlayerHandler.getOfflinePlayer(requestSettings.getPlayerName()); return switch (requestSettings.getStatistic().getType()) { case UNTYPED -> player.getStatistic(requestSettings.getStatistic()); @@ -31,14 +31,14 @@ public final class StatCalculator { }; } - public LinkedHashMap getTopStats(RequestSettings requestSettings) { + public LinkedHashMap getTopStats(StatRequest.Settings requestSettings) { return getAllStatsAsync(requestSettings).entrySet().stream() .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())) .limit(requestSettings.getTopListSize()) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new)); } - public long getServerStat(RequestSettings requestSettings) { + public long getServerStat(StatRequest.Settings requestSettings) { List numbers = getAllStatsAsync(requestSettings) .values() .parallelStream() @@ -50,7 +50,7 @@ public final class StatCalculator { * Invokes a bunch of worker pool threads to get the statistics for * all players that are stored in the {@link OfflinePlayerHandler}). */ - private @NotNull ConcurrentHashMap getAllStatsAsync(RequestSettings requestSettings) { + private @NotNull ConcurrentHashMap getAllStatsAsync(StatRequest.Settings requestSettings) { long time = System.currentTimeMillis(); ForkJoinPool commonPool = ForkJoinPool.commonPool(); @@ -72,7 +72,7 @@ public final class StatCalculator { return allStats; } - private StatAction getStatTask(RequestSettings requestSettings) { + private StatAction getStatTask(StatRequest.Settings requestSettings) { int size = offlinePlayerHandler.getOfflinePlayerCount() != 0 ? offlinePlayerHandler.getOfflinePlayerCount() : 16; ConcurrentHashMap allStats = new ConcurrentHashMap<>(size); ImmutableList playerNames = ImmutableList.copyOf(offlinePlayerHandler.getOfflinePlayerNames()); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatThread.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatThread.java index bb6f999..aad139b 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatThread.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatThread.java @@ -2,6 +2,7 @@ package com.artemis.the.gr8.playerstats.statistic; import com.artemis.the.gr8.playerstats.ThreadManager; import com.artemis.the.gr8.playerstats.msg.OutputManager; +import com.artemis.the.gr8.playerstats.statistic.request.StatRequest; import com.artemis.the.gr8.playerstats.utils.MyLogger; import com.artemis.the.gr8.playerstats.enums.StandardMessage; import com.artemis.the.gr8.playerstats.enums.Target; @@ -21,9 +22,9 @@ public final class StatThread extends Thread { private static StatCalculator statCalculator; private final ReloadThread reloadThread; - private final RequestSettings requestSettings; + private final StatRequest.Settings requestSettings; - public StatThread(OutputManager m, StatCalculator t, int ID, RequestSettings s, @Nullable ReloadThread r) { + public StatThread(OutputManager m, StatCalculator t, int ID, StatRequest.Settings s, @Nullable ReloadThread r) { outputManager = m; statCalculator = t; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/PlayerStatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/PlayerStatRequest.java index 45739da..d84ffd8 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/PlayerStatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/PlayerStatRequest.java @@ -5,51 +5,52 @@ import com.artemis.the.gr8.playerstats.statistic.result.PlayerStatResult; import com.artemis.the.gr8.playerstats.api.RequestGenerator; import com.artemis.the.gr8.playerstats.msg.components.ComponentUtils; import net.kyori.adventure.text.TextComponent; +import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Statistic; +import org.bukkit.command.CommandSender; import org.bukkit.entity.EntityType; import org.jetbrains.annotations.NotNull; public final class PlayerStatRequest extends StatRequest implements RequestGenerator { - private final RequestHandler requestHandler; + public PlayerStatRequest(String playerName) { + this(Bukkit.getConsoleSender(), playerName); + } - public PlayerStatRequest(RequestSettings request) { - super(request); - requestHandler = new RequestHandler(request); + public PlayerStatRequest(CommandSender requester, String playerName) { + super(requester); + super.settings.configureForPlayer(playerName); } @Override - public PlayerStatRequest untyped(@NotNull Statistic statistic) { - RequestSettings completedRequest = requestHandler.untyped(statistic); - return new PlayerStatRequest(completedRequest); + public StatRequest untyped(@NotNull Statistic statistic) { + return super.configureUntyped(statistic); } @Override - public PlayerStatRequest blockOrItemType(@NotNull Statistic statistic, @NotNull Material material) { - RequestSettings completedRequest = requestHandler.blockOrItemType(statistic, material); - return new PlayerStatRequest(completedRequest); + public StatRequest blockOrItemType(@NotNull Statistic statistic, @NotNull Material material) { + return super.configureBlockOrItemType(statistic, material); } @Override - public PlayerStatRequest entityType(@NotNull Statistic statistic, @NotNull EntityType entityType) { - RequestSettings completedRequest = requestHandler.entityType(statistic, entityType); - return new PlayerStatRequest(completedRequest); + public StatRequest entityType(@NotNull Statistic statistic, @NotNull EntityType entityType) { + return super.configureEntityType(statistic, entityType); } @Override public PlayerStatResult execute() { - return getStatResult(super.requestSettings); + return getStatResult(); } - private PlayerStatResult getStatResult(RequestSettings completedRequest) { + private PlayerStatResult getStatResult() { int stat = Main .getStatCalculator() - .getPlayerStat(completedRequest); + .getPlayerStat(settings); TextComponent prettyComponent = Main .getOutputManager() - .formatAndSavePlayerStat(completedRequest, stat); + .formatAndSavePlayerStat(settings, stat); String prettyString = ComponentUtils .getTranslatableComponentSerializer() diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/ServerStatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/ServerStatRequest.java index 15521a3..f4b19fb 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/ServerStatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/ServerStatRequest.java @@ -5,51 +5,52 @@ import com.artemis.the.gr8.playerstats.statistic.result.ServerStatResult; import com.artemis.the.gr8.playerstats.api.RequestGenerator; import com.artemis.the.gr8.playerstats.msg.components.ComponentUtils; import net.kyori.adventure.text.TextComponent; +import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Statistic; +import org.bukkit.command.CommandSender; import org.bukkit.entity.EntityType; import org.jetbrains.annotations.NotNull; public final class ServerStatRequest extends StatRequest implements RequestGenerator { - private final RequestHandler requestHandler; + public ServerStatRequest() { + this(Bukkit.getConsoleSender()); + } - public ServerStatRequest(RequestSettings request) { - super(request); - requestHandler = new RequestHandler(requestSettings); + public ServerStatRequest(CommandSender requester) { + super(requester); + super.settings.configureForServer(); } @Override - public ServerStatRequest untyped(@NotNull Statistic statistic) { - RequestSettings completedRequest = requestHandler.untyped(statistic); - return new ServerStatRequest(completedRequest); + public StatRequest untyped(@NotNull Statistic statistic) { + return super.configureUntyped(statistic); } @Override - public ServerStatRequest blockOrItemType(@NotNull Statistic statistic, @NotNull Material material) { - RequestSettings completedRequest = requestHandler.blockOrItemType(statistic, material); - return new ServerStatRequest(completedRequest); + public StatRequest blockOrItemType(@NotNull Statistic statistic, @NotNull Material material) { + return super.configureBlockOrItemType(statistic, material); } @Override - public ServerStatRequest entityType(@NotNull Statistic statistic, @NotNull EntityType entityType) { - RequestSettings completedRequest = requestHandler.entityType(statistic, entityType); - return new ServerStatRequest(completedRequest); + public StatRequest entityType(@NotNull Statistic statistic, @NotNull EntityType entityType) { + return super.configureEntityType(statistic, entityType); } @Override public ServerStatResult execute() { - return getStatResult(requestSettings); + return getStatResult(); } - private ServerStatResult getStatResult(RequestSettings completedRequest) { + private ServerStatResult getStatResult() { long stat = Main .getStatCalculator() - .getServerStat(completedRequest); + .getServerStat(settings); TextComponent prettyComponent = Main .getOutputManager() - .formatAndSaveServerStat(completedRequest, stat); + .formatAndSaveServerStat(settings, stat); String prettyString = ComponentUtils .getTranslatableComponentSerializer() diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/StatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/StatRequest.java index c5567e2..dfd656a 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/StatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/StatRequest.java @@ -1,11 +1,15 @@ package com.artemis.the.gr8.playerstats.statistic.request; +import com.artemis.the.gr8.playerstats.Main; import com.artemis.the.gr8.playerstats.api.PlayerStats; import com.artemis.the.gr8.playerstats.statistic.result.StatResult; import com.artemis.the.gr8.playerstats.enums.Target; import org.bukkit.Material; import org.bukkit.Statistic; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; import org.bukkit.entity.EntityType; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** @@ -18,10 +22,44 @@ import org.jetbrains.annotations.Nullable; */ public abstract class StatRequest { - protected final RequestSettings requestSettings; + protected final Settings settings; - protected StatRequest(RequestSettings request) { - requestSettings = request; + protected StatRequest(CommandSender requester) { + settings = new Settings(requester); + } + + protected StatRequest configureUntyped(@NotNull Statistic statistic) { + if (statistic.getType() == Statistic.Type.UNTYPED) { + settings.setStatistic(statistic); + return this; + } + throw new IllegalArgumentException("This statistic is not of Type.Untyped"); + } + + protected StatRequest configureBlockOrItemType(@NotNull Statistic statistic, @NotNull Material material) throws IllegalArgumentException { + Statistic.Type type = statistic.getType(); + if (type == Statistic.Type.BLOCK && material.isBlock()) { + settings.setBlock(material); + } + else if (type == Statistic.Type.ITEM && material.isItem()){ + settings.setItem(material); + } + else { + throw new IllegalArgumentException("Either this statistic is not of Type.Block or Type.Item, or no valid block or item has been provided"); + } + settings.setStatistic(statistic); + settings.setSubStatEntryName(material.toString()); + return this; + } + + protected StatRequest configureEntityType(@NotNull Statistic statistic, @NotNull EntityType entityType) throws IllegalArgumentException { + if (statistic.getType() == Statistic.Type.ENTITY) { + settings.setStatistic(statistic); + settings.setSubStatEntryName(entityType.toString()); + settings.setEntity(entityType); + return this; + } + throw new IllegalArgumentException("This statistic is not of Type.Entity"); } /** @@ -35,53 +73,167 @@ public abstract class StatRequest { */ public abstract StatResult execute(); - /** - * Gets the Statistic that calling {@link #execute()} will calculate - * the data for. - * @return the Statistic - */ - public Statistic getStatisticSetting() { - return requestSettings.getStatistic(); + public boolean isValid() { + if (settings.statistic == null) { + return false; + } else if (settings.target == Target.PLAYER && settings.playerName == null) { + return false; + } else if (settings.statistic.getType() != Statistic.Type.UNTYPED && + settings.subStatEntryName == null) { + return false; + } else { + return hasMatchingSubStat(); + } + } + + private boolean hasMatchingSubStat() { + switch (settings.statistic.getType()) { + case BLOCK -> { + return settings.block != null; + } + case ENTITY -> { + return settings.entity != null; + } + case ITEM -> { + return settings.item != null; + } + default -> { + return true; + } + } } /** - * If the Statistic setting for this StatRequest is of Type.Block, - * this will get the Material that was set. - * - * @return a Material for which #isBlock is true, or null if no - * Material was set + * Use this method to view the settings that have + * been configured for this StatRequest. */ - public @Nullable Material getBlockSetting() { - return requestSettings.getBlock(); + public Settings getSettings() { + return settings; } - /** - * If the Statistic setting for this StatRequest is of Type.Item, - * this will get the Material that was set. - * - * @return a Material for which #isItem is true, or null if no - * Material was set - */ - public @Nullable Material getItemSetting() { - return requestSettings.getItem(); - } + public static final class Settings { + private final CommandSender sender; + private Statistic statistic; + private String playerName; + private Target target; + private int topListSize; - /** - * If the Statistic setting for this StatRequest is of Type.Entity, - * this will get the EntityType that was set. - * - * @return an EntityType, or null if no EntityType was set - */ - public @Nullable EntityType getEntitySetting() { - return requestSettings.getEntity(); - } + private String subStatEntryName; + private EntityType entity; + private Material block; + private Material item; + private boolean playerFlag; - /** - * Gets the Target that will be used when calling {@link #execute()}. - * - * @return the Target for this lookup (either Player, Server or Top) - */ - public Target getTargetSetting() { - return requestSettings.getTarget(); + /** + * Create a new {@link Settings} with default values: + *
- CommandSender sender (provided) + *
- Target target = {@link Target#TOP} + *
- int topListSize = 10 + *
- boolean playerFlag = false + * + * @param sender the CommandSender who prompted this RequestGenerator + */ + private Settings(@NotNull CommandSender sender) { + this.sender = sender; + target = Target.TOP; + playerFlag = false; + } + + void configureForPlayer(String playerName) { + setTarget(Target.PLAYER); + setPlayerName(playerName); + } + + void configureForServer() { + setTarget(Target.SERVER); + } + + void configureForTop(int topListSize) { + setTarget(Target.TOP); + + this.topListSize = topListSize != 0 ? + topListSize : + Main.getConfigHandler().getTopListMaxSize(); + } + + public @NotNull CommandSender getCommandSender() { + return sender; + } + + public boolean isConsoleSender() { + return sender instanceof ConsoleCommandSender; + } + + void setStatistic(Statistic statistic) { + this.statistic = statistic; + } + + public Statistic getStatistic() { + return statistic; + } + + private void setSubStatEntryName(String subStatEntry) { + this.subStatEntryName = subStatEntry; + } + + public @Nullable String getSubStatEntryName() { + return subStatEntryName; + } + + void setPlayerName(String playerName) { + this.playerName = playerName; + } + + public String getPlayerName() { + return playerName; + } + + void setPlayerFlag(boolean playerFlag) { + this.playerFlag = playerFlag; + } + + public boolean getPlayerFlag() { + return playerFlag; + } + + void setTarget(@NotNull Target target) { + this.target = target; + } + + public @NotNull Target getTarget() { + return target; + } + + void setTopListSize(int topListSize) { + this.topListSize = topListSize; + } + + public int getTopListSize() { + return this.topListSize; + } + + void setEntity(EntityType entity) { + this.entity = entity; + } + + public EntityType getEntity() { + return entity; + } + + void setBlock(Material block) { + this.block = block; + } + + public Material getBlock() { + return block; + } + + void setItem(Material item) { + this.item = item; + } + + public Material getItem() { + return item; + } } } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/TopStatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/TopStatRequest.java index 04c8f25..64bf073 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/TopStatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/TopStatRequest.java @@ -5,8 +5,10 @@ import com.artemis.the.gr8.playerstats.statistic.result.TopStatResult; import com.artemis.the.gr8.playerstats.api.RequestGenerator; import com.artemis.the.gr8.playerstats.msg.components.ComponentUtils; import net.kyori.adventure.text.TextComponent; +import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Statistic; +import org.bukkit.command.CommandSender; import org.bukkit.entity.EntityType; import org.jetbrains.annotations.NotNull; @@ -14,44 +16,43 @@ import java.util.LinkedHashMap; public final class TopStatRequest extends StatRequest> implements RequestGenerator> { - private final RequestHandler requestHandler; + public TopStatRequest(int topListSize) { + this(Bukkit.getConsoleSender(), topListSize); + } - public TopStatRequest(RequestSettings request) { - super(request); - requestHandler = new RequestHandler(request); + public TopStatRequest(CommandSender requester, int topListSize) { + super(requester); + super.settings.configureForTop(topListSize); } @Override - public TopStatRequest untyped(@NotNull Statistic statistic) { - RequestSettings completedRequest = requestHandler.untyped(statistic); - return new TopStatRequest(completedRequest); + public StatRequest> untyped(@NotNull Statistic statistic) { + return super.configureUntyped(statistic); } @Override - public TopStatRequest blockOrItemType(@NotNull Statistic statistic, @NotNull Material material) { - RequestSettings completedRequest = requestHandler.blockOrItemType(statistic, material); - return new TopStatRequest(completedRequest); + public StatRequest> blockOrItemType(@NotNull Statistic statistic, @NotNull Material material) { + return super.configureBlockOrItemType(statistic, material); } @Override - public TopStatRequest entityType(@NotNull Statistic statistic, @NotNull EntityType entityType) { - RequestSettings completedRequest = requestHandler.entityType(statistic, entityType); - return new TopStatRequest(completedRequest); + public StatRequest> entityType(@NotNull Statistic statistic, @NotNull EntityType entityType) { + return super.configureEntityType(statistic, entityType); } @Override public TopStatResult execute() { - return getStatResult(super.requestSettings); + return getStatResult(); } - private TopStatResult getStatResult(RequestSettings completedRequest) { + private TopStatResult getStatResult() { LinkedHashMap stat = Main .getStatCalculator() - .getTopStats(completedRequest); + .getTopStats(settings); TextComponent prettyComponent = Main .getOutputManager() - .formatAndSaveTopStat(completedRequest, stat); + .formatAndSaveTopStat(settings, stat); String prettyString = ComponentUtils .getTranslatableComponentSerializer() From e4fca5a0c8e5eccb146cfbf85447bdb451a7373f Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Fri, 7 Oct 2022 17:45:56 +0200 Subject: [PATCH 06/43] Rewrote StatCommand logic, got rid of RequestSettings and RequestHandler and instead made InternalStatRequest to mirror the other StatRequest classes --- .../com/artemis/the/gr8/playerstats/Main.java | 3 +- .../the/gr8/playerstats/ThreadManager.java | 15 +- .../gr8/playerstats/commands/StatCommand.java | 35 ++-- .../playerstats/msg/InternalFormatter.java | 37 ---- .../gr8/playerstats/msg/OutputManager.java | 18 +- .../gr8/playerstats/statistic/StatThread.java | 29 ++- .../request/InternalStatRequest.java | 142 ++++++++++++++ .../statistic/request/RequestHandler.java | 178 ----------------- .../statistic/request/RequestSettings.java | 183 ------------------ .../statistic/request/StatRequest.java | 66 ++----- 10 files changed, 213 insertions(+), 493 deletions(-) delete mode 100644 src/main/java/com/artemis/the/gr8/playerstats/msg/InternalFormatter.java create mode 100644 src/main/java/com/artemis/the/gr8/playerstats/statistic/request/InternalStatRequest.java delete mode 100644 src/main/java/com/artemis/the/gr8/playerstats/statistic/request/RequestHandler.java delete mode 100644 src/main/java/com/artemis/the/gr8/playerstats/statistic/request/RequestSettings.java diff --git a/src/main/java/com/artemis/the/gr8/playerstats/Main.java b/src/main/java/com/artemis/the/gr8/playerstats/Main.java index 655f669..ddba6d4 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/Main.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/Main.java @@ -9,7 +9,6 @@ import com.artemis.the.gr8.playerstats.commands.StatCommand; import com.artemis.the.gr8.playerstats.commands.TabCompleter; import com.artemis.the.gr8.playerstats.config.ConfigHandler; import com.artemis.the.gr8.playerstats.listeners.JoinListener; -import com.artemis.the.gr8.playerstats.msg.InternalFormatter; import com.artemis.the.gr8.playerstats.msg.MessageBuilder; import com.artemis.the.gr8.playerstats.msg.msgutils.LanguageKeyHandler; import com.artemis.the.gr8.playerstats.statistic.StatCalculator; @@ -111,7 +110,7 @@ public final class Main extends JavaPlugin { return playerStatsAPI; } - public static @NotNull InternalFormatter getOutputManager() throws IllegalStateException { + public static @NotNull OutputManager getOutputManager() throws IllegalStateException { if (outputManager == null) { throw new IllegalStateException("PlayerStats does not seem to be loaded!"); } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/ThreadManager.java b/src/main/java/com/artemis/the/gr8/playerstats/ThreadManager.java index 6dbd29d..e98b80a 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/ThreadManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/ThreadManager.java @@ -3,7 +3,6 @@ package com.artemis.the.gr8.playerstats; import com.artemis.the.gr8.playerstats.msg.OutputManager; import com.artemis.the.gr8.playerstats.config.ConfigHandler; import com.artemis.the.gr8.playerstats.enums.StandardMessage; -import com.artemis.the.gr8.playerstats.statistic.request.RequestSettings; import com.artemis.the.gr8.playerstats.reload.ReloadThread; import com.artemis.the.gr8.playerstats.statistic.StatCalculator; import com.artemis.the.gr8.playerstats.statistic.StatThread; @@ -64,19 +63,19 @@ public final class ThreadManager { } } - public void startStatThread(StatRequest.Settings requestSettings) { + public void startStatThread(StatRequest request) { statThreadID += 1; - String cmdSender = requestSettings.getCommandSender().getName(); + String cmdSender = request.getSettings().getCommandSender().getName(); if (config.limitStatRequests() && statThreads.containsKey(cmdSender)) { Thread runningThread = statThreads.get(cmdSender); if (runningThread.isAlive()) { - outputManager.sendFeedbackMsg(requestSettings.getCommandSender(), StandardMessage.REQUEST_ALREADY_RUNNING); + outputManager.sendFeedbackMsg(request.getSettings().getCommandSender(), StandardMessage.REQUEST_ALREADY_RUNNING); } else { - startNewStatThread(requestSettings); + startNewStatThread(request); } } else { - startNewStatThread(requestSettings); + startNewStatThread(request); } } @@ -96,9 +95,9 @@ public final class ThreadManager { return lastRecordedCalcTime; } - private void startNewStatThread(StatRequest.Settings requestSettings) { + private void startNewStatThread(StatRequest requestSettings) { lastActiveStatThread = new StatThread(outputManager, statCalculator, statThreadID, requestSettings, lastActiveReloadThread); - statThreads.put(requestSettings.getCommandSender().getName(), lastActiveStatThread); + statThreads.put(requestSettings.getSettings().getCommandSender().getName(), lastActiveStatThread); lastActiveStatThread.start(); } } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java b/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java index 84d4456..8d0639b 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java @@ -4,15 +4,14 @@ import com.artemis.the.gr8.playerstats.ThreadManager; import com.artemis.the.gr8.playerstats.enums.StandardMessage; import com.artemis.the.gr8.playerstats.enums.Target; import com.artemis.the.gr8.playerstats.msg.OutputManager; -import com.artemis.the.gr8.playerstats.statistic.request.RequestHandler; -import com.artemis.the.gr8.playerstats.statistic.request.RequestSettings; +import com.artemis.the.gr8.playerstats.statistic.request.*; import org.bukkit.Statistic; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.jetbrains.annotations.NotNull; -public final class StatCommand implements CommandExecutor { +public class StatCommand implements CommandExecutor { private static ThreadManager threadManager; private static OutputManager outputManager; @@ -32,14 +31,11 @@ public final class StatCommand implements CommandExecutor { outputManager.sendExamples(sender); } else { - RequestSettings baseRequest = RequestHandler.getBasicInternalStatRequest(sender); - RequestHandler requestHandler = new RequestHandler(baseRequest); - - RequestSettings completedRequest = requestHandler.getRequestFromArgs(args); - if (completedRequest.isValid()) { - threadManager.startStatThread(completedRequest); + InternalStatRequest request = new InternalStatRequest(sender, args); + if (request.isValid()) { + threadManager.startStatThread(request); } else { - sendFeedback(completedRequest); + sendFeedback(request); return false; } } @@ -47,7 +43,7 @@ public final class StatCommand implements CommandExecutor { } /** - * If a given {@link RequestSettings} object does not result in a valid + * If a given {@link StatRequest} object does not result in a valid * statistic look-up, this will send a feedback message to the CommandSender * that made the request. The following is checked: *
    @@ -56,23 +52,24 @@ public final class StatCommand implements CommandExecutor { *
  • If the target is Player, is a valid playerName provided? *
* - * @param requestSettings the RequestSettings to give feedback on + * @param request the StatRequest to give feedback on */ - private void sendFeedback(RequestSettings requestSettings) { - CommandSender sender = requestSettings.getCommandSender(); + private void sendFeedback(InternalStatRequest request) { + StatRequest.Settings settings = request.getSettings(); + CommandSender sender = settings.getCommandSender(); - if (requestSettings.getStatistic() == null) { + if (settings.getStatistic() == null) { outputManager.sendFeedbackMsg(sender, StandardMessage.MISSING_STAT_NAME); } - else if (requestSettings.getTarget() == Target.PLAYER && requestSettings.getPlayerName() == null) { + else if (settings.getTarget() == Target.PLAYER && settings.getPlayerName() == null) { outputManager.sendFeedbackMsg(sender, StandardMessage.MISSING_PLAYER_NAME); } else { - Statistic.Type type = requestSettings.getStatistic().getType(); - if (type != Statistic.Type.UNTYPED && requestSettings.getSubStatEntryName() == null) { + Statistic.Type type = settings.getStatistic().getType(); + if (type != Statistic.Type.UNTYPED && settings.getSubStatEntryName() == null) { outputManager.sendFeedbackMsgMissingSubStat(sender, type); } else { - outputManager.sendFeedbackMsgWrongSubStat(sender, type, requestSettings.getSubStatEntryName()); + outputManager.sendFeedbackMsgWrongSubStat(sender, type, settings.getSubStatEntryName()); } } } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/InternalFormatter.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/InternalFormatter.java deleted file mode 100644 index d63c8aa..0000000 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/InternalFormatter.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.artemis.the.gr8.playerstats.msg; - -import com.artemis.the.gr8.playerstats.statistic.request.RequestSettings; -import com.artemis.the.gr8.playerstats.statistic.StatCalculator; -import com.artemis.the.gr8.playerstats.statistic.request.StatRequest; -import net.kyori.adventure.text.*; -import org.jetbrains.annotations.ApiStatus.Internal; - -import java.util.LinkedHashMap; - -/** The {@link InternalFormatter} formats raw numbers into pretty messages. - * This Formatter takes a {@link RequestSettings} object and combines it - * with the raw data returned by the {@link StatCalculator}, and transforms - * those into a pretty message with all the relevant information in it. - * @see MessageBuilder - */ -@Internal -public interface InternalFormatter { - - /** @return a TextComponent with the following parts: - *
[player-name]: [number] [stat-name] {sub-stat-name} - */ - TextComponent formatAndSavePlayerStat(StatRequest.Settings requestSettings, int playerStat); - - /** @return a TextComponent with the following parts: - *
[Total on] [server-name]: [number] [stat-name] [sub-stat-name] - */ - TextComponent formatAndSaveServerStat(StatRequest.Settings requestSettings, long serverStat); - - /** @return a TextComponent with the following parts: - *
[PlayerStats] [Top 10] [stat-name] [sub-stat-name] - *
[1.] [player-name] [number] - *
[2.] [player-name] [number] - *
[3.] etc... - */ - TextComponent formatAndSaveTopStat(StatRequest.Settings requestSettings, LinkedHashMap topStats); -} \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java index 22bbc95..1b1ae25 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java @@ -3,7 +3,6 @@ package com.artemis.the.gr8.playerstats.msg; import com.artemis.the.gr8.playerstats.ShareManager; import com.artemis.the.gr8.playerstats.config.ConfigHandler; import com.artemis.the.gr8.playerstats.enums.StandardMessage; -import com.artemis.the.gr8.playerstats.statistic.request.RequestSettings; import com.artemis.the.gr8.playerstats.msg.components.BukkitConsoleComponentFactory; import com.artemis.the.gr8.playerstats.msg.components.PrideComponentFactory; import com.artemis.the.gr8.playerstats.statistic.request.StatRequest; @@ -32,7 +31,7 @@ import static com.artemis.the.gr8.playerstats.enums.StandardMessage.*; * for Players (mainly to deal with the lack of hover-text, * and for Bukkit consoles to make up for the lack of hex-colors). */ -public final class OutputManager implements InternalFormatter { +public final class OutputManager { private static BukkitAudiences adventure; private static ConfigHandler config; @@ -55,7 +54,9 @@ public final class OutputManager implements InternalFormatter { getMessageBuilders(); } - @Override + /** @return a TextComponent with the following parts: + *
[player-name]: [number] [stat-name] {sub-stat-name} + */ public TextComponent formatAndSavePlayerStat(@NotNull StatRequest.Settings requestSettings, int playerStat) { BiFunction playerStatFunction = getMessageBuilder(requestSettings.getCommandSender()).formattedPlayerStatFunction(playerStat, requestSettings); @@ -63,7 +64,9 @@ public final class OutputManager implements InternalFormatter { return processFunction(requestSettings.getCommandSender(), playerStatFunction); } - @Override + /** @return a TextComponent with the following parts: + *
[Total on] [server-name]: [number] [stat-name] [sub-stat-name] + */ public TextComponent formatAndSaveServerStat(@NotNull StatRequest.Settings requestSettings, long serverStat) { BiFunction serverStatFunction = getMessageBuilder(requestSettings.getCommandSender()).formattedServerStatFunction(serverStat, requestSettings); @@ -71,7 +74,12 @@ public final class OutputManager implements InternalFormatter { return processFunction(requestSettings.getCommandSender(), serverStatFunction); } - @Override + /** @return a TextComponent with the following parts: + *
[PlayerStats] [Top 10] [stat-name] [sub-stat-name] + *
[1.] [player-name] [number] + *
[2.] [player-name] [number] + *
[3.] etc... + */ public TextComponent formatAndSaveTopStat(@NotNull StatRequest.Settings requestSettings, @NotNull LinkedHashMap topStats) { BiFunction topStatFunction = getMessageBuilder(requestSettings.getCommandSender()).formattedTopStatFunction(topStats, requestSettings); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatThread.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatThread.java index aad139b..a907dd4 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatThread.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatThread.java @@ -6,7 +6,6 @@ import com.artemis.the.gr8.playerstats.statistic.request.StatRequest; import com.artemis.the.gr8.playerstats.utils.MyLogger; import com.artemis.the.gr8.playerstats.enums.StandardMessage; import com.artemis.the.gr8.playerstats.enums.Target; -import com.artemis.the.gr8.playerstats.statistic.request.RequestSettings; import com.artemis.the.gr8.playerstats.reload.ReloadThread; import net.kyori.adventure.text.TextComponent; import org.jetbrains.annotations.Nullable; @@ -22,16 +21,16 @@ public final class StatThread extends Thread { private static StatCalculator statCalculator; private final ReloadThread reloadThread; - private final StatRequest.Settings requestSettings; + private final StatRequest statRequest; - public StatThread(OutputManager m, StatCalculator t, int ID, StatRequest.Settings s, @Nullable ReloadThread r) { + public StatThread(OutputManager m, StatCalculator t, int ID, StatRequest s, @Nullable ReloadThread r) { outputManager = m; statCalculator = t; reloadThread = r; - requestSettings = s; + statRequest = s; - this.setName("StatThread-" + requestSettings.getCommandSender().getName() + "-" + ID); + this.setName("StatThread-" + statRequest.getSettings().getCommandSender().getName() + "-" + ID); MyLogger.logHighLevelMsg(this.getName() + " created!"); } @@ -39,13 +38,13 @@ public final class StatThread extends Thread { public void run() throws IllegalStateException, NullPointerException { MyLogger.logHighLevelMsg(this.getName() + " started!"); - if (requestSettings == null) { + if (statRequest == null) { throw new NullPointerException("No statistic requestSettings was found!"); } if (reloadThread != null && reloadThread.isAlive()) { try { MyLogger.logLowLevelMsg(this.getName() + ": Waiting for " + reloadThread.getName() + " to finish up..."); - outputManager.sendFeedbackMsg(requestSettings.getCommandSender(), StandardMessage.STILL_RELOADING); + outputManager.sendFeedbackMsg(statRequest.getSettings().getCommandSender(), StandardMessage.STILL_RELOADING); reloadThread.join(); } catch (InterruptedException e) { @@ -56,21 +55,21 @@ public final class StatThread extends Thread { long lastCalc = ThreadManager.getLastRecordedCalcTime(); if (lastCalc > 2000) { - outputManager.sendFeedbackMsgWaitAMoment(requestSettings.getCommandSender(), lastCalc > 20000); + outputManager.sendFeedbackMsgWaitAMoment(statRequest.getSettings().getCommandSender(), lastCalc > 20000); } - Target selection = requestSettings.getTarget(); + Target selection = statRequest.getSettings().getTarget(); try { TextComponent statResult = switch (selection) { - case PLAYER -> outputManager.formatAndSavePlayerStat(requestSettings, statCalculator.getPlayerStat(requestSettings)); - case TOP -> outputManager.formatAndSaveTopStat(requestSettings, statCalculator.getTopStats(requestSettings)); - case SERVER -> outputManager.formatAndSaveServerStat(requestSettings, statCalculator.getServerStat(requestSettings)); + case PLAYER -> outputManager.formatAndSavePlayerStat(statRequest.getSettings(), statCalculator.getPlayerStat(statRequest.getSettings())); + case TOP -> outputManager.formatAndSaveTopStat(statRequest.getSettings(), statCalculator.getTopStats(statRequest.getSettings())); + case SERVER -> outputManager.formatAndSaveServerStat(statRequest.getSettings(), statCalculator.getServerStat(statRequest.getSettings())); }; - outputManager.sendToCommandSender(requestSettings.getCommandSender(), statResult); + outputManager.sendToCommandSender(statRequest.getSettings().getCommandSender(), statResult); } catch (ConcurrentModificationException e) { - if (!requestSettings.isConsoleSender()) { - outputManager.sendFeedbackMsg(requestSettings.getCommandSender(), StandardMessage.UNKNOWN_ERROR); + if (!statRequest.getSettings().isConsoleSender()) { + outputManager.sendFeedbackMsg(statRequest.getSettings().getCommandSender(), StandardMessage.UNKNOWN_ERROR); } } } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/InternalStatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/InternalStatRequest.java new file mode 100644 index 0000000..403d2bd --- /dev/null +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/InternalStatRequest.java @@ -0,0 +1,142 @@ +package com.artemis.the.gr8.playerstats.statistic.request; + +import com.artemis.the.gr8.playerstats.Main; +import com.artemis.the.gr8.playerstats.statistic.result.StatResult; +import com.artemis.the.gr8.playerstats.utils.EnumHandler; +import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; +import org.bukkit.Material; +import org.bukkit.Statistic; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class InternalStatRequest extends StatRequest { + + private final OfflinePlayerHandler offlinePlayerHandler; + private final EnumHandler enumHandler; + private final Pattern targetPattern; + + public InternalStatRequest(CommandSender sender, String[] args) { + super(sender); + offlinePlayerHandler = Main.getOfflinePlayerHandler(); + enumHandler = Main.getEnumHandler(); + targetPattern = Pattern.compile("top|server|me|player"); + + String[] argsMinusTarget = extractAndStoreTarget(sender, args); + String[] argsMinusStatistic = extractAndStoreStatistic(argsMinusTarget); + findAndStoreSubStat(argsMinusStatistic); + } + + @Override + public StatResult execute() { + return null; + } + + private String[] extractAndStoreTarget(CommandSender sender, @NotNull String[] leftoverArgs) { + String playerName = tryToFindPlayerName(leftoverArgs); + + for (String arg : leftoverArgs) { + Matcher targetMatcher = targetPattern.matcher(arg); + if (targetMatcher.find()) { + switch (targetMatcher.group()) { + case "player" -> { + if (playerName == null) { + continue; + } + else { + super.settings.configureForPlayer(playerName); + String[] extractedPlayerName = removeArg(leftoverArgs, playerName); + return removeArg(extractedPlayerName, arg); + } + } + case "me" -> { + if (sender instanceof Player) { + super.settings.configureForPlayer(sender.getName()); + } else { + super.settings.configureForServer(); + } + } + case "server" -> super.settings.configureForServer(); + case "top" -> super.settings.configureForTop(); + } + return removeArg(leftoverArgs, arg); + } + } + //if no target is found, but there is a playerName, assume target = Target.PLAYER + if (playerName != null) { + super.settings.configureForPlayer(playerName); + return removeArg(leftoverArgs, playerName); + } + //otherwise, assume target = Target.TOP + super.settings.configureForTop(); + return leftoverArgs; + } + + private String[] extractAndStoreStatistic(@NotNull String[] leftoverArgs) { + for (String arg : leftoverArgs) { + if (enumHandler.isStatistic(arg)) { + super.settings.setStatistic(EnumHandler.getStatEnum(arg)); + return removeArg(leftoverArgs, arg); + } + } + return leftoverArgs; + } + + private void findAndStoreSubStat(@NotNull String[] leftoverArgs) { + Statistic statistic = super.settings.getStatistic(); + if (statistic == null || leftoverArgs.length == 0) { + return; + } + + for (String arg : leftoverArgs) { + if (enumHandler.isSubStatEntry(arg)) { + switch (statistic.getType()) { + case UNTYPED -> super.configureUntyped(statistic); + case ITEM -> { + Material item = EnumHandler.getItemEnum(arg); + if (item != null) { + super.configureBlockOrItemType(statistic, item); + } + } + case BLOCK -> { + Material block = EnumHandler.getBlockEnum(arg); + if (block != null) { + super.configureBlockOrItemType(statistic, block); + } + } + case ENTITY -> { + EntityType entityType = EnumHandler.getEntityEnum(arg); + if (entityType != null) { + super.configureEntityType(statistic, entityType); + } + } + } + break; + } + } + } + + @Contract(pure = true) + private @Nullable String tryToFindPlayerName(@NotNull String[] args) { + for (String arg : args) { + if (offlinePlayerHandler.isRelevantPlayer(arg)) { + return arg; + } + } + return null; + } + + private String[] removeArg(@NotNull String[] args, String argToRemove) { + ArrayList currentArgs = new ArrayList<>(Arrays.asList(args)); + currentArgs.remove(argToRemove); + return currentArgs.toArray(String[]::new); + } +} diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/RequestHandler.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/RequestHandler.java deleted file mode 100644 index 9fdfe21..0000000 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/RequestHandler.java +++ /dev/null @@ -1,178 +0,0 @@ -package com.artemis.the.gr8.playerstats.statistic.request; - -import com.artemis.the.gr8.playerstats.Main; -import com.artemis.the.gr8.playerstats.utils.EnumHandler; -import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; -import com.artemis.the.gr8.playerstats.enums.Target; -import org.bukkit.Material; -import org.bukkit.Statistic; -import org.bukkit.command.CommandSender; -import org.bukkit.command.ConsoleCommandSender; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; - -public final class RequestHandler { - - private final RequestSettings requestSettings; - - public RequestHandler(RequestSettings request) { - requestSettings = request; - } - - public static RequestSettings getBasicPlayerStatRequest(String playerName) { - RequestSettings request = RequestSettings.getBasicAPIRequest(); - request.setTarget(Target.PLAYER); - request.setPlayerName(playerName); - return request; - } - - public static RequestSettings getBasicServerStatRequest() { - RequestSettings request = RequestSettings.getBasicAPIRequest(); - request.setTarget(Target.SERVER); - return request; - } - - public static RequestSettings getBasicTopStatRequest(int topListSize) { - RequestSettings request = RequestSettings.getBasicAPIRequest(); - request.setTarget(Target.TOP); - request.setTopListSize(topListSize != 0 ? topListSize : Main.getConfigHandler().getTopListMaxSize()); - return request; - } - - /** - * @param sender the CommandSender that requested this specific statistic - */ - public static RequestSettings getBasicInternalStatRequest(CommandSender sender) { - RequestSettings request = RequestSettings.getBasicRequest(sender); - request.setTopListSize(Main.getConfigHandler().getTopListMaxSize()); - return request; - } - - public RequestSettings untyped(@NotNull Statistic statistic) throws IllegalArgumentException { - if (statistic.getType() == Statistic.Type.UNTYPED) { - requestSettings.setStatistic(statistic); - return requestSettings; - } - throw new IllegalArgumentException("This statistic is not of Type.Untyped"); - } - - public RequestSettings blockOrItemType(@NotNull Statistic statistic, @NotNull Material material) throws IllegalArgumentException { - Statistic.Type type = statistic.getType(); - if (type == Statistic.Type.BLOCK && material.isBlock()) { - requestSettings.setBlock(material); - } - else if (type == Statistic.Type.ITEM && material.isItem()){ - requestSettings.setItem(material); - } - else { - throw new IllegalArgumentException("Either this statistic is not of Type.Block or Type.Item, or no valid block or item has been provided"); - } - requestSettings.setStatistic(statistic); - requestSettings.setSubStatEntryName(material.toString()); - return requestSettings; - } - - public RequestSettings entityType(@NotNull Statistic statistic, @NotNull EntityType entityType) throws IllegalArgumentException { - if (statistic.getType() == Statistic.Type.ENTITY) { - requestSettings.setStatistic(statistic); - requestSettings.setSubStatEntryName(entityType.toString()); - requestSettings.setEntity(entityType); - return requestSettings; - } - throw new IllegalArgumentException("This statistic is not of Type.Entity"); - } - - /** - * This will create a {@link RequestSettings} object from the provided args, - * with the requesting Player (or Console) as CommandSender. This CommandSender - * will receive feedback messages if the RequestSettings could not be created. - * - * @param args an Array of args such as a CommandSender would put in Minecraft chat: - *
    - *
  • a statName (example: "mine_block") - *
  • if applicable, a subStatEntryName (example: diorite) - *
  • a target for this lookup: can be "top", "server", "player" - * (or "me" to indicate the current CommandSender) - *
  • if "player" was chosen, include a playerName - *
- * @return the generated RequestSettings - */ - public RequestSettings getRequestFromArgs(String[] args) { - EnumHandler enumHandler = Main.getEnumHandler(); - OfflinePlayerHandler offlinePlayerHandler = Main.getOfflinePlayerHandler(); - CommandSender sender = requestSettings.getCommandSender(); - - for (String arg : args) { - //check for statName - if (enumHandler.isStatistic(arg) && requestSettings.getStatistic() == null) { - requestSettings.setStatistic(EnumHandler.getStatEnum(arg)); - } - //check for subStatEntry and playerFlag - else if (enumHandler.isSubStatEntry(arg)) { - if (arg.equalsIgnoreCase("player") && !requestSettings.getPlayerFlag()) { - requestSettings.setPlayerFlag(true); - } else { - if (requestSettings.getSubStatEntryName() == null) requestSettings.setSubStatEntryName(arg); - } - } - //check for selection - else if (arg.equalsIgnoreCase("top")) { - requestSettings.setTarget(Target.TOP); - } else if (arg.equalsIgnoreCase("server")) { - requestSettings.setTarget(Target.SERVER); - } else if (arg.equalsIgnoreCase("me")) { - if (sender instanceof Player) { - requestSettings.setPlayerName(sender.getName()); - requestSettings.setTarget(Target.PLAYER); - } else if (sender instanceof ConsoleCommandSender) { - requestSettings.setTarget(Target.SERVER); - } - } else if (offlinePlayerHandler.isRelevantPlayer(arg) && requestSettings.getPlayerName() == null) { - requestSettings.setPlayerName(arg); - requestSettings.setTarget(Target.PLAYER); - } - } - patchRequest(requestSettings); - return requestSettings; - } - - /** - * Adjust the RequestSettings object if needed: unpack the playerFlag - * into a subStatEntry, try to retrieve the corresponding Enum Constant - * for any relevant block/entity/item, and remove any unnecessary - * subStatEntries. - */ - private void patchRequest(RequestSettings requestSettings) { - if (requestSettings.getStatistic() != null) { - Statistic.Type type = requestSettings.getStatistic().getType(); - - if (requestSettings.getPlayerFlag()) { //unpack the playerFlag - if (type == Statistic.Type.ENTITY && requestSettings.getSubStatEntryName() == null) { - requestSettings.setSubStatEntryName("player"); - } else { - requestSettings.setTarget(Target.PLAYER); - } - } - - String subStatEntry = requestSettings.getSubStatEntryName(); - switch (type) { //attempt to convert relevant subStatEntries into their corresponding Enum Constant - case BLOCK -> { - Material block = EnumHandler.getBlockEnum(subStatEntry); - if (block != null) requestSettings.setBlock(block); - } - case ENTITY -> { - EntityType entity = EnumHandler.getEntityEnum(subStatEntry); - if (entity != null) requestSettings.setEntity(entity); - } - case ITEM -> { - Material item = EnumHandler.getItemEnum(subStatEntry); - if (item != null) requestSettings.setItem(item); - } - case UNTYPED -> { //remove unnecessary subStatEntries - if (subStatEntry != null) requestSettings.setSubStatEntryName(null); - } - } - } - } -} \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/RequestSettings.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/RequestSettings.java deleted file mode 100644 index 454f674..0000000 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/RequestSettings.java +++ /dev/null @@ -1,183 +0,0 @@ -package com.artemis.the.gr8.playerstats.statistic.request; - -import com.artemis.the.gr8.playerstats.api.RequestGenerator; -import com.artemis.the.gr8.playerstats.enums.Target; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.Statistic; -import org.bukkit.command.CommandSender; -import org.bukkit.command.ConsoleCommandSender; -import org.bukkit.entity.EntityType; -import org.jetbrains.annotations.NotNull; - -/** - * The object PlayerStats uses to calculate and format the requested - * statistic. The settings in this RequestSettings object can be - * configured from two different sources: - *
- Internally: by PlayerStats itself when /stat is called, - * using the args provided by the CommandSender. - *
- Externally: through the API methods provided by the - * {@link RequestGenerator} interface. - *
- *
For this RequestSettings object to be valid, the following - * values need to be set: - *
    - *
  • a {@link Statistic} statistic
  • - *
  • if this Statistic is not of {@link Statistic.Type} Untyped, - * a subStatEntryName needs to be set, together with one - * of the following values: - *
    - for Type.Block: a {@link Material} blockMaterial - *
    - for Type.Item: a {@link Material} itemMaterial - *
    - for Type.Entity: an {@link EntityType} entityType - *
  • a {@link Target} target (defaults to Top) - *
  • if the target is Target.Player, a - * playerName needs to be added - *
- */ -public final class RequestSettings { - - private final CommandSender sender; - private Statistic statistic; - private String playerName; - private Target target; - private int topListSize; - - private String subStatEntryName; - private EntityType entity; - private Material block; - private Material item; - private boolean playerFlag; - - /** - * Create a new {@link RequestSettings} with default values: - *
- CommandSender sender (provided) - *
- Target target = {@link Target#TOP} - *
- int topListSize = 10 - *
- boolean playerFlag = false - * - * @param sender the CommandSender who prompted this RequestGenerator - */ - private RequestSettings(@NotNull CommandSender sender) { - this.sender = sender; - target = Target.TOP; - playerFlag = false; - } - - public static RequestSettings getBasicRequest(CommandSender sender) { - return new RequestSettings(sender); - } - - public static RequestSettings getBasicAPIRequest() { - return new RequestSettings(Bukkit.getConsoleSender()); - } - - public @NotNull CommandSender getCommandSender() { - return sender; - } - - public boolean isConsoleSender() { - return sender instanceof ConsoleCommandSender; - } - - public void setStatistic(Statistic statistic) { - this.statistic = statistic; - } - - public Statistic getStatistic() { - return statistic; - } - - public void setSubStatEntryName(String subStatEntry) { - this.subStatEntryName = subStatEntry; - } - - public String getSubStatEntryName() { - return subStatEntryName; - } - - public void setPlayerName(String playerName) { - this.playerName = playerName; - } - - public String getPlayerName() { - return playerName; - } - - public void setPlayerFlag(boolean playerFlag) { - this.playerFlag = playerFlag; - } - - public boolean getPlayerFlag() { - return playerFlag; - } - - public void setTarget(@NotNull Target target) { - this.target = target; - } - - public @NotNull Target getTarget() { - return target; - } - - public void setTopListSize(int topListSize) { - this.topListSize = topListSize; - } - - public int getTopListSize() { - return this.topListSize; - } - - public void setEntity(EntityType entity) { - this.entity = entity; - } - - public EntityType getEntity() { - return entity; - } - - public void setBlock(Material block) { - this.block = block; - } - - public Material getBlock() { - return block; - } - - public void setItem(Material item) { - this.item = item; - } - - public Material getItem() { - return item; - } - - public boolean isValid() { - if (statistic == null) { - return false; - } else if (target == Target.PLAYER && playerName == null) { - return false; - } else if (statistic.getType() != Statistic.Type.UNTYPED && - subStatEntryName == null) { - return false; - } else { - return hasMatchingSubStat(); - } - } - - private boolean hasMatchingSubStat() { - switch (statistic.getType()) { - case BLOCK -> { - return block != null; - } - case ENTITY -> { - return entity != null; - } - case ITEM -> { - return item != null; - } - default -> { - return true; - } - } - } -} \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/StatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/StatRequest.java index dfd656a..570e25b 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/StatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/StatRequest.java @@ -73,6 +73,14 @@ public abstract class StatRequest { */ public abstract StatResult execute(); + /** + * Use this method to view the settings that have + * been configured for this StatRequest. + */ + public Settings getSettings() { + return settings; + } + public boolean isValid() { if (settings.statistic == null) { return false; @@ -103,14 +111,6 @@ public abstract class StatRequest { } } - /** - * Use this method to view the settings that have - * been configured for this StatRequest. - */ - public Settings getSettings() { - return settings; - } - public static final class Settings { private final CommandSender sender; private Statistic statistic; @@ -122,38 +122,32 @@ public abstract class StatRequest { private EntityType entity; private Material block; private Material item; - private boolean playerFlag; /** - * Create a new {@link Settings} with default values: - *
- CommandSender sender (provided) - *
- Target target = {@link Target#TOP} - *
- int topListSize = 10 - *
- boolean playerFlag = false - * * @param sender the CommandSender who prompted this RequestGenerator */ private Settings(@NotNull CommandSender sender) { - this.sender = sender; - target = Target.TOP; - playerFlag = false; + this.sender = sender; } void configureForPlayer(String playerName) { - setTarget(Target.PLAYER); - setPlayerName(playerName); + this.target = Target.PLAYER; + this.playerName = playerName; } void configureForServer() { - setTarget(Target.SERVER); + this.target = Target.SERVER; + } + + void configureForTop() { + configureForTop(Main.getConfigHandler().getTopListMaxSize()); } void configureForTop(int topListSize) { - setTarget(Target.TOP); - - this.topListSize = topListSize != 0 ? - topListSize : - Main.getConfigHandler().getTopListMaxSize(); + this.target = Target.TOP; + this.topListSize = topListSize != 0 ? + topListSize : + Main.getConfigHandler().getTopListMaxSize(); } public @NotNull CommandSender getCommandSender() { @@ -180,34 +174,14 @@ public abstract class StatRequest { return subStatEntryName; } - void setPlayerName(String playerName) { - this.playerName = playerName; - } - public String getPlayerName() { return playerName; } - void setPlayerFlag(boolean playerFlag) { - this.playerFlag = playerFlag; - } - - public boolean getPlayerFlag() { - return playerFlag; - } - - void setTarget(@NotNull Target target) { - this.target = target; - } - public @NotNull Target getTarget() { return target; } - void setTopListSize(int topListSize) { - this.topListSize = topListSize; - } - public int getTopListSize() { return this.topListSize; } From b46a25d23fd9bc29261588d17ad19426df113f95 Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Fri, 7 Oct 2022 19:48:37 +0200 Subject: [PATCH 07/43] Merged different StatResult classes into one typed record --- .../request/InternalStatRequest.java | 2 +- .../statistic/request/PlayerStatRequest.java | 10 ++-- .../statistic/request/ServerStatRequest.java | 10 ++-- .../statistic/request/TopStatRequest.java | 10 ++-- .../statistic/result/InternalStatResult.java | 5 +- .../statistic/result/PlayerStatResult.java | 21 -------- .../statistic/result/ServerStatResult.java | 21 -------- .../statistic/result/StatResult.java | 48 ++++++++++--------- .../statistic/result/TopStatResult.java | 23 --------- 9 files changed, 36 insertions(+), 114 deletions(-) delete mode 100644 src/main/java/com/artemis/the/gr8/playerstats/statistic/result/PlayerStatResult.java delete mode 100644 src/main/java/com/artemis/the/gr8/playerstats/statistic/result/ServerStatResult.java delete mode 100644 src/main/java/com/artemis/the/gr8/playerstats/statistic/result/TopStatResult.java diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/InternalStatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/InternalStatRequest.java index 403d2bd..69c886c 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/InternalStatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/InternalStatRequest.java @@ -18,7 +18,7 @@ import java.util.Arrays; import java.util.regex.Matcher; import java.util.regex.Pattern; -public class InternalStatRequest extends StatRequest { +public final class InternalStatRequest extends StatRequest { private final OfflinePlayerHandler offlinePlayerHandler; private final EnumHandler enumHandler; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/PlayerStatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/PlayerStatRequest.java index d84ffd8..2052199 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/PlayerStatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/PlayerStatRequest.java @@ -1,9 +1,9 @@ package com.artemis.the.gr8.playerstats.statistic.request; import com.artemis.the.gr8.playerstats.Main; -import com.artemis.the.gr8.playerstats.statistic.result.PlayerStatResult; import com.artemis.the.gr8.playerstats.api.RequestGenerator; import com.artemis.the.gr8.playerstats.msg.components.ComponentUtils; +import com.artemis.the.gr8.playerstats.statistic.result.StatResult; import net.kyori.adventure.text.TextComponent; import org.bukkit.Bukkit; import org.bukkit.Material; @@ -39,11 +39,7 @@ public final class PlayerStatRequest extends StatRequest implements Req } @Override - public PlayerStatResult execute() { - return getStatResult(); - } - - private PlayerStatResult getStatResult() { + public @NotNull StatResult execute() { int stat = Main .getStatCalculator() .getPlayerStat(settings); @@ -56,6 +52,6 @@ public final class PlayerStatRequest extends StatRequest implements Req .getTranslatableComponentSerializer() .serialize(prettyComponent); - return new PlayerStatResult(stat, prettyComponent, prettyString); + return new StatResult<>(stat, prettyComponent, prettyString); } } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/ServerStatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/ServerStatRequest.java index f4b19fb..2e50082 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/ServerStatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/ServerStatRequest.java @@ -1,9 +1,9 @@ package com.artemis.the.gr8.playerstats.statistic.request; import com.artemis.the.gr8.playerstats.Main; -import com.artemis.the.gr8.playerstats.statistic.result.ServerStatResult; import com.artemis.the.gr8.playerstats.api.RequestGenerator; import com.artemis.the.gr8.playerstats.msg.components.ComponentUtils; +import com.artemis.the.gr8.playerstats.statistic.result.StatResult; import net.kyori.adventure.text.TextComponent; import org.bukkit.Bukkit; import org.bukkit.Material; @@ -39,11 +39,7 @@ public final class ServerStatRequest extends StatRequest implements Reques } @Override - public ServerStatResult execute() { - return getStatResult(); - } - - private ServerStatResult getStatResult() { + public @NotNull StatResult execute() { long stat = Main .getStatCalculator() .getServerStat(settings); @@ -56,6 +52,6 @@ public final class ServerStatRequest extends StatRequest implements Reques .getTranslatableComponentSerializer() .serialize(prettyComponent); - return new ServerStatResult(stat, prettyComponent, prettyString); + return new StatResult<>(stat, prettyComponent, prettyString); } } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/TopStatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/TopStatRequest.java index 64bf073..219365b 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/TopStatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/TopStatRequest.java @@ -1,7 +1,7 @@ package com.artemis.the.gr8.playerstats.statistic.request; import com.artemis.the.gr8.playerstats.Main; -import com.artemis.the.gr8.playerstats.statistic.result.TopStatResult; +import com.artemis.the.gr8.playerstats.statistic.result.StatResult; import com.artemis.the.gr8.playerstats.api.RequestGenerator; import com.artemis.the.gr8.playerstats.msg.components.ComponentUtils; import net.kyori.adventure.text.TextComponent; @@ -41,11 +41,7 @@ public final class TopStatRequest extends StatRequest> execute() { LinkedHashMap stat = Main .getStatCalculator() .getTopStats(settings); @@ -58,6 +54,6 @@ public final class TopStatRequest extends StatRequest(stat, prettyComponent, prettyString); } } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/result/InternalStatResult.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/result/InternalStatResult.java index 4afc930..3a63401 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/result/InternalStatResult.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/result/InternalStatResult.java @@ -7,7 +7,7 @@ import net.kyori.adventure.text.TextComponent; * This Record is used to store stat-results internally, * so Players can share them by clicking a share-button. */ -public record InternalStatResult(String executorName, TextComponent formattedValue, int ID) implements StatResult { +public record InternalStatResult(String executorName, TextComponent formattedValue, int ID) { /** * Gets the ID number for this StatResult. Unlike for the @@ -19,17 +19,14 @@ public record InternalStatResult(String executorName, TextComponent formattedVal * @return Integer that represents this StatResult's ID number */ - @Override public Integer getNumericalValue() { return ID; } - @Override public TextComponent getFormattedTextComponent() { return formattedValue; } - @Override public String getFormattedString() { return ComponentUtils.getTranslatableComponentSerializer() .serialize(formattedValue); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/result/PlayerStatResult.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/result/PlayerStatResult.java deleted file mode 100644 index 960d2e7..0000000 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/result/PlayerStatResult.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.artemis.the.gr8.playerstats.statistic.result; - -import net.kyori.adventure.text.TextComponent; - -public record PlayerStatResult(int value, TextComponent formattedComponent, String formattedString) implements StatResult { - - @Override - public Integer getNumericalValue() { - return value; - } - - @Override - public TextComponent getFormattedTextComponent() { - return formattedComponent; - } - - @Override - public String getFormattedString() { - return formattedString; - } -} \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/result/ServerStatResult.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/result/ServerStatResult.java deleted file mode 100644 index 0eddb56..0000000 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/result/ServerStatResult.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.artemis.the.gr8.playerstats.statistic.result; - -import net.kyori.adventure.text.TextComponent; - -public record ServerStatResult(long value, TextComponent formattedComponent, String formattedString) implements StatResult { - - @Override - public Long getNumericalValue() { - return value; - } - - @Override - public TextComponent getFormattedTextComponent() { - return formattedComponent; - } - - @Override - public String getFormattedString() { - return formattedString; - } -} diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/result/StatResult.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/result/StatResult.java index 8c38fec..973e5ff 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/result/StatResult.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/result/StatResult.java @@ -25,7 +25,7 @@ import net.kyori.adventure.text.TextComponent; *
[2.] [player-name] [.....] [formatted-number] *
[3.] etc... * - + *

* By default, the resulting message is a {@link TextComponent}, which can be * sent directly to a Minecraft client or console with the Adventure library. * To send a Component, you need to get a {@link BukkitAudiences} object, @@ -35,44 +35,46 @@ import net.kyori.adventure.text.TextComponent; * on how to get and use the BukkitAudiences object can be found on * Adventure's website. * - *

You can also use the provided {@link #getFormattedString()} method to get the + *

You can also use the provided {@link #formattedString ()} method to get the * same information in String-format. Don't use Adventure's #content() * or #toString() methods on the Components - those won't get the actual * message. And finally, if you want the results to be formatted differently, * you can get an instance of the {@link ApiFormatter}. */ -public interface StatResult { +public record StatResult(T value, TextComponent formattedComponent, String formattedString) { /** - * Gets the raw number for the completed stat-lookup this {@link StatResult} - * stores. + * Gets the raw number for the completed stat-lookup this {@link StatResult} stores. * - * @return {@code Integer} for playerStat, {@code Long} for serverStat, - * and {@code LinkedHashMap} for topStat + * @return {@code Integer} for playerStat, {@code Long} for serverStat, and {@code LinkedHashMap} + * for topStat */ - T getNumericalValue(); + T getNumericalValue() { + return value; + } /** - * Gets the formatted message for the completed stat-lookup this - * StatResult stores. - - * @return a {@code TextComponent} message containing the formatted number. - * This message follows the same style/color/language settings that are - * specified in the PlayerStats config. See class description for more + * Gets the formatted message for the completed stat-lookup this StatResult stores. + * + * @return a {@code TextComponent} message containing the formatted number. This message follows the same + * style/color/language settings that are specified in the PlayerStats config. See class description for more * information. * @see StatResult */ - TextComponent getFormattedTextComponent(); + TextComponent getFormattedTextComponent() { + return formattedComponent; + } /** - * Gets the formatted message for the completed stat-lookup this - * StatResult stores. - - * @return a String message containing the formatted number. This message - * follows the same style and color settings that are specified in the - * PlayerStats config, but it is not translatable (it is always plain English). - * See class description for more information. + * Gets the formatted message for the completed stat-lookup this StatResult stores. + * + * @return a String message containing the formatted number. This message follows the same style and color settings + * that are specified in the PlayerStats config, but it is not translatable (it is always plain English). See class + * description for more information. * @see StatResult */ - String getFormattedString(); + @Override + public String formattedString() { + return formattedString; + } } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/result/TopStatResult.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/result/TopStatResult.java deleted file mode 100644 index dcd8eba..0000000 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/result/TopStatResult.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.artemis.the.gr8.playerstats.statistic.result; - -import net.kyori.adventure.text.TextComponent; - -import java.util.LinkedHashMap; - -public record TopStatResult(LinkedHashMap value, TextComponent formattedComponent, String formattedString) implements StatResult> { - - @Override - public LinkedHashMap getNumericalValue() { - return value; - } - - @Override - public TextComponent getFormattedTextComponent() { - return formattedComponent; - } - - @Override - public String getFormattedString() { - return formattedString; - } -} \ No newline at end of file From 31713007f5b2228a9ef9675ace42dd12eaa29e8b Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Tue, 11 Oct 2022 13:08:11 +0200 Subject: [PATCH 08/43] Reworked InternalStatRequest and the other classes dealing with StatRequests (#114) --- .../com/artemis/the/gr8/playerstats/Main.java | 37 +++----- .../the/gr8/playerstats/ThreadManager.java | 40 ++++---- .../the/gr8/playerstats/api/PlayerStats.java | 12 +-- ...ayerStatsAPI.java => PlayerStatsImpl.java} | 23 +++-- .../gr8/playerstats/api/RequestGenerator.java | 4 +- .../{ApiFormatter.java => StatFormatter.java} | 2 +- .../the/gr8/playerstats/api/StatManager.java | 3 +- .../gr8/playerstats/commands/StatCommand.java | 9 +- .../gr8/playerstats/msg/MessageBuilder.java | 4 +- .../gr8/playerstats/msg/OutputManager.java | 6 ++ .../gr8/playerstats/reload/ReloadThread.java | 4 +- ...tCalculator.java => RequestProcessor.java} | 65 ++++++++++--- .../gr8/playerstats/statistic/StatThread.java | 31 +++---- .../request/InternalStatRequest.java | 28 +++--- .../statistic/request/PlayerStatRequest.java | 16 +--- .../statistic/request/ServerStatRequest.java | 16 +--- .../statistic/request/StatRequest.java | 92 ++++++++----------- .../statistic/request/TopStatRequest.java | 16 +--- .../statistic/result/StatResult.java | 6 +- 19 files changed, 197 insertions(+), 217 deletions(-) rename src/main/java/com/artemis/the/gr8/playerstats/api/{PlayerStatsAPI.java => PlayerStatsImpl.java} (52%) rename src/main/java/com/artemis/the/gr8/playerstats/api/{ApiFormatter.java => StatFormatter.java} (99%) rename src/main/java/com/artemis/the/gr8/playerstats/statistic/{StatCalculator.java => RequestProcessor.java} (57%) diff --git a/src/main/java/com/artemis/the/gr8/playerstats/Main.java b/src/main/java/com/artemis/the/gr8/playerstats/Main.java index ddba6d4..922a756 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/Main.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/Main.java @@ -1,17 +1,16 @@ package com.artemis.the.gr8.playerstats; import com.artemis.the.gr8.playerstats.api.PlayerStats; +import com.artemis.the.gr8.playerstats.api.PlayerStatsImpl; import com.artemis.the.gr8.playerstats.msg.OutputManager; -import com.artemis.the.gr8.playerstats.api.PlayerStatsAPI; import com.artemis.the.gr8.playerstats.commands.ReloadCommand; import com.artemis.the.gr8.playerstats.commands.ShareCommand; import com.artemis.the.gr8.playerstats.commands.StatCommand; import com.artemis.the.gr8.playerstats.commands.TabCompleter; import com.artemis.the.gr8.playerstats.config.ConfigHandler; import com.artemis.the.gr8.playerstats.listeners.JoinListener; -import com.artemis.the.gr8.playerstats.msg.MessageBuilder; import com.artemis.the.gr8.playerstats.msg.msgutils.LanguageKeyHandler; -import com.artemis.the.gr8.playerstats.statistic.StatCalculator; +import com.artemis.the.gr8.playerstats.statistic.RequestProcessor; import com.artemis.the.gr8.playerstats.utils.EnumHandler; import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; import me.clip.placeholderapi.PlaceholderAPIPlugin; @@ -35,14 +34,14 @@ public final class Main extends JavaPlugin { private static BukkitAudiences adventure; private static ConfigHandler config; + private static ThreadManager threadManager; private static LanguageKeyHandler languageKeyHandler; private static OfflinePlayerHandler offlinePlayerHandler; private static EnumHandler enumHandler; private static OutputManager outputManager; private static ShareManager shareManager; - private static StatCalculator statCalculator; - private static ThreadManager threadManager; + private static RequestProcessor requestProcessor; private static PlayerStats playerStatsAPI; @@ -110,11 +109,11 @@ public final class Main extends JavaPlugin { return playerStatsAPI; } - public static @NotNull OutputManager getOutputManager() throws IllegalStateException { - if (outputManager == null) { + public static @NotNull RequestProcessor getRequestProcessor() throws IllegalStateException { + if (requestProcessor == null) { throw new IllegalStateException("PlayerStats does not seem to be loaded!"); } - return outputManager; + return requestProcessor; } /** @@ -152,29 +151,21 @@ public final class Main extends JavaPlugin { return enumHandler; } - public static @NotNull StatCalculator getStatCalculator() { - if (statCalculator == null) { - statCalculator = new StatCalculator(getOfflinePlayerHandler()); - } - return statCalculator; - } - private void initializeMainClasses() { pluginInstance = this; adventure = BukkitAudiences.create(this); - - config = new ConfigHandler(); enumHandler = new EnumHandler(); languageKeyHandler = new LanguageKeyHandler(); + + config = new ConfigHandler(); offlinePlayerHandler = new OfflinePlayerHandler(config); - shareManager = new ShareManager(config); - statCalculator = new StatCalculator(offlinePlayerHandler); - outputManager = new OutputManager(adventure, config, shareManager); - threadManager = new ThreadManager(config, statCalculator, outputManager); - MessageBuilder apiMessageBuilder = MessageBuilder.defaultBuilder(config); - playerStatsAPI = new PlayerStatsAPI(apiMessageBuilder, offlinePlayerHandler); + outputManager = new OutputManager(adventure, config, shareManager); + requestProcessor = new RequestProcessor(offlinePlayerHandler, outputManager); + threadManager = new ThreadManager(config, requestProcessor, outputManager); + + playerStatsAPI = new PlayerStatsImpl(outputManager, offlinePlayerHandler); } private void setupMetrics() { diff --git a/src/main/java/com/artemis/the/gr8/playerstats/ThreadManager.java b/src/main/java/com/artemis/the/gr8/playerstats/ThreadManager.java index e98b80a..81e6bf4 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/ThreadManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/ThreadManager.java @@ -4,11 +4,12 @@ import com.artemis.the.gr8.playerstats.msg.OutputManager; import com.artemis.the.gr8.playerstats.config.ConfigHandler; import com.artemis.the.gr8.playerstats.enums.StandardMessage; import com.artemis.the.gr8.playerstats.reload.ReloadThread; -import com.artemis.the.gr8.playerstats.statistic.StatCalculator; +import com.artemis.the.gr8.playerstats.statistic.RequestProcessor; import com.artemis.the.gr8.playerstats.statistic.StatThread; import com.artemis.the.gr8.playerstats.statistic.request.StatRequest; import com.artemis.the.gr8.playerstats.utils.MyLogger; import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; import java.util.HashMap; @@ -29,17 +30,17 @@ public final class ThreadManager { private static ConfigHandler config; private static OutputManager outputManager; - private static StatCalculator statCalculator; + private static RequestProcessor requestProcessor; - private ReloadThread lastActiveReloadThread; - private StatThread lastActiveStatThread; + private ReloadThread activatedReloadThread; + private StatThread activatedStatThread; private final HashMap statThreads; private static long lastRecordedCalcTime; - public ThreadManager(ConfigHandler config, StatCalculator statCalculator, OutputManager outputManager) { + public ThreadManager(ConfigHandler config, RequestProcessor requestProcessor, OutputManager outputManager) { ThreadManager.config = config; ThreadManager.outputManager = outputManager; - ThreadManager.statCalculator = statCalculator; + ThreadManager.requestProcessor = requestProcessor; statThreads = new HashMap<>(); statThreadID = 0; @@ -52,25 +53,26 @@ public final class ThreadManager { } public void startReloadThread(CommandSender sender) { - if (lastActiveReloadThread == null || !lastActiveReloadThread.isAlive()) { + if (activatedReloadThread == null || !activatedReloadThread.isAlive()) { reloadThreadID += 1; - lastActiveReloadThread = new ReloadThread(config, outputManager, reloadThreadID, lastActiveStatThread, sender); - lastActiveReloadThread.start(); + activatedReloadThread = new ReloadThread(config, outputManager, reloadThreadID, activatedStatThread, sender); + activatedReloadThread.start(); } else { - MyLogger.logLowLevelMsg("Another reloadThread is already running! (" + lastActiveReloadThread.getName() + ")"); + MyLogger.logLowLevelMsg("Another reloadThread is already running! (" + activatedReloadThread.getName() + ")"); } } - public void startStatThread(StatRequest request) { + public void startStatThread(@NotNull StatRequest request) { statThreadID += 1; - String cmdSender = request.getSettings().getCommandSender().getName(); + CommandSender sender = request.getSettings().getCommandSender(); + + if (config.limitStatRequests() && statThreads.containsKey(sender.getName())) { + Thread runningThread = statThreads.get(sender.getName()); - if (config.limitStatRequests() && statThreads.containsKey(cmdSender)) { - Thread runningThread = statThreads.get(cmdSender); if (runningThread.isAlive()) { - outputManager.sendFeedbackMsg(request.getSettings().getCommandSender(), StandardMessage.REQUEST_ALREADY_RUNNING); + outputManager.sendFeedbackMsg(sender, StandardMessage.REQUEST_ALREADY_RUNNING); } else { startNewStatThread(request); } @@ -95,9 +97,9 @@ public final class ThreadManager { return lastRecordedCalcTime; } - private void startNewStatThread(StatRequest requestSettings) { - lastActiveStatThread = new StatThread(outputManager, statCalculator, statThreadID, requestSettings, lastActiveReloadThread); - statThreads.put(requestSettings.getSettings().getCommandSender().getName(), lastActiveStatThread); - lastActiveStatThread.start(); + private void startNewStatThread(StatRequest request) { + activatedStatThread = new StatThread(outputManager, requestProcessor, statThreadID, request, activatedReloadThread); + statThreads.put(request.getSettings().getCommandSender().getName(), activatedStatThread); + activatedStatThread.start(); } } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStats.java b/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStats.java index 010a66a..813e7d1 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStats.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStats.java @@ -9,7 +9,7 @@ import org.jetbrains.annotations.NotNull; * The outgoing API that represents the core functionality of PlayerStats! * *

To work with it, you'll need to call PlayerStats.{@link #getAPI()} and get an instance of - * {@link PlayerStatsAPI}. You can then use this object to access any of the further methods. + * {@link PlayerStatsImpl}. You can then use this object to access any of the further methods. * *

Since calculating a top or server statistics can take some time, I strongly * encourage you to call {@link StatRequest#execute()} asynchronously. @@ -17,11 +17,11 @@ import org.jetbrains.annotations.NotNull; * and this can severely impact server performance. * * @see StatManager - * @see ApiFormatter + * @see StatFormatter */ public interface PlayerStats { - /** Gets an instance of the {@link PlayerStatsAPI}. + /** Gets an instance of the {@link PlayerStatsImpl}. * @return the PlayerStats API * @throws IllegalStateException if PlayerStats is not loaded on the server when this method is called*/ @@ -31,13 +31,13 @@ public interface PlayerStats { } /** - * Gets the current version of PlayerStatsAPI. + * Gets the current version of PlayerStatsImpl. * Use this method to ensure the correct version of * PlayerStats is running on the server before * accessing further API methods, to prevent * ClassDefNotFoundExceptions. * - * @return the version of PlayerStatsAPI present on the server + * @return the version of PlayerStatsImpl present on the server */ default String getVersion() { return "1.8"; @@ -45,5 +45,5 @@ public interface PlayerStats { StatManager getStatManager(); - ApiFormatter getFormatter(); + StatFormatter getFormatter(); } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStatsAPI.java b/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStatsImpl.java similarity index 52% rename from src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStatsAPI.java rename to src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStatsImpl.java index b6a7636..ed09ad8 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStatsAPI.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStatsImpl.java @@ -1,25 +1,28 @@ package com.artemis.the.gr8.playerstats.api; +import com.artemis.the.gr8.playerstats.msg.OutputManager; import com.artemis.the.gr8.playerstats.statistic.request.*; import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; +import java.util.LinkedHashMap; + import static org.jetbrains.annotations.ApiStatus.Internal; /** The implementation of the API Interface */ -public final class PlayerStatsAPI implements PlayerStats, StatManager { +public final class PlayerStatsImpl implements PlayerStats, StatManager { private final OfflinePlayerHandler offlinePlayerHandler; - private static ApiFormatter apiFormatter; + private static OutputManager outputManager; @Internal - public PlayerStatsAPI(ApiFormatter formatter, OfflinePlayerHandler offlinePlayers) { - apiFormatter = formatter; + public PlayerStatsImpl(OutputManager outputManager, OfflinePlayerHandler offlinePlayers) { + PlayerStatsImpl.outputManager = outputManager; offlinePlayerHandler = offlinePlayers; } @Override - public ApiFormatter getFormatter() { - return apiFormatter; + public StatFormatter getFormatter() { + return outputManager.getCurrentMainMessageBuilder(); } @Override @@ -28,22 +31,22 @@ public final class PlayerStatsAPI implements PlayerStats, StatManager { } @Override - public PlayerStatRequest playerStatRequest(String playerName) { + public RequestGenerator playerStatRequest(String playerName) { return new PlayerStatRequest(playerName); } @Override - public ServerStatRequest serverStatRequest() { + public RequestGenerator serverStatRequest() { return new ServerStatRequest(); } @Override - public TopStatRequest topStatRequest(int topListSize) { + public RequestGenerator> topStatRequest(int topListSize) { return new TopStatRequest(topListSize); } @Override - public TopStatRequest totalTopStatRequest() { + public RequestGenerator> totalTopStatRequest() { int playerCount = offlinePlayerHandler.getOfflinePlayerCount(); return topStatRequest(playerCount); } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/api/RequestGenerator.java b/src/main/java/com/artemis/the/gr8/playerstats/api/RequestGenerator.java index d8df2d2..7072e12 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/api/RequestGenerator.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/api/RequestGenerator.java @@ -1,6 +1,6 @@ package com.artemis.the.gr8.playerstats.api; -import com.artemis.the.gr8.playerstats.statistic.StatCalculator; +import com.artemis.the.gr8.playerstats.statistic.RequestProcessor; import com.artemis.the.gr8.playerstats.statistic.request.StatRequest; import org.bukkit.Material; import org.bukkit.Statistic; @@ -9,7 +9,7 @@ import org.jetbrains.annotations.NotNull; /** * Creates an executable {@link StatRequest}. This Request holds all - * the information PlayerStats needs to work with, and is used by the {@link StatCalculator} + * the information PlayerStats needs to work with, and is used by the {@link RequestProcessor} * to get the desired statistic data. */ public interface RequestGenerator { diff --git a/src/main/java/com/artemis/the/gr8/playerstats/api/ApiFormatter.java b/src/main/java/com/artemis/the/gr8/playerstats/api/StatFormatter.java similarity index 99% rename from src/main/java/com/artemis/the/gr8/playerstats/api/ApiFormatter.java rename to src/main/java/com/artemis/the/gr8/playerstats/api/StatFormatter.java index e6f8b1f..f8f5e5a 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/api/ApiFormatter.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/api/StatFormatter.java @@ -16,7 +16,7 @@ import org.jetbrains.annotations.Nullable; * @see StatResult */ -public interface ApiFormatter { +public interface StatFormatter { /** * Turns a TextComponent into its String representation. This method is equipped diff --git a/src/main/java/com/artemis/the/gr8/playerstats/api/StatManager.java b/src/main/java/com/artemis/the/gr8/playerstats/api/StatManager.java index d920bfc..cc1f7cf 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/api/StatManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/api/StatManager.java @@ -5,7 +5,8 @@ import com.artemis.the.gr8.playerstats.statistic.request.StatRequest; import java.util.LinkedHashMap; /** - * Turns user input into a {@link StatRequest} that can be used to get statistic data + * Turns user input into a {@link StatRequest} that can be + * used to get statistic data. */ public interface StatManager { diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java b/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java index 8d0639b..877de24 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java @@ -5,6 +5,7 @@ import com.artemis.the.gr8.playerstats.enums.StandardMessage; import com.artemis.the.gr8.playerstats.enums.Target; import com.artemis.the.gr8.playerstats.msg.OutputManager; import com.artemis.the.gr8.playerstats.statistic.request.*; +import net.kyori.adventure.text.TextComponent; import org.bukkit.Statistic; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; @@ -31,11 +32,11 @@ public class StatCommand implements CommandExecutor { outputManager.sendExamples(sender); } else { - InternalStatRequest request = new InternalStatRequest(sender, args); + StatRequest request = new InternalStatRequest(sender, args); if (request.isValid()) { threadManager.startStatThread(request); } else { - sendFeedback(request); + sendFeedback(sender, request); return false; } } @@ -52,11 +53,11 @@ public class StatCommand implements CommandExecutor { *

  • If the target is Player, is a valid playerName provided? * * + * @param sender the CommandSender to send feedback to * @param request the StatRequest to give feedback on */ - private void sendFeedback(InternalStatRequest request) { + private void sendFeedback(CommandSender sender, StatRequest request) { StatRequest.Settings settings = request.getSettings(); - CommandSender sender = settings.getCommandSender(); if (settings.getStatistic() == null) { outputManager.sendFeedbackMsg(sender, StandardMessage.MISSING_STAT_NAME); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java index 5923ff1..c61b385 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java @@ -1,7 +1,7 @@ package com.artemis.the.gr8.playerstats.msg; import com.artemis.the.gr8.playerstats.Main; -import com.artemis.the.gr8.playerstats.api.ApiFormatter; +import com.artemis.the.gr8.playerstats.api.StatFormatter; import com.artemis.the.gr8.playerstats.msg.components.ComponentFactory; import com.artemis.the.gr8.playerstats.msg.components.ExampleMessage; import com.artemis.the.gr8.playerstats.msg.components.HelpMessage; @@ -39,7 +39,7 @@ import static net.kyori.adventure.text.Component.*; * @see PrideComponentFactory * @see BukkitConsoleComponentFactory */ -public final class MessageBuilder implements ApiFormatter { +public final class MessageBuilder implements StatFormatter { private static ConfigHandler config; private boolean useHoverText; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java index 1b1ae25..dea0a3a 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java @@ -54,6 +54,12 @@ public final class OutputManager { getMessageBuilders(); } + public MessageBuilder getCurrentMainMessageBuilder() { + return messageBuilder; + } + + //TODO separate formatting from internal saving for sharing + /** @return a TextComponent with the following parts: *
    [player-name]: [number] [stat-name] {sub-stat-name} */ diff --git a/src/main/java/com/artemis/the/gr8/playerstats/reload/ReloadThread.java b/src/main/java/com/artemis/the/gr8/playerstats/reload/ReloadThread.java index 1ca1910..d8bcaf7 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/reload/ReloadThread.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/reload/ReloadThread.java @@ -5,7 +5,7 @@ import com.artemis.the.gr8.playerstats.ShareManager; import com.artemis.the.gr8.playerstats.enums.StandardMessage; import com.artemis.the.gr8.playerstats.msg.OutputManager; import com.artemis.the.gr8.playerstats.msg.msgutils.LanguageKeyHandler; -import com.artemis.the.gr8.playerstats.statistic.StatCalculator; +import com.artemis.the.gr8.playerstats.statistic.RequestProcessor; import com.artemis.the.gr8.playerstats.statistic.StatThread; import com.artemis.the.gr8.playerstats.utils.MyLogger; import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; @@ -40,7 +40,7 @@ public final class ReloadThread extends Thread { * Then, it will reload the config, update the {@link LanguageKeyHandler}, * the {@link OfflinePlayerHandler}, the {@link DebugLevel}, update * the share-settings in {@link ShareManager} and topListSize-settings - * in {@link StatCalculator}, and update the MessageBuilders in the + * in {@link RequestProcessor}, and update the MessageBuilders in the * {@link OutputManager}. */ @Override diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatCalculator.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/RequestProcessor.java similarity index 57% rename from src/main/java/com/artemis/the/gr8/playerstats/statistic/StatCalculator.java rename to src/main/java/com/artemis/the/gr8/playerstats/statistic/RequestProcessor.java index 573df7d..588c6f0 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatCalculator.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/RequestProcessor.java @@ -1,27 +1,68 @@ package com.artemis.the.gr8.playerstats.statistic; import com.artemis.the.gr8.playerstats.ThreadManager; +import com.artemis.the.gr8.playerstats.msg.OutputManager; +import com.artemis.the.gr8.playerstats.msg.components.ComponentUtils; import com.artemis.the.gr8.playerstats.statistic.request.StatRequest; +import com.artemis.the.gr8.playerstats.statistic.result.StatResult; import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; import com.artemis.the.gr8.playerstats.utils.MyLogger; import com.google.common.collect.ImmutableList; +import net.kyori.adventure.text.TextComponent; import org.bukkit.OfflinePlayer; import org.jetbrains.annotations.NotNull; import java.util.*; +import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ForkJoinPool; import java.util.stream.Collectors; -public final class StatCalculator { +public final class RequestProcessor { private final OfflinePlayerHandler offlinePlayerHandler; + private static OutputManager outputManager; - public StatCalculator(OfflinePlayerHandler offlinePlayerHandler) { + public RequestProcessor(OfflinePlayerHandler offlinePlayerHandler, OutputManager outputManager) { this.offlinePlayerHandler = offlinePlayerHandler; + RequestProcessor.outputManager = outputManager; } - public int getPlayerStat(StatRequest.Settings requestSettings) { + public @NotNull StatResult getInternalResult(@NotNull StatRequest.Settings requestSettings) { + StatResult result = switch (requestSettings.getTarget()) { + case PLAYER -> getPlayerResult(requestSettings); + case SERVER -> getServerResult(requestSettings); + case TOP -> getTopResult(requestSettings); + }; + + return new StatResult<>(result.formattedComponent(), result.formattedComponent(), result.formattedString()); + } + + public @NotNull StatResult getPlayerResult(StatRequest.Settings requestSettings) { + int stat = getPlayerStat(requestSettings); + TextComponent result = outputManager.formatAndSavePlayerStat(requestSettings, stat); + String serializedResult = ComponentUtils.getTranslatableComponentSerializer().serialize(result); + + return new StatResult<>(stat, result, serializedResult); + } + + public @NotNull StatResult getServerResult(StatRequest.Settings requestSettings) { + long stat = getServerStat(requestSettings); + TextComponent result = outputManager.formatAndSaveServerStat(requestSettings, stat); + String serializedResult = ComponentUtils.getTranslatableComponentSerializer().serialize(result); + + return new StatResult<>(stat, result, serializedResult); + } + + public @NotNull StatResult> getTopResult(StatRequest.Settings requestSettings) { + LinkedHashMap stats = getTopStats(requestSettings); + TextComponent result = outputManager.formatAndSaveTopStat(requestSettings, stats); + String serializedResult = ComponentUtils.getTranslatableComponentSerializer().serialize(result); + + return new StatResult<>(stats, result, serializedResult); + } + + private int getPlayerStat(@NotNull StatRequest.Settings requestSettings) { OfflinePlayer player = offlinePlayerHandler.getOfflinePlayer(requestSettings.getPlayerName()); return switch (requestSettings.getStatistic().getType()) { case UNTYPED -> player.getStatistic(requestSettings.getStatistic()); @@ -31,14 +72,7 @@ public final class StatCalculator { }; } - public LinkedHashMap getTopStats(StatRequest.Settings requestSettings) { - return getAllStatsAsync(requestSettings).entrySet().stream() - .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())) - .limit(requestSettings.getTopListSize()) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new)); - } - - public long getServerStat(StatRequest.Settings requestSettings) { + private long getServerStat(StatRequest.Settings requestSettings) { List numbers = getAllStatsAsync(requestSettings) .values() .parallelStream() @@ -46,6 +80,13 @@ public final class StatCalculator { return numbers.parallelStream().mapToLong(Integer::longValue).sum(); } + private LinkedHashMap getTopStats(StatRequest.Settings requestSettings) { + return getAllStatsAsync(requestSettings).entrySet().stream() + .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())) + .limit(requestSettings.getTopListSize()) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new)); + } + /** * Invokes a bunch of worker pool threads to get the statistics for * all players that are stored in the {@link OfflinePlayerHandler}). @@ -72,7 +113,7 @@ public final class StatCalculator { return allStats; } - private StatAction getStatTask(StatRequest.Settings requestSettings) { + private @NotNull StatAction getStatTask(StatRequest.Settings requestSettings) { int size = offlinePlayerHandler.getOfflinePlayerCount() != 0 ? offlinePlayerHandler.getOfflinePlayerCount() : 16; ConcurrentHashMap allStats = new ConcurrentHashMap<>(size); ImmutableList playerNames = ImmutableList.copyOf(offlinePlayerHandler.getOfflinePlayerNames()); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatThread.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatThread.java index a907dd4..faa84e0 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatThread.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatThread.java @@ -3,11 +3,11 @@ package com.artemis.the.gr8.playerstats.statistic; import com.artemis.the.gr8.playerstats.ThreadManager; import com.artemis.the.gr8.playerstats.msg.OutputManager; import com.artemis.the.gr8.playerstats.statistic.request.StatRequest; +import com.artemis.the.gr8.playerstats.statistic.result.StatResult; import com.artemis.the.gr8.playerstats.utils.MyLogger; import com.artemis.the.gr8.playerstats.enums.StandardMessage; -import com.artemis.the.gr8.playerstats.enums.Target; import com.artemis.the.gr8.playerstats.reload.ReloadThread; -import net.kyori.adventure.text.TextComponent; +import org.bukkit.command.CommandSender; import org.jetbrains.annotations.Nullable; import java.util.*; @@ -18,14 +18,14 @@ import java.util.*; public final class StatThread extends Thread { private static OutputManager outputManager; - private static StatCalculator statCalculator; + private static RequestProcessor requestProcessor; private final ReloadThread reloadThread; private final StatRequest statRequest; - public StatThread(OutputManager m, StatCalculator t, int ID, StatRequest s, @Nullable ReloadThread r) { + public StatThread(OutputManager m, RequestProcessor t, int ID, StatRequest s, @Nullable ReloadThread r) { outputManager = m; - statCalculator = t; + requestProcessor = t; reloadThread = r; statRequest = s; @@ -35,16 +35,14 @@ public final class StatThread extends Thread { } @Override - public void run() throws IllegalStateException, NullPointerException { + public void run() throws IllegalStateException { MyLogger.logHighLevelMsg(this.getName() + " started!"); + CommandSender statRequester = statRequest.getSettings().getCommandSender(); - if (statRequest == null) { - throw new NullPointerException("No statistic requestSettings was found!"); - } if (reloadThread != null && reloadThread.isAlive()) { try { MyLogger.logLowLevelMsg(this.getName() + ": Waiting for " + reloadThread.getName() + " to finish up..."); - outputManager.sendFeedbackMsg(statRequest.getSettings().getCommandSender(), StandardMessage.STILL_RELOADING); + outputManager.sendFeedbackMsg(statRequester, StandardMessage.STILL_RELOADING); reloadThread.join(); } catch (InterruptedException e) { @@ -55,21 +53,16 @@ public final class StatThread extends Thread { long lastCalc = ThreadManager.getLastRecordedCalcTime(); if (lastCalc > 2000) { - outputManager.sendFeedbackMsgWaitAMoment(statRequest.getSettings().getCommandSender(), lastCalc > 20000); + outputManager.sendFeedbackMsgWaitAMoment(statRequester, lastCalc > 20000); } - Target selection = statRequest.getSettings().getTarget(); try { - TextComponent statResult = switch (selection) { - case PLAYER -> outputManager.formatAndSavePlayerStat(statRequest.getSettings(), statCalculator.getPlayerStat(statRequest.getSettings())); - case TOP -> outputManager.formatAndSaveTopStat(statRequest.getSettings(), statCalculator.getTopStats(statRequest.getSettings())); - case SERVER -> outputManager.formatAndSaveServerStat(statRequest.getSettings(), statCalculator.getServerStat(statRequest.getSettings())); - }; - outputManager.sendToCommandSender(statRequest.getSettings().getCommandSender(), statResult); + StatResult result = statRequest.execute(); + outputManager.sendToCommandSender(statRequester, result.formattedComponent()); } catch (ConcurrentModificationException e) { if (!statRequest.getSettings().isConsoleSender()) { - outputManager.sendFeedbackMsg(statRequest.getSettings().getCommandSender(), StandardMessage.UNKNOWN_ERROR); + outputManager.sendFeedbackMsg(statRequester, StandardMessage.UNKNOWN_ERROR); } } } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/InternalStatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/InternalStatRequest.java index 69c886c..bdd0a09 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/InternalStatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/InternalStatRequest.java @@ -4,6 +4,7 @@ import com.artemis.the.gr8.playerstats.Main; import com.artemis.the.gr8.playerstats.statistic.result.StatResult; import com.artemis.the.gr8.playerstats.utils.EnumHandler; import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; +import net.kyori.adventure.text.TextComponent; import org.bukkit.Material; import org.bukkit.Statistic; import org.bukkit.command.CommandSender; @@ -18,7 +19,7 @@ import java.util.Arrays; import java.util.regex.Matcher; import java.util.regex.Pattern; -public final class InternalStatRequest extends StatRequest { +public final class InternalStatRequest extends StatRequest { private final OfflinePlayerHandler offlinePlayerHandler; private final EnumHandler enumHandler; @@ -30,14 +31,17 @@ public final class InternalStatRequest extends StatRequest { enumHandler = Main.getEnumHandler(); targetPattern = Pattern.compile("top|server|me|player"); - String[] argsMinusTarget = extractAndStoreTarget(sender, args); - String[] argsMinusStatistic = extractAndStoreStatistic(argsMinusTarget); - findAndStoreSubStat(argsMinusStatistic); + processArgs(sender, args); } @Override - public StatResult execute() { - return null; + public @NotNull StatResult execute() { + return Main.getRequestProcessor().getInternalResult(settings); + } + + private void processArgs(CommandSender sender, String[] args) { + String[] argsMinusTarget = extractAndStoreTarget(sender, args); + findStatAndSubStat(argsMinusTarget); } private String[] extractAndStoreTarget(CommandSender sender, @NotNull String[] leftoverArgs) { @@ -80,18 +84,17 @@ public final class InternalStatRequest extends StatRequest { return leftoverArgs; } - private String[] extractAndStoreStatistic(@NotNull String[] leftoverArgs) { + private void findStatAndSubStat(@NotNull String[] leftoverArgs) { for (String arg : leftoverArgs) { if (enumHandler.isStatistic(arg)) { - super.settings.setStatistic(EnumHandler.getStatEnum(arg)); - return removeArg(leftoverArgs, arg); + Statistic stat = EnumHandler.getStatEnum(arg); + String[] argsWithoutStat = removeArg(leftoverArgs, arg); + findAndStoreSubStat(argsWithoutStat, stat); } } - return leftoverArgs; } - private void findAndStoreSubStat(@NotNull String[] leftoverArgs) { - Statistic statistic = super.settings.getStatistic(); + private void findAndStoreSubStat(String[] leftoverArgs, Statistic statistic) { if (statistic == null || leftoverArgs.length == 0) { return; } @@ -139,4 +142,5 @@ public final class InternalStatRequest extends StatRequest { currentArgs.remove(argToRemove); return currentArgs.toArray(String[]::new); } + } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/PlayerStatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/PlayerStatRequest.java index 2052199..dce804f 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/PlayerStatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/PlayerStatRequest.java @@ -2,9 +2,7 @@ package com.artemis.the.gr8.playerstats.statistic.request; import com.artemis.the.gr8.playerstats.Main; import com.artemis.the.gr8.playerstats.api.RequestGenerator; -import com.artemis.the.gr8.playerstats.msg.components.ComponentUtils; import com.artemis.the.gr8.playerstats.statistic.result.StatResult; -import net.kyori.adventure.text.TextComponent; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Statistic; @@ -40,18 +38,6 @@ public final class PlayerStatRequest extends StatRequest implements Req @Override public @NotNull StatResult execute() { - int stat = Main - .getStatCalculator() - .getPlayerStat(settings); - - TextComponent prettyComponent = Main - .getOutputManager() - .formatAndSavePlayerStat(settings, stat); - - String prettyString = ComponentUtils - .getTranslatableComponentSerializer() - .serialize(prettyComponent); - - return new StatResult<>(stat, prettyComponent, prettyString); + return Main.getRequestProcessor().getPlayerResult(settings); } } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/ServerStatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/ServerStatRequest.java index 2e50082..7298a1d 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/ServerStatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/ServerStatRequest.java @@ -2,9 +2,7 @@ package com.artemis.the.gr8.playerstats.statistic.request; import com.artemis.the.gr8.playerstats.Main; import com.artemis.the.gr8.playerstats.api.RequestGenerator; -import com.artemis.the.gr8.playerstats.msg.components.ComponentUtils; import com.artemis.the.gr8.playerstats.statistic.result.StatResult; -import net.kyori.adventure.text.TextComponent; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Statistic; @@ -40,18 +38,6 @@ public final class ServerStatRequest extends StatRequest implements Reques @Override public @NotNull StatResult execute() { - long stat = Main - .getStatCalculator() - .getServerStat(settings); - - TextComponent prettyComponent = Main - .getOutputManager() - .formatAndSaveServerStat(settings, stat); - - String prettyString = ComponentUtils - .getTranslatableComponentSerializer() - .serialize(prettyComponent); - - return new StatResult<>(stat, prettyComponent, prettyString); + return Main.getRequestProcessor().getServerResult(settings); } } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/StatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/StatRequest.java index 570e25b..5402819 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/StatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/StatRequest.java @@ -28,43 +28,9 @@ public abstract class StatRequest { settings = new Settings(requester); } - protected StatRequest configureUntyped(@NotNull Statistic statistic) { - if (statistic.getType() == Statistic.Type.UNTYPED) { - settings.setStatistic(statistic); - return this; - } - throw new IllegalArgumentException("This statistic is not of Type.Untyped"); - } - - protected StatRequest configureBlockOrItemType(@NotNull Statistic statistic, @NotNull Material material) throws IllegalArgumentException { - Statistic.Type type = statistic.getType(); - if (type == Statistic.Type.BLOCK && material.isBlock()) { - settings.setBlock(material); - } - else if (type == Statistic.Type.ITEM && material.isItem()){ - settings.setItem(material); - } - else { - throw new IllegalArgumentException("Either this statistic is not of Type.Block or Type.Item, or no valid block or item has been provided"); - } - settings.setStatistic(statistic); - settings.setSubStatEntryName(material.toString()); - return this; - } - - protected StatRequest configureEntityType(@NotNull Statistic statistic, @NotNull EntityType entityType) throws IllegalArgumentException { - if (statistic.getType() == Statistic.Type.ENTITY) { - settings.setStatistic(statistic); - settings.setSubStatEntryName(entityType.toString()); - settings.setEntity(entityType); - return this; - } - throw new IllegalArgumentException("This statistic is not of Type.Entity"); - } - /** - * Executes this StatRequest. For a Top- or ServerRequest, this can - * take some time! + * Executes this StatRequest. This calculation can take some time, + * so don't call this from the main Thread if you can help it! * * @return a StatResult containing the value of this lookup, both as * numerical value and as formatted message @@ -111,6 +77,40 @@ public abstract class StatRequest { } } + protected StatRequest configureUntyped(@NotNull Statistic statistic) { + if (statistic.getType() == Statistic.Type.UNTYPED) { + settings.statistic = statistic; + return this; + } + throw new IllegalArgumentException("This statistic is not of Type.Untyped"); + } + + protected StatRequest configureBlockOrItemType(@NotNull Statistic statistic, @NotNull Material material) throws IllegalArgumentException { + Statistic.Type type = statistic.getType(); + if (type == Statistic.Type.BLOCK && material.isBlock()) { + settings.block = material; + } + else if (type == Statistic.Type.ITEM && material.isItem()){ + settings.item = material; + } + else { + throw new IllegalArgumentException("Either this statistic is not of Type.Block or Type.Item, or no valid block or item has been provided"); + } + settings.statistic = statistic; + settings.subStatEntryName = material.toString(); + return this; + } + + protected StatRequest configureEntityType(@NotNull Statistic statistic, @NotNull EntityType entityType) throws IllegalArgumentException { + if (statistic.getType() == Statistic.Type.ENTITY) { + settings.statistic = statistic; + settings.entity = entityType; + settings.subStatEntryName = entityType.toString(); + return this; + } + throw new IllegalArgumentException("This statistic is not of Type.Entity"); + } + public static final class Settings { private final CommandSender sender; private Statistic statistic; @@ -158,18 +158,10 @@ public abstract class StatRequest { return sender instanceof ConsoleCommandSender; } - void setStatistic(Statistic statistic) { - this.statistic = statistic; - } - public Statistic getStatistic() { return statistic; } - private void setSubStatEntryName(String subStatEntry) { - this.subStatEntryName = subStatEntry; - } - public @Nullable String getSubStatEntryName() { return subStatEntryName; } @@ -186,26 +178,14 @@ public abstract class StatRequest { return this.topListSize; } - void setEntity(EntityType entity) { - this.entity = entity; - } - public EntityType getEntity() { return entity; } - void setBlock(Material block) { - this.block = block; - } - public Material getBlock() { return block; } - void setItem(Material item) { - this.item = item; - } - public Material getItem() { return item; } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/TopStatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/TopStatRequest.java index 219365b..f9ad3d2 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/TopStatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/TopStatRequest.java @@ -3,8 +3,6 @@ package com.artemis.the.gr8.playerstats.statistic.request; import com.artemis.the.gr8.playerstats.Main; import com.artemis.the.gr8.playerstats.statistic.result.StatResult; import com.artemis.the.gr8.playerstats.api.RequestGenerator; -import com.artemis.the.gr8.playerstats.msg.components.ComponentUtils; -import net.kyori.adventure.text.TextComponent; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Statistic; @@ -42,18 +40,6 @@ public final class TopStatRequest extends StatRequest> execute() { - LinkedHashMap stat = Main - .getStatCalculator() - .getTopStats(settings); - - TextComponent prettyComponent = Main - .getOutputManager() - .formatAndSaveTopStat(settings, stat); - - String prettyString = ComponentUtils - .getTranslatableComponentSerializer() - .serialize(prettyComponent); - - return new StatResult<>(stat, prettyComponent, prettyString); + return Main.getRequestProcessor().getTopResult(settings); } } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/result/StatResult.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/result/StatResult.java index 973e5ff..46c5ea1 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/result/StatResult.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/result/StatResult.java @@ -1,6 +1,6 @@ package com.artemis.the.gr8.playerstats.statistic.result; -import com.artemis.the.gr8.playerstats.api.ApiFormatter; +import com.artemis.the.gr8.playerstats.api.StatFormatter; import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.text.TextComponent; @@ -31,7 +31,7 @@ import net.kyori.adventure.text.TextComponent; * To send a Component, you need to get a {@link BukkitAudiences} object, * and use that to send the desired Component. Normally you would have to add * Adventure as a dependency to your project, but since the library is included - * in PlayerStats, you can access it through the PlayerStatsAPI. Information + * in PlayerStats, you can access it through the PlayerStatsImpl. Information * on how to get and use the BukkitAudiences object can be found on * Adventure's website. * @@ -39,7 +39,7 @@ import net.kyori.adventure.text.TextComponent; * same information in String-format. Don't use Adventure's #content() * or #toString() methods on the Components - those won't get the actual * message. And finally, if you want the results to be formatted differently, - * you can get an instance of the {@link ApiFormatter}. + * you can get an instance of the {@link StatFormatter}. */ public record StatResult(T value, TextComponent formattedComponent, String formattedString) { From d16e6db036f72d0e87e3552a140158c0d871e5cc Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Wed, 12 Oct 2022 16:23:06 +0200 Subject: [PATCH 09/43] Separated responsibility of OutputManager and ShareManager and made the RequestProcessor handle the StatRequest executing (#114) --- .../com/artemis/the/gr8/playerstats/Main.java | 18 +-- .../the/gr8/playerstats/ThreadManager.java | 9 +- .../the/gr8/playerstats/api/PlayerStats.java | 2 +- .../gr8/playerstats/api/PlayerStatsImpl.java | 10 +- .../gr8/playerstats/api/RequestGenerator.java | 2 +- .../gr8/playerstats/api/StatFormatter.java | 2 +- .../the/gr8/playerstats/api/StatManager.java | 2 +- .../playerstats/commands/ShareCommand.java | 6 +- .../gr8/playerstats/commands/StatCommand.java | 3 +- .../playerstats/commands/TabCompleter.java | 143 +++++++++++------- .../commands/cmdutils/TabCompleteHelper.java | 57 ------- .../playerstats/msg/FormattingFunction.java | 31 ++++ .../gr8/playerstats/msg/MessageBuilder.java | 16 +- .../gr8/playerstats/msg/OutputManager.java | 61 +++----- .../gr8/playerstats/reload/ReloadThread.java | 2 +- .../playerstats/{ => share}/ShareManager.java | 14 +- .../gr8/playerstats/share/StoredResult.java | 10 ++ .../{request => }/InternalStatRequest.java | 33 ++-- .../{request => }/PlayerStatRequest.java | 23 ++- .../statistic/RequestProcessor.java | 57 ++++--- .../{request => }/ServerStatRequest.java | 23 ++- .../gr8/playerstats/statistic/StatAction.java | 1 - .../statistic/{request => }/StatRequest.java | 79 +++++----- .../statistic/{result => }/StatResult.java | 2 +- .../gr8/playerstats/statistic/StatThread.java | 7 +- .../{request => }/TopStatRequest.java | 23 ++- .../statistic/result/InternalStatResult.java | 34 ----- 27 files changed, 317 insertions(+), 353 deletions(-) delete mode 100644 src/main/java/com/artemis/the/gr8/playerstats/commands/cmdutils/TabCompleteHelper.java create mode 100644 src/main/java/com/artemis/the/gr8/playerstats/msg/FormattingFunction.java rename src/main/java/com/artemis/the/gr8/playerstats/{ => share}/ShareManager.java (90%) create mode 100644 src/main/java/com/artemis/the/gr8/playerstats/share/StoredResult.java rename src/main/java/com/artemis/the/gr8/playerstats/statistic/{request => }/InternalStatRequest.java (79%) rename src/main/java/com/artemis/the/gr8/playerstats/statistic/{request => }/PlayerStatRequest.java (57%) rename src/main/java/com/artemis/the/gr8/playerstats/statistic/{request => }/ServerStatRequest.java (60%) rename src/main/java/com/artemis/the/gr8/playerstats/statistic/{request => }/StatRequest.java (66%) rename src/main/java/com/artemis/the/gr8/playerstats/statistic/{result => }/StatResult.java (98%) rename src/main/java/com/artemis/the/gr8/playerstats/statistic/{request => }/TopStatRequest.java (61%) delete mode 100644 src/main/java/com/artemis/the/gr8/playerstats/statistic/result/InternalStatResult.java diff --git a/src/main/java/com/artemis/the/gr8/playerstats/Main.java b/src/main/java/com/artemis/the/gr8/playerstats/Main.java index 922a756..e1d6391 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/Main.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/Main.java @@ -10,6 +10,7 @@ import com.artemis.the.gr8.playerstats.commands.TabCompleter; import com.artemis.the.gr8.playerstats.config.ConfigHandler; import com.artemis.the.gr8.playerstats.listeners.JoinListener; import com.artemis.the.gr8.playerstats.msg.msgutils.LanguageKeyHandler; +import com.artemis.the.gr8.playerstats.share.ShareManager; import com.artemis.the.gr8.playerstats.statistic.RequestProcessor; import com.artemis.the.gr8.playerstats.utils.EnumHandler; import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; @@ -43,7 +44,7 @@ public final class Main extends JavaPlugin { private static ShareManager shareManager; private static RequestProcessor requestProcessor; - private static PlayerStats playerStatsAPI; + private static PlayerStats playerStatsImpl; @Override @@ -103,10 +104,10 @@ public final class Main extends JavaPlugin { } public static @NotNull PlayerStats getPlayerStatsAPI() throws IllegalStateException { - if (playerStatsAPI == null) { + if (playerStatsImpl == null) { throw new IllegalStateException("PlayerStats does not seem to be loaded!"); } - return playerStatsAPI; + return playerStatsImpl; } public static @NotNull RequestProcessor getRequestProcessor() throws IllegalStateException { @@ -156,16 +157,15 @@ public final class Main extends JavaPlugin { adventure = BukkitAudiences.create(this); enumHandler = new EnumHandler(); languageKeyHandler = new LanguageKeyHandler(); - config = new ConfigHandler(); + offlinePlayerHandler = new OfflinePlayerHandler(config); shareManager = new ShareManager(config); + outputManager = new OutputManager(adventure, config); + requestProcessor = new RequestProcessor(offlinePlayerHandler, outputManager, shareManager); - outputManager = new OutputManager(adventure, config, shareManager); - requestProcessor = new RequestProcessor(offlinePlayerHandler, outputManager); - threadManager = new ThreadManager(config, requestProcessor, outputManager); - - playerStatsAPI = new PlayerStatsImpl(outputManager, offlinePlayerHandler); + threadManager = new ThreadManager(config, outputManager); + playerStatsImpl = new PlayerStatsImpl(offlinePlayerHandler, outputManager); } private void setupMetrics() { diff --git a/src/main/java/com/artemis/the/gr8/playerstats/ThreadManager.java b/src/main/java/com/artemis/the/gr8/playerstats/ThreadManager.java index 81e6bf4..72ab480 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/ThreadManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/ThreadManager.java @@ -4,9 +4,8 @@ import com.artemis.the.gr8.playerstats.msg.OutputManager; import com.artemis.the.gr8.playerstats.config.ConfigHandler; import com.artemis.the.gr8.playerstats.enums.StandardMessage; import com.artemis.the.gr8.playerstats.reload.ReloadThread; -import com.artemis.the.gr8.playerstats.statistic.RequestProcessor; import com.artemis.the.gr8.playerstats.statistic.StatThread; -import com.artemis.the.gr8.playerstats.statistic.request.StatRequest; +import com.artemis.the.gr8.playerstats.statistic.StatRequest; import com.artemis.the.gr8.playerstats.utils.MyLogger; import org.bukkit.command.CommandSender; import org.jetbrains.annotations.NotNull; @@ -30,17 +29,15 @@ public final class ThreadManager { private static ConfigHandler config; private static OutputManager outputManager; - private static RequestProcessor requestProcessor; private ReloadThread activatedReloadThread; private StatThread activatedStatThread; private final HashMap statThreads; private static long lastRecordedCalcTime; - public ThreadManager(ConfigHandler config, RequestProcessor requestProcessor, OutputManager outputManager) { + public ThreadManager(ConfigHandler config, OutputManager outputManager) { ThreadManager.config = config; ThreadManager.outputManager = outputManager; - ThreadManager.requestProcessor = requestProcessor; statThreads = new HashMap<>(); statThreadID = 0; @@ -98,7 +95,7 @@ public final class ThreadManager { } private void startNewStatThread(StatRequest request) { - activatedStatThread = new StatThread(outputManager, requestProcessor, statThreadID, request, activatedReloadThread); + activatedStatThread = new StatThread(outputManager, statThreadID, request, activatedReloadThread); statThreads.put(request.getSettings().getCommandSender().getName(), activatedStatThread); activatedStatThread.start(); } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStats.java b/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStats.java index 813e7d1..bf6e8e0 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStats.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStats.java @@ -1,7 +1,7 @@ package com.artemis.the.gr8.playerstats.api; import com.artemis.the.gr8.playerstats.Main; -import com.artemis.the.gr8.playerstats.statistic.request.StatRequest; +import com.artemis.the.gr8.playerstats.statistic.StatRequest; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStatsImpl.java b/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStatsImpl.java index ed09ad8..80a0ad2 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStatsImpl.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStatsImpl.java @@ -1,7 +1,9 @@ package com.artemis.the.gr8.playerstats.api; import com.artemis.the.gr8.playerstats.msg.OutputManager; -import com.artemis.the.gr8.playerstats.statistic.request.*; +import com.artemis.the.gr8.playerstats.statistic.PlayerStatRequest; +import com.artemis.the.gr8.playerstats.statistic.ServerStatRequest; +import com.artemis.the.gr8.playerstats.statistic.TopStatRequest; import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; import java.util.LinkedHashMap; @@ -11,13 +13,13 @@ import static org.jetbrains.annotations.ApiStatus.Internal; /** The implementation of the API Interface */ public final class PlayerStatsImpl implements PlayerStats, StatManager { - private final OfflinePlayerHandler offlinePlayerHandler; private static OutputManager outputManager; + private final OfflinePlayerHandler offlinePlayerHandler; @Internal - public PlayerStatsImpl(OutputManager outputManager, OfflinePlayerHandler offlinePlayers) { + public PlayerStatsImpl(OfflinePlayerHandler offlinePlayerHandler, OutputManager outputManager) { PlayerStatsImpl.outputManager = outputManager; - offlinePlayerHandler = offlinePlayers; + this.offlinePlayerHandler = offlinePlayerHandler; } @Override diff --git a/src/main/java/com/artemis/the/gr8/playerstats/api/RequestGenerator.java b/src/main/java/com/artemis/the/gr8/playerstats/api/RequestGenerator.java index 7072e12..a0eb419 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/api/RequestGenerator.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/api/RequestGenerator.java @@ -1,7 +1,7 @@ package com.artemis.the.gr8.playerstats.api; import com.artemis.the.gr8.playerstats.statistic.RequestProcessor; -import com.artemis.the.gr8.playerstats.statistic.request.StatRequest; +import com.artemis.the.gr8.playerstats.statistic.StatRequest; import org.bukkit.Material; import org.bukkit.Statistic; import org.bukkit.entity.EntityType; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/api/StatFormatter.java b/src/main/java/com/artemis/the/gr8/playerstats/api/StatFormatter.java index f8f5e5a..a99a6a4 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/api/StatFormatter.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/api/StatFormatter.java @@ -3,7 +3,7 @@ package com.artemis.the.gr8.playerstats.api; import com.artemis.the.gr8.playerstats.enums.Unit; import com.artemis.the.gr8.playerstats.msg.components.ComponentUtils; import com.artemis.the.gr8.playerstats.msg.msgutils.NumberFormatter; -import com.artemis.the.gr8.playerstats.statistic.result.StatResult; +import com.artemis.the.gr8.playerstats.statistic.StatResult; import net.kyori.adventure.text.TextComponent; import org.bukkit.Statistic; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/api/StatManager.java b/src/main/java/com/artemis/the/gr8/playerstats/api/StatManager.java index cc1f7cf..52f64b8 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/api/StatManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/api/StatManager.java @@ -1,6 +1,6 @@ package com.artemis.the.gr8.playerstats.api; -import com.artemis.the.gr8.playerstats.statistic.request.StatRequest; +import com.artemis.the.gr8.playerstats.statistic.StatRequest; import java.util.LinkedHashMap; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/ShareCommand.java b/src/main/java/com/artemis/the/gr8/playerstats/commands/ShareCommand.java index f3961c4..4285f4f 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/ShareCommand.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/commands/ShareCommand.java @@ -1,9 +1,9 @@ package com.artemis.the.gr8.playerstats.commands; -import com.artemis.the.gr8.playerstats.ShareManager; +import com.artemis.the.gr8.playerstats.share.ShareManager; import com.artemis.the.gr8.playerstats.enums.StandardMessage; import com.artemis.the.gr8.playerstats.msg.OutputManager; -import com.artemis.the.gr8.playerstats.statistic.result.InternalStatResult; +import com.artemis.the.gr8.playerstats.share.StoredResult; import com.artemis.the.gr8.playerstats.utils.MyLogger; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; @@ -37,7 +37,7 @@ public final class ShareCommand implements CommandExecutor { outputManager.sendFeedbackMsg(sender, StandardMessage.STILL_ON_SHARE_COOLDOWN); } else { - InternalStatResult result = shareManager.getStatResult(sender.getName(), shareCode); + StoredResult result = shareManager.getStatResult(sender.getName(), shareCode); if (result == null) { //at this point the only possible cause of formattedComponent being null is the request being older than 25 player-requests ago outputManager.sendFeedbackMsg(sender, StandardMessage.STAT_RESULTS_TOO_OLD); } else { diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java b/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java index 877de24..f3b62b1 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java @@ -4,7 +4,8 @@ import com.artemis.the.gr8.playerstats.ThreadManager; import com.artemis.the.gr8.playerstats.enums.StandardMessage; import com.artemis.the.gr8.playerstats.enums.Target; import com.artemis.the.gr8.playerstats.msg.OutputManager; -import com.artemis.the.gr8.playerstats.statistic.request.*; +import com.artemis.the.gr8.playerstats.statistic.InternalStatRequest; +import com.artemis.the.gr8.playerstats.statistic.StatRequest; import net.kyori.adventure.text.TextComponent; import org.bukkit.Statistic; import org.bukkit.command.Command; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/TabCompleter.java b/src/main/java/com/artemis/the/gr8/playerstats/commands/TabCompleter.java index 6a8238b..68819f7 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/TabCompleter.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/commands/TabCompleter.java @@ -1,14 +1,18 @@ package com.artemis.the.gr8.playerstats.commands; +import com.artemis.the.gr8.playerstats.api.PlayerStats; +import com.artemis.the.gr8.playerstats.statistic.StatRequest; import com.artemis.the.gr8.playerstats.utils.EnumHandler; import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; -import com.artemis.the.gr8.playerstats.commands.cmdutils.TabCompleteHelper; +import org.bukkit.Material; import org.bukkit.Statistic; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; +import org.bukkit.entity.EntityType; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; @@ -16,100 +20,137 @@ public final class TabCompleter implements org.bukkit.command.TabCompleter { private final EnumHandler enumHandler; private final OfflinePlayerHandler offlinePlayerHandler; - private final TabCompleteHelper tabCompleteHelper; - private final List commandOptions; + private List targetSuggestions; + private List itemBrokenSuggestions; + private List entitySuggestions; public TabCompleter(EnumHandler enumHandler, OfflinePlayerHandler offlinePlayerHandler) { this.enumHandler = enumHandler; this.offlinePlayerHandler = offlinePlayerHandler; - tabCompleteHelper = new TabCompleteHelper(enumHandler); - - commandOptions = new ArrayList<>(); - commandOptions.add("top"); - commandOptions.add("player"); - commandOptions.add("server"); - commandOptions.add("me"); + prepareLists(); } - //args[0] = statistic (length = 1) - //args[1] = commandOption (top/player/me) OR substatistic (block/item/entitytype) (length = 2) - //args[2] = executorName OR commandOption (top/player/me) (length = 3) - //args[3] = executorName (length = 4) + //args[0] = statistic (length = 1) + //args[1] = target (player/server/top) OR sub-stat (block/item/entity) (length = 2) + //args[2] = playerName OR target (player/server/top) (length = 3) + //args[3] = playerName (length = 4) @Override public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { - List tabSuggestions = new ArrayList<>(); - if (args.length >= 1) { - String currentArg = args[args.length -1]; + String currentArg = args[args.length-1]; - if (args.length == 1) { //after typing "stat", suggest a list of viable statistics - tabSuggestions = getFirstArgSuggestions(args[0]); + if (args.length == 1) { + return getFirstArgSuggestions(args[0]); } - else { //after checking if args[0] is a viable statistic, suggest substatistic OR commandOptions - String previousArg = args[args.length -2]; + //after checking if args[0] is a viable statistic, suggest sub-stat OR targets + String previousArg = args[args.length-2]; - if (enumHandler.isStatistic(previousArg)) { - Statistic stat = EnumHandler.getStatEnum(previousArg); - if (stat != null) { - tabSuggestions = getTabSuggestions(getRelevantList(stat), currentArg); - } - } - - //if previous arg = "player" - else if (previousArg.equalsIgnoreCase("player")) { - - 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 - tabSuggestions = getTabSuggestions(offlinePlayerHandler.getOfflinePlayerNames(), currentArg); - } - } - - //after a substatistic, suggest commandOptions - else if (enumHandler.isSubStatEntry(previousArg)) { - tabSuggestions = commandOptions; + if (enumHandler.isStatistic(previousArg)) { + Statistic stat = EnumHandler.getStatEnum(previousArg); + if (stat != null) { + return getDynamicTabSuggestions(getAfterStatSuggestions(stat), currentArg); } } + else if (previousArg.equalsIgnoreCase("player")) { + + if (args.length >= 3 && enumHandler.isEntityStatistic(args[args.length-3])) { + return targetSuggestions; //if arg before "player" was entity-sub-stat, suggest targets + } + else { //otherwise "player" is the target: suggest playerNames + return getDynamicTabSuggestions(offlinePlayerHandler.getOfflinePlayerNames(), currentArg); + } + } + + //after a substatistic, suggest targets + else if (enumHandler.isSubStatEntry(previousArg)) { + return targetSuggestions; + } + } - return tabSuggestions; + return null; } private List getFirstArgSuggestions(String currentArg) { List suggestions = enumHandler.getStatNames(); suggestions.add("examples"); suggestions.add("help"); - return getTabSuggestions(suggestions, currentArg); + return getDynamicTabSuggestions(suggestions, currentArg); } - private List getTabSuggestions(List completeList, String currentArg) { + /** + * These tabSuggestions take into account that the commandSender + * will have been typing, so they are filtered for the letters + * that have already been typed. + */ + private List getDynamicTabSuggestions(@NotNull List completeList, String currentArg) { return completeList.stream() .filter(item -> item.toLowerCase().contains(currentArg.toLowerCase())) .collect(Collectors.toList()); } - private List getRelevantList(Statistic stat) { + private List getAfterStatSuggestions(@NotNull Statistic stat) { switch (stat.getType()) { case BLOCK -> { - return tabCompleteHelper.getAllBlockNames(); + return getAllBlockNames(); } case ITEM -> { if (stat == Statistic.BREAK_ITEM) { - return tabCompleteHelper.getItemBrokenSuggestions(); + return getItemBrokenSuggestions(); } else { - return tabCompleteHelper.getAllItemNames(); + return getAllItemNames(); } } case ENTITY -> { - return tabCompleteHelper.getEntitySuggestions(); + return getEntitySuggestions(); } default -> { - return commandOptions; + return targetSuggestions; } } } + + private List getAllItemNames() { + return enumHandler.getItemNames(); + } + + private List getItemBrokenSuggestions() { + return itemBrokenSuggestions; + } + + private List getAllBlockNames() { + return enumHandler.getBlockNames(); + } + + private List getEntitySuggestions() { + return entitySuggestions; + } + + private void prepareLists() { + targetSuggestions = new ArrayList<>(); + targetSuggestions.add("top"); + targetSuggestions.add("player"); + targetSuggestions.add("server"); + targetSuggestions.add("me"); + + //breaking an item means running its durability negative + itemBrokenSuggestions = Arrays.stream(Material.values()) + .parallel() + .filter(Material::isItem) + .filter(item -> item.getMaxDurability() != 0) + .map(Material::toString) + .map(String::toLowerCase) + .collect(Collectors.toList()); + + //the only statistics dealing with entities are killed_entity and entity_killed_by + entitySuggestions = Arrays.stream(EntityType.values()) + .parallel() + .filter(EntityType::isAlive) + .map(EntityType::toString) + .map(String::toLowerCase) + .collect(Collectors.toList()); + } } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/cmdutils/TabCompleteHelper.java b/src/main/java/com/artemis/the/gr8/playerstats/commands/cmdutils/TabCompleteHelper.java deleted file mode 100644 index d9839cc..0000000 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/cmdutils/TabCompleteHelper.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.artemis.the.gr8.playerstats.commands.cmdutils; - -import com.artemis.the.gr8.playerstats.utils.EnumHandler; -import org.bukkit.Material; -import org.bukkit.entity.EntityType; - -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - -public final class TabCompleteHelper { - - private final EnumHandler enumHandler; - private static List itemBrokenSuggestions; - private static List entitySuggestions; - - public TabCompleteHelper(EnumHandler enumHandler) { - this.enumHandler = enumHandler; - prepareLists(); - } - - public List getAllItemNames() { - return enumHandler.getItemNames(); - } - - public List getItemBrokenSuggestions() { - return itemBrokenSuggestions; - } - - public List getAllBlockNames() { - return enumHandler.getBlockNames(); - } - - public List getEntitySuggestions() { - return entitySuggestions; - } - - - private static void prepareLists() { - //breaking an item means running its durability negative - itemBrokenSuggestions = Arrays.stream(Material.values()) - .parallel() - .filter(Material::isItem) - .filter(item -> item.getMaxDurability() != 0) - .map(Material::toString) - .map(String::toLowerCase) - .collect(Collectors.toList()); - - //the only statistics dealing with entities are killed_entity and entity_killed_by - entitySuggestions = Arrays.stream(EntityType.values()) - .parallel() - .filter(EntityType::isAlive) - .map(EntityType::toString) - .map(String::toLowerCase) - .collect(Collectors.toList()); - } -} \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/FormattingFunction.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/FormattingFunction.java new file mode 100644 index 0000000..5f8a0e4 --- /dev/null +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/FormattingFunction.java @@ -0,0 +1,31 @@ +package com.artemis.the.gr8.playerstats.msg; + +import net.kyori.adventure.text.TextComponent; +import org.bukkit.command.CommandSender; + +import java.util.function.BiFunction; + +public final class FormattingFunction { + + private final BiFunction formattingFunction; + + public FormattingFunction(BiFunction formattingFunction) { + this.formattingFunction = formattingFunction; + } + + public TextComponent getResultWithShareButton(Integer shareCode) { + return this.apply(shareCode, null); + } + + public TextComponent getResultWithSharerName(CommandSender sender) { + return this.apply(null, sender); + } + + public TextComponent getDefaultResult() { + return this.apply(null, null); + } + + private TextComponent apply(Integer shareCode, CommandSender sender) { + return formattingFunction.apply(shareCode, sender); + } +} diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java index c61b385..20b0fba 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java @@ -8,7 +8,7 @@ import com.artemis.the.gr8.playerstats.msg.components.HelpMessage; import com.artemis.the.gr8.playerstats.msg.components.BukkitConsoleComponentFactory; import com.artemis.the.gr8.playerstats.msg.components.PrideComponentFactory; import com.artemis.the.gr8.playerstats.msg.msgutils.*; -import com.artemis.the.gr8.playerstats.statistic.request.StatRequest; +import com.artemis.the.gr8.playerstats.statistic.StatRequest; import com.artemis.the.gr8.playerstats.utils.EnumHandler; import com.artemis.the.gr8.playerstats.utils.MyLogger; import com.artemis.the.gr8.playerstats.enums.Target; @@ -313,7 +313,7 @@ public final class MessageBuilder implements StatFormatter { *
    - If both parameters are null, the formattedComponent will be returned * as is. */ - public @NotNull BiFunction formattedPlayerStatFunction(int stat, @NotNull StatRequest.Settings request) { + public @NotNull FormattingFunction formattedPlayerStatFunction(int stat, @NotNull StatRequest.Settings request) { TextComponent playerStat = formatPlayerStat(request.getPlayerName(), stat, request.getStatistic(), request.getSubStatEntryName()); return getFormattingFunction(playerStat, Target.PLAYER); } @@ -329,7 +329,7 @@ public final class MessageBuilder implements StatFormatter { *
    - If both parameters are null, the formattedComponent will be returned * as is. */ - public @NotNull BiFunction formattedServerStatFunction(long stat, @NotNull StatRequest.Settings request) { + public @NotNull FormattingFunction formattedServerStatFunction(long stat, @NotNull StatRequest.Settings request) { TextComponent serverStat = formatServerStat(stat, request.getStatistic(), request.getSubStatEntryName()); return getFormattingFunction(serverStat, Target.SERVER); } @@ -345,13 +345,13 @@ public final class MessageBuilder implements StatFormatter { *
    - If both parameters are null, the formattedComponent will be returned * as is. */ - public @NotNull BiFunction formattedTopStatFunction(@NotNull LinkedHashMap topStats, @NotNull StatRequest.Settings request) { + public @NotNull FormattingFunction formattedTopStatFunction(@NotNull LinkedHashMap topStats, @NotNull StatRequest.Settings request) { final TextComponent title = getTopStatTitle(topStats.size(), request.getStatistic(), request.getSubStatEntryName()); final TextComponent list = getTopStatListComponent(topStats, request.getStatistic()); final boolean useEnters = config.useEnters(Target.TOP, false); final boolean useEntersForShared = config.useEnters(Target.TOP, true); - return (shareCode, sender) -> { + BiFunction biFunction = (shareCode, sender) -> { TextComponent.Builder topBuilder = text(); //if we're adding a share-button @@ -395,6 +395,7 @@ public final class MessageBuilder implements StatFormatter { } return topBuilder.build(); }; + return new FormattingFunction(biFunction); } private @NotNull TextComponent getPlayerStatComponent(String playerName, TextComponent statNumberComponent, Statistic statistic, @Nullable String subStatName, @Nullable Unit unit) { @@ -676,11 +677,11 @@ public final class MessageBuilder implements StatFormatter { return componentFactory.sharerName(sender.getName()); } - private @NotNull BiFunction getFormattingFunction(@NotNull TextComponent statResult, Target target) { + private @NotNull FormattingFunction getFormattingFunction(@NotNull TextComponent statResult, Target target) { boolean useEnters = config.useEnters(target, false); boolean useEntersForShared = config.useEnters(target, true); - return (shareCode, sender) -> { + BiFunction biFunction = (shareCode, sender) -> { TextComponent.Builder statBuilder = text(); //if we're adding a share-button @@ -711,6 +712,7 @@ public final class MessageBuilder implements StatFormatter { } return statBuilder.build(); }; + return new FormattingFunction(biFunction); } private int getNumberOfDotsToAlign(String displayText) { diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java index dea0a3a..40b3bd8 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java @@ -1,11 +1,10 @@ package com.artemis.the.gr8.playerstats.msg; -import com.artemis.the.gr8.playerstats.ShareManager; import com.artemis.the.gr8.playerstats.config.ConfigHandler; import com.artemis.the.gr8.playerstats.enums.StandardMessage; import com.artemis.the.gr8.playerstats.msg.components.BukkitConsoleComponentFactory; import com.artemis.the.gr8.playerstats.msg.components.PrideComponentFactory; -import com.artemis.the.gr8.playerstats.statistic.request.StatRequest; +import com.artemis.the.gr8.playerstats.statistic.StatRequest; import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.text.TextComponent; import org.bukkit.Bukkit; @@ -19,7 +18,6 @@ import java.time.LocalDate; import java.time.Month; import java.util.EnumMap; import java.util.LinkedHashMap; -import java.util.function.BiFunction; import java.util.function.Function; import static com.artemis.the.gr8.playerstats.enums.StandardMessage.*; @@ -35,16 +33,13 @@ public final class OutputManager { private static BukkitAudiences adventure; private static ConfigHandler config; - private static ShareManager shareManager; private static MessageBuilder messageBuilder; private static MessageBuilder consoleMessageBuilder; - private static EnumMap> standardMessages; - public OutputManager(BukkitAudiences adventure, ConfigHandler config, ShareManager shareManager) { + public OutputManager(BukkitAudiences adventure, ConfigHandler config) { OutputManager.adventure = adventure; OutputManager.config = config; - OutputManager.shareManager = shareManager; getMessageBuilders(); prepareFunctions(); @@ -58,39 +53,34 @@ public final class OutputManager { return messageBuilder; } - //TODO separate formatting from internal saving for sharing - - /** @return a TextComponent with the following parts: + /** + * @return a TextComponent with the following parts: *
    [player-name]: [number] [stat-name] {sub-stat-name} */ - public TextComponent formatAndSavePlayerStat(@NotNull StatRequest.Settings requestSettings, int playerStat) { - BiFunction playerStatFunction = - getMessageBuilder(requestSettings.getCommandSender()).formattedPlayerStatFunction(playerStat, requestSettings); - - return processFunction(requestSettings.getCommandSender(), playerStatFunction); + public @NotNull FormattingFunction formatPlayerStat(@NotNull StatRequest.Settings requestSettings, int playerStat) { + return getMessageBuilder(requestSettings.getCommandSender()) + .formattedPlayerStatFunction(playerStat, requestSettings); } - /** @return a TextComponent with the following parts: + /** + * @return a TextComponent with the following parts: *
    [Total on] [server-name]: [number] [stat-name] [sub-stat-name] */ - public TextComponent formatAndSaveServerStat(@NotNull StatRequest.Settings requestSettings, long serverStat) { - BiFunction serverStatFunction = - getMessageBuilder(requestSettings.getCommandSender()).formattedServerStatFunction(serverStat, requestSettings); - - return processFunction(requestSettings.getCommandSender(), serverStatFunction); + public @NotNull FormattingFunction formatServerStat(@NotNull StatRequest.Settings requestSettings, long serverStat) { + return getMessageBuilder(requestSettings.getCommandSender()) + .formattedServerStatFunction(serverStat, requestSettings); } - /** @return a TextComponent with the following parts: + /** + * @return a TextComponent with the following parts: *
    [PlayerStats] [Top 10] [stat-name] [sub-stat-name] *
    [1.] [player-name] [number] *
    [2.] [player-name] [number] *
    [3.] etc... */ - public TextComponent formatAndSaveTopStat(@NotNull StatRequest.Settings requestSettings, @NotNull LinkedHashMap topStats) { - BiFunction topStatFunction = - getMessageBuilder(requestSettings.getCommandSender()).formattedTopStatFunction(topStats, requestSettings); - - return processFunction(requestSettings.getCommandSender(), topStatFunction); + public @NotNull FormattingFunction formatTopStats(@NotNull StatRequest.Settings requestSettings, @NotNull LinkedHashMap topStats) { + return getMessageBuilder(requestSettings.getCommandSender()) + .formattedTopStatFunction(topStats, requestSettings); } public void sendFeedbackMsg(@NotNull CommandSender sender, StandardMessage message) { @@ -137,21 +127,6 @@ public final class OutputManager { adventure.sender(sender).sendMessage(component); } - private TextComponent processFunction(CommandSender sender, @NotNull BiFunction statResultFunction) { - boolean saveOutput = !(sender instanceof ConsoleCommandSender) && - ShareManager.isEnabled() && - shareManager.senderHasPermission(sender); - - if (saveOutput) { - int shareCode = - shareManager.saveStatResult(sender.getName(), statResultFunction.apply(null, sender)); - return statResultFunction.apply(shareCode, null); - } - else { - return statResultFunction.apply(null, null); - } - } - private MessageBuilder getMessageBuilder(CommandSender sender) { return sender instanceof ConsoleCommandSender ? consoleMessageBuilder : messageBuilder; } @@ -168,7 +143,7 @@ public final class OutputManager { return MessageBuilder.defaultBuilder(config); } - private static MessageBuilder getConsoleMessageBuilder() { + private static @NotNull MessageBuilder getConsoleMessageBuilder() { MessageBuilder consoleBuilder; if (isBukkit()) { consoleBuilder = MessageBuilder.fromComponentFactory(config, new BukkitConsoleComponentFactory(config)); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/reload/ReloadThread.java b/src/main/java/com/artemis/the/gr8/playerstats/reload/ReloadThread.java index d8bcaf7..b6c8d63 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/reload/ReloadThread.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/reload/ReloadThread.java @@ -1,7 +1,7 @@ package com.artemis.the.gr8.playerstats.reload; import com.artemis.the.gr8.playerstats.Main; -import com.artemis.the.gr8.playerstats.ShareManager; +import com.artemis.the.gr8.playerstats.share.ShareManager; import com.artemis.the.gr8.playerstats.enums.StandardMessage; import com.artemis.the.gr8.playerstats.msg.OutputManager; import com.artemis.the.gr8.playerstats.msg.msgutils.LanguageKeyHandler; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/ShareManager.java b/src/main/java/com/artemis/the/gr8/playerstats/share/ShareManager.java similarity index 90% rename from src/main/java/com/artemis/the/gr8/playerstats/ShareManager.java rename to src/main/java/com/artemis/the/gr8/playerstats/share/ShareManager.java index 13990e4..9b91bb9 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/ShareManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/share/ShareManager.java @@ -1,6 +1,5 @@ -package com.artemis.the.gr8.playerstats; +package com.artemis.the.gr8.playerstats.share; -import com.artemis.the.gr8.playerstats.statistic.result.InternalStatResult; import com.artemis.the.gr8.playerstats.config.ConfigHandler; import com.artemis.the.gr8.playerstats.utils.MyLogger; import net.kyori.adventure.text.TextComponent; @@ -30,7 +29,7 @@ public final class ShareManager { private static int waitingTime; private static volatile AtomicInteger resultID; - private static ConcurrentHashMap statResultQueue; + private static ConcurrentHashMap statResultQueue; private static ConcurrentHashMap shareTimeStamp; private static ArrayBlockingQueue sharedResults; @@ -75,8 +74,7 @@ public final class ShareManager { removeExcessResults(playerName); int ID = getNextIDNumber(); - //UUID shareCode = UUID.randomUUID(); - InternalStatResult result = new InternalStatResult(playerName, statResult, ID); + StoredResult result = new StoredResult(playerName, statResult, ID); int shareCode = result.hashCode(); statResultQueue.put(shareCode, result); MyLogger.logMediumLevelMsg("Saving statResults with no. " + ID); @@ -103,7 +101,7 @@ public final class ShareManager { * and returns the formattedComponent. If no formattedComponent was found, * returns null. */ - public @Nullable InternalStatResult getStatResult(String playerName, int shareCode) { + public @Nullable StoredResult getStatResult(String playerName, int shareCode) { if (statResultQueue.containsKey(shareCode)) { shareTimeStamp.put(playerName, Instant.now()); @@ -134,7 +132,7 @@ public final class ShareManager { * StatResults saved, remove the oldest one. */ private void removeExcessResults(String playerName) { - List alreadySavedResults = statResultQueue.values() + List alreadySavedResults = statResultQueue.values() .parallelStream() .filter(result -> result.executorName().equalsIgnoreCase(playerName)) .toList(); @@ -142,7 +140,7 @@ public final class ShareManager { if (alreadySavedResults.size() > 25) { int hashCode = alreadySavedResults .parallelStream() - .min(Comparator.comparing(InternalStatResult::ID)) + .min(Comparator.comparing(StoredResult::ID)) .orElseThrow().hashCode(); MyLogger.logMediumLevelMsg("Removing old stat no. " + statResultQueue.get(hashCode).ID() + " for player " + playerName); statResultQueue.remove(hashCode); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/share/StoredResult.java b/src/main/java/com/artemis/the/gr8/playerstats/share/StoredResult.java new file mode 100644 index 0000000..afbb940 --- /dev/null +++ b/src/main/java/com/artemis/the/gr8/playerstats/share/StoredResult.java @@ -0,0 +1,10 @@ +package com.artemis.the.gr8.playerstats.share; + +import net.kyori.adventure.text.TextComponent; + +/** + * This Record is used to store stat-results internally, + * so Players can share them by clicking a share-button. + */ +public record StoredResult(String executorName, TextComponent formattedValue, int ID) { +} \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/InternalStatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/InternalStatRequest.java similarity index 79% rename from src/main/java/com/artemis/the/gr8/playerstats/statistic/request/InternalStatRequest.java rename to src/main/java/com/artemis/the/gr8/playerstats/statistic/InternalStatRequest.java index bdd0a09..bc7485e 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/InternalStatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/InternalStatRequest.java @@ -1,7 +1,7 @@ -package com.artemis.the.gr8.playerstats.statistic.request; +package com.artemis.the.gr8.playerstats.statistic; import com.artemis.the.gr8.playerstats.Main; -import com.artemis.the.gr8.playerstats.statistic.result.StatResult; +import com.artemis.the.gr8.playerstats.config.ConfigHandler; import com.artemis.the.gr8.playerstats.utils.EnumHandler; import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; import net.kyori.adventure.text.TextComponent; @@ -21,12 +21,14 @@ import java.util.regex.Pattern; public final class InternalStatRequest extends StatRequest { + private final ConfigHandler config; private final OfflinePlayerHandler offlinePlayerHandler; private final EnumHandler enumHandler; private final Pattern targetPattern; public InternalStatRequest(CommandSender sender, String[] args) { super(sender); + config = Main.getConfigHandler(); offlinePlayerHandler = Main.getOfflinePlayerHandler(); enumHandler = Main.getEnumHandler(); targetPattern = Pattern.compile("top|server|me|player"); @@ -36,7 +38,7 @@ public final class InternalStatRequest extends StatRequest { @Override public @NotNull StatResult execute() { - return Main.getRequestProcessor().getInternalResult(settings); + return Main.getRequestProcessor().getInternalResult(super.getSettings()); } private void processArgs(CommandSender sender, String[] args) { @@ -56,31 +58,31 @@ public final class InternalStatRequest extends StatRequest { continue; } else { - super.settings.configureForPlayer(playerName); + super.getSettings().configureForPlayer(playerName); String[] extractedPlayerName = removeArg(leftoverArgs, playerName); return removeArg(extractedPlayerName, arg); } } case "me" -> { if (sender instanceof Player) { - super.settings.configureForPlayer(sender.getName()); + super.getSettings().configureForPlayer(sender.getName()); } else { - super.settings.configureForServer(); + super.getSettings().configureForServer(); } } - case "server" -> super.settings.configureForServer(); - case "top" -> super.settings.configureForTop(); + case "server" -> super.getSettings().configureForServer(); + case "top" -> super.getSettings().configureForTop(config.getTopListMaxSize()); } return removeArg(leftoverArgs, arg); } } //if no target is found, but there is a playerName, assume target = Target.PLAYER if (playerName != null) { - super.settings.configureForPlayer(playerName); + super.getSettings().configureForPlayer(playerName); return removeArg(leftoverArgs, playerName); } //otherwise, assume target = Target.TOP - super.settings.configureForTop(); + super.getSettings().configureForTop(config.getTopListMaxSize()); return leftoverArgs; } @@ -102,23 +104,23 @@ public final class InternalStatRequest extends StatRequest { for (String arg : leftoverArgs) { if (enumHandler.isSubStatEntry(arg)) { switch (statistic.getType()) { - case UNTYPED -> super.configureUntyped(statistic); + case UNTYPED -> super.getSettings().configureUntyped(statistic); case ITEM -> { Material item = EnumHandler.getItemEnum(arg); if (item != null) { - super.configureBlockOrItemType(statistic, item); + super.getSettings().configureBlockOrItemType(statistic, item); } } case BLOCK -> { Material block = EnumHandler.getBlockEnum(arg); if (block != null) { - super.configureBlockOrItemType(statistic, block); + super.getSettings().configureBlockOrItemType(statistic, block); } } case ENTITY -> { EntityType entityType = EnumHandler.getEntityEnum(arg); if (entityType != null) { - super.configureEntityType(statistic, entityType); + super.getSettings().configureEntityType(statistic, entityType); } } } @@ -142,5 +144,4 @@ public final class InternalStatRequest extends StatRequest { currentArgs.remove(argToRemove); return currentArgs.toArray(String[]::new); } - -} +} \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/PlayerStatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/PlayerStatRequest.java similarity index 57% rename from src/main/java/com/artemis/the/gr8/playerstats/statistic/request/PlayerStatRequest.java rename to src/main/java/com/artemis/the/gr8/playerstats/statistic/PlayerStatRequest.java index dce804f..11e4e36 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/PlayerStatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/PlayerStatRequest.java @@ -1,43 +1,40 @@ -package com.artemis.the.gr8.playerstats.statistic.request; +package com.artemis.the.gr8.playerstats.statistic; import com.artemis.the.gr8.playerstats.Main; import com.artemis.the.gr8.playerstats.api.RequestGenerator; -import com.artemis.the.gr8.playerstats.statistic.result.StatResult; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Statistic; -import org.bukkit.command.CommandSender; import org.bukkit.entity.EntityType; import org.jetbrains.annotations.NotNull; public final class PlayerStatRequest extends StatRequest implements RequestGenerator { public PlayerStatRequest(String playerName) { - this(Bukkit.getConsoleSender(), playerName); - } - - public PlayerStatRequest(CommandSender requester, String playerName) { - super(requester); - super.settings.configureForPlayer(playerName); + super(Bukkit.getConsoleSender()); + super.getSettings().configureForPlayer(playerName); } @Override public StatRequest untyped(@NotNull Statistic statistic) { - return super.configureUntyped(statistic); + super.getSettings().configureUntyped(statistic); + return this; } @Override public StatRequest blockOrItemType(@NotNull Statistic statistic, @NotNull Material material) { - return super.configureBlockOrItemType(statistic, material); + super.getSettings().configureBlockOrItemType(statistic, material); + return this; } @Override public StatRequest entityType(@NotNull Statistic statistic, @NotNull EntityType entityType) { - return super.configureEntityType(statistic, entityType); + super.getSettings().configureEntityType(statistic, entityType); + return this; } @Override public @NotNull StatResult execute() { - return Main.getRequestProcessor().getPlayerResult(settings); + return Main.getRequestProcessor().processPlayerRequest(super.getSettings()); } } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/RequestProcessor.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/RequestProcessor.java index 588c6f0..2efe9d2 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/RequestProcessor.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/RequestProcessor.java @@ -1,15 +1,17 @@ package com.artemis.the.gr8.playerstats.statistic; import com.artemis.the.gr8.playerstats.ThreadManager; +import com.artemis.the.gr8.playerstats.msg.FormattingFunction; import com.artemis.the.gr8.playerstats.msg.OutputManager; import com.artemis.the.gr8.playerstats.msg.components.ComponentUtils; -import com.artemis.the.gr8.playerstats.statistic.request.StatRequest; -import com.artemis.the.gr8.playerstats.statistic.result.StatResult; +import com.artemis.the.gr8.playerstats.share.ShareManager; import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; import com.artemis.the.gr8.playerstats.utils.MyLogger; import com.google.common.collect.ImmutableList; import net.kyori.adventure.text.TextComponent; import org.bukkit.OfflinePlayer; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; import org.jetbrains.annotations.NotNull; import java.util.*; @@ -22,44 +24,49 @@ public final class RequestProcessor { private final OfflinePlayerHandler offlinePlayerHandler; private static OutputManager outputManager; + private static ShareManager shareManager; - public RequestProcessor(OfflinePlayerHandler offlinePlayerHandler, OutputManager outputManager) { + public RequestProcessor(OfflinePlayerHandler offlinePlayerHandler, OutputManager outputManager, ShareManager shareManager) { this.offlinePlayerHandler = offlinePlayerHandler; RequestProcessor.outputManager = outputManager; + RequestProcessor.shareManager = shareManager; } public @NotNull StatResult getInternalResult(@NotNull StatRequest.Settings requestSettings) { StatResult result = switch (requestSettings.getTarget()) { - case PLAYER -> getPlayerResult(requestSettings); - case SERVER -> getServerResult(requestSettings); - case TOP -> getTopResult(requestSettings); + case PLAYER -> processPlayerRequest(requestSettings); + case SERVER -> processServerRequest(requestSettings); + case TOP -> processTopRequest(requestSettings); }; return new StatResult<>(result.formattedComponent(), result.formattedComponent(), result.formattedString()); } - public @NotNull StatResult getPlayerResult(StatRequest.Settings requestSettings) { + public @NotNull StatResult processPlayerRequest(StatRequest.Settings requestSettings) { int stat = getPlayerStat(requestSettings); - TextComponent result = outputManager.formatAndSavePlayerStat(requestSettings, stat); - String serializedResult = ComponentUtils.getTranslatableComponentSerializer().serialize(result); + FormattingFunction formattingFunction = outputManager.formatPlayerStat(requestSettings, stat); + TextComponent formattedResult = processFunction(requestSettings.getCommandSender(), formattingFunction); + String resultAsString = ComponentUtils.getTranslatableComponentSerializer().serialize(formattedResult); - return new StatResult<>(stat, result, serializedResult); + return new StatResult<>(stat, formattedResult, resultAsString); } - public @NotNull StatResult getServerResult(StatRequest.Settings requestSettings) { + public @NotNull StatResult processServerRequest(StatRequest.Settings requestSettings) { long stat = getServerStat(requestSettings); - TextComponent result = outputManager.formatAndSaveServerStat(requestSettings, stat); - String serializedResult = ComponentUtils.getTranslatableComponentSerializer().serialize(result); + FormattingFunction formattingFunction = outputManager.formatServerStat(requestSettings, stat); + TextComponent formattedResult = processFunction(requestSettings.getCommandSender(), formattingFunction); + String resultAsString = ComponentUtils.getTranslatableComponentSerializer().serialize(formattedResult); - return new StatResult<>(stat, result, serializedResult); + return new StatResult<>(stat, formattedResult, resultAsString); } - public @NotNull StatResult> getTopResult(StatRequest.Settings requestSettings) { + public @NotNull StatResult> processTopRequest(StatRequest.Settings requestSettings) { LinkedHashMap stats = getTopStats(requestSettings); - TextComponent result = outputManager.formatAndSaveTopStat(requestSettings, stats); - String serializedResult = ComponentUtils.getTranslatableComponentSerializer().serialize(result); + FormattingFunction formattingFunction = outputManager.formatTopStats(requestSettings, stats); + TextComponent formattedResult = processFunction(requestSettings.getCommandSender(), formattingFunction); + String resultAsString = ComponentUtils.getTranslatableComponentSerializer().serialize(formattedResult); - return new StatResult<>(stats, result, serializedResult); + return new StatResult<>(stats, formattedResult, resultAsString); } private int getPlayerStat(@NotNull StatRequest.Settings requestSettings) { @@ -87,6 +94,20 @@ public final class RequestProcessor { .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new)); } + private TextComponent processFunction(CommandSender sender, FormattingFunction function) { + if (outputShouldBeStored(sender)) { + int shareCode = shareManager.saveStatResult(sender.getName(), function.getResultWithSharerName(sender)); + return function.getResultWithShareButton(shareCode); + } + return function.getDefaultResult(); + } + + private boolean outputShouldBeStored(CommandSender sender) { + return !(sender instanceof ConsoleCommandSender) && + ShareManager.isEnabled() && + shareManager.senderHasPermission(sender); + } + /** * Invokes a bunch of worker pool threads to get the statistics for * all players that are stored in the {@link OfflinePlayerHandler}). diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/ServerStatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/ServerStatRequest.java similarity index 60% rename from src/main/java/com/artemis/the/gr8/playerstats/statistic/request/ServerStatRequest.java rename to src/main/java/com/artemis/the/gr8/playerstats/statistic/ServerStatRequest.java index 7298a1d..762ce4d 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/ServerStatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/ServerStatRequest.java @@ -1,8 +1,7 @@ -package com.artemis.the.gr8.playerstats.statistic.request; +package com.artemis.the.gr8.playerstats.statistic; import com.artemis.the.gr8.playerstats.Main; import com.artemis.the.gr8.playerstats.api.RequestGenerator; -import com.artemis.the.gr8.playerstats.statistic.result.StatResult; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Statistic; @@ -12,32 +11,32 @@ import org.jetbrains.annotations.NotNull; public final class ServerStatRequest extends StatRequest implements RequestGenerator { - public ServerStatRequest() { - this(Bukkit.getConsoleSender()); - } - public ServerStatRequest(CommandSender requester) { - super(requester); - super.settings.configureForServer(); + public ServerStatRequest() { + super(Bukkit.getConsoleSender()); + super.getSettings().configureForServer(); } @Override public StatRequest untyped(@NotNull Statistic statistic) { - return super.configureUntyped(statistic); + super.getSettings().configureUntyped(statistic); + return this; } @Override public StatRequest blockOrItemType(@NotNull Statistic statistic, @NotNull Material material) { - return super.configureBlockOrItemType(statistic, material); + super.getSettings().configureBlockOrItemType(statistic, material); + return this; } @Override public StatRequest entityType(@NotNull Statistic statistic, @NotNull EntityType entityType) { - return super.configureEntityType(statistic, entityType); + super.getSettings().configureEntityType(statistic, entityType); + return this; } @Override public @NotNull StatResult execute() { - return Main.getRequestProcessor().getServerResult(settings); + return Main.getRequestProcessor().processServerRequest(super.getSettings()); } } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatAction.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatAction.java index 7f1d598..f1bfcd3 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatAction.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatAction.java @@ -1,7 +1,6 @@ package com.artemis.the.gr8.playerstats.statistic; import com.artemis.the.gr8.playerstats.ThreadManager; -import com.artemis.the.gr8.playerstats.statistic.request.StatRequest; import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; import com.artemis.the.gr8.playerstats.utils.MyLogger; import com.google.common.collect.ImmutableList; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/StatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatRequest.java similarity index 66% rename from src/main/java/com/artemis/the/gr8/playerstats/statistic/request/StatRequest.java rename to src/main/java/com/artemis/the/gr8/playerstats/statistic/StatRequest.java index 5402819..7af52d2 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/StatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatRequest.java @@ -1,8 +1,6 @@ -package com.artemis.the.gr8.playerstats.statistic.request; +package com.artemis.the.gr8.playerstats.statistic; -import com.artemis.the.gr8.playerstats.Main; import com.artemis.the.gr8.playerstats.api.PlayerStats; -import com.artemis.the.gr8.playerstats.statistic.result.StatResult; import com.artemis.the.gr8.playerstats.enums.Target; import org.bukkit.Material; import org.bukkit.Statistic; @@ -22,7 +20,7 @@ import org.jetbrains.annotations.Nullable; */ public abstract class StatRequest { - protected final Settings settings; + private final Settings settings; protected StatRequest(CommandSender requester) { settings = new Settings(requester); @@ -77,40 +75,6 @@ public abstract class StatRequest { } } - protected StatRequest configureUntyped(@NotNull Statistic statistic) { - if (statistic.getType() == Statistic.Type.UNTYPED) { - settings.statistic = statistic; - return this; - } - throw new IllegalArgumentException("This statistic is not of Type.Untyped"); - } - - protected StatRequest configureBlockOrItemType(@NotNull Statistic statistic, @NotNull Material material) throws IllegalArgumentException { - Statistic.Type type = statistic.getType(); - if (type == Statistic.Type.BLOCK && material.isBlock()) { - settings.block = material; - } - else if (type == Statistic.Type.ITEM && material.isItem()){ - settings.item = material; - } - else { - throw new IllegalArgumentException("Either this statistic is not of Type.Block or Type.Item, or no valid block or item has been provided"); - } - settings.statistic = statistic; - settings.subStatEntryName = material.toString(); - return this; - } - - protected StatRequest configureEntityType(@NotNull Statistic statistic, @NotNull EntityType entityType) throws IllegalArgumentException { - if (statistic.getType() == Statistic.Type.ENTITY) { - settings.statistic = statistic; - settings.entity = entityType; - settings.subStatEntryName = entityType.toString(); - return this; - } - throw new IllegalArgumentException("This statistic is not of Type.Entity"); - } - public static final class Settings { private final CommandSender sender; private Statistic statistic; @@ -139,15 +103,40 @@ public abstract class StatRequest { this.target = Target.SERVER; } - void configureForTop() { - configureForTop(Main.getConfigHandler().getTopListMaxSize()); - } - void configureForTop(int topListSize) { this.target = Target.TOP; - this.topListSize = topListSize != 0 ? - topListSize : - Main.getConfigHandler().getTopListMaxSize(); + this.topListSize = topListSize; + } + + void configureUntyped(@NotNull Statistic statistic) { + if (statistic.getType() == Statistic.Type.UNTYPED) { + this.statistic = statistic; + } + throw new IllegalArgumentException("This statistic is not of Type.Untyped"); + } + + void configureBlockOrItemType(@NotNull Statistic statistic, @NotNull Material material) throws IllegalArgumentException { + Statistic.Type type = statistic.getType(); + if (type == Statistic.Type.BLOCK && material.isBlock()) { + this.block = material; + } + else if (type == Statistic.Type.ITEM && material.isItem()){ + this.item = material; + } + else { + throw new IllegalArgumentException("Either this statistic is not of Type.Block or Type.Item, or no valid block or item has been provided"); + } + this.statistic = statistic; + this.subStatEntryName = material.toString(); + } + + void configureEntityType(@NotNull Statistic statistic, @NotNull EntityType entityType) throws IllegalArgumentException { + if (statistic.getType() == Statistic.Type.ENTITY) { + this.statistic = statistic; + this.entity = entityType; + this.subStatEntryName = entityType.toString(); + } + throw new IllegalArgumentException("This statistic is not of Type.Entity"); } public @NotNull CommandSender getCommandSender() { diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/result/StatResult.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatResult.java similarity index 98% rename from src/main/java/com/artemis/the/gr8/playerstats/statistic/result/StatResult.java rename to src/main/java/com/artemis/the/gr8/playerstats/statistic/StatResult.java index 46c5ea1..97fd1c5 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/result/StatResult.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatResult.java @@ -1,4 +1,4 @@ -package com.artemis.the.gr8.playerstats.statistic.result; +package com.artemis.the.gr8.playerstats.statistic; import com.artemis.the.gr8.playerstats.api.StatFormatter; import net.kyori.adventure.platform.bukkit.BukkitAudiences; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatThread.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatThread.java index faa84e0..3ac5868 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatThread.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatThread.java @@ -2,8 +2,6 @@ package com.artemis.the.gr8.playerstats.statistic; import com.artemis.the.gr8.playerstats.ThreadManager; import com.artemis.the.gr8.playerstats.msg.OutputManager; -import com.artemis.the.gr8.playerstats.statistic.request.StatRequest; -import com.artemis.the.gr8.playerstats.statistic.result.StatResult; import com.artemis.the.gr8.playerstats.utils.MyLogger; import com.artemis.the.gr8.playerstats.enums.StandardMessage; import com.artemis.the.gr8.playerstats.reload.ReloadThread; @@ -18,15 +16,12 @@ import java.util.*; public final class StatThread extends Thread { private static OutputManager outputManager; - private static RequestProcessor requestProcessor; private final ReloadThread reloadThread; private final StatRequest statRequest; - public StatThread(OutputManager m, RequestProcessor t, int ID, StatRequest s, @Nullable ReloadThread r) { + public StatThread(OutputManager m, int ID, StatRequest s, @Nullable ReloadThread r) { outputManager = m; - requestProcessor = t; - reloadThread = r; statRequest = s; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/TopStatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/TopStatRequest.java similarity index 61% rename from src/main/java/com/artemis/the/gr8/playerstats/statistic/request/TopStatRequest.java rename to src/main/java/com/artemis/the/gr8/playerstats/statistic/TopStatRequest.java index f9ad3d2..f475ec9 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/request/TopStatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/TopStatRequest.java @@ -1,12 +1,10 @@ -package com.artemis.the.gr8.playerstats.statistic.request; +package com.artemis.the.gr8.playerstats.statistic; import com.artemis.the.gr8.playerstats.Main; -import com.artemis.the.gr8.playerstats.statistic.result.StatResult; import com.artemis.the.gr8.playerstats.api.RequestGenerator; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Statistic; -import org.bukkit.command.CommandSender; import org.bukkit.entity.EntityType; import org.jetbrains.annotations.NotNull; @@ -15,31 +13,30 @@ import java.util.LinkedHashMap; public final class TopStatRequest extends StatRequest> implements RequestGenerator> { public TopStatRequest(int topListSize) { - this(Bukkit.getConsoleSender(), topListSize); - } - - public TopStatRequest(CommandSender requester, int topListSize) { - super(requester); - super.settings.configureForTop(topListSize); + super(Bukkit.getConsoleSender()); + super.getSettings().configureForTop(topListSize); } @Override public StatRequest> untyped(@NotNull Statistic statistic) { - return super.configureUntyped(statistic); + super.getSettings().configureUntyped(statistic); + return this; } @Override public StatRequest> blockOrItemType(@NotNull Statistic statistic, @NotNull Material material) { - return super.configureBlockOrItemType(statistic, material); + super.getSettings().configureBlockOrItemType(statistic, material); + return this; } @Override public StatRequest> entityType(@NotNull Statistic statistic, @NotNull EntityType entityType) { - return super.configureEntityType(statistic, entityType); + super.getSettings().configureEntityType(statistic, entityType); + return this; } @Override public @NotNull StatResult> execute() { - return Main.getRequestProcessor().getTopResult(settings); + return Main.getRequestProcessor().processTopRequest(super.getSettings()); } } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/result/InternalStatResult.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/result/InternalStatResult.java deleted file mode 100644 index 3a63401..0000000 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/result/InternalStatResult.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.artemis.the.gr8.playerstats.statistic.result; - -import com.artemis.the.gr8.playerstats.msg.components.ComponentUtils; -import net.kyori.adventure.text.TextComponent; - -/** - * This Record is used to store stat-results internally, - * so Players can share them by clicking a share-button. - */ -public record InternalStatResult(String executorName, TextComponent formattedValue, int ID) { - - /** - * Gets the ID number for this StatResult. Unlike for the - * other {@link StatResult} implementations, this one does - * not return the actual statistic data, because this - * implementation is meant for internal saving-and-sharing only. - * This method is only for Interface-consistency, - * InternalStatResult#ID is better. - * - @return Integer that represents this StatResult's ID number - */ - public Integer getNumericalValue() { - return ID; - } - - public TextComponent getFormattedTextComponent() { - return formattedValue; - } - - public String getFormattedString() { - return ComponentUtils.getTranslatableComponentSerializer() - .serialize(formattedValue); - } -} \ No newline at end of file From b1c015e156259f7e9fc14f36e1f05c6a4da22198 Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Fri, 14 Oct 2022 16:40:39 +0200 Subject: [PATCH 10/43] Started to move arg-processing to StatCommand after testing (feedback is no longer working with the increased StatRequest conditions of what settings are accepted) --- .../gr8/playerstats/commands/StatCommand.java | 94 +++++++++++++++++++ .../statistic/InternalStatRequest.java | 15 ++- .../playerstats/statistic/StatRequest.java | 16 ++-- 3 files changed, 116 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java b/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java index f3b62b1..fea7533 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java @@ -5,18 +5,30 @@ import com.artemis.the.gr8.playerstats.enums.StandardMessage; import com.artemis.the.gr8.playerstats.enums.Target; import com.artemis.the.gr8.playerstats.msg.OutputManager; import com.artemis.the.gr8.playerstats.statistic.InternalStatRequest; +import com.artemis.the.gr8.playerstats.statistic.PlayerStatRequest; import com.artemis.the.gr8.playerstats.statistic.StatRequest; +import com.artemis.the.gr8.playerstats.utils.EnumHandler; +import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; import net.kyori.adventure.text.TextComponent; import org.bukkit.Statistic; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class StatCommand implements CommandExecutor { private static ThreadManager threadManager; private static OutputManager outputManager; + private OfflinePlayerHandler offlinePlayerHandler; + private EnumHandler enumHandler; public StatCommand(OutputManager m, ThreadManager t) { threadManager = t; @@ -44,6 +56,88 @@ public class StatCommand implements CommandExecutor { return true; } + private final class ArgProcessor { + + private String[] argsToProcess; + private Statistic statistic; + private String subStatistic; + + private ArgProcessor(CommandSender sender, String[] args) { + argsToProcess = args; + process(sender); + } + + private StatRequest process(CommandSender sender) { + Pattern pattern = Pattern.compile("top|server|me|player"); + extractStatistic(); + + String playerName = tryToFindPlayerName(argsToProcess); + + for (String arg : argsToProcess) { + Matcher matcher = pattern.matcher(arg); + if (matcher.find()) { + switch (matcher.group()) { + case "player" -> { + if (playerName != null || containsPlayerTwice(argsToProcess)) { + new PlayerStatRequest(playerName); + } + } + } + } + } + } + + private void extractStatistic() { + String statName = null; + for (String arg : argsToProcess) { + if (enumHandler.isStatistic(arg)) { + statName = arg; + break; + } + } + if (statName != null) { + statistic = EnumHandler.getStatEnum(statName); + argsToProcess = removeArg(argsToProcess, statName); + } + } + + private void extractSubStatistic() { + if (statistic == null || + statistic.getType() == Statistic.Type.UNTYPED || + argsToProcess.length == 0) { + return; + } + + for (String arg : argsToProcess) { + + } + } + + @Contract(pure = true) + private @Nullable String tryToFindPlayerName(@NotNull String[] args) { + for (String arg : args) { + if (offlinePlayerHandler.isRelevantPlayer(arg)) { + return arg; + } + } + return null; + } + + private boolean containsPlayerTwice(String[] args) { + return Arrays.stream(args) + .filter(arg -> arg.equalsIgnoreCase("player")) + .toList() + .size() >= 2; + } + + private String[] removeArg(@NotNull String[] args, String argToRemove) { + ArrayList currentArgs = new ArrayList<>(Arrays.asList(args)); + currentArgs.remove(argToRemove); + return currentArgs.toArray(String[]::new); + } + + } + /** * If a given {@link StatRequest} object does not result in a valid * statistic look-up, this will send a feedback message to the CommandSender diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/InternalStatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/InternalStatRequest.java index bc7485e..9dfeb09 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/InternalStatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/InternalStatRequest.java @@ -3,6 +3,7 @@ package com.artemis.the.gr8.playerstats.statistic; import com.artemis.the.gr8.playerstats.Main; import com.artemis.the.gr8.playerstats.config.ConfigHandler; import com.artemis.the.gr8.playerstats.utils.EnumHandler; +import com.artemis.the.gr8.playerstats.utils.MyLogger; import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; import net.kyori.adventure.text.TextComponent; import org.bukkit.Material; @@ -42,7 +43,11 @@ public final class InternalStatRequest extends StatRequest { } private void processArgs(CommandSender sender, String[] args) { + MyLogger.logWarning("processArgs: " + Arrays.toString(args)); + String[] argsMinusTarget = extractAndStoreTarget(sender, args); + MyLogger.logWarning("processArgs minus target: " + Arrays.toString(argsMinusTarget)); + findStatAndSubStat(argsMinusTarget); } @@ -59,6 +64,7 @@ public final class InternalStatRequest extends StatRequest { } else { super.getSettings().configureForPlayer(playerName); + String[] extractedPlayerName = removeArg(leftoverArgs, playerName); return removeArg(extractedPlayerName, arg); } @@ -87,8 +93,10 @@ public final class InternalStatRequest extends StatRequest { } private void findStatAndSubStat(@NotNull String[] leftoverArgs) { + MyLogger.logWarning("findStatAndSubStat: " + Arrays.toString(leftoverArgs)); for (String arg : leftoverArgs) { if (enumHandler.isStatistic(arg)) { + MyLogger.logWarning("statistic found: " + arg); Statistic stat = EnumHandler.getStatEnum(arg); String[] argsWithoutStat = removeArg(leftoverArgs, arg); findAndStoreSubStat(argsWithoutStat, stat); @@ -97,7 +105,12 @@ public final class InternalStatRequest extends StatRequest { } private void findAndStoreSubStat(String[] leftoverArgs, Statistic statistic) { - if (statistic == null || leftoverArgs.length == 0) { + MyLogger.logWarning("findAndStoreSubStat: " + Arrays.toString(leftoverArgs)); + if (statistic == null) { + return; + } + else if (leftoverArgs.length == 0) { + super.getSettings().configureUntyped(statistic); return; } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatRequest.java index 7af52d2..f7fe80e 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatRequest.java @@ -109,10 +109,10 @@ public abstract class StatRequest { } void configureUntyped(@NotNull Statistic statistic) { - if (statistic.getType() == Statistic.Type.UNTYPED) { - this.statistic = statistic; + if (statistic.getType() != Statistic.Type.UNTYPED) { + throw new IllegalArgumentException("This statistic is not of Type.Untyped"); } - throw new IllegalArgumentException("This statistic is not of Type.Untyped"); + this.statistic = statistic; } void configureBlockOrItemType(@NotNull Statistic statistic, @NotNull Material material) throws IllegalArgumentException { @@ -131,12 +131,12 @@ public abstract class StatRequest { } void configureEntityType(@NotNull Statistic statistic, @NotNull EntityType entityType) throws IllegalArgumentException { - if (statistic.getType() == Statistic.Type.ENTITY) { - this.statistic = statistic; - this.entity = entityType; - this.subStatEntryName = entityType.toString(); + if (statistic.getType() != Statistic.Type.ENTITY) { + throw new IllegalArgumentException("This statistic is not of Type.Entity"); } - throw new IllegalArgumentException("This statistic is not of Type.Entity"); + this.statistic = statistic; + this.entity = entityType; + this.subStatEntryName = entityType.toString(); } public @NotNull CommandSender getCommandSender() { From 03efe136b04aa4736024decc476c4fe62c5b12f5 Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Sat, 15 Oct 2022 17:34:52 +0200 Subject: [PATCH 11/43] Moved all arg-analyzing to StatCommand and got rid of InternalStatRequest (#114) --- .../com/artemis/the/gr8/playerstats/Main.java | 38 +--- .../gr8/playerstats/commands/StatCommand.java | 215 ++++++++++++------ .../statistic/InternalStatRequest.java | 160 ------------- .../gr8/playerstats/statistic/StatResult.java | 6 +- 4 files changed, 154 insertions(+), 265 deletions(-) delete mode 100644 src/main/java/com/artemis/the/gr8/playerstats/statistic/InternalStatRequest.java diff --git a/src/main/java/com/artemis/the/gr8/playerstats/Main.java b/src/main/java/com/artemis/the/gr8/playerstats/Main.java index e1d6391..511c484 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/Main.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/Main.java @@ -56,7 +56,7 @@ public final class Main extends JavaPlugin { //register all commands and the tabCompleter PluginCommand statcmd = this.getCommand("statistic"); if (statcmd != null) { - statcmd.setExecutor(new StatCommand(outputManager, threadManager)); + statcmd.setExecutor(new StatCommand(outputManager, threadManager, config, offlinePlayerHandler, enumHandler)); statcmd.setTabCompleter(new TabCompleter(enumHandler, offlinePlayerHandler)); } PluginCommand reloadcmd = this.getCommand("statisticreload"); @@ -80,17 +80,6 @@ public final class Main extends JavaPlugin { this.getLogger().info("Disabled PlayerStats!"); } - /** - * @return Adventure's BukkitAudiences object - * @throws IllegalStateException if PlayerStats is not enabled - */ - public static @NotNull BukkitAudiences getAdventure() throws IllegalStateException { - if (adventure == null) { - throw new IllegalStateException("Tried to access Adventure without PlayerStats being enabled!"); - } - return adventure; - } - /** * * @return the JavaPlugin instance associated with PlayerStats @@ -117,19 +106,9 @@ public final class Main extends JavaPlugin { return requestProcessor; } - /** - * @return PlayerStats' ConfigHandler - */ - public static @NotNull ConfigHandler getConfigHandler() { - if (config == null) { - config = new ConfigHandler(); - } - return config; - } - - public static @NotNull OfflinePlayerHandler getOfflinePlayerHandler() { + public static @NotNull OfflinePlayerHandler getOfflinePlayerHandler() throws IllegalStateException { if (offlinePlayerHandler == null) { - offlinePlayerHandler = new OfflinePlayerHandler(getConfigHandler()); + throw new IllegalStateException("PlayerStats does not seem to be loaded!"); } return offlinePlayerHandler; } @@ -141,17 +120,6 @@ public final class Main extends JavaPlugin { return languageKeyHandler; } - /** - * Gets the EnumHandler. If there is no EnumHandler, one will be created. - * @return PlayerStat's EnumHandler - */ - public static @NotNull EnumHandler getEnumHandler() { - if (enumHandler == null) { - enumHandler = new EnumHandler(); - } - return enumHandler; - } - private void initializeMainClasses() { pluginInstance = this; adventure = BukkitAudiences.create(this); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java b/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java index fea7533..ede5e8d 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java @@ -1,38 +1,47 @@ package com.artemis.the.gr8.playerstats.commands; import com.artemis.the.gr8.playerstats.ThreadManager; +import com.artemis.the.gr8.playerstats.api.RequestGenerator; +import com.artemis.the.gr8.playerstats.config.ConfigHandler; import com.artemis.the.gr8.playerstats.enums.StandardMessage; import com.artemis.the.gr8.playerstats.enums.Target; import com.artemis.the.gr8.playerstats.msg.OutputManager; -import com.artemis.the.gr8.playerstats.statistic.InternalStatRequest; -import com.artemis.the.gr8.playerstats.statistic.PlayerStatRequest; -import com.artemis.the.gr8.playerstats.statistic.StatRequest; +import com.artemis.the.gr8.playerstats.statistic.*; import com.artemis.the.gr8.playerstats.utils.EnumHandler; import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; -import net.kyori.adventure.text.TextComponent; +import org.bukkit.Material; import org.bukkit.Statistic; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; public class StatCommand implements CommandExecutor { + private static final Pattern pattern = Pattern.compile("top|server|me|player"); + private static ThreadManager threadManager; private static OutputManager outputManager; - private OfflinePlayerHandler offlinePlayerHandler; - private EnumHandler enumHandler; + private static ConfigHandler config; + private final OfflinePlayerHandler offlinePlayerHandler; + private final EnumHandler enumHandler; - public StatCommand(OutputManager m, ThreadManager t) { + public StatCommand(OutputManager m, ThreadManager t, ConfigHandler c, OfflinePlayerHandler o, EnumHandler e) { threadManager = t; outputManager = m; + config = c; + offlinePlayerHandler = o; + enumHandler = e; } @Override @@ -45,44 +54,138 @@ public class StatCommand implements CommandExecutor { outputManager.sendExamples(sender); } else { - StatRequest request = new InternalStatRequest(sender, args); - if (request.isValid()) { - threadManager.startStatThread(request); + ArgProcessor processor = new ArgProcessor(sender, args); + if (processor.request != null) { + threadManager.startStatThread(processor.request); } else { - sendFeedback(sender, request); + sendFeedback(sender, processor); return false; } } return true; } + /** + * Analyzes the provided args and sends an appropriate + * feedback message to the CommandSender that called the + * stat command. The following is checked: + *
      + *
    • Is a statistic set? + *
    • Is a subStatEntry needed, and if so, + * is a corresponding Material/EntityType present? + *
    • If the target is Player, is a valid + * playerName provided? + *
    + * + * @param sender the CommandSender to send feedback to + * @param processor the ArgProcessor object that holds + * the analyzed args + */ + private void sendFeedback(CommandSender sender, @NotNull ArgProcessor processor) { + if (processor.statistic == null) { + outputManager.sendFeedbackMsg(sender, StandardMessage.MISSING_STAT_NAME); + } + else if (processor.target == Target.PLAYER && processor.playerName == null) { + outputManager.sendFeedbackMsg(sender, StandardMessage.MISSING_PLAYER_NAME); + } + else { + Statistic.Type type = processor.statistic.getType(); + if (type != Statistic.Type.UNTYPED && processor.subStatName == null) { + outputManager.sendFeedbackMsgMissingSubStat(sender, type); + } else { + outputManager.sendFeedbackMsgWrongSubStat(sender, type, processor.subStatName); + } + } + } + private final class ArgProcessor { private String[] argsToProcess; private Statistic statistic; - private String subStatistic; + private String subStatName; + private Target target; + private String playerName; + private StatRequest request; private ArgProcessor(CommandSender sender, String[] args) { argsToProcess = args; - process(sender); + + extractStatistic(); + extractSubStatistic(); + extractTarget(sender); + combineProcessedArgsIntoRequest(); } - private StatRequest process(CommandSender sender) { - Pattern pattern = Pattern.compile("top|server|me|player"); - extractStatistic(); + private void combineProcessedArgsIntoRequest() { + if (statistic == null || + target == Target.PLAYER && playerName == null) { + return; + } - String playerName = tryToFindPlayerName(argsToProcess); + RequestGenerator requestGenerator = + switch (target) { + case PLAYER -> new PlayerStatRequest(playerName); + case SERVER -> new ServerStatRequest(); + case TOP -> new TopStatRequest(config.getTopListMaxSize()); + }; + switch (statistic.getType()) { + case UNTYPED -> request = requestGenerator.untyped(statistic); + case BLOCK -> { + Material block = EnumHandler.getBlockEnum(subStatName); + if (block != null) { + request = requestGenerator.blockOrItemType(statistic, block); + } + } + case ITEM -> { + Material item = EnumHandler.getItemEnum(subStatName); + if (item != null) { + request = requestGenerator.blockOrItemType(statistic, item); + } + } + case ENTITY -> { + EntityType entity = EnumHandler.getEntityEnum(subStatName); + if (entity != null) { + request = requestGenerator.entityType(statistic, entity); + } + } + } + } + + private void extractTarget(CommandSender sender) { + String targetArg = null; for (String arg : argsToProcess) { Matcher matcher = pattern.matcher(arg); if (matcher.find()) { - switch (matcher.group()) { - case "player" -> { - if (playerName != null || containsPlayerTwice(argsToProcess)) { - new PlayerStatRequest(playerName); + targetArg = matcher.group(); + switch (targetArg) { + case "me" -> { + if (sender instanceof Player) { + target = Target.PLAYER; + playerName = sender.getName(); + } else { + target = Target.SERVER; } } + case "player" -> { + target = Target.PLAYER; + playerName = tryToFindPlayerName(argsToProcess); + } + case "server" -> target = Target.SERVER; + case "top" -> target = Target.TOP; } + argsToProcess = removeArg(targetArg); + break; + } + } + + if (targetArg == null) { + String playerName = tryToFindPlayerName(argsToProcess); + if (playerName != null) { + target = Target.PLAYER; + this.playerName = playerName; + } else { + target = Target.TOP; } } } @@ -97,7 +200,7 @@ public class StatCommand implements CommandExecutor { } if (statName != null) { statistic = EnumHandler.getStatEnum(statName); - argsToProcess = removeArg(argsToProcess, statName); + argsToProcess = removeArg(statName); } } @@ -108,9 +211,29 @@ public class StatCommand implements CommandExecutor { return; } - for (String arg : argsToProcess) { - + String subStatName = null; + List subStats = Arrays.stream(argsToProcess) + .filter(enumHandler::isSubStatEntry) + .toList(); + if (subStats.isEmpty()) { + return; } + else if (subStats.size() == 1) { + subStatName = subStats.get(0); + } + else { + for (String arg : subStats) { + if (!arg.equalsIgnoreCase("player")) { + subStatName = arg; + break; + } + } + if (subStatName == null) { + subStatName = "player"; + } + } + this.subStatName = subStatName; + argsToProcess = removeArg(subStatName); } @Contract(pure = true) @@ -123,50 +246,10 @@ public class StatCommand implements CommandExecutor { return null; } - private boolean containsPlayerTwice(String[] args) { - return Arrays.stream(args) - .filter(arg -> arg.equalsIgnoreCase("player")) - .toList() - .size() >= 2; - } - - private String[] removeArg(@NotNull String[] args, String argToRemove) { - ArrayList currentArgs = new ArrayList<>(Arrays.asList(args)); + private String[] removeArg(String argToRemove) { + ArrayList currentArgs = new ArrayList<>(Arrays.asList(argsToProcess)); currentArgs.remove(argToRemove); return currentArgs.toArray(String[]::new); } - - } - - /** - * If a given {@link StatRequest} object does not result in a valid - * statistic look-up, this will send a feedback message to the CommandSender - * that made the request. The following is checked: - *
      - *
    • Is a statistic set? - *
    • Is a subStatEntry needed, and if so, is a corresponding Material/EntityType present? - *
    • If the target is Player, is a valid playerName provided? - *
    - * - * @param sender the CommandSender to send feedback to - * @param request the StatRequest to give feedback on - */ - private void sendFeedback(CommandSender sender, StatRequest request) { - StatRequest.Settings settings = request.getSettings(); - - if (settings.getStatistic() == null) { - outputManager.sendFeedbackMsg(sender, StandardMessage.MISSING_STAT_NAME); - } - else if (settings.getTarget() == Target.PLAYER && settings.getPlayerName() == null) { - outputManager.sendFeedbackMsg(sender, StandardMessage.MISSING_PLAYER_NAME); - } - else { - Statistic.Type type = settings.getStatistic().getType(); - if (type != Statistic.Type.UNTYPED && settings.getSubStatEntryName() == null) { - outputManager.sendFeedbackMsgMissingSubStat(sender, type); - } else { - outputManager.sendFeedbackMsgWrongSubStat(sender, type, settings.getSubStatEntryName()); - } - } } } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/InternalStatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/InternalStatRequest.java deleted file mode 100644 index 9dfeb09..0000000 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/InternalStatRequest.java +++ /dev/null @@ -1,160 +0,0 @@ -package com.artemis.the.gr8.playerstats.statistic; - -import com.artemis.the.gr8.playerstats.Main; -import com.artemis.the.gr8.playerstats.config.ConfigHandler; -import com.artemis.the.gr8.playerstats.utils.EnumHandler; -import com.artemis.the.gr8.playerstats.utils.MyLogger; -import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; -import net.kyori.adventure.text.TextComponent; -import org.bukkit.Material; -import org.bukkit.Statistic; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public final class InternalStatRequest extends StatRequest { - - private final ConfigHandler config; - private final OfflinePlayerHandler offlinePlayerHandler; - private final EnumHandler enumHandler; - private final Pattern targetPattern; - - public InternalStatRequest(CommandSender sender, String[] args) { - super(sender); - config = Main.getConfigHandler(); - offlinePlayerHandler = Main.getOfflinePlayerHandler(); - enumHandler = Main.getEnumHandler(); - targetPattern = Pattern.compile("top|server|me|player"); - - processArgs(sender, args); - } - - @Override - public @NotNull StatResult execute() { - return Main.getRequestProcessor().getInternalResult(super.getSettings()); - } - - private void processArgs(CommandSender sender, String[] args) { - MyLogger.logWarning("processArgs: " + Arrays.toString(args)); - - String[] argsMinusTarget = extractAndStoreTarget(sender, args); - MyLogger.logWarning("processArgs minus target: " + Arrays.toString(argsMinusTarget)); - - findStatAndSubStat(argsMinusTarget); - } - - private String[] extractAndStoreTarget(CommandSender sender, @NotNull String[] leftoverArgs) { - String playerName = tryToFindPlayerName(leftoverArgs); - - for (String arg : leftoverArgs) { - Matcher targetMatcher = targetPattern.matcher(arg); - if (targetMatcher.find()) { - switch (targetMatcher.group()) { - case "player" -> { - if (playerName == null) { - continue; - } - else { - super.getSettings().configureForPlayer(playerName); - - String[] extractedPlayerName = removeArg(leftoverArgs, playerName); - return removeArg(extractedPlayerName, arg); - } - } - case "me" -> { - if (sender instanceof Player) { - super.getSettings().configureForPlayer(sender.getName()); - } else { - super.getSettings().configureForServer(); - } - } - case "server" -> super.getSettings().configureForServer(); - case "top" -> super.getSettings().configureForTop(config.getTopListMaxSize()); - } - return removeArg(leftoverArgs, arg); - } - } - //if no target is found, but there is a playerName, assume target = Target.PLAYER - if (playerName != null) { - super.getSettings().configureForPlayer(playerName); - return removeArg(leftoverArgs, playerName); - } - //otherwise, assume target = Target.TOP - super.getSettings().configureForTop(config.getTopListMaxSize()); - return leftoverArgs; - } - - private void findStatAndSubStat(@NotNull String[] leftoverArgs) { - MyLogger.logWarning("findStatAndSubStat: " + Arrays.toString(leftoverArgs)); - for (String arg : leftoverArgs) { - if (enumHandler.isStatistic(arg)) { - MyLogger.logWarning("statistic found: " + arg); - Statistic stat = EnumHandler.getStatEnum(arg); - String[] argsWithoutStat = removeArg(leftoverArgs, arg); - findAndStoreSubStat(argsWithoutStat, stat); - } - } - } - - private void findAndStoreSubStat(String[] leftoverArgs, Statistic statistic) { - MyLogger.logWarning("findAndStoreSubStat: " + Arrays.toString(leftoverArgs)); - if (statistic == null) { - return; - } - else if (leftoverArgs.length == 0) { - super.getSettings().configureUntyped(statistic); - return; - } - - for (String arg : leftoverArgs) { - if (enumHandler.isSubStatEntry(arg)) { - switch (statistic.getType()) { - case UNTYPED -> super.getSettings().configureUntyped(statistic); - case ITEM -> { - Material item = EnumHandler.getItemEnum(arg); - if (item != null) { - super.getSettings().configureBlockOrItemType(statistic, item); - } - } - case BLOCK -> { - Material block = EnumHandler.getBlockEnum(arg); - if (block != null) { - super.getSettings().configureBlockOrItemType(statistic, block); - } - } - case ENTITY -> { - EntityType entityType = EnumHandler.getEntityEnum(arg); - if (entityType != null) { - super.getSettings().configureEntityType(statistic, entityType); - } - } - } - break; - } - } - } - - @Contract(pure = true) - private @Nullable String tryToFindPlayerName(@NotNull String[] args) { - for (String arg : args) { - if (offlinePlayerHandler.isRelevantPlayer(arg)) { - return arg; - } - } - return null; - } - - private String[] removeArg(@NotNull String[] args, String argToRemove) { - ArrayList currentArgs = new ArrayList<>(Arrays.asList(args)); - currentArgs.remove(argToRemove); - return currentArgs.toArray(String[]::new); - } -} \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatResult.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatResult.java index 97fd1c5..12cdfc0 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatResult.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatResult.java @@ -29,10 +29,8 @@ import net.kyori.adventure.text.TextComponent; * By default, the resulting message is a {@link TextComponent}, which can be * sent directly to a Minecraft client or console with the Adventure library. * To send a Component, you need to get a {@link BukkitAudiences} object, - * and use that to send the desired Component. Normally you would have to add - * Adventure as a dependency to your project, but since the library is included - * in PlayerStats, you can access it through the PlayerStatsImpl. Information - * on how to get and use the BukkitAudiences object can be found on + * and use that to send the desired Component. Information on how to get + * and use the BukkitAudiences object can be found on * Adventure's website. * *

    You can also use the provided {@link #formattedString ()} method to get the From abf85b3948e680d26e36a344dd9df1e009c064d4 Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Sun, 16 Oct 2022 15:23:13 +0200 Subject: [PATCH 12/43] Separated request-generating from request-executing to keep all execute-logic within the statistic package (#114) --- .../com/artemis/the/gr8/playerstats/Main.java | 44 +++++------- .../the/gr8/playerstats/ThreadManager.java | 11 ++- .../the/gr8/playerstats/api/PlayerStats.java | 17 ++--- .../gr8/playerstats/api/PlayerStatsAPI.java | 28 ++++++++ .../gr8/playerstats/api/PlayerStatsImpl.java | 55 --------------- .../gr8/playerstats/api/StatFormatter.java | 24 +++---- .../the/gr8/playerstats/api/StatManager.java | 48 ++++++++++--- .../gr8/playerstats/msg/MessageBuilder.java | 30 +++++---- .../gr8/playerstats/msg/OutputManager.java | 36 ++++++---- .../ComponentSerializer.java} | 15 +++-- .../gr8/playerstats/reload/ReloadThread.java | 19 ++---- .../statistic/PlayerStatRequest.java | 6 -- .../playerstats/statistic/RequestManager.java | 67 +++++++++++++++++++ .../statistic/RequestProcessor.java | 19 ++---- .../statistic/ServerStatRequest.java | 7 -- .../playerstats/statistic/StatRequest.java | 20 +----- .../gr8/playerstats/statistic/StatThread.java | 6 +- .../playerstats/statistic/TopStatRequest.java | 6 -- 18 files changed, 239 insertions(+), 219 deletions(-) create mode 100644 src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStatsAPI.java delete mode 100644 src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStatsImpl.java rename src/main/java/com/artemis/the/gr8/playerstats/msg/{components/ComponentUtils.java => msgutils/ComponentSerializer.java} (92%) create mode 100644 src/main/java/com/artemis/the/gr8/playerstats/statistic/RequestManager.java diff --git a/src/main/java/com/artemis/the/gr8/playerstats/Main.java b/src/main/java/com/artemis/the/gr8/playerstats/Main.java index 511c484..d1cd611 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/Main.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/Main.java @@ -1,7 +1,8 @@ package com.artemis.the.gr8.playerstats; import com.artemis.the.gr8.playerstats.api.PlayerStats; -import com.artemis.the.gr8.playerstats.api.PlayerStatsImpl; +import com.artemis.the.gr8.playerstats.api.PlayerStatsAPI; +import com.artemis.the.gr8.playerstats.statistic.RequestManager; import com.artemis.the.gr8.playerstats.msg.OutputManager; import com.artemis.the.gr8.playerstats.commands.ReloadCommand; import com.artemis.the.gr8.playerstats.commands.ShareCommand; @@ -13,6 +14,7 @@ import com.artemis.the.gr8.playerstats.msg.msgutils.LanguageKeyHandler; import com.artemis.the.gr8.playerstats.share.ShareManager; import com.artemis.the.gr8.playerstats.statistic.RequestProcessor; import com.artemis.the.gr8.playerstats.utils.EnumHandler; +import com.artemis.the.gr8.playerstats.utils.MyLogger; import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.expansion.PlaceholderExpansion; @@ -42,7 +44,6 @@ public final class Main extends JavaPlugin { private static OutputManager outputManager; private static ShareManager shareManager; - private static RequestProcessor requestProcessor; private static PlayerStats playerStatsImpl; @@ -80,6 +81,15 @@ public final class Main extends JavaPlugin { this.getLogger().info("Disabled PlayerStats!"); } + public void reloadPlugin() { + config.reload(); + MyLogger.setDebugLevel(config.getDebugLevel()); + languageKeyHandler.reload(); + offlinePlayerHandler.reload(); + outputManager.update(); + ShareManager.updateSettings(config); + } + /** * * @return the JavaPlugin instance associated with PlayerStats @@ -99,27 +109,6 @@ public final class Main extends JavaPlugin { return playerStatsImpl; } - public static @NotNull RequestProcessor getRequestProcessor() throws IllegalStateException { - if (requestProcessor == null) { - throw new IllegalStateException("PlayerStats does not seem to be loaded!"); - } - return requestProcessor; - } - - public static @NotNull OfflinePlayerHandler getOfflinePlayerHandler() throws IllegalStateException { - if (offlinePlayerHandler == null) { - throw new IllegalStateException("PlayerStats does not seem to be loaded!"); - } - return offlinePlayerHandler; - } - - public static @NotNull LanguageKeyHandler getLanguageKeyHandler() { - if (languageKeyHandler == null) { - languageKeyHandler = new LanguageKeyHandler(); - } - return languageKeyHandler; - } - private void initializeMainClasses() { pluginInstance = this; adventure = BukkitAudiences.create(this); @@ -129,11 +118,12 @@ public final class Main extends JavaPlugin { offlinePlayerHandler = new OfflinePlayerHandler(config); shareManager = new ShareManager(config); - outputManager = new OutputManager(adventure, config); - requestProcessor = new RequestProcessor(offlinePlayerHandler, outputManager, shareManager); + outputManager = new OutputManager(adventure, config, languageKeyHandler); - threadManager = new ThreadManager(config, outputManager); - playerStatsImpl = new PlayerStatsImpl(offlinePlayerHandler, outputManager); + RequestProcessor requestProcessor = new RequestProcessor(offlinePlayerHandler, outputManager, shareManager); + RequestManager statManager = new RequestManager(offlinePlayerHandler, requestProcessor); + threadManager = new ThreadManager(this, config, outputManager, statManager); + playerStatsImpl = new PlayerStatsAPI(statManager, outputManager); } private void setupMetrics() { diff --git a/src/main/java/com/artemis/the/gr8/playerstats/ThreadManager.java b/src/main/java/com/artemis/the/gr8/playerstats/ThreadManager.java index 72ab480..511ee63 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/ThreadManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/ThreadManager.java @@ -6,6 +6,7 @@ import com.artemis.the.gr8.playerstats.enums.StandardMessage; import com.artemis.the.gr8.playerstats.reload.ReloadThread; import com.artemis.the.gr8.playerstats.statistic.StatThread; import com.artemis.the.gr8.playerstats.statistic.StatRequest; +import com.artemis.the.gr8.playerstats.statistic.RequestManager; import com.artemis.the.gr8.playerstats.utils.MyLogger; import org.bukkit.command.CommandSender; import org.jetbrains.annotations.NotNull; @@ -27,17 +28,21 @@ public final class ThreadManager { private int statThreadID; private int reloadThreadID; + private final Main main; private static ConfigHandler config; private static OutputManager outputManager; + private final RequestManager statManager; private ReloadThread activatedReloadThread; private StatThread activatedStatThread; private final HashMap statThreads; private static long lastRecordedCalcTime; - public ThreadManager(ConfigHandler config, OutputManager outputManager) { + public ThreadManager(Main main, ConfigHandler config, OutputManager outputManager, RequestManager statManager) { + this.main = main; ThreadManager.config = config; ThreadManager.outputManager = outputManager; + this.statManager = statManager; statThreads = new HashMap<>(); statThreadID = 0; @@ -53,7 +58,7 @@ public final class ThreadManager { if (activatedReloadThread == null || !activatedReloadThread.isAlive()) { reloadThreadID += 1; - activatedReloadThread = new ReloadThread(config, outputManager, reloadThreadID, activatedStatThread, sender); + activatedReloadThread = new ReloadThread(main, outputManager, reloadThreadID, activatedStatThread, sender); activatedReloadThread.start(); } else { @@ -95,7 +100,7 @@ public final class ThreadManager { } private void startNewStatThread(StatRequest request) { - activatedStatThread = new StatThread(outputManager, statThreadID, request, activatedReloadThread); + activatedStatThread = new StatThread(outputManager, statManager, statThreadID, request, activatedReloadThread); statThreads.put(request.getSettings().getCommandSender().getName(), activatedStatThread); activatedStatThread.start(); } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStats.java b/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStats.java index bf6e8e0..af0fc74 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStats.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStats.java @@ -1,7 +1,7 @@ package com.artemis.the.gr8.playerstats.api; import com.artemis.the.gr8.playerstats.Main; -import com.artemis.the.gr8.playerstats.statistic.StatRequest; +import com.artemis.the.gr8.playerstats.statistic.RequestManager; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; @@ -9,19 +9,14 @@ import org.jetbrains.annotations.NotNull; * The outgoing API that represents the core functionality of PlayerStats! * *

    To work with it, you'll need to call PlayerStats.{@link #getAPI()} and get an instance of - * {@link PlayerStatsImpl}. You can then use this object to access any of the further methods. + * {@link PlayerStatsAPI}. You can then use this object to access any of the further methods. * - *

    Since calculating a top or server statistics can take some time, I strongly - * encourage you to call {@link StatRequest#execute()} asynchronously. - * Otherwise, the main Thread will have to wait until all calculations are done, - * and this can severely impact server performance. - * - * @see StatManager + * @see RequestManager * @see StatFormatter */ public interface PlayerStats { - /** Gets an instance of the {@link PlayerStatsImpl}. + /** Gets an instance of the {@link PlayerStatsAPI}. * @return the PlayerStats API * @throws IllegalStateException if PlayerStats is not loaded on the server when this method is called*/ @@ -31,13 +26,13 @@ public interface PlayerStats { } /** - * Gets the current version of PlayerStatsImpl. + * Gets the current version of PlayerStatsAPI. * Use this method to ensure the correct version of * PlayerStats is running on the server before * accessing further API methods, to prevent * ClassDefNotFoundExceptions. * - * @return the version of PlayerStatsImpl present on the server + * @return the version of PlayerStatsAPI present on the server */ default String getVersion() { return "1.8"; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStatsAPI.java b/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStatsAPI.java new file mode 100644 index 0000000..a65d1e6 --- /dev/null +++ b/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStatsAPI.java @@ -0,0 +1,28 @@ +package com.artemis.the.gr8.playerstats.api; + +import com.artemis.the.gr8.playerstats.msg.OutputManager; + +import static org.jetbrains.annotations.ApiStatus.Internal; + +/** The implementation of the API Interface */ +public final class PlayerStatsAPI implements PlayerStats { + + private static OutputManager outputManager; + private final StatManager statManager; + + @Internal + public PlayerStatsAPI(StatManager statManager, OutputManager outputManager) { + PlayerStatsAPI.outputManager = outputManager; + this.statManager = statManager; + } + + @Override + public StatFormatter getFormatter() { + return outputManager.getMainMessageBuilder(); + } + + @Override + public StatManager getStatManager() { + return statManager; + } +} \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStatsImpl.java b/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStatsImpl.java deleted file mode 100644 index 80a0ad2..0000000 --- a/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStatsImpl.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.artemis.the.gr8.playerstats.api; - -import com.artemis.the.gr8.playerstats.msg.OutputManager; -import com.artemis.the.gr8.playerstats.statistic.PlayerStatRequest; -import com.artemis.the.gr8.playerstats.statistic.ServerStatRequest; -import com.artemis.the.gr8.playerstats.statistic.TopStatRequest; -import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; - -import java.util.LinkedHashMap; - -import static org.jetbrains.annotations.ApiStatus.Internal; - -/** The implementation of the API Interface */ -public final class PlayerStatsImpl implements PlayerStats, StatManager { - - private static OutputManager outputManager; - private final OfflinePlayerHandler offlinePlayerHandler; - - @Internal - public PlayerStatsImpl(OfflinePlayerHandler offlinePlayerHandler, OutputManager outputManager) { - PlayerStatsImpl.outputManager = outputManager; - this.offlinePlayerHandler = offlinePlayerHandler; - } - - @Override - public StatFormatter getFormatter() { - return outputManager.getCurrentMainMessageBuilder(); - } - - @Override - public StatManager getStatManager() { - return this; - } - - @Override - public RequestGenerator playerStatRequest(String playerName) { - return new PlayerStatRequest(playerName); - } - - @Override - public RequestGenerator serverStatRequest() { - return new ServerStatRequest(); - } - - @Override - public RequestGenerator> topStatRequest(int topListSize) { - return new TopStatRequest(topListSize); - } - - @Override - public RequestGenerator> totalTopStatRequest() { - int playerCount = offlinePlayerHandler.getOfflinePlayerCount(); - return topStatRequest(playerCount); - } -} \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/api/StatFormatter.java b/src/main/java/com/artemis/the/gr8/playerstats/api/StatFormatter.java index a99a6a4..afeb6e8 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/api/StatFormatter.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/api/StatFormatter.java @@ -1,7 +1,6 @@ package com.artemis.the.gr8.playerstats.api; import com.artemis.the.gr8.playerstats.enums.Unit; -import com.artemis.the.gr8.playerstats.msg.components.ComponentUtils; import com.artemis.the.gr8.playerstats.msg.msgutils.NumberFormatter; import com.artemis.the.gr8.playerstats.statistic.StatResult; import net.kyori.adventure.text.TextComponent; @@ -18,6 +17,15 @@ import org.jetbrains.annotations.Nullable; */ public interface StatFormatter { + /** + * Gets a {@link NumberFormatter} to format raw numbers into something more readable. + * + * @return the NumberFormatter + */ + default NumberFormatter getNumberFormatter() { + return new NumberFormatter(); + } + /** * Turns a TextComponent into its String representation. This method is equipped * to turn all PlayerStats' formatted statResults into String, using a custom @@ -28,19 +36,7 @@ public interface StatFormatter { * but with color, style and formatting. TranslatableComponents will be turned into * plain English. */ - default String TextComponentToString(TextComponent component) { - return ComponentUtils.getTranslatableComponentSerializer() - .serialize(component); - } - - /** - * Gets a {@link NumberFormatter} to format raw numbers into something more readable. - * - * @return the NumberFormatter - */ - default NumberFormatter getNumberFormatter() { - return new NumberFormatter(); - } + String textComponentToString(TextComponent component); /** * Gets the default prefix PlayerStats uses. diff --git a/src/main/java/com/artemis/the/gr8/playerstats/api/StatManager.java b/src/main/java/com/artemis/the/gr8/playerstats/api/StatManager.java index 52f64b8..96b7e97 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/api/StatManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/api/StatManager.java @@ -1,13 +1,10 @@ package com.artemis.the.gr8.playerstats.api; import com.artemis.the.gr8.playerstats.statistic.StatRequest; +import com.artemis.the.gr8.playerstats.statistic.StatResult; import java.util.LinkedHashMap; -/** - * Turns user input into a {@link StatRequest} that can be - * used to get statistic data. - */ public interface StatManager { /** Gets a RequestGenerator that can be used to create a PlayerStatRequest. @@ -16,14 +13,36 @@ public interface StatManager { * * @param playerName the player whose statistic is being requested * @return the RequestGenerator */ - RequestGenerator playerStatRequest(String playerName); + RequestGenerator createPlayerStatRequest(String playerName); + + /** + * Executes this StatRequest. This calculation can take some time, + * so don't call this from the main Thread if you can help it! + * + * @return a StatResult containing the value of this lookup, both as + * numerical value and as formatted message + * @see PlayerStats + * @see StatResult + */ + StatResult executePlayerStatRequest(StatRequest request); /** Gets a RequestGenerator that can be used to create a ServerStatRequest. * This RequestGenerator will make sure all default settings * for a server-statistic-lookup are configured. * * @return the RequestGenerator*/ - RequestGenerator serverStatRequest(); + RequestGenerator createServerStatRequest(); + + /** + * Executes this StatRequest. This calculation can take some time, + * so don't call this from the main Thread if you can help it! + * + * @return a StatResult containing the value of this lookup, both as + * numerical value and as formatted message + * @see PlayerStats + * @see StatResult + */ + StatResult executeServerStatRequest(StatRequest request); /** Gets a RequestGenerator that can be used to create a TopStatRequest * for a top-list of the specified size. This RequestGenerator will @@ -31,7 +50,7 @@ public interface StatManager { * * @param topListSize how big the top-x should be (10 by default) * @return the RequestGenerator*/ - RequestGenerator> topStatRequest(int topListSize); + RequestGenerator> createTopStatRequest(int topListSize); /** Gets a RequestGenerator that can be used to create a TopStatRequest * for all offline players on the server (those that are included by @@ -39,5 +58,16 @@ public interface StatManager { * all default settings for a top-statistic-lookup are configured. * * @return the RequestGenerator*/ - RequestGenerator> totalTopStatRequest(); -} \ No newline at end of file + RequestGenerator> createTotalTopStatRequest(); + + /** + * Executes this StatRequest. This calculation can take some time, + * so don't call this from the main Thread if you can help it! + * + * @return a StatResult containing the value of this lookup, both as + * numerical value and as formatted message + * @see PlayerStats + * @see StatResult + */ + StatResult> executeTopRequest(StatRequest> request); +} diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java index 20b0fba..d713b1c 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java @@ -1,6 +1,5 @@ package com.artemis.the.gr8.playerstats.msg; -import com.artemis.the.gr8.playerstats.Main; import com.artemis.the.gr8.playerstats.api.StatFormatter; import com.artemis.the.gr8.playerstats.msg.components.ComponentFactory; import com.artemis.the.gr8.playerstats.msg.components.ExampleMessage; @@ -48,28 +47,30 @@ public final class MessageBuilder implements StatFormatter { private final ComponentFactory componentFactory; private final LanguageKeyHandler languageKeyHandler; private final NumberFormatter formatter; + private final ComponentSerializer serializer; - private MessageBuilder(ConfigHandler config) { - this (config, new ComponentFactory(config)); + private MessageBuilder(ConfigHandler config, LanguageKeyHandler language) { + this (config, language, new ComponentFactory(config)); } - private MessageBuilder(ConfigHandler configHandler, ComponentFactory factory) { + private MessageBuilder(ConfigHandler configHandler, LanguageKeyHandler language, ComponentFactory factory) { config = configHandler; useHoverText = config.useHoverText(); componentFactory = factory; + languageKeyHandler = language; formatter = new NumberFormatter(); - languageKeyHandler = Main.getLanguageKeyHandler(); - } - - @Contract("_ -> new") - public static @NotNull MessageBuilder defaultBuilder(ConfigHandler config) { - return new MessageBuilder(config); + serializer = new ComponentSerializer(languageKeyHandler); } @Contract("_, _ -> new") - public static @NotNull MessageBuilder fromComponentFactory(ConfigHandler config, ComponentFactory factory) { - return new MessageBuilder(config, factory); + public static @NotNull MessageBuilder defaultBuilder(ConfigHandler config, LanguageKeyHandler language) { + return new MessageBuilder(config, language); + } + + @Contract("_, _, _ -> new") + public static @NotNull MessageBuilder fromComponentFactory(ConfigHandler config, LanguageKeyHandler language, ComponentFactory factory) { + return new MessageBuilder(config, language, factory); } /** @@ -84,6 +85,11 @@ public final class MessageBuilder implements StatFormatter { this.isConsoleBuilder = isConsoleBuilder; } + @Override + public @NotNull String textComponentToString(TextComponent component) { + return serializer.getTranslatableComponentSerializer().serialize(component); + } + @Override public TextComponent getPluginPrefix() { return componentFactory.pluginPrefix(); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java index 40b3bd8..57aec04 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java @@ -1,9 +1,11 @@ package com.artemis.the.gr8.playerstats.msg; +import com.artemis.the.gr8.playerstats.api.StatFormatter; import com.artemis.the.gr8.playerstats.config.ConfigHandler; import com.artemis.the.gr8.playerstats.enums.StandardMessage; import com.artemis.the.gr8.playerstats.msg.components.BukkitConsoleComponentFactory; import com.artemis.the.gr8.playerstats.msg.components.PrideComponentFactory; +import com.artemis.the.gr8.playerstats.msg.msgutils.LanguageKeyHandler; import com.artemis.the.gr8.playerstats.statistic.StatRequest; import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.text.TextComponent; @@ -33,26 +35,32 @@ public final class OutputManager { private static BukkitAudiences adventure; private static ConfigHandler config; - private static MessageBuilder messageBuilder; - private static MessageBuilder consoleMessageBuilder; private static EnumMap> standardMessages; - public OutputManager(BukkitAudiences adventure, ConfigHandler config) { + private final LanguageKeyHandler languageKeyHandler; + private MessageBuilder messageBuilder; + private MessageBuilder consoleMessageBuilder; + + public OutputManager(BukkitAudiences adventure, ConfigHandler config, LanguageKeyHandler language) { OutputManager.adventure = adventure; OutputManager.config = config; - + languageKeyHandler = language; getMessageBuilders(); prepareFunctions(); } - public static void updateMessageBuilders() { + public void update() { getMessageBuilders(); } - public MessageBuilder getCurrentMainMessageBuilder() { + public StatFormatter getMainMessageBuilder() { return messageBuilder; } + public @NotNull String textComponentToString(TextComponent component) { + return messageBuilder.textComponentToString(component); + } + /** * @return a TextComponent with the following parts: *
    [player-name]: [number] [stat-name] {sub-stat-name} @@ -131,22 +139,22 @@ public final class OutputManager { return sender instanceof ConsoleCommandSender ? consoleMessageBuilder : messageBuilder; } - private static void getMessageBuilders() { + private void getMessageBuilders() { messageBuilder = getClientMessageBuilder(); consoleMessageBuilder = getConsoleMessageBuilder(); } - private static MessageBuilder getClientMessageBuilder() { + private MessageBuilder getClientMessageBuilder() { if (useRainbowStyle()) { - return MessageBuilder.fromComponentFactory(config, new PrideComponentFactory(config)); + return MessageBuilder.fromComponentFactory(config, languageKeyHandler, new PrideComponentFactory(config)); } - return MessageBuilder.defaultBuilder(config); + return MessageBuilder.defaultBuilder(config, languageKeyHandler); } - private static @NotNull MessageBuilder getConsoleMessageBuilder() { + private @NotNull MessageBuilder getConsoleMessageBuilder() { MessageBuilder consoleBuilder; if (isBukkit()) { - consoleBuilder = MessageBuilder.fromComponentFactory(config, new BukkitConsoleComponentFactory(config)); + consoleBuilder = MessageBuilder.fromComponentFactory(config,languageKeyHandler, new BukkitConsoleComponentFactory(config)); } else { consoleBuilder = getClientMessageBuilder(); } @@ -155,11 +163,11 @@ public final class OutputManager { return consoleBuilder; } - private static boolean useRainbowStyle() { + private boolean useRainbowStyle() { return config.useRainbowMode() || (config.useFestiveFormatting() && LocalDate.now().getMonth().equals(Month.JUNE)); } - private static boolean isBukkit() { + private boolean isBukkit() { return Bukkit.getName().equalsIgnoreCase("CraftBukkit"); } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentUtils.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/ComponentSerializer.java similarity index 92% rename from src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentUtils.java rename to src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/ComponentSerializer.java index efdb20c..b34f37e 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentUtils.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/ComponentSerializer.java @@ -1,7 +1,5 @@ -package com.artemis.the.gr8.playerstats.msg.components; +package com.artemis.the.gr8.playerstats.msg.msgutils; -import com.artemis.the.gr8.playerstats.Main; -import com.artemis.the.gr8.playerstats.msg.msgutils.LanguageKeyHandler; import net.kyori.adventure.text.*; import net.kyori.adventure.text.flattener.ComponentFlattener; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; @@ -11,7 +9,13 @@ import org.jetbrains.annotations.NotNull; /** * A small utility class for turning PlayerStats' custom Components into String. */ -public final class ComponentUtils { +public final class ComponentSerializer { + + private final LanguageKeyHandler languageKeyHandler; + + public ComponentSerializer(LanguageKeyHandler languageKeyHandler) { + this.languageKeyHandler = languageKeyHandler; + } /** * Returns a LegacyComponentSerializer that is capable of serializing @@ -23,8 +27,7 @@ public final class ComponentUtils { * @return the Serializer * @see LanguageKeyHandler */ - public static @NotNull LegacyComponentSerializer getTranslatableComponentSerializer() { - LanguageKeyHandler languageKeyHandler = Main.getLanguageKeyHandler(); + public @NotNull LegacyComponentSerializer getTranslatableComponentSerializer() { LegacyComponentSerializer serializer = getTextComponentSerializer(); ComponentFlattener flattener = ComponentFlattener.basic().toBuilder() diff --git a/src/main/java/com/artemis/the/gr8/playerstats/reload/ReloadThread.java b/src/main/java/com/artemis/the/gr8/playerstats/reload/ReloadThread.java index b6c8d63..a579803 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/reload/ReloadThread.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/reload/ReloadThread.java @@ -9,7 +9,6 @@ import com.artemis.the.gr8.playerstats.statistic.RequestProcessor; import com.artemis.the.gr8.playerstats.statistic.StatThread; import com.artemis.the.gr8.playerstats.utils.MyLogger; import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; -import com.artemis.the.gr8.playerstats.config.ConfigHandler; import com.artemis.the.gr8.playerstats.enums.DebugLevel; import org.bukkit.command.CommandSender; import org.jetbrains.annotations.Nullable; @@ -17,14 +16,14 @@ import org.jetbrains.annotations.Nullable; /** The Thread that is in charge of reloading PlayerStats. */ public final class ReloadThread extends Thread { - private static ConfigHandler config; + private final Main main; private static OutputManager outputManager; private final StatThread statThread; private final CommandSender sender; - public ReloadThread(ConfigHandler c, OutputManager m, int ID, @Nullable StatThread s, @Nullable CommandSender se) { - config = c; + public ReloadThread(Main main, OutputManager m, int ID, @Nullable StatThread s, @Nullable CommandSender se) { + this.main = main; outputManager = m; statThread = s; @@ -58,20 +57,10 @@ public final class ReloadThread extends Thread { } MyLogger.logLowLevelMsg("Reloading!"); - reloadEverything(); + main.reloadPlugin(); if (sender != null) { outputManager.sendFeedbackMsg(sender, StandardMessage.RELOADED_CONFIG); } } - - private void reloadEverything() { - config.reload(); - MyLogger.setDebugLevel(config.getDebugLevel()); - Main.getLanguageKeyHandler().reload(); - Main.getOfflinePlayerHandler().reload(); - - OutputManager.updateMessageBuilders(); - ShareManager.updateSettings(config); - } } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/PlayerStatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/PlayerStatRequest.java index 11e4e36..52855a5 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/PlayerStatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/PlayerStatRequest.java @@ -1,6 +1,5 @@ package com.artemis.the.gr8.playerstats.statistic; -import com.artemis.the.gr8.playerstats.Main; import com.artemis.the.gr8.playerstats.api.RequestGenerator; import org.bukkit.Bukkit; import org.bukkit.Material; @@ -32,9 +31,4 @@ public final class PlayerStatRequest extends StatRequest implements Req super.getSettings().configureEntityType(statistic, entityType); return this; } - - @Override - public @NotNull StatResult execute() { - return Main.getRequestProcessor().processPlayerRequest(super.getSettings()); - } } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/RequestManager.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/RequestManager.java new file mode 100644 index 0000000..2ef1511 --- /dev/null +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/RequestManager.java @@ -0,0 +1,67 @@ +package com.artemis.the.gr8.playerstats.statistic; + +import com.artemis.the.gr8.playerstats.api.RequestGenerator; +import com.artemis.the.gr8.playerstats.api.StatManager; +import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; +import org.jetbrains.annotations.NotNull; + +import java.util.LinkedHashMap; + +/** + * Turns user input into a {@link StatRequest} that can be + * used to get statistic data. + */ +public final class RequestManager implements StatManager { + + private static OfflinePlayerHandler offlinePlayerHandler; + private final RequestProcessor processor; + + public RequestManager(OfflinePlayerHandler offlinePlayerHandler, RequestProcessor processor) { + RequestManager.offlinePlayerHandler = offlinePlayerHandler; + this.processor = processor; + } + + public StatResult execute(@NotNull StatRequest request) { + return switch (request.getSettings().getTarget()) { + case PLAYER -> processor.processPlayerRequest(request.getSettings()); + case SERVER -> processor.processServerRequest(request.getSettings()); + case TOP -> processor.processTopRequest(request.getSettings()); + }; + } + + @Override + public RequestGenerator createPlayerStatRequest(String playerName) { + return new PlayerStatRequest(playerName); + } + + @Override + public StatResult executePlayerStatRequest(StatRequest request) { + return processor.processPlayerRequest(request.getSettings()); + } + + @Override + public RequestGenerator createServerStatRequest() { + return new ServerStatRequest(); + } + + @Override + public StatResult executeServerStatRequest(StatRequest request) { + return processor.processServerRequest(request.getSettings()); + } + + @Override + public RequestGenerator> createTopStatRequest(int topListSize) { + return new TopStatRequest(topListSize); + } + + @Override + public RequestGenerator> createTotalTopStatRequest() { + int playerCount = offlinePlayerHandler.getOfflinePlayerCount(); + return createTopStatRequest(playerCount); + } + + @Override + public StatResult> executeTopRequest(StatRequest> request) { + return processor.processTopRequest(request.getSettings()); + } +} \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/RequestProcessor.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/RequestProcessor.java index 2efe9d2..a36c988 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/RequestProcessor.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/RequestProcessor.java @@ -3,7 +3,6 @@ package com.artemis.the.gr8.playerstats.statistic; import com.artemis.the.gr8.playerstats.ThreadManager; import com.artemis.the.gr8.playerstats.msg.FormattingFunction; import com.artemis.the.gr8.playerstats.msg.OutputManager; -import com.artemis.the.gr8.playerstats.msg.components.ComponentUtils; import com.artemis.the.gr8.playerstats.share.ShareManager; import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; import com.artemis.the.gr8.playerstats.utils.MyLogger; @@ -20,7 +19,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ForkJoinPool; import java.util.stream.Collectors; -public final class RequestProcessor { +public class RequestProcessor { private final OfflinePlayerHandler offlinePlayerHandler; private static OutputManager outputManager; @@ -32,21 +31,11 @@ public final class RequestProcessor { RequestProcessor.shareManager = shareManager; } - public @NotNull StatResult getInternalResult(@NotNull StatRequest.Settings requestSettings) { - StatResult result = switch (requestSettings.getTarget()) { - case PLAYER -> processPlayerRequest(requestSettings); - case SERVER -> processServerRequest(requestSettings); - case TOP -> processTopRequest(requestSettings); - }; - - return new StatResult<>(result.formattedComponent(), result.formattedComponent(), result.formattedString()); - } - public @NotNull StatResult processPlayerRequest(StatRequest.Settings requestSettings) { int stat = getPlayerStat(requestSettings); FormattingFunction formattingFunction = outputManager.formatPlayerStat(requestSettings, stat); TextComponent formattedResult = processFunction(requestSettings.getCommandSender(), formattingFunction); - String resultAsString = ComponentUtils.getTranslatableComponentSerializer().serialize(formattedResult); + String resultAsString = outputManager.textComponentToString(formattedResult); return new StatResult<>(stat, formattedResult, resultAsString); } @@ -55,7 +44,7 @@ public final class RequestProcessor { long stat = getServerStat(requestSettings); FormattingFunction formattingFunction = outputManager.formatServerStat(requestSettings, stat); TextComponent formattedResult = processFunction(requestSettings.getCommandSender(), formattingFunction); - String resultAsString = ComponentUtils.getTranslatableComponentSerializer().serialize(formattedResult); + String resultAsString = outputManager.textComponentToString(formattedResult); return new StatResult<>(stat, formattedResult, resultAsString); } @@ -64,7 +53,7 @@ public final class RequestProcessor { LinkedHashMap stats = getTopStats(requestSettings); FormattingFunction formattingFunction = outputManager.formatTopStats(requestSettings, stats); TextComponent formattedResult = processFunction(requestSettings.getCommandSender(), formattingFunction); - String resultAsString = ComponentUtils.getTranslatableComponentSerializer().serialize(formattedResult); + String resultAsString = outputManager.textComponentToString(formattedResult); return new StatResult<>(stats, formattedResult, resultAsString); } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/ServerStatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/ServerStatRequest.java index 762ce4d..8170a61 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/ServerStatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/ServerStatRequest.java @@ -1,11 +1,9 @@ package com.artemis.the.gr8.playerstats.statistic; -import com.artemis.the.gr8.playerstats.Main; import com.artemis.the.gr8.playerstats.api.RequestGenerator; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Statistic; -import org.bukkit.command.CommandSender; import org.bukkit.entity.EntityType; import org.jetbrains.annotations.NotNull; @@ -34,9 +32,4 @@ public final class ServerStatRequest extends StatRequest implements Reques super.getSettings().configureEntityType(statistic, entityType); return this; } - - @Override - public @NotNull StatResult execute() { - return Main.getRequestProcessor().processServerRequest(super.getSettings()); - } } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatRequest.java index f7fe80e..e060146 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatRequest.java @@ -1,6 +1,6 @@ package com.artemis.the.gr8.playerstats.statistic; -import com.artemis.the.gr8.playerstats.api.PlayerStats; +import com.artemis.the.gr8.playerstats.api.StatManager; import com.artemis.the.gr8.playerstats.enums.Target; import org.bukkit.Material; import org.bukkit.Statistic; @@ -12,11 +12,8 @@ import org.jetbrains.annotations.Nullable; /** * Holds all the information PlayerStats needs to perform - * a lookup, and can be executed to get the results. Calling - * {@link #execute()} on a Top- or ServerRequest can take some - * time (especially if there is a substantial amount of - * OfflinePlayers on this particular server), so I strongly - * advice you to call this asynchronously! + * a lookup, and can be executed by the {@link StatManager} + * to get the results. */ public abstract class StatRequest { @@ -26,17 +23,6 @@ public abstract class StatRequest { settings = new Settings(requester); } - /** - * Executes this StatRequest. This calculation can take some time, - * so don't call this from the main Thread if you can help it! - * - * @return a StatResult containing the value of this lookup, both as - * numerical value and as formatted message - * @see PlayerStats - * @see StatResult - */ - public abstract StatResult execute(); - /** * Use this method to view the settings that have * been configured for this StatRequest. diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatThread.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatThread.java index 3ac5868..ff03a55 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatThread.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatThread.java @@ -16,12 +16,14 @@ import java.util.*; public final class StatThread extends Thread { private static OutputManager outputManager; + private final RequestManager statManager; private final ReloadThread reloadThread; private final StatRequest statRequest; - public StatThread(OutputManager m, int ID, StatRequest s, @Nullable ReloadThread r) { + public StatThread(OutputManager m, RequestManager stat, int ID, StatRequest s, @Nullable ReloadThread r) { outputManager = m; + statManager = stat; reloadThread = r; statRequest = s; @@ -52,7 +54,7 @@ public final class StatThread extends Thread { } try { - StatResult result = statRequest.execute(); + StatResult result = statManager.execute(statRequest); outputManager.sendToCommandSender(statRequester, result.formattedComponent()); } catch (ConcurrentModificationException e) { diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/TopStatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/TopStatRequest.java index f475ec9..d911fb2 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/TopStatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/TopStatRequest.java @@ -1,6 +1,5 @@ package com.artemis.the.gr8.playerstats.statistic; -import com.artemis.the.gr8.playerstats.Main; import com.artemis.the.gr8.playerstats.api.RequestGenerator; import org.bukkit.Bukkit; import org.bukkit.Material; @@ -34,9 +33,4 @@ public final class TopStatRequest extends StatRequest> execute() { - return Main.getRequestProcessor().processTopRequest(super.getSettings()); - } } \ No newline at end of file From eca25980e541a3a452cebfe2d7bff931d2fd475d Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Sun, 16 Oct 2022 15:39:28 +0200 Subject: [PATCH 13/43] Moved implementation of the API interface to the Main class --- .../com/artemis/the/gr8/playerstats/Main.java | 37 +++++++++++++------ .../the/gr8/playerstats/api/PlayerStats.java | 15 ++++---- .../gr8/playerstats/api/PlayerStatsAPI.java | 28 -------------- .../playerstats/commands/TabCompleter.java | 4 -- .../the/gr8/playerstats/enums/Unit.java | 9 ----- .../msg/msgutils/NumberFormatter.java | 4 +- 6 files changed, 36 insertions(+), 61 deletions(-) delete mode 100644 src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStatsAPI.java diff --git a/src/main/java/com/artemis/the/gr8/playerstats/Main.java b/src/main/java/com/artemis/the/gr8/playerstats/Main.java index d1cd611..f3d30e5 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/Main.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/Main.java @@ -1,7 +1,8 @@ package com.artemis.the.gr8.playerstats; import com.artemis.the.gr8.playerstats.api.PlayerStats; -import com.artemis.the.gr8.playerstats.api.PlayerStatsAPI; +import com.artemis.the.gr8.playerstats.api.StatFormatter; +import com.artemis.the.gr8.playerstats.api.StatManager; import com.artemis.the.gr8.playerstats.statistic.RequestManager; import com.artemis.the.gr8.playerstats.msg.OutputManager; import com.artemis.the.gr8.playerstats.commands.ReloadCommand; @@ -27,13 +28,13 @@ import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.scheduler.BukkitRunnable; import org.jetbrains.annotations.NotNull; - /** * PlayerStats' Main class */ -public final class Main extends JavaPlugin { +public final class Main extends JavaPlugin implements PlayerStats { private static JavaPlugin pluginInstance; + private static PlayerStats playerStatsAPI; private static BukkitAudiences adventure; private static ConfigHandler config; @@ -42,12 +43,10 @@ public final class Main extends JavaPlugin { private static OfflinePlayerHandler offlinePlayerHandler; private static EnumHandler enumHandler; + private static RequestManager statRequestManager; private static OutputManager outputManager; private static ShareManager shareManager; - private static PlayerStats playerStatsImpl; - - @Override public void onEnable() { //initialize all the Managers, singletons, ConfigHandler and the API @@ -103,14 +102,16 @@ public final class Main extends JavaPlugin { } public static @NotNull PlayerStats getPlayerStatsAPI() throws IllegalStateException { - if (playerStatsImpl == null) { + if (playerStatsAPI == null) { throw new IllegalStateException("PlayerStats does not seem to be loaded!"); } - return playerStatsImpl; + return playerStatsAPI; } private void initializeMainClasses() { pluginInstance = this; + playerStatsAPI = this; + adventure = BukkitAudiences.create(this); enumHandler = new EnumHandler(); languageKeyHandler = new LanguageKeyHandler(); @@ -121,9 +122,8 @@ public final class Main extends JavaPlugin { outputManager = new OutputManager(adventure, config, languageKeyHandler); RequestProcessor requestProcessor = new RequestProcessor(offlinePlayerHandler, outputManager, shareManager); - RequestManager statManager = new RequestManager(offlinePlayerHandler, requestProcessor); - threadManager = new ThreadManager(this, config, outputManager, statManager); - playerStatsImpl = new PlayerStatsAPI(statManager, outputManager); + statRequestManager = new RequestManager(offlinePlayerHandler, requestProcessor); + threadManager = new ThreadManager(this, config, outputManager, statRequestManager); } private void setupMetrics() { @@ -145,4 +145,19 @@ public final class Main extends JavaPlugin { } }.runTaskLaterAsynchronously(this, 200); } + + @Override + public String getVersion() { + return "1.8"; + } + + @Override + public StatManager getStatManager() { + return statRequestManager; + } + + @Override + public StatFormatter getFormatter() { + return outputManager.getMainMessageBuilder(); + } } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStats.java b/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStats.java index af0fc74..ef00776 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStats.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStats.java @@ -8,18 +8,21 @@ import org.jetbrains.annotations.NotNull; /** * The outgoing API that represents the core functionality of PlayerStats! * - *

    To work with it, you'll need to call PlayerStats.{@link #getAPI()} and get an instance of - * {@link PlayerStatsAPI}. You can then use this object to access any of the further methods. + *

    To work with it, you'll need to call PlayerStats.{@link #getAPI()} + * and get an instance of PlayerStats. You can then use this object to + * access any of the further methods. * * @see RequestManager * @see StatFormatter */ public interface PlayerStats { - /** Gets an instance of the {@link PlayerStatsAPI}. + /** Gets an instance of the PlayerStatsAPI. * @return the PlayerStats API - * @throws IllegalStateException if PlayerStats is not loaded on the server when this method is called*/ + * @throws IllegalStateException if PlayerStats is not loaded on + * the server when this method is called + */ @Contract(pure = true) static @NotNull PlayerStats getAPI() throws IllegalStateException { return Main.getPlayerStatsAPI(); @@ -34,9 +37,7 @@ public interface PlayerStats { * * @return the version of PlayerStatsAPI present on the server */ - default String getVersion() { - return "1.8"; - } + String getVersion(); StatManager getStatManager(); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStatsAPI.java b/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStatsAPI.java deleted file mode 100644 index a65d1e6..0000000 --- a/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStatsAPI.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.artemis.the.gr8.playerstats.api; - -import com.artemis.the.gr8.playerstats.msg.OutputManager; - -import static org.jetbrains.annotations.ApiStatus.Internal; - -/** The implementation of the API Interface */ -public final class PlayerStatsAPI implements PlayerStats { - - private static OutputManager outputManager; - private final StatManager statManager; - - @Internal - public PlayerStatsAPI(StatManager statManager, OutputManager outputManager) { - PlayerStatsAPI.outputManager = outputManager; - this.statManager = statManager; - } - - @Override - public StatFormatter getFormatter() { - return outputManager.getMainMessageBuilder(); - } - - @Override - public StatManager getStatManager() { - return statManager; - } -} \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/TabCompleter.java b/src/main/java/com/artemis/the/gr8/playerstats/commands/TabCompleter.java index 68819f7..2a53914 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/TabCompleter.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/commands/TabCompleter.java @@ -1,7 +1,5 @@ package com.artemis.the.gr8.playerstats.commands; -import com.artemis.the.gr8.playerstats.api.PlayerStats; -import com.artemis.the.gr8.playerstats.statistic.StatRequest; import com.artemis.the.gr8.playerstats.utils.EnumHandler; import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; import org.bukkit.Material; @@ -29,14 +27,12 @@ public final class TabCompleter implements org.bukkit.command.TabCompleter { this.enumHandler = enumHandler; this.offlinePlayerHandler = offlinePlayerHandler; prepareLists(); - } //args[0] = statistic (length = 1) //args[1] = target (player/server/top) OR sub-stat (block/item/entity) (length = 2) //args[2] = playerName OR target (player/server/top) (length = 3) //args[3] = playerName (length = 4) - @Override public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { if (args.length >= 1) { diff --git a/src/main/java/com/artemis/the/gr8/playerstats/enums/Unit.java b/src/main/java/com/artemis/the/gr8/playerstats/enums/Unit.java index cdd08e3..ed07595 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/enums/Unit.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/enums/Unit.java @@ -131,15 +131,6 @@ public enum Unit { }; } - /** - * Gets the Unit corresponding to the given String. This String - * does not need to match exactly (it can be "day" or "days", - * for example), and is case-insensitive. - * - * @param unitName the name belonging to the desired Unit, - * case-insensitive - * @return the Unit - */ /** Converts the current Unit into a short label (and returns a '?' if the current Unit is not of Type TIME)*/ public char getShortLabel(){ return switch (this) { diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/NumberFormatter.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/NumberFormatter.java index 4f8c79c..74ff77a 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/NumberFormatter.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/NumberFormatter.java @@ -83,9 +83,9 @@ public final class NumberFormatter { while(currUnit != null){ //Define amount of units - int amount = 0; + int amount; - //Current unit is equal to smallest unit, in this case round the remainder + //Current unit is equal to the smallest unit, in this case round the remainder if(currUnit == smallestUnit){ amount = (int) Math.round(leftoverSeconds / currUnit.getSeconds()); } From ca63eca1a0bcd8e9699e77d24d4d4d419823323a Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Tue, 18 Oct 2022 14:41:55 +0200 Subject: [PATCH 14/43] Gathered the request-rewrite and pre-work for excluding players into new branch for v2.0 --- pom.xml | 8 ++++---- src/main/resources/plugin.yml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 73925e7..63dd96c 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.ithotl PlayerStats - 1.8 + 2.0-SNAPSHOT PlayerStats Statistics Plugin @@ -152,15 +152,15 @@ net.kyori - com.artemis.the.gr8.lib.kyori + com.artemis.the.gr8.playerstats.lib.kyori com.tchristofferson - com.artemis.the.gr8.util.tchristofferson + com.artemis.the.gr8.playerstats.lib.tchristofferson org.bstats - com.artemis.the.gr8.util.bstats + com.artemis.the.gr8.playerstats.lib.bstats diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 72bcee5..38521e6 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ main: com.artemis.the.gr8.playerstats.Main name: PlayerStats -version: 1.8 +version: 2.0 api-version: 1.13 description: adds commands to view player statistics in chat author: Artemis_the_gr8 From 51a9140a9a89828daf45bfeba445636acffdc16b Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Wed, 19 Oct 2022 13:17:02 +0200 Subject: [PATCH 15/43] Added ExcludeCommand and added methods for excluding players/checking exclude status in OfflinePlayerHandler (#88) --- .../com/artemis/the/gr8/playerstats/Main.java | 8 +-- .../playerstats/commands/ExcludeCommand.java | 23 ++++++++ .../playerstats/commands/ReloadCommand.java | 2 +- .../playerstats/commands/ShareCommand.java | 2 +- .../gr8/playerstats/commands/StatCommand.java | 4 +- .../playerstats/commands/TabCompleter.java | 3 +- .../gr8/playerstats/config/ConfigHandler.java | 3 +- .../config/DefaultValueGetter.java | 4 +- .../gr8/playerstats/msg/OutputManager.java | 2 +- .../playerstats/reload/PlayerLoadAction.java | 7 ++- .../gr8/playerstats/share/ShareManager.java | 18 +++---- .../statistic/RequestProcessor.java | 2 +- .../gr8/playerstats/utils/FileHandler.java | 52 ++++++++++++++----- .../utils/OfflinePlayerHandler.java | 26 +++++++++- src/main/resources/plugin.yml | 14 ++++- 15 files changed, 125 insertions(+), 45 deletions(-) create mode 100644 src/main/java/com/artemis/the/gr8/playerstats/commands/ExcludeCommand.java diff --git a/src/main/java/com/artemis/the/gr8/playerstats/Main.java b/src/main/java/com/artemis/the/gr8/playerstats/Main.java index f3d30e5..d3e9f2b 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/Main.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/Main.java @@ -26,6 +26,7 @@ import org.bukkit.Bukkit; import org.bukkit.command.PluginCommand; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.scheduler.BukkitRunnable; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; /** @@ -85,8 +86,8 @@ public final class Main extends JavaPlugin implements PlayerStats { MyLogger.setDebugLevel(config.getDebugLevel()); languageKeyHandler.reload(); offlinePlayerHandler.reload(); - outputManager.update(); - ShareManager.updateSettings(config); + outputManager.updateSettings(); + shareManager.updateSettings(config); } /** @@ -146,8 +147,9 @@ public final class Main extends JavaPlugin implements PlayerStats { }.runTaskLaterAsynchronously(this, 200); } + @Contract(pure = true) @Override - public String getVersion() { + public @NotNull String getVersion() { return "1.8"; } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/ExcludeCommand.java b/src/main/java/com/artemis/the/gr8/playerstats/commands/ExcludeCommand.java new file mode 100644 index 0000000..45459b8 --- /dev/null +++ b/src/main/java/com/artemis/the/gr8/playerstats/commands/ExcludeCommand.java @@ -0,0 +1,23 @@ +package com.artemis.the.gr8.playerstats.commands; + + +import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; + +public final class ExcludeCommand implements CommandExecutor { + + private final OfflinePlayerHandler offlinePlayerHandler; + + public ExcludeCommand(OfflinePlayerHandler offlinePlayerHandler) { + this.offlinePlayerHandler = offlinePlayerHandler; + } + + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { + + return false; + } +} diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/ReloadCommand.java b/src/main/java/com/artemis/the/gr8/playerstats/commands/ReloadCommand.java index 6b13458..6a3774a 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/ReloadCommand.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/commands/ReloadCommand.java @@ -16,7 +16,7 @@ public final class ReloadCommand implements CommandExecutor { } @Override - public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { threadManager.startReloadThread(sender); return true; } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/ShareCommand.java b/src/main/java/com/artemis/the/gr8/playerstats/commands/ShareCommand.java index 4285f4f..b60e7c8 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/ShareCommand.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/commands/ShareCommand.java @@ -21,7 +21,7 @@ public final class ShareCommand implements CommandExecutor { } @Override - public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String label, String[] args) { + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String label, @NotNull String[] args) { if (args.length == 1 && ShareManager.isEnabled()) { int shareCode; try { diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java b/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java index ede5e8d..5a3cdc4 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java @@ -26,7 +26,7 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; -public class StatCommand implements CommandExecutor { +public final class StatCommand implements CommandExecutor { private static final Pattern pattern = Pattern.compile("top|server|me|player"); @@ -45,7 +45,7 @@ public class StatCommand implements CommandExecutor { } @Override - public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { if (args.length == 0 || args[0].equalsIgnoreCase("help")) { //in case of less than 1 argument or "help", display the help message outputManager.sendHelp(sender); } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/TabCompleter.java b/src/main/java/com/artemis/the/gr8/playerstats/commands/TabCompleter.java index 2a53914..e8169c1 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/TabCompleter.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/commands/TabCompleter.java @@ -8,6 +8,7 @@ import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.entity.EntityType; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Arrays; @@ -34,7 +35,7 @@ public final class TabCompleter implements org.bukkit.command.TabCompleter { //args[2] = playerName OR target (player/server/top) (length = 3) //args[3] = playerName (length = 4) @Override - public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { + public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { if (args.length >= 1) { String currentArg = args[args.length-1]; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/config/ConfigHandler.java b/src/main/java/com/artemis/the/gr8/playerstats/config/ConfigHandler.java index 56c9085..0035f62 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/config/ConfigHandler.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/config/ConfigHandler.java @@ -48,8 +48,7 @@ public final class ConfigHandler extends FileHandler { Map defaultValues = defaultValueGetter.getValuesToAdjust(); defaultValues.put("config-version", configVersion); - super.addValues(defaultValues); - super.updateFile(); + super.addValuesToFile(defaultValues); reload(); MyLogger.logLowLevelMsg("Your config has been updated to version " + configVersion + diff --git a/src/main/java/com/artemis/the/gr8/playerstats/config/DefaultValueGetter.java b/src/main/java/com/artemis/the/gr8/playerstats/config/DefaultValueGetter.java index b0038dd..c2761c1 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/config/DefaultValueGetter.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/config/DefaultValueGetter.java @@ -5,7 +5,7 @@ import org.bukkit.configuration.file.FileConfiguration; import java.util.HashMap; import java.util.Map; -public class DefaultValueGetter { +public final class DefaultValueGetter { private final FileConfiguration config; private final Map defaultValuesToAdjust; @@ -53,4 +53,4 @@ public class DefaultValueGetter { defaultValuesToAdjust.put(path, newValue); } } -} +} \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java index 57aec04..e3858c0 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java @@ -49,7 +49,7 @@ public final class OutputManager { prepareFunctions(); } - public void update() { + public void updateSettings() { getMessageBuilders(); } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/reload/PlayerLoadAction.java b/src/main/java/com/artemis/the/gr8/playerstats/reload/PlayerLoadAction.java index 6d3dc4f..2d7bd71 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/reload/PlayerLoadAction.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/reload/PlayerLoadAction.java @@ -28,8 +28,8 @@ public final class PlayerLoadAction extends RecursiveAction { * Fills a ConcurrentHashMap with PlayerNames and UUIDs for all OfflinePlayers * that should be included in statistic calculations. * - * @param players array of all OfflinePlayers (straight from Bukkit) - * @param lastPlayedLimit whether to set a limit based on last-played-date + * @param players array of all OfflinePlayers to filter and load + * @param lastPlayedLimit optional limit for amount of days ago players last played * @param offlinePlayerUUIDs the ConcurrentHashMap to put playerNames and UUIDs in * @see OfflinePlayerHandler */ @@ -76,8 +76,7 @@ public final class PlayerLoadAction extends RecursiveAction { OfflinePlayer player = players[i]; String playerName = player.getName(); MyLogger.actionRunning(Thread.currentThread().getName()); - if (playerName != null && - (lastPlayedLimit == 0 || UnixTimeHandler.hasPlayedSince(lastPlayedLimit, player.getLastPlayed()))) { + if (playerName != null && UnixTimeHandler.hasPlayedSince(lastPlayedLimit, player.getLastPlayed())) { offlinePlayerUUIDs.put(playerName, player.getUniqueId()); } } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/share/ShareManager.java b/src/main/java/com/artemis/the/gr8/playerstats/share/ShareManager.java index 9b91bb9..2c2c87c 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/share/ShareManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/share/ShareManager.java @@ -26,12 +26,12 @@ import static java.time.temporal.ChronoUnit.SECONDS; public final class ShareManager { private static boolean isEnabled; - private static int waitingTime; + private int waitingTime; - private static volatile AtomicInteger resultID; - private static ConcurrentHashMap statResultQueue; - private static ConcurrentHashMap shareTimeStamp; - private static ArrayBlockingQueue sharedResults; + private volatile AtomicInteger NumberOfStoredResults; + private ConcurrentHashMap statResultQueue; + private ConcurrentHashMap shareTimeStamp; + private ArrayBlockingQueue sharedResults; public ShareManager(ConfigHandler config) { updateSettings(config); @@ -41,14 +41,14 @@ public final class ShareManager { return isEnabled; } - public static synchronized void updateSettings(ConfigHandler config) { + public void updateSettings(ConfigHandler config) { isEnabled = config.allowStatSharing() && config.useHoverText(); waitingTime = config.getStatShareWaitingTime(); if (isEnabled) { sharedResults = new ArrayBlockingQueue<>(500); //reset the sharedResultsQueue - if (resultID == null) { //if we went from disabled to enabled, initialize - resultID = new AtomicInteger(); //always starts with value 0 + if (NumberOfStoredResults == null) { //if we went from disabled to enabled, initialize + NumberOfStoredResults = new AtomicInteger(); //always starts with value 0 statResultQueue = new ConcurrentHashMap<>(); shareTimeStamp = new ConcurrentHashMap<>(); } @@ -148,6 +148,6 @@ public final class ShareManager { } private int getNextIDNumber() { - return resultID.incrementAndGet(); + return NumberOfStoredResults.incrementAndGet(); } } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/RequestProcessor.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/RequestProcessor.java index a36c988..4f32dec 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/RequestProcessor.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/RequestProcessor.java @@ -19,7 +19,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ForkJoinPool; import java.util.stream.Collectors; -public class RequestProcessor { +public final class RequestProcessor { private final OfflinePlayerHandler offlinePlayerHandler; private static OutputManager outputManager; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/utils/FileHandler.java b/src/main/java/com/artemis/the/gr8/playerstats/utils/FileHandler.java index ebe26b3..7acdbab 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/utils/FileHandler.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/utils/FileHandler.java @@ -9,6 +9,8 @@ import org.jetbrains.annotations.NotNull; import java.io.File; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; import java.util.Map; public abstract class FileHandler { @@ -45,22 +47,31 @@ public abstract class FileHandler { return fileConfiguration; } - /** - * Add new key-value pairs to the config without losing comments, - * using tchristofferson's Config-Updater - */ - public void updateFile() { - JavaPlugin plugin = Main.getPluginInstance(); - try { - ConfigUpdater.update(plugin, fileName, file); - } catch (IOException e) { - e.printStackTrace(); - } - } - - public void addValues(@NotNull Map keyValuePairs) { + public void addValuesToFile(@NotNull Map keyValuePairs) { keyValuePairs.forEach(this::addValue); save(); + updateFile(); + } + + /** + * @param key the Key under which the List will be stored + * (or expanded if it already exists) + * @param value the value(s) to expand the List with + */ + public void addValueToListInFile(@NotNull String key, @NotNull Object value) { + List currentValues = fileConfiguration.getList(key); + + List updatedValues; + if (currentValues != null) { + updatedValues = new ArrayList<>(currentValues); + } else { + updatedValues = new ArrayList<>(); + } + updatedValues.add(value); + + addValue(key, updatedValues); + save(); + updateFile(); } private void addValue(String key, Object value) { @@ -74,4 +85,17 @@ public abstract class FileHandler { e.printStackTrace(); } } + + /** + * Add new key-value pairs to the config without losing comments, + * using tchristofferson's Config-Updater + */ + private void updateFile() { + JavaPlugin plugin = Main.getPluginInstance(); + try { + ConfigUpdater.update(plugin, fileName, file); + } catch (IOException e) { + e.printStackTrace(); + } + } } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/utils/OfflinePlayerHandler.java b/src/main/java/com/artemis/the/gr8/playerstats/utils/OfflinePlayerHandler.java index f6765f7..821b49e 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/utils/OfflinePlayerHandler.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/utils/OfflinePlayerHandler.java @@ -4,6 +4,8 @@ import com.artemis.the.gr8.playerstats.config.ConfigHandler; import com.artemis.the.gr8.playerstats.reload.PlayerLoadAction; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; +import org.bukkit.configuration.file.FileConfiguration; +import org.jetbrains.annotations.NotNull; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @@ -20,11 +22,13 @@ import java.util.function.Predicate; public final class OfflinePlayerHandler extends FileHandler { private static ConfigHandler config; + private static FileConfiguration excludedPlayers; private ConcurrentHashMap offlinePlayerUUIDs; private ArrayList playerNames; public OfflinePlayerHandler(ConfigHandler configHandler) { super("excluded_players.yml"); + excludedPlayers = super.getFileConfiguration(); config = configHandler; loadOfflinePlayers(); } @@ -32,6 +36,7 @@ public final class OfflinePlayerHandler extends FileHandler { @Override public void reload() { super.reload(); + excludedPlayers = super.getFileConfiguration(); loadOfflinePlayers(); } @@ -46,6 +51,23 @@ public final class OfflinePlayerHandler extends FileHandler { return offlinePlayerUUIDs.containsKey(playerName); } + public void excludePlayer(UUID uniqueID) { + super.addValueToListInFile("excluded", uniqueID); + } + + public static boolean isExcluded(UUID uniqueID) { + List excluded = excludedPlayers.getList("excluded"); + if (excluded == null) { + return false; + } + for (Object obj : excluded) { + if (obj.equals(uniqueID)) { + return true; + } + } + return false; + } + /** * Gets the number of OfflinePlayers that are included in * statistic calculations. @@ -75,7 +97,7 @@ public final class OfflinePlayerHandler extends FileHandler { * @throws IllegalArgumentException if this player is not on the list * of players that should be included in statistic calculations */ - public OfflinePlayer getOfflinePlayer(String playerName) throws IllegalArgumentException { + public @NotNull OfflinePlayer getOfflinePlayer(String playerName) throws IllegalArgumentException { if (offlinePlayerUUIDs.get(playerName) != null) { return Bukkit.getOfflinePlayer(offlinePlayerUUIDs.get(playerName)); } @@ -119,7 +141,7 @@ public final class OfflinePlayerHandler extends FileHandler { return Bukkit.getWhitelistedPlayers().toArray(OfflinePlayer[]::new); } - private OfflinePlayer[] getNonBannedPlayers() { + private @NotNull OfflinePlayer[] getNonBannedPlayers() { if (Bukkit.getPluginManager().isPluginEnabled("LiteBans")) { return Arrays.stream(Bukkit.getOfflinePlayers()) .parallel() diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 38521e6..0c90827 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -11,13 +11,13 @@ commands: aliases: - stat - stats - description: general statistic command + description: show player statistics in private chat permission: playerstats.stat statisticshare: aliases: - statshare - statsshare - description: shares last stat lookup in chat + description: share last stat lookup in chat usage: "§b/statshare" permission: playerstats.share statisticreload: @@ -27,6 +27,13 @@ commands: description: reloads the config usage: "§a/statreload" permission: playerstats.reload + statisticexclude: + aliases: + - statexclude + - statsexclude + description: hide this player's statistics from /stat results + usage: "§c/statexclude" + permission: playerstats.exclude permissions: playerstats.stat: description: allows usage of /statistic @@ -34,6 +41,9 @@ permissions: playerstats.share: description: allows sharing stats in chat default: true + playerstats.exclude: + description: allows usage of /statexclude + default: op playerstats.reload: description: allows usage of /statreload default: op \ No newline at end of file From fc759da1004877a34a0eab1dcd0efcdf6c14e428 Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Thu, 20 Oct 2022 15:58:30 +0200 Subject: [PATCH 16/43] Added TabCompleter for ExcludeCommand, moved command initializing to its own method in Main, and fixed bug where commandsender wasn't set for internal StatRequests (#88) --- dependency-reduced-pom.xml | 8 +-- .../com/artemis/the/gr8/playerstats/Main.java | 54 +++++++++++++------ .../gr8/playerstats/commands/StatCommand.java | 15 +++--- .../playerstats/commands/TabCompleter.java | 34 ++++++++---- .../playerstats/msg/msgutils/StringUtils.java | 16 +++++- .../statistic/PlayerStatRequest.java | 7 ++- .../statistic/ServerStatRequest.java | 7 ++- .../playerstats/statistic/TopStatRequest.java | 7 ++- 8 files changed, 107 insertions(+), 41 deletions(-) diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml index 991fecf..e1cc09b 100644 --- a/dependency-reduced-pom.xml +++ b/dependency-reduced-pom.xml @@ -4,7 +4,7 @@ io.github.ithotl PlayerStats PlayerStats - 1.8 + 2.0-SNAPSHOT Statistics Plugin https://www.spigotmc.org/resources/playerstats.102347/ @@ -60,15 +60,15 @@ net.kyori - com.artemis.the.gr8.lib.kyori + com.artemis.the.gr8.playerstats.lib.kyori com.tchristofferson - com.artemis.the.gr8.util.tchristofferson + com.artemis.the.gr8.playerstats.lib.tchristofferson org.bstats - com.artemis.the.gr8.util.bstats + com.artemis.the.gr8.playerstats.lib.bstats diff --git a/src/main/java/com/artemis/the/gr8/playerstats/Main.java b/src/main/java/com/artemis/the/gr8/playerstats/Main.java index d3e9f2b..3537658 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/Main.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/Main.java @@ -3,12 +3,9 @@ package com.artemis.the.gr8.playerstats; import com.artemis.the.gr8.playerstats.api.PlayerStats; import com.artemis.the.gr8.playerstats.api.StatFormatter; import com.artemis.the.gr8.playerstats.api.StatManager; +import com.artemis.the.gr8.playerstats.commands.*; import com.artemis.the.gr8.playerstats.statistic.RequestManager; import com.artemis.the.gr8.playerstats.msg.OutputManager; -import com.artemis.the.gr8.playerstats.commands.ReloadCommand; -import com.artemis.the.gr8.playerstats.commands.ShareCommand; -import com.artemis.the.gr8.playerstats.commands.StatCommand; -import com.artemis.the.gr8.playerstats.commands.TabCompleter; import com.artemis.the.gr8.playerstats.config.ConfigHandler; import com.artemis.the.gr8.playerstats.listeners.JoinListener; import com.artemis.the.gr8.playerstats.msg.msgutils.LanguageKeyHandler; @@ -50,21 +47,10 @@ public final class Main extends JavaPlugin implements PlayerStats { @Override public void onEnable() { - //initialize all the Managers, singletons, ConfigHandler and the API initializeMainClasses(); + registerCommands(); setupMetrics(); - //register all commands and the tabCompleter - PluginCommand statcmd = this.getCommand("statistic"); - if (statcmd != null) { - statcmd.setExecutor(new StatCommand(outputManager, threadManager, config, offlinePlayerHandler, enumHandler)); - statcmd.setTabCompleter(new TabCompleter(enumHandler, offlinePlayerHandler)); - } - PluginCommand reloadcmd = this.getCommand("statisticreload"); - if (reloadcmd != null) reloadcmd.setExecutor(new ReloadCommand(threadManager)); - PluginCommand sharecmd = this.getCommand("statisticshare"); - if (sharecmd != null) sharecmd.setExecutor(new ShareCommand(shareManager, outputManager)); - //register the listener Bukkit.getPluginManager().registerEvents(new JoinListener(threadManager), this); @@ -109,6 +95,11 @@ public final class Main extends JavaPlugin implements PlayerStats { return playerStatsAPI; } + /** + * Initialize all classes that need initializing, + * and store references to classes that are + * needed for the Command classes or the API. + */ private void initializeMainClasses() { pluginInstance = this; playerStatsAPI = this; @@ -127,6 +118,37 @@ public final class Main extends JavaPlugin implements PlayerStats { threadManager = new ThreadManager(this, config, outputManager, statRequestManager); } + /** + * Register all commands and assign the tabCompleter + * to the relevant commands. + */ + private void registerCommands() { + TabCompleter tabCompleter = new TabCompleter(enumHandler, offlinePlayerHandler); + + PluginCommand statcmd = this.getCommand("statistic"); + if (statcmd != null) { + statcmd.setExecutor(new StatCommand(outputManager, threadManager, config, offlinePlayerHandler, enumHandler)); + statcmd.setTabCompleter(tabCompleter); + } + PluginCommand excludecmd = this.getCommand("statisticexclude"); + if (excludecmd != null) { + excludecmd.setExecutor(new ExcludeCommand(offlinePlayerHandler)); + excludecmd.setTabCompleter(tabCompleter); + } + + PluginCommand reloadcmd = this.getCommand("statisticreload"); + if (reloadcmd != null) { + reloadcmd.setExecutor(new ReloadCommand(threadManager)); + } + PluginCommand sharecmd = this.getCommand("statisticshare"); + if (sharecmd != null) { + sharecmd.setExecutor(new ShareCommand(shareManager, outputManager)); + } + } + + /** + * Setup bstats + */ private void setupMetrics() { new BukkitRunnable() { @Override diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java b/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java index 5a3cdc4..6f76183 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java @@ -100,7 +100,9 @@ public final class StatCommand implements CommandExecutor { private final class ArgProcessor { + private final CommandSender sender; private String[] argsToProcess; + private Statistic statistic; private String subStatName; private Target target; @@ -108,11 +110,12 @@ public final class StatCommand implements CommandExecutor { private StatRequest request; private ArgProcessor(CommandSender sender, String[] args) { - argsToProcess = args; + this.sender = sender; + this.argsToProcess = args; extractStatistic(); extractSubStatistic(); - extractTarget(sender); + extractTarget(); combineProcessedArgsIntoRequest(); } @@ -124,9 +127,9 @@ public final class StatCommand implements CommandExecutor { RequestGenerator requestGenerator = switch (target) { - case PLAYER -> new PlayerStatRequest(playerName); - case SERVER -> new ServerStatRequest(); - case TOP -> new TopStatRequest(config.getTopListMaxSize()); + case PLAYER -> new PlayerStatRequest(sender, playerName); + case SERVER -> new ServerStatRequest(sender); + case TOP -> new TopStatRequest(sender, config.getTopListMaxSize()); }; switch (statistic.getType()) { @@ -152,7 +155,7 @@ public final class StatCommand implements CommandExecutor { } } - private void extractTarget(CommandSender sender) { + private void extractTarget() { String targetArg = null; for (String arg : argsToProcess) { Matcher matcher = pattern.matcher(arg); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/TabCompleter.java b/src/main/java/com/artemis/the/gr8/playerstats/commands/TabCompleter.java index e8169c1..c8e2a81 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/TabCompleter.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/commands/TabCompleter.java @@ -36,24 +36,38 @@ public final class TabCompleter implements org.bukkit.command.TabCompleter { //args[3] = playerName (length = 4) @Override public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { - if (args.length >= 1) { + if (command.getName().equalsIgnoreCase("statistic")) { + return getStatCommandSuggestions(args); + } + else if (command.getName().equalsIgnoreCase("statisticexclude")) { + return getExcludeCommandSuggestions(args); + } + return null; + } + + private @Nullable List getExcludeCommandSuggestions(@NotNull String[] args) { + if (args.length == 1) { + return getDynamicTabSuggestions(offlinePlayerHandler.getOfflinePlayerNames(), args[0]); + } + return null; + } + + private @Nullable List getStatCommandSuggestions(@NotNull String[] args) { + if (args.length == 1) { + return getFirstArgSuggestions(args[0]); + } + else if (args.length > 1) { String currentArg = args[args.length-1]; - - if (args.length == 1) { - return getFirstArgSuggestions(args[0]); - } - - //after checking if args[0] is a viable statistic, suggest sub-stat OR targets String previousArg = args[args.length-2]; + //after checking if args[0] is a viable statistic, suggest sub-stat or targets if (enumHandler.isStatistic(previousArg)) { Statistic stat = EnumHandler.getStatEnum(previousArg); if (stat != null) { - return getDynamicTabSuggestions(getAfterStatSuggestions(stat), currentArg); + return getDynamicTabSuggestions(getSuggestionsAfterStat(stat), currentArg); } } else if (previousArg.equalsIgnoreCase("player")) { - if (args.length >= 3 && enumHandler.isEntityStatistic(args[args.length-3])) { return targetSuggestions; //if arg before "player" was entity-sub-stat, suggest targets } @@ -89,7 +103,7 @@ public final class TabCompleter implements org.bukkit.command.TabCompleter { .collect(Collectors.toList()); } - private List getAfterStatSuggestions(@NotNull Statistic stat) { + private List getSuggestionsAfterStat(@NotNull Statistic stat) { switch (stat.getType()) { case BLOCK -> { return getAllBlockNames(); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/StringUtils.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/StringUtils.java index ff62aec..d6cb464 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/StringUtils.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/StringUtils.java @@ -2,12 +2,22 @@ package com.artemis.the.gr8.playerstats.msg.msgutils; import com.artemis.the.gr8.playerstats.utils.MyLogger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + /** * A small utility class that helps make enum constant * names prettier for output in stat-messages. */ public final class StringUtils { + private static final Pattern lowercaseLetterAfterSpace; + private static final Pattern underscore; + + static { + lowercaseLetterAfterSpace = Pattern.compile("(?<= )[a-z]"); + underscore = Pattern.compile("_"); + } private StringUtils() { } @@ -18,6 +28,7 @@ public final class StringUtils { */ public static String prettify(String input) { if (input == null) return null; + MyLogger.logHighLevelMsg("Prettifying [" + input + "]"); StringBuilder capitals = new StringBuilder(input.toLowerCase()); capitals.setCharAt(0, Character.toUpperCase(capitals.charAt(0))); @@ -28,9 +39,10 @@ public final class StringUtils { capitals.setCharAt(index, ' '); } - while (capitals.indexOf(" ") != -1) { + Matcher matcher = lowercaseLetterAfterSpace.matcher(capitals); + while (matcher.find()) { MyLogger.logHighLevelMsg("Capitalizing names..."); - int index = capitals.indexOf(" ") + 1; + int index = matcher.start(); capitals.setCharAt(index, Character.toUpperCase(capitals.charAt(index))); } return capitals.toString(); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/PlayerStatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/PlayerStatRequest.java index 52855a5..c8f9bc2 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/PlayerStatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/PlayerStatRequest.java @@ -4,13 +4,18 @@ import com.artemis.the.gr8.playerstats.api.RequestGenerator; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Statistic; +import org.bukkit.command.CommandSender; import org.bukkit.entity.EntityType; import org.jetbrains.annotations.NotNull; public final class PlayerStatRequest extends StatRequest implements RequestGenerator { public PlayerStatRequest(String playerName) { - super(Bukkit.getConsoleSender()); + this(Bukkit.getConsoleSender(), playerName); + } + + public PlayerStatRequest(CommandSender sender, String playerName) { + super(sender); super.getSettings().configureForPlayer(playerName); } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/ServerStatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/ServerStatRequest.java index 8170a61..239ef57 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/ServerStatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/ServerStatRequest.java @@ -4,6 +4,7 @@ import com.artemis.the.gr8.playerstats.api.RequestGenerator; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Statistic; +import org.bukkit.command.CommandSender; import org.bukkit.entity.EntityType; import org.jetbrains.annotations.NotNull; @@ -11,7 +12,11 @@ public final class ServerStatRequest extends StatRequest implements Reques public ServerStatRequest() { - super(Bukkit.getConsoleSender()); + this(Bukkit.getConsoleSender()); + } + + public ServerStatRequest(CommandSender sender) { + super(sender); super.getSettings().configureForServer(); } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/TopStatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/TopStatRequest.java index d911fb2..32a6dec 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/TopStatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/TopStatRequest.java @@ -4,6 +4,7 @@ import com.artemis.the.gr8.playerstats.api.RequestGenerator; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Statistic; +import org.bukkit.command.CommandSender; import org.bukkit.entity.EntityType; import org.jetbrains.annotations.NotNull; @@ -12,7 +13,11 @@ import java.util.LinkedHashMap; public final class TopStatRequest extends StatRequest> implements RequestGenerator> { public TopStatRequest(int topListSize) { - super(Bukkit.getConsoleSender()); + this(Bukkit.getConsoleSender(), topListSize); + } + + public TopStatRequest(CommandSender sender, int topListSize) { + super(sender); super.getSettings().configureForTop(topListSize); } From 6c9e8b2b9d47ef983628a5779bd31ae8cdd5a93b Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Fri, 21 Oct 2022 12:37:53 +0200 Subject: [PATCH 17/43] Fixed StringUtils bug (#125) --- .../the/gr8/playerstats/msg/msgutils/StringUtils.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/StringUtils.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/StringUtils.java index d6cb464..8db7f71 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/StringUtils.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/StringUtils.java @@ -12,12 +12,11 @@ import java.util.regex.Pattern; public final class StringUtils { private static final Pattern lowercaseLetterAfterSpace; - private static final Pattern underscore; static { lowercaseLetterAfterSpace = Pattern.compile("(?<= )[a-z]"); - underscore = Pattern.compile("_"); } + private StringUtils() { } @@ -34,16 +33,16 @@ public final class StringUtils { capitals.setCharAt(0, Character.toUpperCase(capitals.charAt(0))); while (capitals.indexOf("_") != -1) { - MyLogger.logHighLevelMsg("Replacing underscores..."); int index = capitals.indexOf("_"); capitals.setCharAt(index, ' '); + MyLogger.logHighLevelMsg("Replacing underscores: " + capitals); } Matcher matcher = lowercaseLetterAfterSpace.matcher(capitals); while (matcher.find()) { - MyLogger.logHighLevelMsg("Capitalizing names..."); int index = matcher.start(); capitals.setCharAt(index, Character.toUpperCase(capitals.charAt(index))); + MyLogger.logHighLevelMsg("Capitalizing names: " + capitals); } return capitals.toString(); } From e158b4480df22e4848cd035427cb305f103e0c55 Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Fri, 21 Oct 2022 17:34:08 +0200 Subject: [PATCH 18/43] Made ConfigHandler, LanguageKeyHandler, OfflinePlayerHandler and EnumHandler into singletons, merged RequestProcessor into RequestManager and wrote TabComplete logic (#88) --- .../com/artemis/the/gr8/playerstats/Main.java | 34 ++--- .../gr8/playerstats/api/RequestGenerator.java | 4 +- .../playerstats/commands/ExcludeCommand.java | 4 +- .../playerstats/commands/ReloadCommand.java | 2 +- .../gr8/playerstats/commands/StatCommand.java | 27 ++-- .../playerstats/commands/TabCompleter.java | 122 +++++++++------- .../gr8/playerstats/config/ConfigHandler.java | 17 ++- .../playerstats/listeners/JoinListener.java | 2 +- .../gr8/playerstats/msg/MessageBuilder.java | 16 ++- .../gr8/playerstats/msg/OutputManager.java | 9 +- .../msg/msgutils/LanguageKeyHandler.java | 19 ++- .../PlayerLoadAction.java | 30 ++-- .../ReloadThread.java | 17 +-- .../StatAction.java | 16 +-- .../StatThread.java | 15 +- .../{ => multithreading}/ThreadManager.java | 40 ++++-- .../gr8/playerstats/share/ShareManager.java | 7 +- .../playerstats/statistic/RequestManager.java | 129 ++++++++++++++++- .../statistic/RequestProcessor.java | 136 ------------------ .../gr8/playerstats/utils/EnumHandler.java | 35 +++-- .../utils/OfflinePlayerHandler.java | 63 ++++---- 21 files changed, 400 insertions(+), 344 deletions(-) rename src/main/java/com/artemis/the/gr8/playerstats/{reload => multithreading}/PlayerLoadAction.java (70%) rename src/main/java/com/artemis/the/gr8/playerstats/{reload => multithreading}/ReloadThread.java (66%) rename src/main/java/com/artemis/the/gr8/playerstats/{statistic => multithreading}/StatAction.java (78%) rename src/main/java/com/artemis/the/gr8/playerstats/{statistic => multithreading}/StatThread.java (81%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => multithreading}/ThreadManager.java (69%) delete mode 100644 src/main/java/com/artemis/the/gr8/playerstats/statistic/RequestProcessor.java diff --git a/src/main/java/com/artemis/the/gr8/playerstats/Main.java b/src/main/java/com/artemis/the/gr8/playerstats/Main.java index 3537658..5361ad3 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/Main.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/Main.java @@ -4,14 +4,13 @@ import com.artemis.the.gr8.playerstats.api.PlayerStats; import com.artemis.the.gr8.playerstats.api.StatFormatter; import com.artemis.the.gr8.playerstats.api.StatManager; import com.artemis.the.gr8.playerstats.commands.*; +import com.artemis.the.gr8.playerstats.multithreading.ThreadManager; import com.artemis.the.gr8.playerstats.statistic.RequestManager; import com.artemis.the.gr8.playerstats.msg.OutputManager; import com.artemis.the.gr8.playerstats.config.ConfigHandler; import com.artemis.the.gr8.playerstats.listeners.JoinListener; import com.artemis.the.gr8.playerstats.msg.msgutils.LanguageKeyHandler; import com.artemis.the.gr8.playerstats.share.ShareManager; -import com.artemis.the.gr8.playerstats.statistic.RequestProcessor; -import com.artemis.the.gr8.playerstats.utils.EnumHandler; import com.artemis.the.gr8.playerstats.utils.MyLogger; import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; import me.clip.placeholderapi.PlaceholderAPIPlugin; @@ -39,9 +38,8 @@ public final class Main extends JavaPlugin implements PlayerStats { private static ThreadManager threadManager; private static LanguageKeyHandler languageKeyHandler; private static OfflinePlayerHandler offlinePlayerHandler; - private static EnumHandler enumHandler; - private static RequestManager statRequestManager; + private static RequestManager requestManager; private static OutputManager outputManager; private static ShareManager shareManager; @@ -73,7 +71,7 @@ public final class Main extends JavaPlugin implements PlayerStats { languageKeyHandler.reload(); offlinePlayerHandler.reload(); outputManager.updateSettings(); - shareManager.updateSettings(config); + shareManager.updateSettings(); } /** @@ -103,19 +101,17 @@ public final class Main extends JavaPlugin implements PlayerStats { private void initializeMainClasses() { pluginInstance = this; playerStatsAPI = this; - adventure = BukkitAudiences.create(this); - enumHandler = new EnumHandler(); - languageKeyHandler = new LanguageKeyHandler(); - config = new ConfigHandler(); - offlinePlayerHandler = new OfflinePlayerHandler(config); - shareManager = new ShareManager(config); - outputManager = new OutputManager(adventure, config, languageKeyHandler); + config = ConfigHandler.getInstance(); + languageKeyHandler = LanguageKeyHandler.getInstance(); + offlinePlayerHandler = OfflinePlayerHandler.getInstance(); - RequestProcessor requestProcessor = new RequestProcessor(offlinePlayerHandler, outputManager, shareManager); - statRequestManager = new RequestManager(offlinePlayerHandler, requestProcessor); - threadManager = new ThreadManager(this, config, outputManager, statRequestManager); + outputManager = new OutputManager(adventure); + shareManager = new ShareManager(); + + requestManager = new RequestManager(outputManager, shareManager); + threadManager = new ThreadManager(this, outputManager); } /** @@ -123,16 +119,16 @@ public final class Main extends JavaPlugin implements PlayerStats { * to the relevant commands. */ private void registerCommands() { - TabCompleter tabCompleter = new TabCompleter(enumHandler, offlinePlayerHandler); + TabCompleter tabCompleter = new TabCompleter(); PluginCommand statcmd = this.getCommand("statistic"); if (statcmd != null) { - statcmd.setExecutor(new StatCommand(outputManager, threadManager, config, offlinePlayerHandler, enumHandler)); + statcmd.setExecutor(new StatCommand(outputManager, threadManager)); statcmd.setTabCompleter(tabCompleter); } PluginCommand excludecmd = this.getCommand("statisticexclude"); if (excludecmd != null) { - excludecmd.setExecutor(new ExcludeCommand(offlinePlayerHandler)); + excludecmd.setExecutor(new ExcludeCommand()); excludecmd.setTabCompleter(tabCompleter); } @@ -177,7 +173,7 @@ public final class Main extends JavaPlugin implements PlayerStats { @Override public StatManager getStatManager() { - return statRequestManager; + return requestManager; } @Override diff --git a/src/main/java/com/artemis/the/gr8/playerstats/api/RequestGenerator.java b/src/main/java/com/artemis/the/gr8/playerstats/api/RequestGenerator.java index a0eb419..6d65dda 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/api/RequestGenerator.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/api/RequestGenerator.java @@ -1,6 +1,6 @@ package com.artemis.the.gr8.playerstats.api; -import com.artemis.the.gr8.playerstats.statistic.RequestProcessor; +import com.artemis.the.gr8.playerstats.statistic.RequestManager; import com.artemis.the.gr8.playerstats.statistic.StatRequest; import org.bukkit.Material; import org.bukkit.Statistic; @@ -9,7 +9,7 @@ import org.jetbrains.annotations.NotNull; /** * Creates an executable {@link StatRequest}. This Request holds all - * the information PlayerStats needs to work with, and is used by the {@link RequestProcessor} + * the information PlayerStats needs to work with, and is used * to get the desired statistic data. */ public interface RequestGenerator { diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/ExcludeCommand.java b/src/main/java/com/artemis/the/gr8/playerstats/commands/ExcludeCommand.java index 45459b8..85ac5e2 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/ExcludeCommand.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/commands/ExcludeCommand.java @@ -11,8 +11,8 @@ public final class ExcludeCommand implements CommandExecutor { private final OfflinePlayerHandler offlinePlayerHandler; - public ExcludeCommand(OfflinePlayerHandler offlinePlayerHandler) { - this.offlinePlayerHandler = offlinePlayerHandler; + public ExcludeCommand() { + this.offlinePlayerHandler = OfflinePlayerHandler.getInstance(); } @Override diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/ReloadCommand.java b/src/main/java/com/artemis/the/gr8/playerstats/commands/ReloadCommand.java index 6a3774a..18fbfbd 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/ReloadCommand.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/commands/ReloadCommand.java @@ -1,6 +1,6 @@ package com.artemis.the.gr8.playerstats.commands; -import com.artemis.the.gr8.playerstats.ThreadManager; +import com.artemis.the.gr8.playerstats.multithreading.ThreadManager; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java b/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java index 6f76183..499abd1 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java @@ -1,6 +1,6 @@ package com.artemis.the.gr8.playerstats.commands; -import com.artemis.the.gr8.playerstats.ThreadManager; +import com.artemis.the.gr8.playerstats.multithreading.ThreadManager; import com.artemis.the.gr8.playerstats.api.RequestGenerator; import com.artemis.the.gr8.playerstats.config.ConfigHandler; import com.artemis.the.gr8.playerstats.enums.StandardMessage; @@ -32,16 +32,15 @@ public final class StatCommand implements CommandExecutor { private static ThreadManager threadManager; private static OutputManager outputManager; - private static ConfigHandler config; - private final OfflinePlayerHandler offlinePlayerHandler; + private final ConfigHandler config; private final EnumHandler enumHandler; - public StatCommand(OutputManager m, ThreadManager t, ConfigHandler c, OfflinePlayerHandler o, EnumHandler e) { - threadManager = t; - outputManager = m; - config = c; - offlinePlayerHandler = o; - enumHandler = e; + public StatCommand(OutputManager outputManager, ThreadManager threadManager) { + StatCommand.threadManager = threadManager; + StatCommand.outputManager = outputManager; + + config = ConfigHandler.getInstance(); + enumHandler = EnumHandler.getInstance(); } @Override @@ -135,19 +134,19 @@ public final class StatCommand implements CommandExecutor { switch (statistic.getType()) { case UNTYPED -> request = requestGenerator.untyped(statistic); case BLOCK -> { - Material block = EnumHandler.getBlockEnum(subStatName); + Material block = enumHandler.getBlockEnum(subStatName); if (block != null) { request = requestGenerator.blockOrItemType(statistic, block); } } case ITEM -> { - Material item = EnumHandler.getItemEnum(subStatName); + Material item = enumHandler.getItemEnum(subStatName); if (item != null) { request = requestGenerator.blockOrItemType(statistic, item); } } case ENTITY -> { - EntityType entity = EnumHandler.getEntityEnum(subStatName); + EntityType entity = enumHandler.getEntityEnum(subStatName); if (entity != null) { request = requestGenerator.entityType(statistic, entity); } @@ -202,7 +201,7 @@ public final class StatCommand implements CommandExecutor { } } if (statName != null) { - statistic = EnumHandler.getStatEnum(statName); + statistic = enumHandler.getStatEnum(statName); argsToProcess = removeArg(statName); } } @@ -241,6 +240,8 @@ public final class StatCommand implements CommandExecutor { @Contract(pure = true) private @Nullable String tryToFindPlayerName(@NotNull String[] args) { + OfflinePlayerHandler offlinePlayerHandler = OfflinePlayerHandler.getInstance(); + for (String arg : args) { if (offlinePlayerHandler.isRelevantPlayer(arg)) { return arg; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/TabCompleter.java b/src/main/java/com/artemis/the/gr8/playerstats/commands/TabCompleter.java index c8e2a81..b6ebba3 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/TabCompleter.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/commands/TabCompleter.java @@ -7,6 +7,7 @@ import org.bukkit.Statistic; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.entity.EntityType; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -17,16 +18,18 @@ import java.util.stream.Collectors; public final class TabCompleter implements org.bukkit.command.TabCompleter { - private final EnumHandler enumHandler; private final OfflinePlayerHandler offlinePlayerHandler; + private final EnumHandler enumHandler; - private List targetSuggestions; - private List itemBrokenSuggestions; - private List entitySuggestions; + private List statCommandTargets; + private List excludeCommandOptions; + private List itemsThatCanBreak; + private List entitiesThatCanDie; + + public TabCompleter() { + offlinePlayerHandler = OfflinePlayerHandler.getInstance(); + enumHandler = EnumHandler.getInstance(); - public TabCompleter(EnumHandler enumHandler, OfflinePlayerHandler offlinePlayerHandler) { - this.enumHandler = enumHandler; - this.offlinePlayerHandler = offlinePlayerHandler; prepareLists(); } @@ -46,50 +49,58 @@ public final class TabCompleter implements org.bukkit.command.TabCompleter { } private @Nullable List getExcludeCommandSuggestions(@NotNull String[] args) { - if (args.length == 1) { - return getDynamicTabSuggestions(offlinePlayerHandler.getOfflinePlayerNames(), args[0]); + if (args.length == 0) { + return null; } - return null; + + List tabSuggestions = new ArrayList<>(); + if (args.length == 1) { + tabSuggestions = excludeCommandOptions; + } + else if (args.length == 2) { + tabSuggestions = switch (args[0]) { + case "add" -> offlinePlayerHandler.getOfflinePlayerNames(); + case "remove" -> removablePlayerNames(); + default -> tabSuggestions; + }; + } + return getDynamicTabSuggestions(tabSuggestions, args[args.length-1]); } private @Nullable List getStatCommandSuggestions(@NotNull String[] args) { - if (args.length == 1) { - return getFirstArgSuggestions(args[0]); + if (args.length == 0) { + return null; } - else if (args.length > 1) { - String currentArg = args[args.length-1]; + + List tabSuggestions = new ArrayList<>(); + if (args.length == 1) { + tabSuggestions = firstStatCommandArgSuggestions(); + } + else { String previousArg = args[args.length-2]; //after checking if args[0] is a viable statistic, suggest sub-stat or targets if (enumHandler.isStatistic(previousArg)) { - Statistic stat = EnumHandler.getStatEnum(previousArg); + Statistic stat = enumHandler.getStatEnum(previousArg); if (stat != null) { - return getDynamicTabSuggestions(getSuggestionsAfterStat(stat), currentArg); + tabSuggestions = suggestionsAfterFirstStatCommandArg(stat); } } else if (previousArg.equalsIgnoreCase("player")) { if (args.length >= 3 && enumHandler.isEntityStatistic(args[args.length-3])) { - return targetSuggestions; //if arg before "player" was entity-sub-stat, suggest targets + tabSuggestions = statCommandTargets; //if arg before "player" was entity-sub-stat, suggest targets } else { //otherwise "player" is the target: suggest playerNames - return getDynamicTabSuggestions(offlinePlayerHandler.getOfflinePlayerNames(), currentArg); + tabSuggestions = offlinePlayerHandler.getOfflinePlayerNames(); } } //after a substatistic, suggest targets else if (enumHandler.isSubStatEntry(previousArg)) { - return targetSuggestions; + tabSuggestions = statCommandTargets; } - } - return null; - } - - private List getFirstArgSuggestions(String currentArg) { - List suggestions = enumHandler.getStatNames(); - suggestions.add("examples"); - suggestions.add("help"); - return getDynamicTabSuggestions(suggestions, currentArg); + return getDynamicTabSuggestions(tabSuggestions, args[args.length-1]); } /** @@ -103,52 +114,53 @@ public final class TabCompleter implements org.bukkit.command.TabCompleter { .collect(Collectors.toList()); } - private List getSuggestionsAfterStat(@NotNull Statistic stat) { + private @NotNull List firstStatCommandArgSuggestions() { + List suggestions = enumHandler.getAllStatNames(); + suggestions.add("examples"); + suggestions.add("help"); + return suggestions; + } + + private List suggestionsAfterFirstStatCommandArg(@NotNull Statistic stat) { switch (stat.getType()) { case BLOCK -> { - return getAllBlockNames(); + return enumHandler.getAllBlockNames(); } case ITEM -> { if (stat == Statistic.BREAK_ITEM) { - return getItemBrokenSuggestions(); + return itemsThatCanBreak; } else { - return getAllItemNames(); + return enumHandler.getAllItemNames(); } } case ENTITY -> { - return getEntitySuggestions(); + return entitiesThatCanDie; } default -> { - return targetSuggestions; + return statCommandTargets; } } } - private List getAllItemNames() { - return enumHandler.getItemNames(); - } - - private List getItemBrokenSuggestions() { - return itemBrokenSuggestions; - } - - private List getAllBlockNames() { - return enumHandler.getBlockNames(); - } - - private List getEntitySuggestions() { - return entitySuggestions; + @Contract(pure = true) + private @Nullable List removablePlayerNames() { + return statCommandTargets; } private void prepareLists() { - targetSuggestions = new ArrayList<>(); - targetSuggestions.add("top"); - targetSuggestions.add("player"); - targetSuggestions.add("server"); - targetSuggestions.add("me"); + statCommandTargets = new ArrayList<>(); + statCommandTargets.add("top"); + statCommandTargets.add("player"); + statCommandTargets.add("server"); + statCommandTargets.add("me"); + + excludeCommandOptions = new ArrayList<>(); + excludeCommandOptions.add("add"); + excludeCommandOptions.add("list"); + excludeCommandOptions.add("remove"); //breaking an item means running its durability negative - itemBrokenSuggestions = Arrays.stream(Material.values()) + itemsThatCanBreak = Arrays.stream(Material.values()) .parallel() .filter(Material::isItem) .filter(item -> item.getMaxDurability() != 0) @@ -157,7 +169,7 @@ public final class TabCompleter implements org.bukkit.command.TabCompleter { .collect(Collectors.toList()); //the only statistics dealing with entities are killed_entity and entity_killed_by - entitySuggestions = Arrays.stream(EntityType.values()) + entitiesThatCanDie = Arrays.stream(EntityType.values()) .parallel() .filter(EntityType::isAlive) .map(EntityType::toString) diff --git a/src/main/java/com/artemis/the/gr8/playerstats/config/ConfigHandler.java b/src/main/java/com/artemis/the/gr8/playerstats/config/ConfigHandler.java index 0035f62..7e875c0 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/config/ConfigHandler.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/config/ConfigHandler.java @@ -13,10 +13,11 @@ import java.util.Map; /** Handles all PlayerStats' config-settings. */ public final class ConfigHandler extends FileHandler { + private static volatile ConfigHandler instance; private final int configVersion; private FileConfiguration config; - public ConfigHandler() { + private ConfigHandler() { super("config.yml"); config = super.getFileConfiguration(); @@ -25,6 +26,20 @@ public final class ConfigHandler extends FileHandler { MyLogger.setDebugLevel(getDebugLevel()); } + public static ConfigHandler getInstance() { + ConfigHandler localVar = instance; + if (localVar != null) { + return localVar; + } + + synchronized (ConfigHandler.class) { + if (instance == null) { + instance = new ConfigHandler(); + } + return instance; + } + } + @Override public void reload() { super.reload(); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/listeners/JoinListener.java b/src/main/java/com/artemis/the/gr8/playerstats/listeners/JoinListener.java index d45a654..d7c2d11 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/listeners/JoinListener.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/listeners/JoinListener.java @@ -1,6 +1,6 @@ package com.artemis.the.gr8.playerstats.listeners; -import com.artemis.the.gr8.playerstats.ThreadManager; +import com.artemis.the.gr8.playerstats.multithreading.ThreadManager; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java index d713b1c..5d7fb7d 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java @@ -144,7 +144,9 @@ public final class MessageBuilder implements StatFormatter { 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 " + + EnumHandler.getInstance().getSubStatTypeName(statType) + + " to look up this statistic!")); } public @NotNull TextComponent missingPlayerName() { @@ -160,7 +162,9 @@ public final class MessageBuilder implements StatFormatter { .append(componentFactory.messageAccent().content("\"" + subStatName + "\"")) .append(space()) .append(componentFactory.message().content( - "is not a valid " + EnumHandler.getSubStatTypeName(statType) + "!")); + "is not a valid " + + EnumHandler.getInstance().getSubStatTypeName(statType) + + "!")); } public @NotNull TextComponent requestAlreadyRunning() { @@ -509,12 +513,14 @@ public final class MessageBuilder implements StatFormatter { } private TextComponent getStatAndSubStatNameComponent(Statistic statistic, @Nullable String subStatName, Target target) { + EnumHandler enumHandler = EnumHandler.getInstance(); + String statKey = languageKeyHandler.getStatKey(statistic); String subStatKey = switch (statistic.getType()) { case UNTYPED -> null; - case ENTITY -> languageKeyHandler.getEntityKey(EnumHandler.getEntityEnum(subStatName)); - case BLOCK -> languageKeyHandler.getBlockKey(EnumHandler.getBlockEnum(subStatName)); - case ITEM -> languageKeyHandler.getItemKey(EnumHandler.getItemEnum(subStatName)); + case ENTITY -> languageKeyHandler.getEntityKey(enumHandler.getEntityEnum(subStatName)); + case BLOCK -> languageKeyHandler.getBlockKey(enumHandler.getBlockEnum(subStatName)); + case ITEM -> languageKeyHandler.getItemKey(enumHandler.getItemEnum(subStatName)); }; if (subStatKey == null) { subStatKey = StringUtils.prettify(subStatName); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java index e3858c0..e0a60e4 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java @@ -34,17 +34,18 @@ import static com.artemis.the.gr8.playerstats.enums.StandardMessage.*; public final class OutputManager { private static BukkitAudiences adventure; - private static ConfigHandler config; private static EnumMap> standardMessages; + private final ConfigHandler config; private final LanguageKeyHandler languageKeyHandler; private MessageBuilder messageBuilder; private MessageBuilder consoleMessageBuilder; - public OutputManager(BukkitAudiences adventure, ConfigHandler config, LanguageKeyHandler language) { + public OutputManager(BukkitAudiences adventure) { OutputManager.adventure = adventure; - OutputManager.config = config; - languageKeyHandler = language; + languageKeyHandler = LanguageKeyHandler.getInstance(); + config = ConfigHandler.getInstance(); + getMessageBuilders(); prepareFunctions(); } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/LanguageKeyHandler.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/LanguageKeyHandler.java index 4c9de9c..6204694 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/LanguageKeyHandler.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/LanguageKeyHandler.java @@ -22,15 +22,30 @@ import java.util.regex.Pattern; */ public final class LanguageKeyHandler extends FileHandler { + private static volatile LanguageKeyHandler instance; private static HashMap statisticKeys; private final Pattern subStatKey; - public LanguageKeyHandler() { + private LanguageKeyHandler() { super("language.yml"); statisticKeys = generateStatisticKeys(); subStatKey = Pattern.compile("(item|entity|block)\\.minecraft\\."); } + public static LanguageKeyHandler getInstance() { + LanguageKeyHandler localVar = instance; + if (localVar != null) { + return localVar; + } + + synchronized (LanguageKeyHandler.class) { + if (instance == null) { + instance = new LanguageKeyHandler(); + } + return instance; + } + } + @Contract(pure = true) public @NotNull String getKeyForBlockUnit() { return "soundCategory.block"; @@ -222,7 +237,7 @@ public final class LanguageKeyHandler extends FileHandler { 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_", ""); - Material newBlock = EnumHandler.getBlockEnum(blockName); + Material newBlock = EnumHandler.getInstance().getBlockEnum(blockName); return (newBlock != null) ? "block.minecraft." + newBlock.getKey().getKey() : null; } else { diff --git a/src/main/java/com/artemis/the/gr8/playerstats/reload/PlayerLoadAction.java b/src/main/java/com/artemis/the/gr8/playerstats/multithreading/PlayerLoadAction.java similarity index 70% rename from src/main/java/com/artemis/the/gr8/playerstats/reload/PlayerLoadAction.java rename to src/main/java/com/artemis/the/gr8/playerstats/multithreading/PlayerLoadAction.java index 2d7bd71..7ba037b 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/reload/PlayerLoadAction.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/multithreading/PlayerLoadAction.java @@ -1,6 +1,6 @@ -package com.artemis.the.gr8.playerstats.reload; +package com.artemis.the.gr8.playerstats.multithreading; -import com.artemis.the.gr8.playerstats.ThreadManager; +import com.artemis.the.gr8.playerstats.config.ConfigHandler; import com.artemis.the.gr8.playerstats.utils.MyLogger; import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; import com.artemis.the.gr8.playerstats.utils.UnixTimeHandler; @@ -13,7 +13,7 @@ import java.util.concurrent.RecursiveAction; /** * The action that is executed when a reload-command is triggered. */ -public final class PlayerLoadAction extends RecursiveAction { +final class PlayerLoadAction extends RecursiveAction { private static int threshold; @@ -21,7 +21,6 @@ public final class PlayerLoadAction extends RecursiveAction { private final int start; private final int end; - private final int lastPlayedLimit; private final ConcurrentHashMap offlinePlayerUUIDs; /** @@ -29,25 +28,19 @@ public final class PlayerLoadAction extends RecursiveAction { * that should be included in statistic calculations. * * @param players array of all OfflinePlayers to filter and load - * @param lastPlayedLimit optional limit for amount of days ago players last played * @param offlinePlayerUUIDs the ConcurrentHashMap to put playerNames and UUIDs in * @see OfflinePlayerHandler */ - public PlayerLoadAction(OfflinePlayer[] players, - int lastPlayedLimit, ConcurrentHashMap offlinePlayerUUIDs) { - - this(players, 0, players.length, lastPlayedLimit, offlinePlayerUUIDs); + public PlayerLoadAction(OfflinePlayer[] players, ConcurrentHashMap offlinePlayerUUIDs) { + this(players, 0, players.length, offlinePlayerUUIDs); } - private PlayerLoadAction(OfflinePlayer[] players, int start, int end, - int lastPlayedLimit, ConcurrentHashMap offlinePlayerUUIDs) { + private PlayerLoadAction(OfflinePlayer[] players, int start, int end, ConcurrentHashMap offlinePlayerUUIDs) { threshold = ThreadManager.getTaskThreshold(); this.players = players; this.start = start; this.end = end; - - this.lastPlayedLimit = lastPlayedLimit; this.offlinePlayerUUIDs = offlinePlayerUUIDs; MyLogger.subActionCreated(Thread.currentThread().getName()); @@ -62,9 +55,9 @@ public final class PlayerLoadAction extends RecursiveAction { else { final int split = length / 2; final PlayerLoadAction subTask1 = new PlayerLoadAction(players, start, (start + split), - lastPlayedLimit, offlinePlayerUUIDs); + offlinePlayerUUIDs); final PlayerLoadAction subTask2 = new PlayerLoadAction(players, (start + split), end, - lastPlayedLimit, offlinePlayerUUIDs); + offlinePlayerUUIDs); //queue and compute all subtasks in the right order invokeAll(subTask1, subTask2); @@ -72,11 +65,16 @@ public final class PlayerLoadAction extends RecursiveAction { } private void process() { + OfflinePlayerHandler offlinePlayerHandler = OfflinePlayerHandler.getInstance(); + int lastPlayedLimit = ConfigHandler.getInstance().getLastPlayedLimit(); + for (int i = start; i < end; i++) { OfflinePlayer player = players[i]; String playerName = player.getName(); MyLogger.actionRunning(Thread.currentThread().getName()); - if (playerName != null && UnixTimeHandler.hasPlayedSince(lastPlayedLimit, player.getLastPlayed())) { + if (playerName != null && + !offlinePlayerHandler.isExcluded(player.getUniqueId()) && + UnixTimeHandler.hasPlayedSince(lastPlayedLimit, player.getLastPlayed())) { offlinePlayerUUIDs.put(playerName, player.getUniqueId()); } } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/reload/ReloadThread.java b/src/main/java/com/artemis/the/gr8/playerstats/multithreading/ReloadThread.java similarity index 66% rename from src/main/java/com/artemis/the/gr8/playerstats/reload/ReloadThread.java rename to src/main/java/com/artemis/the/gr8/playerstats/multithreading/ReloadThread.java index a579803..b259bd6 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/reload/ReloadThread.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/multithreading/ReloadThread.java @@ -1,20 +1,14 @@ -package com.artemis.the.gr8.playerstats.reload; +package com.artemis.the.gr8.playerstats.multithreading; import com.artemis.the.gr8.playerstats.Main; -import com.artemis.the.gr8.playerstats.share.ShareManager; import com.artemis.the.gr8.playerstats.enums.StandardMessage; import com.artemis.the.gr8.playerstats.msg.OutputManager; -import com.artemis.the.gr8.playerstats.msg.msgutils.LanguageKeyHandler; -import com.artemis.the.gr8.playerstats.statistic.RequestProcessor; -import com.artemis.the.gr8.playerstats.statistic.StatThread; import com.artemis.the.gr8.playerstats.utils.MyLogger; -import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; -import com.artemis.the.gr8.playerstats.enums.DebugLevel; import org.bukkit.command.CommandSender; import org.jetbrains.annotations.Nullable; /** The Thread that is in charge of reloading PlayerStats. */ -public final class ReloadThread extends Thread { +final class ReloadThread extends Thread { private final Main main; private static OutputManager outputManager; @@ -34,13 +28,8 @@ public final class ReloadThread extends Thread { } /** - * This method will perform a series of tasks. If a {@link StatThread} + * This method will call reload() from Main. If a {@link StatThread} * is still running, it will join the statThread and wait for it to finish. - * Then, it will reload the config, update the {@link LanguageKeyHandler}, - * the {@link OfflinePlayerHandler}, the {@link DebugLevel}, update - * the share-settings in {@link ShareManager} and topListSize-settings - * in {@link RequestProcessor}, and update the MessageBuilders in the - * {@link OutputManager}. */ @Override public void run() { diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatAction.java b/src/main/java/com/artemis/the/gr8/playerstats/multithreading/StatAction.java similarity index 78% rename from src/main/java/com/artemis/the/gr8/playerstats/statistic/StatAction.java rename to src/main/java/com/artemis/the/gr8/playerstats/multithreading/StatAction.java index f1bfcd3..5a9b50d 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatAction.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/multithreading/StatAction.java @@ -1,6 +1,6 @@ -package com.artemis.the.gr8.playerstats.statistic; +package com.artemis.the.gr8.playerstats.multithreading; -import com.artemis.the.gr8.playerstats.ThreadManager; +import com.artemis.the.gr8.playerstats.statistic.StatRequest; import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; import com.artemis.the.gr8.playerstats.utils.MyLogger; import com.google.common.collect.ImmutableList; @@ -16,8 +16,6 @@ import java.util.concurrent.RecursiveTask; final class StatAction extends RecursiveTask> { private static int threshold; - - private final OfflinePlayerHandler offlinePlayerHandler; private final ImmutableList playerNames; private final StatRequest.Settings requestSettings; private final ConcurrentHashMap allStats; @@ -28,15 +26,13 @@ final class StatAction extends RecursiveTask> * ForkJoinPool, and returns the ConcurrentHashMap when * everything is done. * - * @param offlinePlayerHandler the OfflinePlayerHandler to convert playerNames into Players * @param playerNames ImmutableList of playerNames for players that should be included in stat calculations * @param requestSettings a validated requestSettings object * @param allStats the ConcurrentHashMap to put the results on */ - public StatAction(OfflinePlayerHandler offlinePlayerHandler, ImmutableList playerNames, StatRequest.Settings requestSettings, ConcurrentHashMap allStats) { + public StatAction(ImmutableList playerNames, StatRequest.Settings requestSettings, ConcurrentHashMap allStats) { threshold = ThreadManager.getTaskThreshold(); - this.offlinePlayerHandler = offlinePlayerHandler; this.playerNames = playerNames; this.requestSettings = requestSettings; this.allStats = allStats; @@ -50,8 +46,8 @@ final class StatAction extends RecursiveTask> return getStatsDirectly(); } else { - final StatAction subTask1 = new StatAction(offlinePlayerHandler, playerNames.subList(0, playerNames.size()/2), requestSettings, allStats); - final StatAction subTask2 = new StatAction(offlinePlayerHandler, playerNames.subList(playerNames.size()/2, playerNames.size()), requestSettings, allStats); + final StatAction subTask1 = new StatAction(playerNames.subList(0, playerNames.size()/2), requestSettings, allStats); + final StatAction subTask2 = new StatAction(playerNames.subList(playerNames.size()/2, playerNames.size()), requestSettings, allStats); //queue and compute all subtasks in the right order subTask1.fork(); @@ -61,6 +57,8 @@ final class StatAction extends RecursiveTask> } private ConcurrentHashMap getStatsDirectly() { + OfflinePlayerHandler offlinePlayerHandler = OfflinePlayerHandler.getInstance(); + Iterator iterator = playerNames.iterator(); if (iterator.hasNext()) { do { diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatThread.java b/src/main/java/com/artemis/the/gr8/playerstats/multithreading/StatThread.java similarity index 81% rename from src/main/java/com/artemis/the/gr8/playerstats/statistic/StatThread.java rename to src/main/java/com/artemis/the/gr8/playerstats/multithreading/StatThread.java index ff03a55..cc01999 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatThread.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/multithreading/StatThread.java @@ -1,10 +1,11 @@ -package com.artemis.the.gr8.playerstats.statistic; +package com.artemis.the.gr8.playerstats.multithreading; -import com.artemis.the.gr8.playerstats.ThreadManager; import com.artemis.the.gr8.playerstats.msg.OutputManager; +import com.artemis.the.gr8.playerstats.statistic.RequestManager; +import com.artemis.the.gr8.playerstats.statistic.StatRequest; +import com.artemis.the.gr8.playerstats.statistic.StatResult; import com.artemis.the.gr8.playerstats.utils.MyLogger; import com.artemis.the.gr8.playerstats.enums.StandardMessage; -import com.artemis.the.gr8.playerstats.reload.ReloadThread; import org.bukkit.command.CommandSender; import org.jetbrains.annotations.Nullable; @@ -13,17 +14,15 @@ import java.util.*; /** * The Thread that is in charge of getting and calculating statistics. */ -public final class StatThread extends Thread { +final class StatThread extends Thread { private static OutputManager outputManager; - private final RequestManager statManager; private final ReloadThread reloadThread; private final StatRequest statRequest; - public StatThread(OutputManager m, RequestManager stat, int ID, StatRequest s, @Nullable ReloadThread r) { + public StatThread(OutputManager m, int ID, StatRequest s, @Nullable ReloadThread r) { outputManager = m; - statManager = stat; reloadThread = r; statRequest = s; @@ -54,7 +53,7 @@ public final class StatThread extends Thread { } try { - StatResult result = statManager.execute(statRequest); + StatResult result = RequestManager.execute(statRequest); outputManager.sendToCommandSender(statRequester, result.formattedComponent()); } catch (ConcurrentModificationException e) { diff --git a/src/main/java/com/artemis/the/gr8/playerstats/ThreadManager.java b/src/main/java/com/artemis/the/gr8/playerstats/multithreading/ThreadManager.java similarity index 69% rename from src/main/java/com/artemis/the/gr8/playerstats/ThreadManager.java rename to src/main/java/com/artemis/the/gr8/playerstats/multithreading/ThreadManager.java index 511ee63..417e08e 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/ThreadManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/multithreading/ThreadManager.java @@ -1,17 +1,20 @@ -package com.artemis.the.gr8.playerstats; +package com.artemis.the.gr8.playerstats.multithreading; +import com.artemis.the.gr8.playerstats.Main; import com.artemis.the.gr8.playerstats.msg.OutputManager; import com.artemis.the.gr8.playerstats.config.ConfigHandler; import com.artemis.the.gr8.playerstats.enums.StandardMessage; -import com.artemis.the.gr8.playerstats.reload.ReloadThread; -import com.artemis.the.gr8.playerstats.statistic.StatThread; import com.artemis.the.gr8.playerstats.statistic.StatRequest; -import com.artemis.the.gr8.playerstats.statistic.RequestManager; import com.artemis.the.gr8.playerstats.utils.MyLogger; +import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; +import com.google.common.collect.ImmutableList; +import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandSender; import org.jetbrains.annotations.NotNull; import java.util.HashMap; +import java.util.UUID; +import java.util.concurrent.ConcurrentHashMap; /** * The ThreadManager is in charge of the Threads that PlayerStats @@ -29,20 +32,18 @@ public final class ThreadManager { private int reloadThreadID; private final Main main; - private static ConfigHandler config; + private final ConfigHandler config; private static OutputManager outputManager; - private final RequestManager statManager; private ReloadThread activatedReloadThread; private StatThread activatedStatThread; private final HashMap statThreads; private static long lastRecordedCalcTime; - public ThreadManager(Main main, ConfigHandler config, OutputManager outputManager, RequestManager statManager) { + public ThreadManager(Main main, OutputManager outputManager) { this.main = main; - ThreadManager.config = config; + this.config = ConfigHandler.getInstance(); ThreadManager.outputManager = outputManager; - this.statManager = statManager; statThreads = new HashMap<>(); statThreadID = 0; @@ -50,10 +51,27 @@ public final class ThreadManager { lastRecordedCalcTime = 0; } - public static int getTaskThreshold() { + static int getTaskThreshold() { return threshold; } + public static @NotNull StatAction getStatAction(StatRequest.Settings requestSettings) { + OfflinePlayerHandler offlinePlayerHandler = OfflinePlayerHandler.getInstance(); + + ImmutableList relevantPlayerNames = ImmutableList.copyOf(offlinePlayerHandler.getOfflinePlayerNames()); + ConcurrentHashMap resultingStatNumbers = new ConcurrentHashMap<>(relevantPlayerNames.size()); + StatAction task = new StatAction(relevantPlayerNames, requestSettings, resultingStatNumbers); + + MyLogger.actionCreated(relevantPlayerNames.size()); + return task; + } + + public static @NotNull PlayerLoadAction getPlayerLoadAction(OfflinePlayer[] playersToLoad, ConcurrentHashMap mapToFill) { + PlayerLoadAction task = new PlayerLoadAction(playersToLoad, mapToFill); + MyLogger.actionCreated(playersToLoad != null ? playersToLoad.length : 0); + return task; + } + public void startReloadThread(CommandSender sender) { if (activatedReloadThread == null || !activatedReloadThread.isAlive()) { reloadThreadID += 1; @@ -100,7 +118,7 @@ public final class ThreadManager { } private void startNewStatThread(StatRequest request) { - activatedStatThread = new StatThread(outputManager, statManager, statThreadID, request, activatedReloadThread); + activatedStatThread = new StatThread(outputManager, statThreadID, request, activatedReloadThread); statThreads.put(request.getSettings().getCommandSender().getName(), activatedStatThread); activatedStatThread.start(); } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/share/ShareManager.java b/src/main/java/com/artemis/the/gr8/playerstats/share/ShareManager.java index 2c2c87c..20a9a69 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/share/ShareManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/share/ShareManager.java @@ -33,15 +33,16 @@ public final class ShareManager { private ConcurrentHashMap shareTimeStamp; private ArrayBlockingQueue sharedResults; - public ShareManager(ConfigHandler config) { - updateSettings(config); + public ShareManager() { + updateSettings(); } public static boolean isEnabled() { return isEnabled; } - public void updateSettings(ConfigHandler config) { + public void updateSettings() { + ConfigHandler config = ConfigHandler.getInstance(); isEnabled = config.allowStatSharing() && config.useHoverText(); waitingTime = config.getStatShareWaitingTime(); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/RequestManager.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/RequestManager.java index 2ef1511..b604c8c 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/RequestManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/RequestManager.java @@ -2,10 +2,22 @@ package com.artemis.the.gr8.playerstats.statistic; import com.artemis.the.gr8.playerstats.api.RequestGenerator; import com.artemis.the.gr8.playerstats.api.StatManager; +import com.artemis.the.gr8.playerstats.msg.FormattingFunction; +import com.artemis.the.gr8.playerstats.msg.OutputManager; +import com.artemis.the.gr8.playerstats.multithreading.ThreadManager; +import com.artemis.the.gr8.playerstats.share.ShareManager; +import com.artemis.the.gr8.playerstats.utils.MyLogger; import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; +import net.kyori.adventure.text.TextComponent; +import org.bukkit.OfflinePlayer; +import org.bukkit.command.CommandSender; +import org.bukkit.command.ConsoleCommandSender; import org.jetbrains.annotations.NotNull; -import java.util.LinkedHashMap; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ForkJoinPool; +import java.util.stream.Collectors; /** * Turns user input into a {@link StatRequest} that can be @@ -13,15 +25,15 @@ import java.util.LinkedHashMap; */ public final class RequestManager implements StatManager { - private static OfflinePlayerHandler offlinePlayerHandler; - private final RequestProcessor processor; + private static RequestProcessor processor; + private final OfflinePlayerHandler offlinePlayerHandler; - public RequestManager(OfflinePlayerHandler offlinePlayerHandler, RequestProcessor processor) { - RequestManager.offlinePlayerHandler = offlinePlayerHandler; - this.processor = processor; + public RequestManager(OutputManager outputManager, ShareManager shareManager) { + processor = new RequestProcessor(outputManager, shareManager); + offlinePlayerHandler = OfflinePlayerHandler.getInstance(); } - public StatResult execute(@NotNull StatRequest request) { + public static StatResult execute(@NotNull StatRequest request) { return switch (request.getSettings().getTarget()) { case PLAYER -> processor.processPlayerRequest(request.getSettings()); case SERVER -> processor.processServerRequest(request.getSettings()); @@ -64,4 +76,107 @@ public final class RequestManager implements StatManager { public StatResult> executeTopRequest(StatRequest> request) { return processor.processTopRequest(request.getSettings()); } + + private final class RequestProcessor { + + private static OutputManager outputManager; + private static ShareManager shareManager; + + public RequestProcessor(OutputManager outputManager, ShareManager shareManager) { + RequestProcessor.outputManager = outputManager; + RequestProcessor.shareManager = shareManager; + } + + public @NotNull StatResult processPlayerRequest(StatRequest.Settings requestSettings) { + int stat = getPlayerStat(requestSettings); + FormattingFunction formattingFunction = outputManager.formatPlayerStat(requestSettings, stat); + TextComponent formattedResult = processFunction(requestSettings.getCommandSender(), formattingFunction); + String resultAsString = outputManager.textComponentToString(formattedResult); + + return new StatResult<>(stat, formattedResult, resultAsString); + } + + public @NotNull StatResult processServerRequest(StatRequest.Settings requestSettings) { + long stat = getServerStat(requestSettings); + FormattingFunction formattingFunction = outputManager.formatServerStat(requestSettings, stat); + TextComponent formattedResult = processFunction(requestSettings.getCommandSender(), formattingFunction); + String resultAsString = outputManager.textComponentToString(formattedResult); + + return new StatResult<>(stat, formattedResult, resultAsString); + } + + public @NotNull StatResult> processTopRequest(StatRequest.Settings requestSettings) { + LinkedHashMap stats = getTopStats(requestSettings); + FormattingFunction formattingFunction = outputManager.formatTopStats(requestSettings, stats); + TextComponent formattedResult = processFunction(requestSettings.getCommandSender(), formattingFunction); + String resultAsString = outputManager.textComponentToString(formattedResult); + + return new StatResult<>(stats, formattedResult, resultAsString); + } + + private int getPlayerStat(@NotNull StatRequest.Settings requestSettings) { + OfflinePlayer player = offlinePlayerHandler.getOfflinePlayer(requestSettings.getPlayerName()); + return switch (requestSettings.getStatistic().getType()) { + case UNTYPED -> player.getStatistic(requestSettings.getStatistic()); + case ENTITY -> player.getStatistic(requestSettings.getStatistic(), requestSettings.getEntity()); + case BLOCK -> player.getStatistic(requestSettings.getStatistic(), requestSettings.getBlock()); + case ITEM -> player.getStatistic(requestSettings.getStatistic(), requestSettings.getItem()); + }; + } + + private long getServerStat(StatRequest.Settings requestSettings) { + List numbers = getAllStatsAsync(requestSettings) + .values() + .parallelStream() + .toList(); + return numbers.parallelStream().mapToLong(Integer::longValue).sum(); + } + + private LinkedHashMap getTopStats(StatRequest.Settings requestSettings) { + return getAllStatsAsync(requestSettings).entrySet().stream() + .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())) + .limit(requestSettings.getTopListSize()) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new)); + } + + private TextComponent processFunction(CommandSender sender, FormattingFunction function) { + if (outputShouldBeStored(sender)) { + int shareCode = shareManager.saveStatResult(sender.getName(), function.getResultWithSharerName(sender)); + return function.getResultWithShareButton(shareCode); + } + return function.getDefaultResult(); + } + + private boolean outputShouldBeStored(CommandSender sender) { + return !(sender instanceof ConsoleCommandSender) && + ShareManager.isEnabled() && + shareManager.senderHasPermission(sender); + } + + /** + * Invokes a bunch of worker pool threads to get the statistics for + * all players that are stored in the {@link OfflinePlayerHandler}). + */ + private @NotNull ConcurrentHashMap getAllStatsAsync(StatRequest.Settings requestSettings) { + long time = System.currentTimeMillis(); + + ForkJoinPool commonPool = ForkJoinPool.commonPool(); + ConcurrentHashMap allStats; + + try { + allStats = commonPool.invoke(ThreadManager.getStatAction(requestSettings)); + } catch (ConcurrentModificationException e) { + 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!"); + throw new ConcurrentModificationException(e.toString()); + } + + MyLogger.actionFinished(); + ThreadManager.recordCalcTime(System.currentTimeMillis() - time); + MyLogger.logMediumLevelTask("Calculated all stats", time); + + return allStats; + } + } } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/RequestProcessor.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/RequestProcessor.java deleted file mode 100644 index 4f32dec..0000000 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/RequestProcessor.java +++ /dev/null @@ -1,136 +0,0 @@ -package com.artemis.the.gr8.playerstats.statistic; - -import com.artemis.the.gr8.playerstats.ThreadManager; -import com.artemis.the.gr8.playerstats.msg.FormattingFunction; -import com.artemis.the.gr8.playerstats.msg.OutputManager; -import com.artemis.the.gr8.playerstats.share.ShareManager; -import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; -import com.artemis.the.gr8.playerstats.utils.MyLogger; -import com.google.common.collect.ImmutableList; -import net.kyori.adventure.text.TextComponent; -import org.bukkit.OfflinePlayer; -import org.bukkit.command.CommandSender; -import org.bukkit.command.ConsoleCommandSender; -import org.jetbrains.annotations.NotNull; - -import java.util.*; -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ForkJoinPool; -import java.util.stream.Collectors; - -public final class RequestProcessor { - - private final OfflinePlayerHandler offlinePlayerHandler; - private static OutputManager outputManager; - private static ShareManager shareManager; - - public RequestProcessor(OfflinePlayerHandler offlinePlayerHandler, OutputManager outputManager, ShareManager shareManager) { - this.offlinePlayerHandler = offlinePlayerHandler; - RequestProcessor.outputManager = outputManager; - RequestProcessor.shareManager = shareManager; - } - - public @NotNull StatResult processPlayerRequest(StatRequest.Settings requestSettings) { - int stat = getPlayerStat(requestSettings); - FormattingFunction formattingFunction = outputManager.formatPlayerStat(requestSettings, stat); - TextComponent formattedResult = processFunction(requestSettings.getCommandSender(), formattingFunction); - String resultAsString = outputManager.textComponentToString(formattedResult); - - return new StatResult<>(stat, formattedResult, resultAsString); - } - - public @NotNull StatResult processServerRequest(StatRequest.Settings requestSettings) { - long stat = getServerStat(requestSettings); - FormattingFunction formattingFunction = outputManager.formatServerStat(requestSettings, stat); - TextComponent formattedResult = processFunction(requestSettings.getCommandSender(), formattingFunction); - String resultAsString = outputManager.textComponentToString(formattedResult); - - return new StatResult<>(stat, formattedResult, resultAsString); - } - - public @NotNull StatResult> processTopRequest(StatRequest.Settings requestSettings) { - LinkedHashMap stats = getTopStats(requestSettings); - FormattingFunction formattingFunction = outputManager.formatTopStats(requestSettings, stats); - TextComponent formattedResult = processFunction(requestSettings.getCommandSender(), formattingFunction); - String resultAsString = outputManager.textComponentToString(formattedResult); - - return new StatResult<>(stats, formattedResult, resultAsString); - } - - private int getPlayerStat(@NotNull StatRequest.Settings requestSettings) { - OfflinePlayer player = offlinePlayerHandler.getOfflinePlayer(requestSettings.getPlayerName()); - return switch (requestSettings.getStatistic().getType()) { - case UNTYPED -> player.getStatistic(requestSettings.getStatistic()); - case ENTITY -> player.getStatistic(requestSettings.getStatistic(), requestSettings.getEntity()); - case BLOCK -> player.getStatistic(requestSettings.getStatistic(), requestSettings.getBlock()); - case ITEM -> player.getStatistic(requestSettings.getStatistic(), requestSettings.getItem()); - }; - } - - private long getServerStat(StatRequest.Settings requestSettings) { - List numbers = getAllStatsAsync(requestSettings) - .values() - .parallelStream() - .toList(); - return numbers.parallelStream().mapToLong(Integer::longValue).sum(); - } - - private LinkedHashMap getTopStats(StatRequest.Settings requestSettings) { - return getAllStatsAsync(requestSettings).entrySet().stream() - .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())) - .limit(requestSettings.getTopListSize()) - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new)); - } - - private TextComponent processFunction(CommandSender sender, FormattingFunction function) { - if (outputShouldBeStored(sender)) { - int shareCode = shareManager.saveStatResult(sender.getName(), function.getResultWithSharerName(sender)); - return function.getResultWithShareButton(shareCode); - } - return function.getDefaultResult(); - } - - private boolean outputShouldBeStored(CommandSender sender) { - return !(sender instanceof ConsoleCommandSender) && - ShareManager.isEnabled() && - shareManager.senderHasPermission(sender); - } - - /** - * Invokes a bunch of worker pool threads to get the statistics for - * all players that are stored in the {@link OfflinePlayerHandler}). - */ - private @NotNull ConcurrentHashMap getAllStatsAsync(StatRequest.Settings requestSettings) { - long time = System.currentTimeMillis(); - - ForkJoinPool commonPool = ForkJoinPool.commonPool(); - ConcurrentHashMap allStats; - - try { - allStats = commonPool.invoke(getStatTask(requestSettings)); - } catch (ConcurrentModificationException e) { - 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!"); - throw new ConcurrentModificationException(e.toString()); - } - - MyLogger.actionFinished(); - ThreadManager.recordCalcTime(System.currentTimeMillis() - time); - MyLogger.logMediumLevelTask("Calculated all stats", time); - - return allStats; - } - - private @NotNull StatAction getStatTask(StatRequest.Settings requestSettings) { - int size = offlinePlayerHandler.getOfflinePlayerCount() != 0 ? offlinePlayerHandler.getOfflinePlayerCount() : 16; - ConcurrentHashMap allStats = new ConcurrentHashMap<>(size); - ImmutableList playerNames = ImmutableList.copyOf(offlinePlayerHandler.getOfflinePlayerNames()); - - StatAction task = new StatAction(offlinePlayerHandler, playerNames, requestSettings, allStats); - MyLogger.actionCreated(playerNames.size()); - - return task; - } -} \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/utils/EnumHandler.java b/src/main/java/com/artemis/the/gr8/playerstats/utils/EnumHandler.java index c311f25..b44953d 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/utils/EnumHandler.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/utils/EnumHandler.java @@ -21,21 +21,36 @@ import java.util.stream.Stream; */ public final class EnumHandler { + private static volatile EnumHandler instance; private static List blockNames; private static List itemNames; private static List statNames; private static List subStatNames; - public EnumHandler() { + private EnumHandler() { prepareLists(); } + public static EnumHandler getInstance() { + EnumHandler localVar = instance; + if (localVar != null) { + return localVar; + } + + synchronized (EnumHandler.class) { + if (instance == null) { + instance = new EnumHandler(); + } + return instance; + } + } + /** * Returns all block-names in lowercase. * * @return the List */ - public List getBlockNames() { + public List getAllBlockNames() { return blockNames; } @@ -44,7 +59,7 @@ public final class EnumHandler { * * @return the List */ - public List getItemNames() { + public List getAllItemNames() { return itemNames; } @@ -53,7 +68,7 @@ public final class EnumHandler { * * @return the List */ - public List getStatNames() { + public List getAllStatNames() { return statNames; } @@ -64,7 +79,7 @@ public final class EnumHandler { * @return Material enum constant (uppercase), or null if none * can be found */ - public static @Nullable Material getItemEnum(String itemName) { + public @Nullable Material getItemEnum(String itemName) { if (itemName == null) return null; Material item = Material.matchMaterial(itemName); @@ -78,7 +93,7 @@ public final class EnumHandler { * @return EntityType enum constant (uppercase), or null if none * can be found */ - public static @Nullable EntityType getEntityEnum(String entityName) { + public @Nullable EntityType getEntityEnum(String entityName) { try { return EntityType.valueOf(entityName.toUpperCase()); } @@ -94,7 +109,7 @@ public final class EnumHandler { * @return Material enum constant (uppercase), or null if none * can be found */ - public static @Nullable Material getBlockEnum(String materialName) { + public @Nullable Material getBlockEnum(String materialName) { if (materialName == null) return null; Material block = Material.matchMaterial(materialName); @@ -107,7 +122,7 @@ public final class EnumHandler { * @param statName String (case-insensitive) * @return the Statistic enum constant, or null */ - public static @Nullable Statistic getStatEnum(@NotNull String statName) { + public @Nullable Statistic getStatEnum(@NotNull String statName) { try { return Statistic.valueOf(statName.toUpperCase()); } @@ -133,7 +148,7 @@ public final class EnumHandler { * @param statName the String to check (case-insensitive) * @return true if this String is a Statistic of Type.Entity */ - public boolean isEntityStatistic(String statName) { + public boolean isEntityStatistic(@NotNull String statName) { return statName.equalsIgnoreCase(Statistic.ENTITY_KILLED_BY.toString()) || statName.equalsIgnoreCase(Statistic.KILL_ENTITY.toString()); } @@ -157,7 +172,7 @@ public final class EnumHandler { * @return "block", "entity", "item", or "sub-statistic" if the * provided Type is null. */ - public static String getSubStatTypeName(Statistic.Type statType) { + public String getSubStatTypeName(Statistic.Type statType) { String subStat = "sub-statistic"; if (statType == null) return subStat; switch (statType) { diff --git a/src/main/java/com/artemis/the/gr8/playerstats/utils/OfflinePlayerHandler.java b/src/main/java/com/artemis/the/gr8/playerstats/utils/OfflinePlayerHandler.java index 821b49e..177898f 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/utils/OfflinePlayerHandler.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/utils/OfflinePlayerHandler.java @@ -1,10 +1,11 @@ package com.artemis.the.gr8.playerstats.utils; import com.artemis.the.gr8.playerstats.config.ConfigHandler; -import com.artemis.the.gr8.playerstats.reload.PlayerLoadAction; +import com.artemis.the.gr8.playerstats.multithreading.ThreadManager; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.configuration.file.FileConfiguration; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import java.util.*; @@ -21,31 +22,47 @@ import java.util.function.Predicate; */ public final class OfflinePlayerHandler extends FileHandler { - private static ConfigHandler config; + private static volatile OfflinePlayerHandler instance; + private final ConfigHandler config; private static FileConfiguration excludedPlayers; - private ConcurrentHashMap offlinePlayerUUIDs; - private ArrayList playerNames; + private static ConcurrentHashMap offlinePlayerUUIDs; - public OfflinePlayerHandler(ConfigHandler configHandler) { + private OfflinePlayerHandler() { super("excluded_players.yml"); + config = ConfigHandler.getInstance(); + excludedPlayers = super.getFileConfiguration(); - config = configHandler; loadOfflinePlayers(); } + public static OfflinePlayerHandler getInstance() { + OfflinePlayerHandler localVar = instance; + if (localVar != null) { + return localVar; + } + + synchronized (OfflinePlayerHandler.class) { + if (instance == null) { + instance = new OfflinePlayerHandler(); + } + return instance; + } + } + @Override public void reload() { super.reload(); excludedPlayers = super.getFileConfiguration(); + loadOfflinePlayers(); } /** - * Checks if a given playerName is on the private HashMap of players - * that should be included in statistic calculations. + * Checks if a given player is currently + * included for /statistic lookups. * * @param playerName String (case-sensitive) - * @return true if this Player should be included in calculations + * @return true if this player is included */ public boolean isRelevantPlayer(String playerName) { return offlinePlayerUUIDs.containsKey(playerName); @@ -55,22 +72,20 @@ public final class OfflinePlayerHandler extends FileHandler { super.addValueToListInFile("excluded", uniqueID); } - public static boolean isExcluded(UUID uniqueID) { + public boolean isExcluded(UUID uniqueID) { List excluded = excludedPlayers.getList("excluded"); if (excluded == null) { return false; } - for (Object obj : excluded) { - if (obj.equals(uniqueID)) { - return true; - } - } - return false; + + return excluded.stream() + .filter(Objects::nonNull) + .anyMatch(obj -> obj.equals(uniqueID)); } /** - * Gets the number of OfflinePlayers that are included in - * statistic calculations. + * Gets the number of OfflinePlayers that are + * currently included in statistic calculations. * * @return the number of included OfflinePlayers */ @@ -84,8 +99,9 @@ public final class OfflinePlayerHandler extends FileHandler { * * @return the ArrayList */ - public ArrayList getOfflinePlayerNames() { - return playerNames; + @Contract(" -> new") + public @NotNull ArrayList getOfflinePlayerNames() { + return Collections.list(offlinePlayerUUIDs.keys()); } /** @@ -127,12 +143,9 @@ public final class OfflinePlayerHandler extends FileHandler { int size = offlinePlayerUUIDs != null ? offlinePlayerUUIDs.size() : 16; offlinePlayerUUIDs = new ConcurrentHashMap<>(size); - PlayerLoadAction task = new PlayerLoadAction(offlinePlayers, config.getLastPlayedLimit(), offlinePlayerUUIDs); - MyLogger.actionCreated(offlinePlayers != null ? offlinePlayers.length : 0); - ForkJoinPool.commonPool().invoke(task); - MyLogger.actionFinished(); + ForkJoinPool.commonPool().invoke(ThreadManager.getPlayerLoadAction(offlinePlayers, offlinePlayerUUIDs)); - playerNames = Collections.list(offlinePlayerUUIDs.keys()); + MyLogger.actionFinished(); MyLogger.logLowLevelTask(("Loaded " + offlinePlayerUUIDs.size() + " offline players"), time); }); } From da49c46539979655839a163e83be9d64925151e9 Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Sun, 23 Oct 2022 17:37:38 +0200 Subject: [PATCH 19/43] Worked on transforming playerNames into UUIDs and vice versa for the ExcludeCommand (#88) --- .../com/artemis/the/gr8/playerstats/Main.java | 7 ++-- .../playerstats/commands/ExcludeCommand.java | 24 +++++++++++++ .../playerstats/commands/ReloadCommand.java | 4 +-- .../playerstats/commands/ShareCommand.java | 10 +++--- .../gr8/playerstats/commands/StatCommand.java | 2 +- .../playerstats/enums/StandardMessage.java | 2 +- .../gr8/playerstats/msg/OutputManager.java | 1 + .../{ => msgutils}/FormattingFunction.java | 2 +- .../gr8/playerstats/share/ShareManager.java | 19 +++++++++-- .../playerstats/statistic/RequestManager.java | 12 +++---- .../gr8/playerstats/statistic/StatResult.java | 2 +- .../gr8/playerstats/utils/FileHandler.java | 34 ++++++++++++------- .../utils/OfflinePlayerHandler.java | 28 ++++++++++----- src/main/resources/excluded_players.yml | 3 ++ 14 files changed, 106 insertions(+), 44 deletions(-) rename src/main/java/com/artemis/the/gr8/playerstats/msg/{ => msgutils}/FormattingFunction.java (94%) diff --git a/src/main/java/com/artemis/the/gr8/playerstats/Main.java b/src/main/java/com/artemis/the/gr8/playerstats/Main.java index 5361ad3..0df25dd 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/Main.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/Main.java @@ -106,11 +106,10 @@ public final class Main extends JavaPlugin implements PlayerStats { config = ConfigHandler.getInstance(); languageKeyHandler = LanguageKeyHandler.getInstance(); offlinePlayerHandler = OfflinePlayerHandler.getInstance(); + shareManager = ShareManager.getInstance(); outputManager = new OutputManager(adventure); - shareManager = new ShareManager(); - - requestManager = new RequestManager(outputManager, shareManager); + requestManager = new RequestManager(outputManager); threadManager = new ThreadManager(this, outputManager); } @@ -138,7 +137,7 @@ public final class Main extends JavaPlugin implements PlayerStats { } PluginCommand sharecmd = this.getCommand("statisticshare"); if (sharecmd != null) { - sharecmd.setExecutor(new ShareCommand(shareManager, outputManager)); + sharecmd.setExecutor(new ShareCommand(outputManager)); } } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/ExcludeCommand.java b/src/main/java/com/artemis/the/gr8/playerstats/commands/ExcludeCommand.java index 85ac5e2..22ad05b 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/ExcludeCommand.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/commands/ExcludeCommand.java @@ -1,12 +1,16 @@ package com.artemis.the.gr8.playerstats.commands; +import com.artemis.the.gr8.playerstats.utils.MyLogger; import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; +import org.bukkit.OfflinePlayer; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.jetbrains.annotations.NotNull; +import java.util.List; + public final class ExcludeCommand implements CommandExecutor { private final OfflinePlayerHandler offlinePlayerHandler; @@ -17,7 +21,27 @@ public final class ExcludeCommand implements CommandExecutor { @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { + if (args.length == 1 && args[0].equalsIgnoreCase("list")) { + List excludedPlayers = offlinePlayerHandler.getListOfExcludedPlayerNames(); + for (String player : excludedPlayers) { + MyLogger.logLowLevelMsg(player); + } + } + //this is going to return false for all UUIDs in file at boot-up - that's an issue + else if (args.length >= 2 && offlinePlayerHandler.isLoadedPlayer(args[1])) { + String playerName = args[1]; + OfflinePlayer player = offlinePlayerHandler.getOfflinePlayer(playerName); + + switch (args[0]) { + case "add" -> offlinePlayerHandler.addPlayerToExcludeList(player.getUniqueId()); + case "remove" -> offlinePlayerHandler.removePlayerFromExcludeList(player.getUniqueId()); + case "info" -> { + boolean isExcluded = offlinePlayerHandler.isExcluded(player.getUniqueId()); + MyLogger.logLowLevelMsg(player.getName() + " is excluded: " + isExcluded); + } + } + } return false; } } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/ReloadCommand.java b/src/main/java/com/artemis/the/gr8/playerstats/commands/ReloadCommand.java index 18fbfbd..4f2d869 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/ReloadCommand.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/commands/ReloadCommand.java @@ -11,8 +11,8 @@ public final class ReloadCommand implements CommandExecutor { private static ThreadManager threadManager; - public ReloadCommand(ThreadManager t) { - threadManager = t; + public ReloadCommand(ThreadManager threadManager) { + ReloadCommand.threadManager = threadManager; } @Override diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/ShareCommand.java b/src/main/java/com/artemis/the/gr8/playerstats/commands/ShareCommand.java index b60e7c8..6b09b1a 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/ShareCommand.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/commands/ShareCommand.java @@ -12,17 +12,17 @@ import org.jetbrains.annotations.NotNull; public final class ShareCommand implements CommandExecutor { - private static ShareManager shareManager; private static OutputManager outputManager; + private static ShareManager shareManager; - public ShareCommand(ShareManager s, OutputManager m) { - shareManager = s; - outputManager = m; + public ShareCommand(OutputManager outputManager) { + ShareCommand.outputManager = outputManager; + shareManager = ShareManager.getInstance(); } @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String label, @NotNull String[] args) { - if (args.length == 1 && ShareManager.isEnabled()) { + if (args.length == 1 && shareManager.isEnabled()) { int shareCode; try { shareCode = Integer.parseInt(args[0]); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java b/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java index 499abd1..ae6a580 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java @@ -243,7 +243,7 @@ public final class StatCommand implements CommandExecutor { OfflinePlayerHandler offlinePlayerHandler = OfflinePlayerHandler.getInstance(); for (String arg : args) { - if (offlinePlayerHandler.isRelevantPlayer(arg)) { + if (offlinePlayerHandler.isLoadedPlayer(arg)) { return arg; } } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/enums/StandardMessage.java b/src/main/java/com/artemis/the/gr8/playerstats/enums/StandardMessage.java index a7cf69b..46c2360 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/enums/StandardMessage.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/enums/StandardMessage.java @@ -14,5 +14,5 @@ public enum StandardMessage { STILL_ON_SHARE_COOLDOWN, RESULTS_ALREADY_SHARED, STAT_RESULTS_TOO_OLD, - UNKNOWN_ERROR, + UNKNOWN_ERROR } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java index e0a60e4..3210dff 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java @@ -5,6 +5,7 @@ import com.artemis.the.gr8.playerstats.config.ConfigHandler; import com.artemis.the.gr8.playerstats.enums.StandardMessage; import com.artemis.the.gr8.playerstats.msg.components.BukkitConsoleComponentFactory; import com.artemis.the.gr8.playerstats.msg.components.PrideComponentFactory; +import com.artemis.the.gr8.playerstats.msg.msgutils.FormattingFunction; import com.artemis.the.gr8.playerstats.msg.msgutils.LanguageKeyHandler; import com.artemis.the.gr8.playerstats.statistic.StatRequest; import net.kyori.adventure.platform.bukkit.BukkitAudiences; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/FormattingFunction.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/FormattingFunction.java similarity index 94% rename from src/main/java/com/artemis/the/gr8/playerstats/msg/FormattingFunction.java rename to src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/FormattingFunction.java index 5f8a0e4..c231ef9 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/FormattingFunction.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/FormattingFunction.java @@ -1,4 +1,4 @@ -package com.artemis.the.gr8.playerstats.msg; +package com.artemis.the.gr8.playerstats.msg.msgutils; import net.kyori.adventure.text.TextComponent; import org.bukkit.command.CommandSender; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/share/ShareManager.java b/src/main/java/com/artemis/the/gr8/playerstats/share/ShareManager.java index 20a9a69..a2eb460 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/share/ShareManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/share/ShareManager.java @@ -25,6 +25,7 @@ import static java.time.temporal.ChronoUnit.SECONDS; */ public final class ShareManager { + private static volatile ShareManager instance; private static boolean isEnabled; private int waitingTime; @@ -33,11 +34,25 @@ public final class ShareManager { private ConcurrentHashMap shareTimeStamp; private ArrayBlockingQueue sharedResults; - public ShareManager() { + private ShareManager() { updateSettings(); } - public static boolean isEnabled() { + public static ShareManager getInstance() { + ShareManager localVar = instance; + if (localVar != null) { + return localVar; + } + + synchronized (ShareManager.class) { + if (instance == null) { + instance = new ShareManager(); + } + return instance; + } + } + + public boolean isEnabled() { return isEnabled; } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/RequestManager.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/RequestManager.java index b604c8c..c70e88f 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/RequestManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/RequestManager.java @@ -2,7 +2,7 @@ package com.artemis.the.gr8.playerstats.statistic; import com.artemis.the.gr8.playerstats.api.RequestGenerator; import com.artemis.the.gr8.playerstats.api.StatManager; -import com.artemis.the.gr8.playerstats.msg.FormattingFunction; +import com.artemis.the.gr8.playerstats.msg.msgutils.FormattingFunction; import com.artemis.the.gr8.playerstats.msg.OutputManager; import com.artemis.the.gr8.playerstats.multithreading.ThreadManager; import com.artemis.the.gr8.playerstats.share.ShareManager; @@ -28,9 +28,9 @@ public final class RequestManager implements StatManager { private static RequestProcessor processor; private final OfflinePlayerHandler offlinePlayerHandler; - public RequestManager(OutputManager outputManager, ShareManager shareManager) { - processor = new RequestProcessor(outputManager, shareManager); + public RequestManager(OutputManager outputManager) { offlinePlayerHandler = OfflinePlayerHandler.getInstance(); + processor = new RequestProcessor(outputManager); } public static StatResult execute(@NotNull StatRequest request) { @@ -82,9 +82,9 @@ public final class RequestManager implements StatManager { private static OutputManager outputManager; private static ShareManager shareManager; - public RequestProcessor(OutputManager outputManager, ShareManager shareManager) { + public RequestProcessor(OutputManager outputManager) { RequestProcessor.outputManager = outputManager; - RequestProcessor.shareManager = shareManager; + RequestProcessor.shareManager = ShareManager.getInstance(); } public @NotNull StatResult processPlayerRequest(StatRequest.Settings requestSettings) { @@ -149,7 +149,7 @@ public final class RequestManager implements StatManager { private boolean outputShouldBeStored(CommandSender sender) { return !(sender instanceof ConsoleCommandSender) && - ShareManager.isEnabled() && + shareManager.isEnabled() && shareManager.senderHasPermission(sender); } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatResult.java b/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatResult.java index 12cdfc0..fd2b122 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatResult.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatResult.java @@ -33,7 +33,7 @@ import net.kyori.adventure.text.TextComponent; * and use the BukkitAudiences object can be found on * Adventure's website. * - *

    You can also use the provided {@link #formattedString ()} method to get the + *

    You can also use the provided {@link #formattedString()} method to get the * same information in String-format. Don't use Adventure's #content() * or #toString() methods on the Components - those won't get the actual * message. And finally, if you want the results to be formatted differently, diff --git a/src/main/java/com/artemis/the/gr8/playerstats/utils/FileHandler.java b/src/main/java/com/artemis/the/gr8/playerstats/utils/FileHandler.java index 7acdbab..ce42e4a 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/utils/FileHandler.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/utils/FileHandler.java @@ -9,9 +9,10 @@ import org.jetbrains.annotations.NotNull; import java.io.File; import java.io.IOException; -import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; public abstract class FileHandler { @@ -48,7 +49,7 @@ public abstract class FileHandler { } public void addValuesToFile(@NotNull Map keyValuePairs) { - keyValuePairs.forEach(this::addValue); + keyValuePairs.forEach(this::setValue); save(); updateFile(); } @@ -58,23 +59,30 @@ public abstract class FileHandler { * (or expanded if it already exists) * @param value the value(s) to expand the List with */ - public void addValueToListInFile(@NotNull String key, @NotNull Object value) { - List currentValues = fileConfiguration.getList(key); + public void addEntryToListInFile(@NotNull String key, @NotNull String value) { + List existingList = fileConfiguration.getStringList(key); - List updatedValues; - if (currentValues != null) { - updatedValues = new ArrayList<>(currentValues); - } else { - updatedValues = new ArrayList<>(); - } - updatedValues.add(value); + List updatedList = existingList.stream() + .filter(Objects::nonNull) + .collect(Collectors.toList()); + updatedList.add(value); - addValue(key, updatedValues); + setValue(key, updatedList); save(); updateFile(); } - private void addValue(String key, Object value) { + public void removeEntryFromListInFile(@NotNull String key, @NotNull String value) { + List currentValues = fileConfiguration.getStringList(key); + + if (currentValues.remove(value)) { + setValue(key, currentValues); + save(); + updateFile(); + } + } + + private void setValue(String key, Object value) { fileConfiguration.set(key, value); } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/utils/OfflinePlayerHandler.java b/src/main/java/com/artemis/the/gr8/playerstats/utils/OfflinePlayerHandler.java index 177898f..b5cfaca 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/utils/OfflinePlayerHandler.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/utils/OfflinePlayerHandler.java @@ -13,6 +13,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; import java.util.concurrent.ForkJoinPool; import java.util.function.Predicate; +import java.util.stream.Collectors; /** * A utility class that deals with OfflinePlayers. It stores a list @@ -64,23 +65,34 @@ public final class OfflinePlayerHandler extends FileHandler { * @param playerName String (case-sensitive) * @return true if this player is included */ - public boolean isRelevantPlayer(String playerName) { + public boolean isLoadedPlayer(String playerName) { return offlinePlayerUUIDs.containsKey(playerName); } - public void excludePlayer(UUID uniqueID) { - super.addValueToListInFile("excluded", uniqueID); + public void addPlayerToExcludeList(UUID uniqueID) { + super.addEntryToListInFile("excluded", uniqueID.toString()); + } + + public void removePlayerFromExcludeList(UUID uniqueID) { + super.removeEntryFromListInFile("excluded", uniqueID.toString()); + } + + public List getListOfExcludedPlayerNames() { + List excludedUUIDs = excludedPlayers.getStringList("excluded"); + return excludedUUIDs.stream() + .map(UUID::fromString) + .map(Bukkit::getOfflinePlayer) + .map(OfflinePlayer::getName) + .collect(Collectors.toList()); } public boolean isExcluded(UUID uniqueID) { - List excluded = excludedPlayers.getList("excluded"); - if (excluded == null) { - return false; - } + List excluded = excludedPlayers.getStringList("excluded"); return excluded.stream() .filter(Objects::nonNull) - .anyMatch(obj -> obj.equals(uniqueID)); + .map(UUID::fromString) + .anyMatch(uuid -> uuid.equals(uniqueID)); } /** diff --git a/src/main/resources/excluded_players.yml b/src/main/resources/excluded_players.yml index 05cfef6..1dc7bc9 100644 --- a/src/main/resources/excluded_players.yml +++ b/src/main/resources/excluded_players.yml @@ -6,5 +6,8 @@ # This can be used for more fine-grained filtering, for example to exclude alt accounts. # For more general filtering settings, see the config.yml (section 'General') +# Format: +# - playerUUID-1 +# - playerUUID-2 excluded: - \ No newline at end of file From f69367cb31e1233ae2e5274704f9c4091034850d Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Wed, 26 Oct 2022 12:59:10 +0200 Subject: [PATCH 20/43] The exclude function now works completely, the only thing left is give fancier feedback (#88) --- .../com/artemis/the/gr8/playerstats/Main.java | 2 +- .../playerstats/commands/ExcludeCommand.java | 43 ++++-- .../gr8/playerstats/commands/StatCommand.java | 6 +- .../playerstats/commands/TabCompleter.java | 24 ++- .../gr8/playerstats/config/ConfigHandler.java | 2 +- .../msg/components/PrideComponentFactory.java | 5 +- .../multithreading/PlayerLoadAction.java | 2 +- .../multithreading/ThreadManager.java | 2 +- .../gr8/playerstats/utils/FileHandler.java | 8 +- .../utils/OfflinePlayerHandler.java | 140 ++++++++++-------- 10 files changed, 135 insertions(+), 99 deletions(-) diff --git a/src/main/java/com/artemis/the/gr8/playerstats/Main.java b/src/main/java/com/artemis/the/gr8/playerstats/Main.java index 0df25dd..ccdb8b3 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/Main.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/Main.java @@ -127,7 +127,7 @@ public final class Main extends JavaPlugin implements PlayerStats { } PluginCommand excludecmd = this.getCommand("statisticexclude"); if (excludecmd != null) { - excludecmd.setExecutor(new ExcludeCommand()); + excludecmd.setExecutor(new ExcludeCommand(outputManager)); excludecmd.setTabCompleter(tabCompleter); } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/ExcludeCommand.java b/src/main/java/com/artemis/the/gr8/playerstats/commands/ExcludeCommand.java index 22ad05b..c2980fd 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/ExcludeCommand.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/commands/ExcludeCommand.java @@ -1,44 +1,55 @@ package com.artemis.the.gr8.playerstats.commands; -import com.artemis.the.gr8.playerstats.utils.MyLogger; +import com.artemis.the.gr8.playerstats.msg.OutputManager; import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; -import org.bukkit.OfflinePlayer; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.jetbrains.annotations.NotNull; -import java.util.List; +import java.util.ArrayList; public final class ExcludeCommand implements CommandExecutor { + private static OutputManager outputManager; private final OfflinePlayerHandler offlinePlayerHandler; - public ExcludeCommand() { + public ExcludeCommand(OutputManager outputManager) { + ExcludeCommand.outputManager = outputManager; this.offlinePlayerHandler = OfflinePlayerHandler.getInstance(); } @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { if (args.length == 1 && args[0].equalsIgnoreCase("list")) { - List excludedPlayers = offlinePlayerHandler.getListOfExcludedPlayerNames(); - - for (String player : excludedPlayers) { - MyLogger.logLowLevelMsg(player); - } + ArrayList excludedPlayers = offlinePlayerHandler.getExcludedPlayerNames(); + sender.sendMessage(String.valueOf(excludedPlayers)); + return true; } //this is going to return false for all UUIDs in file at boot-up - that's an issue - else if (args.length >= 2 && offlinePlayerHandler.isLoadedPlayer(args[1])) { - String playerName = args[1]; - OfflinePlayer player = offlinePlayerHandler.getOfflinePlayer(playerName); + else if (args.length >= 2) { + String playerName = args[1]; switch (args[0]) { - case "add" -> offlinePlayerHandler.addPlayerToExcludeList(player.getUniqueId()); - case "remove" -> offlinePlayerHandler.removePlayerFromExcludeList(player.getUniqueId()); + case "add" -> { + if (offlinePlayerHandler.isLoadedPlayer(playerName)) { + offlinePlayerHandler.addLoadedPlayerToExcludeList(playerName); + sender.sendMessage("Excluded " + playerName + "!"); + return true; + } + } + case "remove" -> { + if (offlinePlayerHandler.isExcludedPlayer(playerName)) { + offlinePlayerHandler.addExcludedPlayerToLoadedList(playerName); + sender.sendMessage("Removed " + playerName + " from the exclude list again!"); + return true; + } + } case "info" -> { - boolean isExcluded = offlinePlayerHandler.isExcluded(player.getUniqueId()); - MyLogger.logLowLevelMsg(player.getName() + " is excluded: " + isExcluded); + boolean isExcluded = offlinePlayerHandler.isExcludedPlayer(playerName); + sender.sendMessage(playerName+ " is excluded: " + isExcluded); + return true; } } } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java b/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java index ae6a580..d09879e 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java @@ -45,11 +45,13 @@ public final class StatCommand implements CommandExecutor { @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { - if (args.length == 0 || args[0].equalsIgnoreCase("help")) { //in case of less than 1 argument or "help", display the help message + if (args.length == 0 || + args[0].equalsIgnoreCase("help") || + args[0].equalsIgnoreCase("info")) { outputManager.sendHelp(sender); } else if (args[0].equalsIgnoreCase("examples") || - args[0].equalsIgnoreCase("example")) { //in case of "statistic examples", show examples + args[0].equalsIgnoreCase("example")) { outputManager.sendExamples(sender); } else { diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/TabCompleter.java b/src/main/java/com/artemis/the/gr8/playerstats/commands/TabCompleter.java index b6ebba3..836688e 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/TabCompleter.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/commands/TabCompleter.java @@ -7,7 +7,6 @@ import org.bukkit.Statistic; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.entity.EntityType; -import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -29,14 +28,9 @@ public final class TabCompleter implements org.bukkit.command.TabCompleter { public TabCompleter() { offlinePlayerHandler = OfflinePlayerHandler.getInstance(); enumHandler = EnumHandler.getInstance(); - prepareLists(); } - //args[0] = statistic (length = 1) - //args[1] = target (player/server/top) OR sub-stat (block/item/entity) (length = 2) - //args[2] = playerName OR target (player/server/top) (length = 3) - //args[3] = playerName (length = 4) @Override public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { if (command.getName().equalsIgnoreCase("statistic")) { @@ -59,8 +53,13 @@ public final class TabCompleter implements org.bukkit.command.TabCompleter { } else if (args.length == 2) { tabSuggestions = switch (args[0]) { - case "add" -> offlinePlayerHandler.getOfflinePlayerNames(); - case "remove" -> removablePlayerNames(); + case "add" -> offlinePlayerHandler.getLoadedOfflinePlayerNames(); + case "remove" -> offlinePlayerHandler.getExcludedPlayerNames(); + case "info" -> { + ArrayList loadedPlayers = offlinePlayerHandler.getLoadedOfflinePlayerNames(); + loadedPlayers.addAll(offlinePlayerHandler.getExcludedPlayerNames()); + yield loadedPlayers; + } default -> tabSuggestions; }; } @@ -91,7 +90,7 @@ public final class TabCompleter implements org.bukkit.command.TabCompleter { tabSuggestions = statCommandTargets; //if arg before "player" was entity-sub-stat, suggest targets } else { //otherwise "player" is the target: suggest playerNames - tabSuggestions = offlinePlayerHandler.getOfflinePlayerNames(); + tabSuggestions = offlinePlayerHandler.getLoadedOfflinePlayerNames(); } } @@ -117,6 +116,7 @@ public final class TabCompleter implements org.bukkit.command.TabCompleter { private @NotNull List firstStatCommandArgSuggestions() { List suggestions = enumHandler.getAllStatNames(); suggestions.add("examples"); + suggestions.add("info"); suggestions.add("help"); return suggestions; } @@ -142,11 +142,6 @@ public final class TabCompleter implements org.bukkit.command.TabCompleter { } } - @Contract(pure = true) - private @Nullable List removablePlayerNames() { - return statCommandTargets; - } - private void prepareLists() { statCommandTargets = new ArrayList<>(); statCommandTargets.add("top"); @@ -158,6 +153,7 @@ public final class TabCompleter implements org.bukkit.command.TabCompleter { excludeCommandOptions.add("add"); excludeCommandOptions.add("list"); excludeCommandOptions.add("remove"); + excludeCommandOptions.add("info"); //breaking an item means running its durability negative itemsThatCanBreak = Arrays.stream(Material.values()) diff --git a/src/main/java/com/artemis/the/gr8/playerstats/config/ConfigHandler.java b/src/main/java/com/artemis/the/gr8/playerstats/config/ConfigHandler.java index 7e875c0..6da522d 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/config/ConfigHandler.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/config/ConfigHandler.java @@ -63,7 +63,7 @@ public final class ConfigHandler extends FileHandler { Map defaultValues = defaultValueGetter.getValuesToAdjust(); defaultValues.put("config-version", configVersion); - super.addValuesToFile(defaultValues); + super.addValues(defaultValues); reload(); MyLogger.logLowLevelMsg("Your config has been updated to version " + configVersion + diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/PrideComponentFactory.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/PrideComponentFactory.java index dab0dde..c43322c 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/PrideComponentFactory.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/PrideComponentFactory.java @@ -6,6 +6,8 @@ import com.artemis.the.gr8.playerstats.enums.PluginColor; import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.format.TextColor; import net.kyori.adventure.text.minimessage.MiniMessage; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; import java.util.Random; @@ -85,7 +87,8 @@ public class PrideComponentFactory extends ComponentFactory { .build(); } - private TextComponent backwardsPluginPrefixComponent() { + @Contract(" -> new") + private @NotNull TextComponent backwardsPluginPrefixComponent() { return text() .append(MiniMessage.miniMessage() .deserialize("<#631ae6>[" + diff --git a/src/main/java/com/artemis/the/gr8/playerstats/multithreading/PlayerLoadAction.java b/src/main/java/com/artemis/the/gr8/playerstats/multithreading/PlayerLoadAction.java index 7ba037b..0d9e7f1 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/multithreading/PlayerLoadAction.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/multithreading/PlayerLoadAction.java @@ -73,7 +73,7 @@ final class PlayerLoadAction extends RecursiveAction { String playerName = player.getName(); MyLogger.actionRunning(Thread.currentThread().getName()); if (playerName != null && - !offlinePlayerHandler.isExcluded(player.getUniqueId()) && + !offlinePlayerHandler.isExcludedPlayer(player.getUniqueId()) && UnixTimeHandler.hasPlayedSince(lastPlayedLimit, player.getLastPlayed())) { offlinePlayerUUIDs.put(playerName, player.getUniqueId()); } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/multithreading/ThreadManager.java b/src/main/java/com/artemis/the/gr8/playerstats/multithreading/ThreadManager.java index 417e08e..377b071 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/multithreading/ThreadManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/multithreading/ThreadManager.java @@ -58,7 +58,7 @@ public final class ThreadManager { public static @NotNull StatAction getStatAction(StatRequest.Settings requestSettings) { OfflinePlayerHandler offlinePlayerHandler = OfflinePlayerHandler.getInstance(); - ImmutableList relevantPlayerNames = ImmutableList.copyOf(offlinePlayerHandler.getOfflinePlayerNames()); + ImmutableList relevantPlayerNames = ImmutableList.copyOf(offlinePlayerHandler.getLoadedOfflinePlayerNames()); ConcurrentHashMap resultingStatNumbers = new ConcurrentHashMap<>(relevantPlayerNames.size()); StatAction task = new StatAction(relevantPlayerNames, requestSettings, resultingStatNumbers); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/utils/FileHandler.java b/src/main/java/com/artemis/the/gr8/playerstats/utils/FileHandler.java index ce42e4a..24de82e 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/utils/FileHandler.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/utils/FileHandler.java @@ -25,7 +25,7 @@ public abstract class FileHandler { loadFile(); } - public void loadFile() { + private void loadFile() { JavaPlugin plugin = Main.getPluginInstance(); file = new File(plugin.getDataFolder(), fileName); @@ -48,7 +48,7 @@ public abstract class FileHandler { return fileConfiguration; } - public void addValuesToFile(@NotNull Map keyValuePairs) { + public void addValues(@NotNull Map keyValuePairs) { keyValuePairs.forEach(this::setValue); save(); updateFile(); @@ -59,7 +59,7 @@ public abstract class FileHandler { * (or expanded if it already exists) * @param value the value(s) to expand the List with */ - public void addEntryToListInFile(@NotNull String key, @NotNull String value) { + public void writeEntryToList(@NotNull String key, @NotNull String value) { List existingList = fileConfiguration.getStringList(key); List updatedList = existingList.stream() @@ -72,7 +72,7 @@ public abstract class FileHandler { updateFile(); } - public void removeEntryFromListInFile(@NotNull String key, @NotNull String value) { + public void removeEntryFromList(@NotNull String key, @NotNull String value) { List currentValues = fileConfiguration.getStringList(key); if (currentValues.remove(value)) { diff --git a/src/main/java/com/artemis/the/gr8/playerstats/utils/OfflinePlayerHandler.java b/src/main/java/com/artemis/the/gr8/playerstats/utils/OfflinePlayerHandler.java index b5cfaca..1dae341 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/utils/OfflinePlayerHandler.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/utils/OfflinePlayerHandler.java @@ -4,7 +4,6 @@ import com.artemis.the.gr8.playerstats.config.ConfigHandler; import com.artemis.the.gr8.playerstats.multithreading.ThreadManager; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; -import org.bukkit.configuration.file.FileConfiguration; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; @@ -13,7 +12,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; import java.util.concurrent.ForkJoinPool; import java.util.function.Predicate; -import java.util.stream.Collectors; /** * A utility class that deals with OfflinePlayers. It stores a list @@ -25,14 +23,13 @@ public final class OfflinePlayerHandler extends FileHandler { private static volatile OfflinePlayerHandler instance; private final ConfigHandler config; - private static FileConfiguration excludedPlayers; - private static ConcurrentHashMap offlinePlayerUUIDs; + private static ConcurrentHashMap includedPlayerUUIDs; + private static ConcurrentHashMap excludedPlayerUUIDs; private OfflinePlayerHandler() { super("excluded_players.yml"); config = ConfigHandler.getInstance(); - excludedPlayers = super.getFileConfiguration(); loadOfflinePlayers(); } @@ -53,8 +50,6 @@ public final class OfflinePlayerHandler extends FileHandler { @Override public void reload() { super.reload(); - excludedPlayers = super.getFileConfiguration(); - loadOfflinePlayers(); } @@ -66,43 +61,40 @@ public final class OfflinePlayerHandler extends FileHandler { * @return true if this player is included */ public boolean isLoadedPlayer(String playerName) { - return offlinePlayerUUIDs.containsKey(playerName); + return includedPlayerUUIDs.containsKey(playerName); } - public void addPlayerToExcludeList(UUID uniqueID) { - super.addEntryToListInFile("excluded", uniqueID.toString()); + public boolean isExcludedPlayer(String playerName) { + return excludedPlayerUUIDs.containsKey(playerName); } - public void removePlayerFromExcludeList(UUID uniqueID) { - super.removeEntryFromListInFile("excluded", uniqueID.toString()); + public boolean isExcludedPlayer(UUID uniqueID) { + return excludedPlayerUUIDs.containsValue(uniqueID); } - public List getListOfExcludedPlayerNames() { - List excludedUUIDs = excludedPlayers.getStringList("excluded"); - return excludedUUIDs.stream() - .map(UUID::fromString) - .map(Bukkit::getOfflinePlayer) - .map(OfflinePlayer::getName) - .collect(Collectors.toList()); + public void addLoadedPlayerToExcludeList(String playerName) throws IllegalArgumentException { + UUID uuid = includedPlayerUUIDs.get(playerName); + if (uuid == null) { + throw new IllegalArgumentException("This player is not loaded, and therefore cannot be excluded!"); + } + super.writeEntryToList("excluded", uuid.toString()); + includedPlayerUUIDs.remove(playerName); + excludedPlayerUUIDs.put(playerName, uuid); } - public boolean isExcluded(UUID uniqueID) { - List excluded = excludedPlayers.getStringList("excluded"); - - return excluded.stream() - .filter(Objects::nonNull) - .map(UUID::fromString) - .anyMatch(uuid -> uuid.equals(uniqueID)); + public void addExcludedPlayerToLoadedList(String playerName) { + UUID uuid = excludedPlayerUUIDs.get(playerName); + if (uuid == null) { + throw new IllegalArgumentException("This player is not excluded, and therefore cannot be un-excluded!"); + } + super.removeEntryFromList("excluded", uuid.toString()); + excludedPlayerUUIDs.remove(playerName); + includedPlayerUUIDs.put(playerName, uuid); } - /** - * Gets the number of OfflinePlayers that are - * currently included in statistic calculations. - * - * @return the number of included OfflinePlayers - */ - public int getOfflinePlayerCount() { - return offlinePlayerUUIDs.size(); + @Contract(" -> new") + public @NotNull ArrayList getExcludedPlayerNames() { + return Collections.list(excludedPlayerUUIDs.keys()); } /** @@ -112,8 +104,18 @@ public final class OfflinePlayerHandler extends FileHandler { * @return the ArrayList */ @Contract(" -> new") - public @NotNull ArrayList getOfflinePlayerNames() { - return Collections.list(offlinePlayerUUIDs.keys()); + public @NotNull ArrayList getLoadedOfflinePlayerNames() { + return Collections.list(includedPlayerUUIDs.keys()); + } + + /** + * Gets the number of OfflinePlayers that are + * currently included in statistic calculations. + * + * @return the number of included OfflinePlayers + */ + public int getOfflinePlayerCount() { + return includedPlayerUUIDs.size(); } /** @@ -126,8 +128,8 @@ public final class OfflinePlayerHandler extends FileHandler { * of players that should be included in statistic calculations */ public @NotNull OfflinePlayer getOfflinePlayer(String playerName) throws IllegalArgumentException { - if (offlinePlayerUUIDs.get(playerName) != null) { - return Bukkit.getOfflinePlayer(offlinePlayerUUIDs.get(playerName)); + if (includedPlayerUUIDs.get(playerName) != null) { + return Bukkit.getOfflinePlayer(includedPlayerUUIDs.get(playerName)); } else { MyLogger.logWarning("Cannot calculate statistics for player-name: " + playerName + @@ -139,29 +141,51 @@ public final class OfflinePlayerHandler extends FileHandler { private void loadOfflinePlayers() { Executors.newSingleThreadExecutor().execute(() -> { - long time = System.currentTimeMillis(); - - OfflinePlayer[] offlinePlayers; - if (config.whitelistOnly()) { - offlinePlayers = getWhitelistedPlayers(); - } - else if (config.excludeBanned()) { - offlinePlayers = getNonBannedPlayers(); - } - else { - offlinePlayers = Bukkit.getOfflinePlayers(); - } - - int size = offlinePlayerUUIDs != null ? offlinePlayerUUIDs.size() : 16; - offlinePlayerUUIDs = new ConcurrentHashMap<>(size); - - ForkJoinPool.commonPool().invoke(ThreadManager.getPlayerLoadAction(offlinePlayers, offlinePlayerUUIDs)); - - MyLogger.actionFinished(); - MyLogger.logLowLevelTask(("Loaded " + offlinePlayerUUIDs.size() + " offline players"), time); + loadExcludedPlayerNames(); + loadIncludedOfflinePlayers(); }); } + private void loadIncludedOfflinePlayers() { + long time = System.currentTimeMillis(); + + OfflinePlayer[] offlinePlayers; + if (config.whitelistOnly()) { + offlinePlayers = getWhitelistedPlayers(); + } else if (config.excludeBanned()) { + offlinePlayers = getNonBannedPlayers(); + } else { + offlinePlayers = Bukkit.getOfflinePlayers(); + } + + int size = includedPlayerUUIDs != null ? includedPlayerUUIDs.size() : 16; + includedPlayerUUIDs = new ConcurrentHashMap<>(size); + + ForkJoinPool.commonPool().invoke(ThreadManager.getPlayerLoadAction(offlinePlayers, includedPlayerUUIDs)); + + MyLogger.actionFinished(); + MyLogger.logLowLevelTask(("Loaded " + includedPlayerUUIDs.size() + " offline players"), time); + } + + private void loadExcludedPlayerNames() { + long time = System.currentTimeMillis(); + + excludedPlayerUUIDs = new ConcurrentHashMap<>(); + List excluded = super.getFileConfiguration().getStringList("excluded"); + excluded.stream() + .filter(Objects::nonNull) + .map(UUID::fromString) + .forEach(uuid -> { + OfflinePlayer player = Bukkit.getOfflinePlayer(uuid); + String playerName = player.getName(); + if (playerName != null) { + excludedPlayerUUIDs.put(playerName, uuid); + } + }); + + MyLogger.logLowLevelTask("Loaded " + excludedPlayerUUIDs.size() + " excluded players from file", time); + } + private OfflinePlayer[] getWhitelistedPlayers() { return Bukkit.getWhitelistedPlayers().toArray(OfflinePlayer[]::new); } From c7a6160cc8786c0566326aea93a996c489eeb744 Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Wed, 26 Oct 2022 21:20:22 +0200 Subject: [PATCH 21/43] Started working on feedback (#88, #51) --- .../playerstats/commands/ExcludeCommand.java | 3 +- .../gr8/playerstats/commands/StatCommand.java | 6 +- .../playerstats/enums/StandardMessage.java | 4 +- .../gr8/playerstats/msg/MessageBuilder.java | 82 ++++++++----------- .../gr8/playerstats/msg/OutputManager.java | 35 ++++---- .../msg/components/ComponentFactory.java | 10 ++- .../msg/components/HelpMessage.java | 2 +- .../multithreading/StatThread.java | 6 +- 8 files changed, 75 insertions(+), 73 deletions(-) diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/ExcludeCommand.java b/src/main/java/com/artemis/the/gr8/playerstats/commands/ExcludeCommand.java index c2980fd..f7242b2 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/ExcludeCommand.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/commands/ExcludeCommand.java @@ -47,8 +47,7 @@ public final class ExcludeCommand implements CommandExecutor { } } case "info" -> { - boolean isExcluded = offlinePlayerHandler.isExcludedPlayer(playerName); - sender.sendMessage(playerName+ " is excluded: " + isExcluded); + outputManager.sendExcludeInfo(sender); return true; } } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java b/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java index d09879e..9e921ac 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java @@ -91,10 +91,12 @@ public final class StatCommand implements CommandExecutor { } else { Statistic.Type type = processor.statistic.getType(); + String statType = enumHandler.getSubStatTypeName(type); + if (type != Statistic.Type.UNTYPED && processor.subStatName == null) { - outputManager.sendFeedbackMsgMissingSubStat(sender, type); + outputManager.sendFeedbackMsgMissingSubStat(sender, statType); } else { - outputManager.sendFeedbackMsgWrongSubStat(sender, type, processor.subStatName); + outputManager.sendFeedbackMsgWrongSubStat(sender, statType, processor.subStatName); } } } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/enums/StandardMessage.java b/src/main/java/com/artemis/the/gr8/playerstats/enums/StandardMessage.java index 46c2360..dd43f03 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/enums/StandardMessage.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/enums/StandardMessage.java @@ -10,9 +10,11 @@ public enum StandardMessage { STILL_RELOADING, MISSING_STAT_NAME, MISSING_PLAYER_NAME, + WAIT_A_MOMENT, + WAIT_A_MINUTE, REQUEST_ALREADY_RUNNING, STILL_ON_SHARE_COOLDOWN, RESULTS_ALREADY_SHARED, STAT_RESULTS_TOO_OLD, UNKNOWN_ERROR -} +} \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java index 5d7fb7d..4c7955e 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java @@ -113,65 +113,44 @@ public final class MessageBuilder implements StatFormatter { } public @NotNull TextComponent reloadedConfig() { - return componentFactory.pluginPrefix() - .append(space()) - .append(componentFactory.message().content("Config reloaded!")); + return composePluginMessage("Config reloaded!"); } public @NotNull TextComponent stillReloading() { - return componentFactory.pluginPrefix() - .append(space()) - .append(componentFactory.message().content( - "The plugin is (re)loading, your request will be processed when it is done!")); + return composePluginMessage("The plugin is (re)loading, your request will be processed when it is done!"); } - public @NotNull TextComponent waitAMoment(boolean longWait) { - String msg = longWait ? "Calculating statistics, this may take a minute..." : - "Calculating statistics, this may take a few moments..."; - return componentFactory.pluginPrefix() - .append(space()) - .append(componentFactory.message().content(msg)); + public @NotNull TextComponent waitAMinute() { + return composePluginMessage("Calculating statistics, this may take a minute..."); + } + + public @NotNull TextComponent waitAMoment() { + return composePluginMessage("Calculating statistics, this may take a few moments..."); } public @NotNull TextComponent missingStatName() { - return componentFactory.pluginPrefix() - .append(space()) - .append(componentFactory.message().content( - "Please provide a valid statistic name!")); + return composePluginMessage("Please provide a valid statistic name!"); } - public @NotNull TextComponent missingSubStatName(Statistic.Type statType) { - return componentFactory.pluginPrefix() - .append(space()) - .append(componentFactory.message().content( - "Please add a valid " + - EnumHandler.getInstance().getSubStatTypeName(statType) + - " to look up this statistic!")); + public @NotNull TextComponent missingSubStatName(String statType) { + return composePluginMessage("Please add a valid " + statType + " to look up this statistic!"); } public @NotNull TextComponent missingPlayerName() { - return componentFactory.pluginPrefix() - .append(space()) - .append(componentFactory.message().content( - "Please specify a valid player-name!")); + return composePluginMessage("Please specify a valid player-name!"); } - public @NotNull TextComponent wrongSubStatType(Statistic.Type statType, String subStatName) { + public @NotNull TextComponent wrongSubStatType(String statType, String subStatName) { return componentFactory.pluginPrefix() .append(space()) .append(componentFactory.messageAccent().content("\"" + subStatName + "\"")) .append(space()) .append(componentFactory.message().content( - "is not a valid " + - EnumHandler.getInstance().getSubStatTypeName(statType) + - "!")); + "is not a valid " + statType + "!")); } public @NotNull TextComponent requestAlreadyRunning() { - return componentFactory.pluginPrefix() - .append(space()) - .append(componentFactory.message().content( - "Please wait for your previous lookup to finish!")); + return composePluginMessage("Please wait for your previous lookup to finish!"); } public @NotNull TextComponent stillOnShareCoolDown() { @@ -189,24 +168,23 @@ public final class MessageBuilder implements StatFormatter { } public @NotNull TextComponent resultsAlreadyShared() { - return componentFactory.pluginPrefix() - .append(space()) - .append(componentFactory.message().content("You already shared these results!")); + return composePluginMessage("You already shared these results!"); } public @NotNull TextComponent statResultsTooOld() { - return componentFactory.pluginPrefix() - .append(space()) - .append(componentFactory.message().content( - "It has been too long since you looked up this statistic, please repeat the original command!")); + return composePluginMessage("It has been too long since you looked up " + + "this statistic, please repeat the original command!"); } public @NotNull TextComponent unknownError() { - return componentFactory.pluginPrefix() + return composePluginMessage("Something went wrong with your request, " + + "please try again or see /statistic for a usage explanation!"); + } + + private @NotNull TextComponent composePluginMessage(String content) { + return getPluginPrefix() .append(space()) - .append(componentFactory.message().content( - "Something went wrong with your request, " + - "please try again or see /statistic for a usage explanation!")); + .append(componentFactory.message().content(content)); } @Contract(" -> new") @@ -223,6 +201,16 @@ public final class MessageBuilder implements StatFormatter { } } + public @NotNull TextComponent excludeInfoMsg() { + return getPluginPrefixAsTitle() + .append(newline()) + .append(componentFactory.subTitle("The /statexclude command " + + "can be used to exclude individual players from /statistic lookups.") + .append(newline()) + .append(text("This means their results won't show up in top-10 results, " + + "and they won't be counted for the server total."))); + } + @Override public @NotNull TextComponent getStatTitle(Statistic statistic, @Nullable String subStatName) { return getTopStatTitleComponent(0, statistic, subStatName, null); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java index 3210dff..8b74d66 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java @@ -11,7 +11,6 @@ import com.artemis.the.gr8.playerstats.statistic.StatRequest; import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.text.TextComponent; import org.bukkit.Bukkit; -import org.bukkit.Statistic; import org.bukkit.command.CommandSender; import org.bukkit.command.ConsoleCommandSender; import org.jetbrains.annotations.NotNull; @@ -100,17 +99,12 @@ public final class OutputManager { } } - public void sendFeedbackMsgWaitAMoment(@NotNull CommandSender sender, boolean longWait) { - adventure.sender(sender).sendMessage(getMessageBuilder(sender) - .waitAMoment(longWait)); - } - - public void sendFeedbackMsgMissingSubStat(@NotNull CommandSender sender, Statistic.Type statType) { + public void sendFeedbackMsgMissingSubStat(@NotNull CommandSender sender, String statType) { adventure.sender(sender).sendMessage(getMessageBuilder(sender) .missingSubStatName(statType)); } - public void sendFeedbackMsgWrongSubStat(@NotNull CommandSender sender, Statistic.Type statType, @Nullable String subStatName) { + public void sendFeedbackMsgWrongSubStat(@NotNull CommandSender sender, String statType, @Nullable String subStatName) { if (subStatName == null) { sendFeedbackMsgMissingSubStat(sender, statType); } else { @@ -129,6 +123,11 @@ public final class OutputManager { .helpMsg()); } + public void sendExcludeInfo(@NotNull CommandSender sender) { + adventure.sender(sender).sendMessage(getMessageBuilder(sender) + .excludeInfoMsg()); + } + public void sendToAllPlayers(@NotNull TextComponent component) { adventure.players().sendMessage(component); } @@ -176,14 +175,16 @@ public final class OutputManager { private void prepareFunctions() { standardMessages = new EnumMap<>(StandardMessage.class); - standardMessages.put(RELOADED_CONFIG, (MessageBuilder::reloadedConfig)); - standardMessages.put(STILL_RELOADING, (MessageBuilder::stillReloading)); - standardMessages.put(MISSING_STAT_NAME, (MessageBuilder::missingStatName)); - standardMessages.put(MISSING_PLAYER_NAME, (MessageBuilder::missingPlayerName)); - standardMessages.put(REQUEST_ALREADY_RUNNING, (MessageBuilder::requestAlreadyRunning)); - standardMessages.put(STILL_ON_SHARE_COOLDOWN, (MessageBuilder::stillOnShareCoolDown)); - standardMessages.put(RESULTS_ALREADY_SHARED, (MessageBuilder::resultsAlreadyShared)); - standardMessages.put(STAT_RESULTS_TOO_OLD, (MessageBuilder::statResultsTooOld)); - standardMessages.put(UNKNOWN_ERROR, (MessageBuilder::unknownError)); + standardMessages.put(RELOADED_CONFIG, MessageBuilder::reloadedConfig); + standardMessages.put(STILL_RELOADING, MessageBuilder::stillReloading); + standardMessages.put(MISSING_STAT_NAME, MessageBuilder::missingStatName); + standardMessages.put(MISSING_PLAYER_NAME, MessageBuilder::missingPlayerName); + standardMessages.put(WAIT_A_MOMENT, MessageBuilder::waitAMoment); + standardMessages.put(WAIT_A_MINUTE, MessageBuilder::waitAMinute); + standardMessages.put(REQUEST_ALREADY_RUNNING, MessageBuilder::requestAlreadyRunning); + standardMessages.put(STILL_ON_SHARE_COOLDOWN, MessageBuilder::stillOnShareCoolDown); + standardMessages.put(RESULTS_ALREADY_SHARED, MessageBuilder::resultsAlreadyShared); + standardMessages.put(STAT_RESULTS_TOO_OLD, MessageBuilder::statResultsTooOld); + standardMessages.put(UNKNOWN_ERROR, MessageBuilder::unknownError); } } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentFactory.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentFactory.java index 4f853ae..6c18249 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentFactory.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentFactory.java @@ -107,9 +107,17 @@ public class ComponentFactory { /** * Returns a TextComponent with the input String as content, - * with color Gray and decoration Italic. + * with color Gray. */ public TextComponent subTitle(String content) { + return text(content).color(BRACKETS); + } + + /** + * Returns a TextComponent with the input String as content, + * with color Gray and decoration Italic. + */ + public TextComponent italicSubTitle(String content) { return text(content).color(BRACKETS).decorate(TextDecoration.ITALIC); } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/HelpMessage.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/HelpMessage.java index 20ecb02..71e5da4 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/HelpMessage.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/HelpMessage.java @@ -93,7 +93,7 @@ public final class HelpMessage implements TextComponent { return Component.newline() .append(factory.pluginPrefixAsTitle()) .append(newline()) - .append(factory.subTitle("Hover over the arguments for more information!")) + .append(factory.italicSubTitle("Hover over the arguments for more information!")) .append(newline()) .append(text("Usage:").color(factory.MSG_MAIN_2)).append(space()) .append(text("/statistic").color(factory.MSG_HOVER_ACCENT)) diff --git a/src/main/java/com/artemis/the/gr8/playerstats/multithreading/StatThread.java b/src/main/java/com/artemis/the/gr8/playerstats/multithreading/StatThread.java index cc01999..f0ee179 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/multithreading/StatThread.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/multithreading/StatThread.java @@ -48,8 +48,10 @@ final class StatThread extends Thread { } long lastCalc = ThreadManager.getLastRecordedCalcTime(); - if (lastCalc > 2000) { - outputManager.sendFeedbackMsgWaitAMoment(statRequester, lastCalc > 20000); + if (lastCalc > 6000) { + outputManager.sendFeedbackMsg(statRequester, StandardMessage.WAIT_A_MINUTE); + } else if (lastCalc > 2000) { + outputManager.sendFeedbackMsg(statRequester, StandardMessage.WAIT_A_MOMENT); } try { From d5c1c448416b8e4925104b525e953298d1b0fd53 Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Thu, 27 Oct 2022 18:09:34 +0200 Subject: [PATCH 22/43] Wrote exclude info message and added more rainbow easter eggs --- .../playerstats/commands/ExcludeCommand.java | 22 ++--- .../gr8/playerstats/enums/PluginColor.java | 17 ++-- .../gr8/playerstats/msg/MessageBuilder.java | 14 +--- .../BukkitConsoleComponentFactory.java | 12 +-- .../msg/components/ComponentFactory.java | 48 +++++------ .../msg/components/ExampleMessage.java | 38 ++++----- .../msg/components/ExcludeInfoMessage.java | 80 +++++++++++++++++++ .../msg/components/HelpMessage.java | 37 +++++---- .../msg/components/PrideComponentFactory.java | 38 +++------ .../msg/msgutils/EasterEggProvider.java | 45 +++++++---- 10 files changed, 208 insertions(+), 143 deletions(-) create mode 100644 src/main/java/com/artemis/the/gr8/playerstats/msg/components/ExcludeInfoMessage.java diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/ExcludeCommand.java b/src/main/java/com/artemis/the/gr8/playerstats/commands/ExcludeCommand.java index f7242b2..dde9478 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/ExcludeCommand.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/commands/ExcludeCommand.java @@ -22,14 +22,20 @@ public final class ExcludeCommand implements CommandExecutor { @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { - if (args.length == 1 && args[0].equalsIgnoreCase("list")) { - ArrayList excludedPlayers = offlinePlayerHandler.getExcludedPlayerNames(); - sender.sendMessage(String.valueOf(excludedPlayers)); - return true; + if (args.length == 1) { + switch (args[0]) { + case "list" -> { + ArrayList excludedPlayers = offlinePlayerHandler.getExcludedPlayerNames(); + sender.sendMessage(String.valueOf(excludedPlayers)); + return true; + } + case "info" -> { + outputManager.sendExcludeInfo(sender); + return true; + } + } } - //this is going to return false for all UUIDs in file at boot-up - that's an issue else if (args.length >= 2) { - String playerName = args[1]; switch (args[0]) { case "add" -> { @@ -46,10 +52,6 @@ public final class ExcludeCommand implements CommandExecutor { return true; } } - case "info" -> { - outputManager.sendExcludeInfo(sender); - return true; - } } } return false; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/enums/PluginColor.java b/src/main/java/com/artemis/the/gr8/playerstats/enums/PluginColor.java index 9663992..8a8302e 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/enums/PluginColor.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/enums/PluginColor.java @@ -29,20 +29,15 @@ public enum PluginColor { LIGHT_PURPLE (TextColor.fromHexString("#845EC2")), /** - * ChatColor Blue (#5555FF) - */ - BLUE (NamedTextColor.BLUE), - - /** - * A Medium Blue that is used for default feedback and error messages (#55AAFF). - */ - MEDIUM_BLUE (TextColor.fromHexString("#55AAFF")), - - /** - * A Light Blue that is used for hover-messages and the share-button (#55C6FF). + * A Light Blue that is used for the share-button and feedback message accents (#55C6FF). */ LIGHT_BLUE (TextColor.fromHexString("#55C6FF")), + /** + * A very light blue that is used for feedback messages and hover-text (#ADE7FF) + */ + LIGHTEST_BLUE(TextColor.fromHexString("#ADE7FF")), + /** * ChatColor Gold (#FFAA00) */ diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java index 4c7955e..cd5e99f 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java @@ -1,11 +1,7 @@ package com.artemis.the.gr8.playerstats.msg; import com.artemis.the.gr8.playerstats.api.StatFormatter; -import com.artemis.the.gr8.playerstats.msg.components.ComponentFactory; -import com.artemis.the.gr8.playerstats.msg.components.ExampleMessage; -import com.artemis.the.gr8.playerstats.msg.components.HelpMessage; -import com.artemis.the.gr8.playerstats.msg.components.BukkitConsoleComponentFactory; -import com.artemis.the.gr8.playerstats.msg.components.PrideComponentFactory; +import com.artemis.the.gr8.playerstats.msg.components.*; import com.artemis.the.gr8.playerstats.msg.msgutils.*; import com.artemis.the.gr8.playerstats.statistic.StatRequest; import com.artemis.the.gr8.playerstats.utils.EnumHandler; @@ -202,13 +198,7 @@ public final class MessageBuilder implements StatFormatter { } public @NotNull TextComponent excludeInfoMsg() { - return getPluginPrefixAsTitle() - .append(newline()) - .append(componentFactory.subTitle("The /statexclude command " + - "can be used to exclude individual players from /statistic lookups.") - .append(newline()) - .append(text("This means their results won't show up in top-10 results, " + - "and they won't be counted for the server total."))); + return ExcludeInfoMessage.construct(componentFactory); } @Override diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/BukkitConsoleComponentFactory.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/BukkitConsoleComponentFactory.java index 8c51065..65eb4e5 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/BukkitConsoleComponentFactory.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/BukkitConsoleComponentFactory.java @@ -29,14 +29,14 @@ public class BukkitConsoleComponentFactory extends ComponentFactory { UNDERSCORE = PluginColor.DARK_PURPLE.getConsoleColor(); HEARTS = PluginColor.RED.getConsoleColor(); - MSG_MAIN = PluginColor.MEDIUM_BLUE.getConsoleColor(); - MSG_ACCENT = PluginColor.BLUE.getConsoleColor(); + FEEDBACK_MSG = PluginColor.LIGHTEST_BLUE.getConsoleColor(); + FEEDBACK_MSG_ACCENT = PluginColor.LIGHT_BLUE.getConsoleColor(); - MSG_MAIN_2 = PluginColor.GOLD.getConsoleColor(); - MSG_ACCENT_2A = PluginColor.MEDIUM_GOLD.getConsoleColor(); - MSG_ACCENT_2B = PluginColor.LIGHT_YELLOW.getConsoleColor(); + INFO_MSG = PluginColor.GOLD.getConsoleColor(); + INFO_MSG_ACCENT_1 = PluginColor.MEDIUM_GOLD.getConsoleColor(); + INFO_MSG_ACCENT_2 = PluginColor.LIGHT_YELLOW.getConsoleColor(); - MSG_HOVER = PluginColor.LIGHT_BLUE.getConsoleColor(); + MSG_HOVER = PluginColor.LIGHTEST_BLUE.getConsoleColor(); MSG_CLICKED = PluginColor.LIGHT_PURPLE.getConsoleColor(); MSG_HOVER_ACCENT = PluginColor.LIGHT_GOLD.getConsoleColor(); } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentFactory.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentFactory.java index 6c18249..4c2bc70 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentFactory.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentFactory.java @@ -40,16 +40,16 @@ public class ComponentFactory { protected TextColor UNDERSCORE; //dark_purple protected TextColor HEARTS; //red - protected TextColor MSG_MAIN; //medium_blue - protected TextColor MSG_ACCENT; //blue + protected TextColor FEEDBACK_MSG; //lightest_blue + protected TextColor FEEDBACK_MSG_ACCENT; //light_blue - protected TextColor MSG_MAIN_2; //gold - protected TextColor MSG_ACCENT_2A; //medium_gold - protected TextColor MSG_ACCENT_2B; //light_yellow + protected TextColor INFO_MSG; //gold + protected TextColor INFO_MSG_ACCENT_1; //medium_gold + protected TextColor INFO_MSG_ACCENT_2; //light_yellow - protected TextColor MSG_HOVER; //light_blue - protected TextColor MSG_CLICKED; //light_purple + protected TextColor MSG_HOVER; //lightest_blue protected TextColor MSG_HOVER_ACCENT; //light_gold + protected TextColor MSG_CLICKED; //light_purple public ComponentFactory(ConfigHandler c) { @@ -63,20 +63,20 @@ public class ComponentFactory { UNDERSCORE = PluginColor.DARK_PURPLE.getColor(); HEARTS = PluginColor.RED.getColor(); - MSG_MAIN = PluginColor.MEDIUM_BLUE.getColor(); - MSG_ACCENT = PluginColor.BLUE.getColor(); + FEEDBACK_MSG = PluginColor.LIGHTEST_BLUE.getColor(); + FEEDBACK_MSG_ACCENT = PluginColor.LIGHT_BLUE.getColor(); - MSG_MAIN_2 = PluginColor.GOLD.getColor(); - MSG_ACCENT_2A = PluginColor.MEDIUM_GOLD.getColor(); - MSG_ACCENT_2B = PluginColor.LIGHT_YELLOW.getColor(); + INFO_MSG = PluginColor.GOLD.getColor(); + INFO_MSG_ACCENT_1 = PluginColor.MEDIUM_GOLD.getColor(); + INFO_MSG_ACCENT_2 = PluginColor.LIGHT_YELLOW.getColor(); - MSG_HOVER = PluginColor.LIGHT_BLUE.getColor(); + MSG_HOVER = PluginColor.LIGHTEST_BLUE.getColor(); MSG_HOVER_ACCENT = PluginColor.LIGHT_GOLD.getColor(); MSG_CLICKED = PluginColor.LIGHT_PURPLE.getColor(); } - public TextColor getExampleNameColor() { - return MSG_ACCENT_2B; + public TextComponent getExampleName() { + return text("Artemis_the_gr8").color(INFO_MSG_ACCENT_2); } public TextColor getSharerNameColor() { @@ -105,19 +105,11 @@ public class ComponentFactory { .append(text("____________")); } - /** - * Returns a TextComponent with the input String as content, - * with color Gray. - */ - public TextComponent subTitle(String content) { - return text(content).color(BRACKETS); - } - /** * Returns a TextComponent with the input String as content, * with color Gray and decoration Italic. */ - public TextComponent italicSubTitle(String content) { + public TextComponent subTitle(String content) { return text(content).color(BRACKETS).decorate(TextDecoration.ITALIC); } @@ -126,11 +118,11 @@ public class ComponentFactory { * with color Medium_Blue. */ public TextComponent message() { - return text().color(MSG_MAIN).build(); + return text().color(FEEDBACK_MSG).build(); } public TextComponent messageAccent() { - return text().color(MSG_ACCENT).build(); + return text().color(FEEDBACK_MSG_ACCENT).build(); } public TextComponent title(String content, Target target) { @@ -173,14 +165,14 @@ public class ComponentFactory { public TextComponent sharerName(String sharerName) { return getComponent(sharerName, - getSharerNameColor(), + getColorFromString(config.getSharerNameDecoration(false)), getStyleFromString(config.getSharerNameDecoration(true))); } public TextComponent shareButton(int shareCode) { return surroundWithBrackets( text("Share") - .color(MSG_HOVER) + .color(FEEDBACK_MSG_ACCENT) .clickEvent(ClickEvent.runCommand("/statshare " + shareCode)) .hoverEvent(HoverEvent.showText(text("Click here to share this statistic in chat!") .color(MSG_HOVER_ACCENT)))); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ExampleMessage.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ExampleMessage.java index 33bc58d..25c0afa 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ExampleMessage.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ExampleMessage.java @@ -4,6 +4,7 @@ import net.kyori.adventure.text.Component; import net.kyori.adventure.text.ComponentLike; import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.format.Style; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Unmodifiable; @@ -22,34 +23,35 @@ public final class ExampleMessage implements TextComponent { exampleMessage = buildMessage(factory); } - public static ExampleMessage construct(ComponentFactory factory) { + @Contract("_ -> new") + public static @NotNull ExampleMessage construct(ComponentFactory factory) { return new ExampleMessage(factory); } - private TextComponent buildMessage(ComponentFactory factory) { - String arrow = factory instanceof BukkitConsoleComponentFactory ? " -> " : " → "; //4 spaces, alt + 26, 1 space + private @NotNull TextComponent buildMessage(@NotNull ComponentFactory factory) { + String arrowString = factory instanceof BukkitConsoleComponentFactory ? " -> " : " → "; //4 spaces, alt + 26, 1 space + TextComponent arrow = text(arrowString).color(factory.INFO_MSG); return Component.newline() .append(factory.pluginPrefixAsTitle()) .append(Component.newline()) - .append(text("Examples: ").color(factory.MSG_MAIN_2)) + .append(factory.subTitle("Examples: ")) .append(Component.newline()) - .append(text(arrow).color(factory.MSG_MAIN_2) - .append(text("/statistic ") - .append(text("animals_bred ").color(factory.MSG_ACCENT_2A) - .append(text("top").color(factory.MSG_ACCENT_2B))))) + .append(arrow) + .append(text("/stat ").color(factory.INFO_MSG) + .append(text("animals_bred ").color(factory.INFO_MSG_ACCENT_1) + .append(text("top").color(factory.INFO_MSG_ACCENT_2)))) .append(Component.newline()) - .append(text(arrow).color(factory.MSG_MAIN_2) - .append(text("/statistic ") - .append(text("mine_block diorite ").color(factory.MSG_ACCENT_2A) - .append(text("me").color(factory.MSG_ACCENT_2B))))) + .append(arrow) + .append(text("/stat ").color(factory.INFO_MSG) + .append(text("mine_block diorite ").color(factory.INFO_MSG_ACCENT_1) + .append(text("me").color(factory.INFO_MSG_ACCENT_2)))) .append(Component.newline()) - .append(text(arrow).color(factory.MSG_MAIN_2) - .append(text("/statistic ") - .append(text("deaths ").color(factory.MSG_ACCENT_2A) - .append(text("player ").color(factory.MSG_ACCENT_2B) - .append(text("Artemis_the_gr8") - .color(factory.getExampleNameColor())))))); + .append(arrow) + .append(text("/stat ").color(factory.INFO_MSG) + .append(text("deaths ").color(factory.INFO_MSG_ACCENT_1) + .append(text("player ").color(factory.INFO_MSG_ACCENT_2) + .append(factory.getExampleName())))); } @Override diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ExcludeInfoMessage.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ExcludeInfoMessage.java new file mode 100644 index 0000000..991d7bd --- /dev/null +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ExcludeInfoMessage.java @@ -0,0 +1,80 @@ +package com.artemis.the.gr8.playerstats.msg.components; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.ComponentLike; +import net.kyori.adventure.text.TextComponent; +import net.kyori.adventure.text.format.Style; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Unmodifiable; + +import java.util.List; + +import static net.kyori.adventure.text.Component.text; + +public class ExcludeInfoMessage implements TextComponent { + + private final TextComponent excludeInfo; + + private ExcludeInfoMessage(ComponentFactory factory) { + excludeInfo = buildMessage(factory); + } + + @Contract("_ -> new") + public static @NotNull ExcludeInfoMessage construct(ComponentFactory factory) { + return new ExcludeInfoMessage(factory); + } + + private @NotNull TextComponent buildMessage(@NotNull ComponentFactory factory) { + String arrowString = factory instanceof BukkitConsoleComponentFactory ? " -> " : " → "; //4 spaces, alt + 26, 1 space + TextComponent arrow = text(arrowString).color(factory.INFO_MSG); + + return Component.newline() + .append(factory.pluginPrefixAsTitle()) + .append(Component.newline()) + .append(factory.subTitle("The /statexclude command is used to hide")) + .append(Component.newline()) + .append(factory.subTitle("specific players' results from /stat lookups")) + .append(Component.newline()) + .append(text("Excluded players are:").color(factory.INFO_MSG)) + .append(Component.newline()) + .append(arrow).append(text("not visible in the top 10").color(factory.INFO_MSG_ACCENT_1)) + .append(Component.newline()) + .append(arrow).append(text("not counted for the server total").color(factory.INFO_MSG_ACCENT_1)); + } + + @Override + public @NotNull String content() { + return excludeInfo.content(); + } + + @Override + public @NotNull TextComponent content(@NotNull String content) { + return excludeInfo.content(content); + } + + @Override + public @NotNull Builder toBuilder() { + return excludeInfo.toBuilder(); + } + + @Override + public @Unmodifiable @NotNull List children() { + return excludeInfo.children(); + } + + @Override + public @NotNull TextComponent children(@NotNull List children) { + return excludeInfo.children(children); + } + + @Override + public @NotNull Style style() { + return excludeInfo.style(); + } + + @Override + public @NotNull TextComponent style(@NotNull Style style) { + return excludeInfo.style(style); + } +} \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/HelpMessage.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/HelpMessage.java index 71e5da4..179dda8 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/HelpMessage.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/HelpMessage.java @@ -6,6 +6,7 @@ import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.event.HoverEvent; import net.kyori.adventure.text.format.Style; import net.kyori.adventure.text.format.TextDecoration; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Unmodifiable; @@ -28,15 +29,17 @@ public final class HelpMessage implements TextComponent { } } - public static HelpMessage constructPlainMsg(ComponentFactory factory, int listSize) { + @Contract("_, _ -> new") + public static @NotNull HelpMessage constructPlainMsg(ComponentFactory factory, int listSize) { return new HelpMessage(factory, false, listSize); } - public static HelpMessage constructHoverMsg(ComponentFactory factory, int listSize) { + @Contract("_, _ -> new") + public static @NotNull HelpMessage constructHoverMsg(ComponentFactory factory, int listSize) { return new HelpMessage(factory, true, listSize); } - private TextComponent buildPlainMsg(ComponentFactory factory, int listSize) { + private @NotNull TextComponent buildPlainMsg(ComponentFactory factory, int listSize) { String arrowSymbol = "→"; //alt + 26 String bulletSymbol = "•"; //alt + 7 @@ -45,15 +48,15 @@ public final class HelpMessage implements TextComponent { bulletSymbol = "*"; } TextComponent spaces = text(" "); //4 spaces - TextComponent arrow = text(arrowSymbol).color(factory.MSG_MAIN_2); - TextComponent bullet = text(bulletSymbol).color(factory.MSG_MAIN_2); + TextComponent arrow = text(arrowSymbol).color(factory.INFO_MSG); + TextComponent bullet = text(bulletSymbol).color(factory.INFO_MSG); return Component.newline() .append(factory.pluginPrefixAsTitle()) .append(newline()) .append(text("Type \"/statistic examples\" to see examples!").color(factory.BRACKETS).decorate(TextDecoration.ITALIC)) .append(newline()) - .append(text("Usage:").color(factory.MSG_MAIN_2)).append(space()) + .append(text("Usage:").color(factory.INFO_MSG)).append(space()) .append(text("/statistic").color(factory.MSG_HOVER_ACCENT)) .append(newline()) .append(spaces).append(arrow).append(space()) @@ -67,42 +70,42 @@ public final class HelpMessage implements TextComponent { .append(text("me | player | server | top").color(factory.MSG_HOVER_ACCENT)) .append(newline()) .append(spaces).append(spaces).append(bullet).append(space()) - .append(text("me:").color(factory.MSG_ACCENT_2A)).append(space()) + .append(text("me:").color(factory.INFO_MSG_ACCENT_1)).append(space()) .append(text("your own statistic").color(factory.BRACKETS)) .append(newline()) .append(spaces).append(spaces).append(bullet).append(space()) - .append(text("player:").color(factory.MSG_ACCENT_2A)).append(space()) + .append(text("player:").color(factory.INFO_MSG_ACCENT_1)).append(space()) .append(text("choose a player").color(factory.BRACKETS)) .append(newline()) .append(spaces).append(spaces).append(bullet).append(space()) - .append(text("server:").color(factory.MSG_ACCENT_2A)).append(space()) + .append(text("server:").color(factory.INFO_MSG_ACCENT_1)).append(space()) .append(text("everyone on the server combined").color(factory.BRACKETS)) .append(newline()) .append(spaces).append(spaces).append(bullet).append(space()) - .append(text("top:").color(factory.MSG_ACCENT_2A)).append(space()) + .append(text("top:").color(factory.INFO_MSG_ACCENT_1)).append(space()) .append(text("the top").color(factory.BRACKETS).append(space()).append(text(listSize))) .append(newline()) .append(spaces).append(arrow).append(space()) .append(text("{player-name}").color(factory.MSG_HOVER_ACCENT)); } - private TextComponent buildHoverMsg(ComponentFactory factory, int listSize) { + private @NotNull TextComponent buildHoverMsg(@NotNull ComponentFactory factory, int listSize) { TextComponent spaces = text(" "); - TextComponent arrow = text("→").color(factory.MSG_MAIN_2); + TextComponent arrow = text("→").color(factory.INFO_MSG); return Component.newline() .append(factory.pluginPrefixAsTitle()) .append(newline()) - .append(factory.italicSubTitle("Hover over the arguments for more information!")) + .append(factory.subTitle("Hover over the arguments for more information!")) .append(newline()) - .append(text("Usage:").color(factory.MSG_MAIN_2)).append(space()) + .append(text("Usage:").color(factory.INFO_MSG)).append(space()) .append(text("/statistic").color(factory.MSG_HOVER_ACCENT)) .append(newline()) .append(spaces).append(arrow).append(space()) .append(text("name").color(factory.MSG_HOVER_ACCENT) .hoverEvent(HoverEvent.showText(text("The name that describes the statistic").color(factory.MSG_HOVER) .append(newline()) - .append(text("Example: ").color(factory.MSG_MAIN_2)) + .append(text("Example: ").color(factory.INFO_MSG)) .append(text("\"animals_bred\"").color(factory.MSG_HOVER_ACCENT))))) .append(newline()) .append(spaces).append(arrow).append(space()) @@ -110,12 +113,12 @@ public final class HelpMessage implements TextComponent { .hoverEvent(HoverEvent.showText( text("Some statistics need an item, block or entity as extra input").color(factory.MSG_HOVER) .append(newline()) - .append(text("Example: ").color(factory.MSG_MAIN_2) + .append(text("Example: ").color(factory.INFO_MSG) .append(text("\"mine_block diorite\"").color(factory.MSG_HOVER_ACCENT)))))) .append(newline()) .append(spaces).append(arrow .hoverEvent(HoverEvent.showText( - text("Choose one").color(factory.UNDERSCORE)))).append(space()) + text("Choose one").color(factory.MSG_CLICKED)))).append(space()) .append(text("me").color(factory.MSG_HOVER_ACCENT) .hoverEvent(HoverEvent.showText( text("See your own statistic").color(factory.MSG_HOVER)))) diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/PrideComponentFactory.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/PrideComponentFactory.java index c43322c..af965af 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/PrideComponentFactory.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/PrideComponentFactory.java @@ -2,9 +2,8 @@ package com.artemis.the.gr8.playerstats.msg.components; import com.artemis.the.gr8.playerstats.config.ConfigHandler; -import com.artemis.the.gr8.playerstats.enums.PluginColor; +import com.artemis.the.gr8.playerstats.msg.msgutils.EasterEggProvider; import net.kyori.adventure.text.TextComponent; -import net.kyori.adventure.text.format.TextColor; import net.kyori.adventure.text.minimessage.MiniMessage; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; @@ -18,37 +17,22 @@ import static net.kyori.adventure.text.Component.*; */ public class PrideComponentFactory extends ComponentFactory { - public PrideComponentFactory(ConfigHandler c) { - super(c); + public PrideComponentFactory(ConfigHandler config) { + super(config); } @Override - protected void prepareColors() { - PREFIX = PluginColor.GOLD.getColor(); - BRACKETS = PluginColor.GRAY.getColor(); - UNDERSCORE = PluginColor.DARK_PURPLE.getColor(); - HEARTS = PluginColor.RED.getColor(); - - MSG_MAIN = PluginColor.GRAY.getColor(); //difference 1 - MSG_ACCENT = PluginColor.LIGHT_GOLD.getColor(); //difference 2 - - MSG_MAIN_2 = PluginColor.GOLD.getColor(); - MSG_ACCENT_2A = PluginColor.MEDIUM_GOLD.getColor(); - MSG_ACCENT_2B = PluginColor.LIGHT_YELLOW.getColor(); - - MSG_HOVER = PluginColor.LIGHT_BLUE.getColor(); - MSG_CLICKED = PluginColor.LIGHT_PURPLE.getColor(); - MSG_HOVER_ACCENT = PluginColor.LIGHT_GOLD.getColor(); + public TextComponent getExampleName() { + return text() + .append(EasterEggProvider.getFestiveName("Artemis_the_gr8")) + .build(); } @Override - public TextColor getExampleNameColor() { - return getSharerNameColor(); - } - - @Override - public TextColor getSharerNameColor() { - return PluginColor.getRandomNameColor(); + public TextComponent sharerName(String sharerName) { + return text() + .append(EasterEggProvider.getFestiveName(sharerName)) + .build(); } @Override diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/EasterEggProvider.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/EasterEggProvider.java index 34cfa24..e52de7e 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/EasterEggProvider.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/EasterEggProvider.java @@ -8,7 +8,9 @@ import net.kyori.adventure.text.minimessage.tag.Tag; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; import org.bukkit.entity.Player; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Random; @@ -19,26 +21,17 @@ import java.util.Random; */ public final class EasterEggProvider { - private static boolean isEnabled; private static final Random random; - static{ - enable(); + static { random = new Random(); } - public static void enable() { - isEnabled = true; - } - public static void disable() { - isEnabled = false; + public static @NotNull Component getFestiveName(String playerName) { + return MiniMessage.miniMessage().deserialize(decorateWithRandomGradient(playerName)); } - public static Component getPlayerName(Player player) { - if (!isEnabled) { - return null; - } - + public static @Nullable Component getPlayerName(@NotNull Player player) { int sillyNumber = getSillyNumber(); String playerName = null; switch (player.getUniqueId().toString()) { @@ -109,6 +102,29 @@ public final class EasterEggProvider { } } + private static @NotNull String decorateWithRandomGradient(String input) { + String colorString = switch (random.nextInt(9)) { + case 0 -> { + if (input.equalsIgnoreCase("Artemis_the_gr8")) { + yield ""; + } + else { + yield ""; + } + } + case 1 -> ""; + case 2 -> ""; + case 3 -> ""; + case 4 -> ""; + case 5 -> ""; + case 6 -> ""; + case 7 -> ""; + case 8 -> ""; + default -> ""; + }; + return colorString + input + ""; + } + private static int getSillyNumber() { return random.nextInt(100); } @@ -117,7 +133,8 @@ public final class EasterEggProvider { return sillyNumber >= lowerBound && sillyNumber <= upperBound; } - private static TagResolver papiTag(final @NotNull Player player) { + @Contract("_ -> new") + private static @NotNull TagResolver papiTag(final @NotNull Player player) { return TagResolver.resolver("papi", (argumentQueue, context) -> { final String papiPlaceholder = argumentQueue.popOr("papi tag requires an argument").value(); final String parsedPlaceholder = PlaceholderAPI.setPlaceholders(player, '%' + papiPlaceholder + '%'); From 260fad2d4a358f0b358faccf5533e67da38baa97 Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Fri, 28 Oct 2022 12:00:26 +0200 Subject: [PATCH 23/43] Made sharerName have a random rainbow gradient in rainbow mode --- .../msg/components/PrideComponentFactory.java | 55 +++++++++++-------- .../msg/msgutils/EasterEggProvider.java | 27 --------- 2 files changed, 33 insertions(+), 49 deletions(-) diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/PrideComponentFactory.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/PrideComponentFactory.java index af965af..2f51434 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/PrideComponentFactory.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/PrideComponentFactory.java @@ -2,7 +2,6 @@ package com.artemis.the.gr8.playerstats.msg.components; import com.artemis.the.gr8.playerstats.config.ConfigHandler; -import com.artemis.the.gr8.playerstats.msg.msgutils.EasterEggProvider; import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.minimessage.MiniMessage; import org.jetbrains.annotations.Contract; @@ -17,45 +16,39 @@ import static net.kyori.adventure.text.Component.*; */ public class PrideComponentFactory extends ComponentFactory { + private final Random random; + public PrideComponentFactory(ConfigHandler config) { super(config); + random = new Random(); } @Override public TextComponent getExampleName() { - return text() - .append(EasterEggProvider.getFestiveName("Artemis_the_gr8")) - .build(); + return deserialize("Artemis_the_gr8"); } @Override public TextComponent sharerName(String sharerName) { - return text() - .append(EasterEggProvider.getFestiveName(sharerName)) - .build(); + return deserialize(decorateWithRandomGradient(sharerName)); } @Override + //12 underscores public TextComponent pluginPrefixAsTitle() { - String title = "____________ [PlayerStats] ____________"; //12 underscores - return text() - .append(MiniMessage.miniMessage().deserialize(title)) - .build(); + return deserialize("____________ [PlayerStats] ____________"); } @Override public TextComponent pluginPrefix() { - Random randomizer = new Random(); - if (randomizer.nextBoolean()) { + if (random.nextBoolean()) { return backwardsPluginPrefixComponent(); } return rainbowPrefix(); } public TextComponent rainbowPrefix() { - return text() - .append(MiniMessage.miniMessage() - .deserialize("<#f74040>[" + + return deserialize("<#f74040>[" + "<#F54D39>P" + "<#F16E28>l" + "<#ee8a19>a" + @@ -67,15 +60,12 @@ public class PrideComponentFactory extends ComponentFactory { "<#01c1a7>a" + "<#1F8BEB>t" + "<#3341E6>s" + - "<#631ae6>]")) - .build(); + "<#631ae6>]"); } @Contract(" -> new") private @NotNull TextComponent backwardsPluginPrefixComponent() { - return text() - .append(MiniMessage.miniMessage() - .deserialize("<#631ae6>[" + + return deserialize("<#631ae6>[" + "<#3341E6>P" + "<#1F8BEB>l" + "<#01c1a7>a" + @@ -87,7 +77,28 @@ public class PrideComponentFactory extends ComponentFactory { "<#ee8a19>a" + "<#f67824>t" + "<#f76540>s" + - "<#f74040>]")) + "<#f74040>]"); + } + + private @NotNull String decorateWithRandomGradient(@NotNull String input) { + String colorString = switch (random.nextInt(9)) { + case 0 -> ""; + case 1 -> ""; + case 2 -> ""; + case 3 -> ""; + case 4 -> ""; + case 5 -> ""; + case 6 -> ""; + case 7 -> ""; + default -> ""; + }; + return colorString + input + ""; + } + + @Contract("_ -> new") + private @NotNull TextComponent deserialize(String input) { + return text() + .append(MiniMessage.miniMessage().deserialize(input)) .build(); } } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/EasterEggProvider.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/EasterEggProvider.java index e52de7e..c908020 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/EasterEggProvider.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/EasterEggProvider.java @@ -27,10 +27,6 @@ public final class EasterEggProvider { random = new Random(); } - public static @NotNull Component getFestiveName(String playerName) { - return MiniMessage.miniMessage().deserialize(decorateWithRandomGradient(playerName)); - } - public static @Nullable Component getPlayerName(@NotNull Player player) { int sillyNumber = getSillyNumber(); String playerName = null; @@ -102,29 +98,6 @@ public final class EasterEggProvider { } } - private static @NotNull String decorateWithRandomGradient(String input) { - String colorString = switch (random.nextInt(9)) { - case 0 -> { - if (input.equalsIgnoreCase("Artemis_the_gr8")) { - yield ""; - } - else { - yield ""; - } - } - case 1 -> ""; - case 2 -> ""; - case 3 -> ""; - case 4 -> ""; - case 5 -> ""; - case 6 -> ""; - case 7 -> ""; - case 8 -> ""; - default -> ""; - }; - return colorString + input + ""; - } - private static int getSillyNumber() { return random.nextInt(100); } From 2d5e9d4515f34e3a57f97d39f3fe740ba8ec0954 Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Fri, 28 Oct 2022 12:11:36 +0200 Subject: [PATCH 24/43] Removed unnecessary name colors in PluginColor --- .../gr8/playerstats/enums/PluginColor.java | 71 +------------------ .../msg/components/ComponentFactory.java | 4 -- 2 files changed, 3 insertions(+), 72 deletions(-) diff --git a/src/main/java/com/artemis/the/gr8/playerstats/enums/PluginColor.java b/src/main/java/com/artemis/the/gr8/playerstats/enums/PluginColor.java index 8a8302e..ac70cbb 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/enums/PluginColor.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/enums/PluginColor.java @@ -2,8 +2,7 @@ package com.artemis.the.gr8.playerstats.enums; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.TextColor; - -import java.util.Random; +import org.jetbrains.annotations.NotNull; /** * This enum represents the colorscheme PlayerStats uses in its output messages. @@ -61,42 +60,7 @@ public enum PluginColor { /** * The color of vanilla Minecraft hearts (#FF1313). */ - RED (TextColor.fromHexString("#FF1313")), - - /** - * ChatColor Blue (#5555FF) - */ - NAME_1 (NamedTextColor.BLUE), //#5555FF - blue - - /** - * A shade of blue between Blue and Medium Blue (#4287F5) - */ - NAME_2 (TextColor.fromHexString("#4287F5")), - - /** - * Medium Blue (#55AAFF) - */ - NAME_3 (TextColor.fromHexString("#55AAFF")), - - /** - * A shade of magenta/purple (#D65DB1) - */ - NAME_4 (TextColor.fromHexString("#D65DB1")), - - /** - * A dark shade of orange (#EE8A19) - */ - NAME_5 (TextColor.fromHexString("#EE8A19")), - - /** - * A shade of green/aqua/cyan-ish (#01C1A7) - */ - NAME_6 (TextColor.fromHexString("#01C1A7")), - - /** - * A light shade of green (#46D858) - */ - NAME_7 (TextColor.fromHexString("#46D858")); + RED (TextColor.fromHexString("#FF1313")); private final TextColor color; @@ -115,36 +79,7 @@ public enum PluginColor { /** * Gets the nearest NamedTextColor for the corresponding enum constant. */ - public TextColor getConsoleColor() { + public @NotNull TextColor getConsoleColor() { return NamedTextColor.nearestTo(color); } - - /** - * Randomly selects one of the 7 different NAME-colors. - */ - public static TextColor getRandomNameColor() { - return getRandomNameColor(false); - } - - /** - * Randomly selects one of the 7 different NAME-colors, and if isConsole is true, - * returns the closest NamedTextColor - */ - public static TextColor getRandomNameColor(boolean isConsole) { - Random randomizer = new Random(); - PluginColor color = switch (randomizer.nextInt(7)) { - case 0 -> NAME_1; - case 2 -> NAME_3; - case 3 -> NAME_4; - case 4 -> NAME_5; - case 5 -> NAME_6; - case 6 -> NAME_7; - default -> NAME_2; - }; - return getCorrespondingColor(color, isConsole); - } - - private static TextColor getCorrespondingColor(PluginColor nameColor, boolean isConsole) { - return isConsole ? nameColor.getConsoleColor() : nameColor.getColor(); - } } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentFactory.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentFactory.java index 4c2bc70..633d7a6 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentFactory.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentFactory.java @@ -79,10 +79,6 @@ public class ComponentFactory { return text("Artemis_the_gr8").color(INFO_MSG_ACCENT_2); } - public TextColor getSharerNameColor() { - return getColorFromString(config.getSharerNameDecoration(false)); - } - /** * Returns [PlayerStats]. */ From a43a4e5d16498513bc73892cac3fdec35d36827e Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Sat, 29 Oct 2022 13:16:59 +0200 Subject: [PATCH 25/43] Added Halloween decorations --- .../playerstats/commands/ExcludeCommand.java | 8 +++++ .../gr8/playerstats/msg/MessageBuilder.java | 32 ++++++++----------- .../gr8/playerstats/msg/OutputManager.java | 28 ++++++++++++---- .../BukkitConsoleComponentFactory.java | 5 ++- .../msg/components/ComponentFactory.java | 12 +++++-- .../msg/components/ExcludeInfoMessage.java | 2 +- .../components/HalloweenComponentFactory.java | 25 +++++++++++++++ .../msg/components/PrideComponentFactory.java | 26 ++++----------- .../msg/msgutils/ComponentSerializer.java | 4 +-- 9 files changed, 91 insertions(+), 51 deletions(-) create mode 100644 src/main/java/com/artemis/the/gr8/playerstats/msg/components/HalloweenComponentFactory.java diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/ExcludeCommand.java b/src/main/java/com/artemis/the/gr8/playerstats/commands/ExcludeCommand.java index dde9478..60fc7c1 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/ExcludeCommand.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/commands/ExcludeCommand.java @@ -9,6 +9,8 @@ import org.bukkit.command.CommandSender; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; public final class ExcludeCommand implements CommandExecutor { @@ -38,6 +40,12 @@ public final class ExcludeCommand implements CommandExecutor { else if (args.length >= 2) { String playerName = args[1]; switch (args[0]) { + case "test" -> { + List converted = new ArrayList<>(List.copyOf(Arrays.asList(args))); + converted.remove(0); + outputManager.sendTest(sender, converted.toArray(new String[0])); + return true; + } case "add" -> { if (offlinePlayerHandler.isLoadedPlayer(playerName)) { offlinePlayerHandler.addLoadedPlayerToExcludeList(playerName); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java index cd5e99f..67d4f3f 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java @@ -36,7 +36,7 @@ import static net.kyori.adventure.text.Component.*; */ public final class MessageBuilder implements StatFormatter { - private static ConfigHandler config; + private final ConfigHandler config; private boolean useHoverText; private boolean isConsoleBuilder; @@ -45,28 +45,24 @@ public final class MessageBuilder implements StatFormatter { private final NumberFormatter formatter; private final ComponentSerializer serializer; - private MessageBuilder(ConfigHandler config, LanguageKeyHandler language) { - this (config, language, new ComponentFactory(config)); - } - - private MessageBuilder(ConfigHandler configHandler, LanguageKeyHandler language, ComponentFactory factory) { - config = configHandler; - useHoverText = config.useHoverText(); + private MessageBuilder(ComponentFactory factory) { + config = ConfigHandler.getInstance(); + languageKeyHandler = LanguageKeyHandler.getInstance(); componentFactory = factory; - languageKeyHandler = language; + useHoverText = config.useHoverText(); formatter = new NumberFormatter(); - serializer = new ComponentSerializer(languageKeyHandler); + serializer = new ComponentSerializer(); } - @Contract("_, _ -> new") - public static @NotNull MessageBuilder defaultBuilder(ConfigHandler config, LanguageKeyHandler language) { - return new MessageBuilder(config, language); + @Contract(" -> new") + public static @NotNull MessageBuilder defaultBuilder() { + return new MessageBuilder(new ComponentFactory()); } - @Contract("_, _, _ -> new") - public static @NotNull MessageBuilder fromComponentFactory(ConfigHandler config, LanguageKeyHandler language, ComponentFactory factory) { - return new MessageBuilder(config, language, factory); + @Contract("_ -> new") + public static @NotNull MessageBuilder fromComponentFactory(ComponentFactory factory) { + return new MessageBuilder(factory); } /** @@ -93,7 +89,7 @@ public final class MessageBuilder implements StatFormatter { @Override public TextComponent getRainbowPluginPrefix() { - PrideComponentFactory pride = new PrideComponentFactory(config); + PrideComponentFactory pride = new PrideComponentFactory(); return pride.rainbowPrefix(); } @@ -104,7 +100,7 @@ public final class MessageBuilder implements StatFormatter { @Override public TextComponent getRainbowPluginPrefixAsTitle() { - PrideComponentFactory pride = new PrideComponentFactory(config); + PrideComponentFactory pride = new PrideComponentFactory(); return pride.pluginPrefixAsTitle(); } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java index 8b74d66..931bcb5 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java @@ -4,12 +4,14 @@ import com.artemis.the.gr8.playerstats.api.StatFormatter; import com.artemis.the.gr8.playerstats.config.ConfigHandler; import com.artemis.the.gr8.playerstats.enums.StandardMessage; import com.artemis.the.gr8.playerstats.msg.components.BukkitConsoleComponentFactory; +import com.artemis.the.gr8.playerstats.msg.components.HalloweenComponentFactory; import com.artemis.the.gr8.playerstats.msg.components.PrideComponentFactory; import com.artemis.the.gr8.playerstats.msg.msgutils.FormattingFunction; -import com.artemis.the.gr8.playerstats.msg.msgutils.LanguageKeyHandler; import com.artemis.the.gr8.playerstats.statistic.StatRequest; import net.kyori.adventure.platform.bukkit.BukkitAudiences; +import net.kyori.adventure.text.Component; import net.kyori.adventure.text.TextComponent; +import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.command.ConsoleCommandSender; @@ -37,13 +39,11 @@ public final class OutputManager { private static EnumMap> standardMessages; private final ConfigHandler config; - private final LanguageKeyHandler languageKeyHandler; private MessageBuilder messageBuilder; private MessageBuilder consoleMessageBuilder; public OutputManager(BukkitAudiences adventure) { OutputManager.adventure = adventure; - languageKeyHandler = LanguageKeyHandler.getInstance(); config = ConfigHandler.getInstance(); getMessageBuilders(); @@ -128,6 +128,16 @@ public final class OutputManager { .excludeInfoMsg()); } + public void sendTest(@NotNull CommandSender sender, String[] args) { + StringBuilder msg = new StringBuilder(); + for (String arg : args) { + char text = (char) Integer.parseInt(arg, 16); + msg.append(text); + } + Component test = MiniMessage.miniMessage().deserialize(msg.toString()); + adventure.sender(sender).sendMessage(test); + } + public void sendToAllPlayers(@NotNull TextComponent component) { adventure.players().sendMessage(component); } @@ -147,15 +157,17 @@ public final class OutputManager { private MessageBuilder getClientMessageBuilder() { if (useRainbowStyle()) { - return MessageBuilder.fromComponentFactory(config, languageKeyHandler, new PrideComponentFactory(config)); + return MessageBuilder.fromComponentFactory(new PrideComponentFactory()); + } else if (useHalloweenStyle()) { + return MessageBuilder.fromComponentFactory(new HalloweenComponentFactory()); } - return MessageBuilder.defaultBuilder(config, languageKeyHandler); + return MessageBuilder.defaultBuilder(); } private @NotNull MessageBuilder getConsoleMessageBuilder() { MessageBuilder consoleBuilder; if (isBukkit()) { - consoleBuilder = MessageBuilder.fromComponentFactory(config,languageKeyHandler, new BukkitConsoleComponentFactory(config)); + consoleBuilder = MessageBuilder.fromComponentFactory(new BukkitConsoleComponentFactory()); } else { consoleBuilder = getClientMessageBuilder(); } @@ -168,6 +180,10 @@ public final class OutputManager { return config.useRainbowMode() || (config.useFestiveFormatting() && LocalDate.now().getMonth().equals(Month.JUNE)); } + private boolean useHalloweenStyle() { + return config.useFestiveFormatting() && LocalDate.now().getMonth().equals(Month.OCTOBER); + } + private boolean isBukkit() { return Bukkit.getName().equalsIgnoreCase("CraftBukkit"); } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/BukkitConsoleComponentFactory.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/BukkitConsoleComponentFactory.java index 65eb4e5..5cfd5de 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/BukkitConsoleComponentFactory.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/BukkitConsoleComponentFactory.java @@ -1,7 +1,6 @@ package com.artemis.the.gr8.playerstats.msg.components; import com.artemis.the.gr8.playerstats.enums.PluginColor; -import com.artemis.the.gr8.playerstats.config.ConfigHandler; import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.TextColor; @@ -18,8 +17,8 @@ import static net.kyori.adventure.text.Component.text; */ public class BukkitConsoleComponentFactory extends ComponentFactory { - public BukkitConsoleComponentFactory(ConfigHandler config) { - super(config); + public BukkitConsoleComponentFactory() { + super(); } @Override diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentFactory.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentFactory.java index 633d7a6..16dd0ce 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentFactory.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentFactory.java @@ -14,6 +14,7 @@ import net.kyori.adventure.text.event.HoverEvent; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.TextColor; import net.kyori.adventure.text.format.TextDecoration; +import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.util.HSVLike; import net.kyori.adventure.util.Index; import org.bukkit.Bukkit; @@ -52,8 +53,8 @@ public class ComponentFactory { protected TextColor MSG_CLICKED; //light_purple - public ComponentFactory(ConfigHandler c) { - config = c; + public ComponentFactory() { + config = ConfigHandler.getInstance(); prepareColors(); } @@ -75,6 +76,13 @@ public class ComponentFactory { MSG_CLICKED = PluginColor.LIGHT_PURPLE.getColor(); } + @Contract("_ -> new") + protected @NotNull TextComponent miniMessageToComponent(String input) { + return text() + .append(MiniMessage.miniMessage().deserialize(input)) + .build(); + } + public TextComponent getExampleName() { return text("Artemis_the_gr8").color(INFO_MSG_ACCENT_2); } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ExcludeInfoMessage.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ExcludeInfoMessage.java index 991d7bd..322a4bd 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ExcludeInfoMessage.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ExcludeInfoMessage.java @@ -12,7 +12,7 @@ import java.util.List; import static net.kyori.adventure.text.Component.text; -public class ExcludeInfoMessage implements TextComponent { +public final class ExcludeInfoMessage implements TextComponent { private final TextComponent excludeInfo; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/HalloweenComponentFactory.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/HalloweenComponentFactory.java new file mode 100644 index 0000000..915400a --- /dev/null +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/HalloweenComponentFactory.java @@ -0,0 +1,25 @@ +package com.artemis.the.gr8.playerstats.msg.components; + +import net.kyori.adventure.text.TextComponent; + +public class HalloweenComponentFactory extends ComponentFactory { + + + public HalloweenComponentFactory() { + super(); + } + + @Override + public TextComponent pluginPrefixAsTitle() { + return miniMessageToComponent( + "" + + "\u2620 __________ [PlayerStats] __________ " + + "\u2620"); + } + + @Override + public TextComponent pluginPrefix() { + return miniMessageToComponent( + "[PlayerStats]"); + } +} \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/PrideComponentFactory.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/PrideComponentFactory.java index 2f51434..71630c3 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/PrideComponentFactory.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/PrideComponentFactory.java @@ -1,16 +1,11 @@ package com.artemis.the.gr8.playerstats.msg.components; -import com.artemis.the.gr8.playerstats.config.ConfigHandler; - import net.kyori.adventure.text.TextComponent; -import net.kyori.adventure.text.minimessage.MiniMessage; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import java.util.Random; -import static net.kyori.adventure.text.Component.*; - /** * A festive version of the {@link ComponentFactory} */ @@ -18,25 +13,25 @@ public class PrideComponentFactory extends ComponentFactory { private final Random random; - public PrideComponentFactory(ConfigHandler config) { - super(config); + public PrideComponentFactory() { + super(); random = new Random(); } @Override public TextComponent getExampleName() { - return deserialize("Artemis_the_gr8"); + return miniMessageToComponent("Artemis_the_gr8"); } @Override public TextComponent sharerName(String sharerName) { - return deserialize(decorateWithRandomGradient(sharerName)); + return miniMessageToComponent(decorateWithRandomGradient(sharerName)); } @Override //12 underscores public TextComponent pluginPrefixAsTitle() { - return deserialize("____________ [PlayerStats] ____________"); + return miniMessageToComponent("____________ [PlayerStats] ____________"); } @Override @@ -48,7 +43,7 @@ public class PrideComponentFactory extends ComponentFactory { } public TextComponent rainbowPrefix() { - return deserialize("<#f74040>[" + + return miniMessageToComponent("<#f74040>[" + "<#F54D39>P" + "<#F16E28>l" + "<#ee8a19>a" + @@ -65,7 +60,7 @@ public class PrideComponentFactory extends ComponentFactory { @Contract(" -> new") private @NotNull TextComponent backwardsPluginPrefixComponent() { - return deserialize("<#631ae6>[" + + return miniMessageToComponent("<#631ae6>[" + "<#3341E6>P" + "<#1F8BEB>l" + "<#01c1a7>a" + @@ -94,11 +89,4 @@ public class PrideComponentFactory extends ComponentFactory { }; return colorString + input + ""; } - - @Contract("_ -> new") - private @NotNull TextComponent deserialize(String input) { - return text() - .append(MiniMessage.miniMessage().deserialize(input)) - .build(); - } } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/ComponentSerializer.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/ComponentSerializer.java index b34f37e..80f6c03 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/ComponentSerializer.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/ComponentSerializer.java @@ -13,8 +13,8 @@ public final class ComponentSerializer { private final LanguageKeyHandler languageKeyHandler; - public ComponentSerializer(LanguageKeyHandler languageKeyHandler) { - this.languageKeyHandler = languageKeyHandler; + public ComponentSerializer() { + languageKeyHandler = LanguageKeyHandler.getInstance(); } /** From fc1ac7c07ef9f476d287d328cb81950f2efd6f80 Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Sat, 29 Oct 2022 13:45:39 +0200 Subject: [PATCH 26/43] Improved rainbow theme --- .../msg/components/PrideComponentFactory.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/PrideComponentFactory.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/PrideComponentFactory.java index 71630c3..19cb4ac 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/PrideComponentFactory.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/msg/components/PrideComponentFactory.java @@ -76,16 +76,16 @@ public class PrideComponentFactory extends ComponentFactory { } private @NotNull String decorateWithRandomGradient(@NotNull String input) { - String colorString = switch (random.nextInt(9)) { - case 0 -> ""; + String colorString = switch (random.nextInt(8)) { + case 0 -> ""; case 1 -> ""; - case 2 -> ""; - case 3 -> ""; - case 4 -> ""; - case 5 -> ""; - case 6 -> ""; - case 7 -> ""; - default -> ""; + case 2 -> ""; + case 3 -> ""; + case 4 -> ""; + case 5 -> ""; + case 6 -> ""; + case 7 -> ""; + default -> ""; }; return colorString + input + ""; } From c4b963a057f08d156bbdfac57736c1c8fcc94bf0 Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Tue, 1 Nov 2022 14:18:25 +0100 Subject: [PATCH 27/43] Separated internal code from api code to improve future maintainability --- dependency-reduced-pom.xml | 2 +- pom.xml | 2 +- .../the/gr8/playerstats/api/PlayerStats.java | 12 ++- .../gr8/playerstats/api/RequestGenerator.java | 2 - .../the/gr8/playerstats/api/StatManager.java | 5 +- .../playerstats/api/StatNumberFormatter.java | 12 +++ .../{statistic => api}/StatRequest.java | 95 ++++++++++--------- .../{statistic => api}/StatResult.java | 5 +- ...tFormatter.java => StatTextFormatter.java} | 15 +-- .../playerstats/{ => api}/enums/Target.java | 2 +- .../gr8/playerstats/{ => api}/enums/Unit.java | 2 +- .../the/gr8/playerstats/{ => core}/Main.java | 34 ++++--- .../{ => core}/commands/ExcludeCommand.java | 6 +- .../{ => core}/commands/ReloadCommand.java | 4 +- .../{ => core}/commands/ShareCommand.java | 12 +-- .../{ => core}/commands/StatCommand.java | 21 ++-- .../{ => core}/commands/TabCompleter.java | 6 +- .../{ => core}/config/ConfigHandler.java | 10 +- .../{ => core}/config/DefaultValueGetter.java | 2 +- .../{ => core}/enums/DebugLevel.java | 2 +- .../{ => core}/enums/PluginColor.java | 2 +- .../{ => core}/enums/StandardMessage.java | 2 +- .../{ => core}/listeners/JoinListener.java | 4 +- .../{ => core}/msg/MessageBuilder.java | 61 +++++------- .../{ => core}/msg/OutputManager.java | 27 +++--- .../BukkitConsoleComponentFactory.java | 27 +++++- .../msg/components/ComponentFactory.java | 54 ++++++----- .../components/ConsoleComponentFactory.java | 24 +++++ .../msg/components/ExampleMessage.java | 14 +-- .../msg/components/ExcludeInfoMessage.java | 18 ++-- .../components/HalloweenComponentFactory.java | 2 +- .../msg/components/HelpMessage.java | 47 +++++---- .../msg/components/PrideComponentFactory.java | 2 +- .../msg/msgutils/ComponentSerializer.java | 2 +- .../msg/msgutils/EasterEggProvider.java | 2 +- .../{ => core}/msg/msgutils/FontUtils.java | 2 +- .../msg/msgutils/FormattingFunction.java | 2 +- .../msg/msgutils/LanguageKeyHandler.java | 8 +- .../msg/msgutils/NumberFormatter.java | 21 ++-- .../{ => core}/msg/msgutils/StringUtils.java | 4 +- .../multithreading/PlayerLoadAction.java | 10 +- .../multithreading/ReloadThread.java | 10 +- .../{ => core}/multithreading/StatAction.java | 8 +- .../{ => core}/multithreading/StatThread.java | 14 +-- .../multithreading/ThreadManager.java | 16 ++-- .../{share => core/sharing}/ShareManager.java | 6 +- .../{share => core/sharing}/StoredResult.java | 2 +- .../statrequest}/PlayerStatRequest.java | 11 ++- .../statrequest}/RequestManager.java | 34 ++++--- .../statrequest}/ServerStatRequest.java | 11 ++- .../statrequest}/TopStatRequest.java | 11 ++- .../{ => core}/utils/EnumHandler.java | 2 +- .../{ => core}/utils/FileHandler.java | 4 +- .../{ => core}/utils/MyLogger.java | 4 +- .../utils/OfflinePlayerHandler.java | 6 +- .../{ => core}/utils/UnixTimeHandler.java | 2 +- src/main/resources/plugin.yml | 2 +- 57 files changed, 395 insertions(+), 334 deletions(-) create mode 100644 src/main/java/com/artemis/the/gr8/playerstats/api/StatNumberFormatter.java rename src/main/java/com/artemis/the/gr8/playerstats/{statistic => api}/StatRequest.java (60%) rename src/main/java/com/artemis/the/gr8/playerstats/{statistic => api}/StatResult.java (95%) rename src/main/java/com/artemis/the/gr8/playerstats/api/{StatFormatter.java => StatTextFormatter.java} (96%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => api}/enums/Target.java (75%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => api}/enums/Unit.java (99%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/Main.java (83%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/commands/ExcludeCommand.java (92%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/commands/ReloadCommand.java (82%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/commands/ShareCommand.java (83%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/commands/StatCommand.java (92%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/commands/TabCompleter.java (97%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/config/ConfigHandler.java (98%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/config/DefaultValueGetter.java (97%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/enums/DebugLevel.java (85%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/enums/PluginColor.java (97%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/enums/StandardMessage.java (89%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/listeners/JoinListener.java (83%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/msg/MessageBuilder.java (95%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/msg/OutputManager.java (88%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/msg/components/BukkitConsoleComponentFactory.java (80%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/msg/components/ComponentFactory.java (93%) create mode 100644 src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ConsoleComponentFactory.java rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/msg/components/ExampleMessage.java (86%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/msg/components/ExcludeInfoMessage.java (75%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/msg/components/HalloweenComponentFactory.java (91%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/msg/components/HelpMessage.java (85%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/msg/components/PrideComponentFactory.java (98%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/msg/msgutils/ComponentSerializer.java (98%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/msg/msgutils/EasterEggProvider.java (98%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/msg/msgutils/FontUtils.java (92%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/msg/msgutils/FormattingFunction.java (93%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/msg/msgutils/LanguageKeyHandler.java (97%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/msg/msgutils/NumberFormatter.java (85%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/msg/msgutils/StringUtils.java (92%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/multithreading/PlayerLoadAction.java (89%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/multithreading/ReloadThread.java (84%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/multithreading/StatAction.java (93%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/multithreading/StatThread.java (83%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/multithreading/ThreadManager.java (89%) rename src/main/java/com/artemis/the/gr8/playerstats/{share => core/sharing}/ShareManager.java (97%) rename src/main/java/com/artemis/the/gr8/playerstats/{share => core/sharing}/StoredResult.java (82%) rename src/main/java/com/artemis/the/gr8/playerstats/{statistic => core/statrequest}/PlayerStatRequest.java (75%) rename src/main/java/com/artemis/the/gr8/playerstats/{statistic => core/statrequest}/RequestManager.java (83%) rename src/main/java/com/artemis/the/gr8/playerstats/{statistic => core/statrequest}/ServerStatRequest.java (74%) rename src/main/java/com/artemis/the/gr8/playerstats/{statistic => core/statrequest}/TopStatRequest.java (77%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/utils/EnumHandler.java (99%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/utils/FileHandler.java (96%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/utils/MyLogger.java (97%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/utils/OfflinePlayerHandler.java (97%) rename src/main/java/com/artemis/the/gr8/playerstats/{ => core}/utils/UnixTimeHandler.java (94%) diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml index e1cc09b..1ca85c8 100644 --- a/dependency-reduced-pom.xml +++ b/dependency-reduced-pom.xml @@ -49,7 +49,7 @@ - com.artemis.the.gr8.playerstats.Main + com.artemis.the.gr8.playerstats.core.Main diff --git a/pom.xml b/pom.xml index 63dd96c..50b63fd 100644 --- a/pom.xml +++ b/pom.xml @@ -141,7 +141,7 @@ - com.artemis.the.gr8.playerstats.Main + com.artemis.the.gr8.playerstats.core.Main diff --git a/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStats.java b/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStats.java index ef00776..0a91708 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStats.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStats.java @@ -1,7 +1,6 @@ package com.artemis.the.gr8.playerstats.api; -import com.artemis.the.gr8.playerstats.Main; -import com.artemis.the.gr8.playerstats.statistic.RequestManager; +import com.artemis.the.gr8.playerstats.core.Main; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; @@ -12,8 +11,9 @@ import org.jetbrains.annotations.NotNull; * and get an instance of PlayerStats. You can then use this object to * access any of the further methods. * - * @see RequestManager - * @see StatFormatter + * @see StatManager + * @see StatTextFormatter + * @see StatNumberFormatter */ public interface PlayerStats { @@ -41,5 +41,7 @@ public interface PlayerStats { StatManager getStatManager(); - StatFormatter getFormatter(); + StatTextFormatter getStatTextFormatter(); + + StatNumberFormatter getStatNumberFormatter(); } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/api/RequestGenerator.java b/src/main/java/com/artemis/the/gr8/playerstats/api/RequestGenerator.java index 6d65dda..d19d531 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/api/RequestGenerator.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/api/RequestGenerator.java @@ -1,7 +1,5 @@ package com.artemis.the.gr8.playerstats.api; -import com.artemis.the.gr8.playerstats.statistic.RequestManager; -import com.artemis.the.gr8.playerstats.statistic.StatRequest; import org.bukkit.Material; import org.bukkit.Statistic; import org.bukkit.entity.EntityType; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/api/StatManager.java b/src/main/java/com/artemis/the/gr8/playerstats/api/StatManager.java index 96b7e97..0317fc3 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/api/StatManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/api/StatManager.java @@ -1,8 +1,5 @@ package com.artemis.the.gr8.playerstats.api; -import com.artemis.the.gr8.playerstats.statistic.StatRequest; -import com.artemis.the.gr8.playerstats.statistic.StatResult; - import java.util.LinkedHashMap; public interface StatManager { @@ -70,4 +67,4 @@ public interface StatManager { * @see StatResult */ StatResult> executeTopRequest(StatRequest> request); -} +} \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/api/StatNumberFormatter.java b/src/main/java/com/artemis/the/gr8/playerstats/api/StatNumberFormatter.java new file mode 100644 index 0000000..a6c2453 --- /dev/null +++ b/src/main/java/com/artemis/the/gr8/playerstats/api/StatNumberFormatter.java @@ -0,0 +1,12 @@ +package com.artemis.the.gr8.playerstats.api; + +import com.artemis.the.gr8.playerstats.api.enums.Unit; + +public interface StatNumberFormatter { + + String formatDamageNumber(long number, Unit statUnit); + + String formatDistanceNumber(long number, Unit statUnit); + + String formatTimeNumber(long number, Unit biggestTimeUnit, Unit smallestTimeUnit); +} diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/api/StatRequest.java similarity index 60% rename from src/main/java/com/artemis/the/gr8/playerstats/statistic/StatRequest.java rename to src/main/java/com/artemis/the/gr8/playerstats/api/StatRequest.java index e060146..2d506cb 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/api/StatRequest.java @@ -1,7 +1,6 @@ -package com.artemis.the.gr8.playerstats.statistic; +package com.artemis.the.gr8.playerstats.api; -import com.artemis.the.gr8.playerstats.api.StatManager; -import com.artemis.the.gr8.playerstats.enums.Target; +import com.artemis.the.gr8.playerstats.api.enums.Target; import org.bukkit.Material; import org.bukkit.Statistic; import org.bukkit.command.CommandSender; @@ -44,6 +43,51 @@ public abstract class StatRequest { } } + protected void configureForPlayer(String playerName) { + this.settings.target = Target.PLAYER; + this.settings.playerName = playerName; + } + + protected void configureForServer() { + this.settings.target = Target.SERVER; + } + + protected void configureForTop(int topListSize) { + this.settings.target = Target.TOP; + this.settings.topListSize = topListSize; + } + + protected void configureUntyped(@NotNull Statistic statistic) { + if (statistic.getType() != Statistic.Type.UNTYPED) { + throw new IllegalArgumentException("This statistic is not of Type.Untyped"); + } + this.settings.statistic = statistic; + } + + protected void configureBlockOrItemType(@NotNull Statistic statistic, @NotNull Material material) throws IllegalArgumentException { + Statistic.Type type = statistic.getType(); + if (type == Statistic.Type.BLOCK && material.isBlock()) { + this.settings.block = material; + } + else if (type == Statistic.Type.ITEM && material.isItem()){ + this.settings.item = material; + } + else { + throw new IllegalArgumentException("Either this statistic is not of Type.Block or Type.Item, or no valid block or item has been provided"); + } + this.settings.statistic = statistic; + this.settings.subStatEntryName = material.toString(); + } + + protected void configureEntityType(@NotNull Statistic statistic, @NotNull EntityType entityType) throws IllegalArgumentException { + if (statistic.getType() != Statistic.Type.ENTITY) { + throw new IllegalArgumentException("This statistic is not of Type.Entity"); + } + this.settings.statistic = statistic; + this.settings.entity = entityType; + this.settings.subStatEntryName = entityType.toString(); + } + private boolean hasMatchingSubStat() { switch (settings.statistic.getType()) { case BLOCK -> { @@ -61,6 +105,7 @@ public abstract class StatRequest { } } + public static final class Settings { private final CommandSender sender; private Statistic statistic; @@ -80,50 +125,6 @@ public abstract class StatRequest { this.sender = sender; } - void configureForPlayer(String playerName) { - this.target = Target.PLAYER; - this.playerName = playerName; - } - - void configureForServer() { - this.target = Target.SERVER; - } - - void configureForTop(int topListSize) { - this.target = Target.TOP; - this.topListSize = topListSize; - } - - void configureUntyped(@NotNull Statistic statistic) { - if (statistic.getType() != Statistic.Type.UNTYPED) { - throw new IllegalArgumentException("This statistic is not of Type.Untyped"); - } - this.statistic = statistic; - } - - void configureBlockOrItemType(@NotNull Statistic statistic, @NotNull Material material) throws IllegalArgumentException { - Statistic.Type type = statistic.getType(); - if (type == Statistic.Type.BLOCK && material.isBlock()) { - this.block = material; - } - else if (type == Statistic.Type.ITEM && material.isItem()){ - this.item = material; - } - else { - throw new IllegalArgumentException("Either this statistic is not of Type.Block or Type.Item, or no valid block or item has been provided"); - } - this.statistic = statistic; - this.subStatEntryName = material.toString(); - } - - void configureEntityType(@NotNull Statistic statistic, @NotNull EntityType entityType) throws IllegalArgumentException { - if (statistic.getType() != Statistic.Type.ENTITY) { - throw new IllegalArgumentException("This statistic is not of Type.Entity"); - } - this.statistic = statistic; - this.entity = entityType; - this.subStatEntryName = entityType.toString(); - } public @NotNull CommandSender getCommandSender() { return sender; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatResult.java b/src/main/java/com/artemis/the/gr8/playerstats/api/StatResult.java similarity index 95% rename from src/main/java/com/artemis/the/gr8/playerstats/statistic/StatResult.java rename to src/main/java/com/artemis/the/gr8/playerstats/api/StatResult.java index fd2b122..8f9aff1 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/StatResult.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/api/StatResult.java @@ -1,6 +1,5 @@ -package com.artemis.the.gr8.playerstats.statistic; +package com.artemis.the.gr8.playerstats.api; -import com.artemis.the.gr8.playerstats.api.StatFormatter; import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.text.TextComponent; @@ -37,7 +36,7 @@ import net.kyori.adventure.text.TextComponent; * same information in String-format. Don't use Adventure's #content() * or #toString() methods on the Components - those won't get the actual * message. And finally, if you want the results to be formatted differently, - * you can get an instance of the {@link StatFormatter}. + * you can get an instance of the {@link StatTextFormatter}. */ public record StatResult(T value, TextComponent formattedComponent, String formattedString) { diff --git a/src/main/java/com/artemis/the/gr8/playerstats/api/StatFormatter.java b/src/main/java/com/artemis/the/gr8/playerstats/api/StatTextFormatter.java similarity index 96% rename from src/main/java/com/artemis/the/gr8/playerstats/api/StatFormatter.java rename to src/main/java/com/artemis/the/gr8/playerstats/api/StatTextFormatter.java index afeb6e8..b062e07 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/api/StatFormatter.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/api/StatTextFormatter.java @@ -1,8 +1,6 @@ package com.artemis.the.gr8.playerstats.api; -import com.artemis.the.gr8.playerstats.enums.Unit; -import com.artemis.the.gr8.playerstats.msg.msgutils.NumberFormatter; -import com.artemis.the.gr8.playerstats.statistic.StatResult; +import com.artemis.the.gr8.playerstats.api.enums.Unit; import net.kyori.adventure.text.TextComponent; import org.bukkit.Statistic; import org.jetbrains.annotations.Nullable; @@ -15,16 +13,7 @@ import org.jetbrains.annotations.Nullable; * @see StatResult */ -public interface StatFormatter { - - /** - * Gets a {@link NumberFormatter} to format raw numbers into something more readable. - * - * @return the NumberFormatter - */ - default NumberFormatter getNumberFormatter() { - return new NumberFormatter(); - } +public interface StatTextFormatter { /** * Turns a TextComponent into its String representation. This method is equipped diff --git a/src/main/java/com/artemis/the/gr8/playerstats/enums/Target.java b/src/main/java/com/artemis/the/gr8/playerstats/api/enums/Target.java similarity index 75% rename from src/main/java/com/artemis/the/gr8/playerstats/enums/Target.java rename to src/main/java/com/artemis/the/gr8/playerstats/api/enums/Target.java index 3824ee1..8444a3c 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/enums/Target.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/api/enums/Target.java @@ -1,4 +1,4 @@ -package com.artemis.the.gr8.playerstats.enums; +package com.artemis.the.gr8.playerstats.api.enums; /** * This enum represents the targets PlayerStats accepts diff --git a/src/main/java/com/artemis/the/gr8/playerstats/enums/Unit.java b/src/main/java/com/artemis/the/gr8/playerstats/api/enums/Unit.java similarity index 99% rename from src/main/java/com/artemis/the/gr8/playerstats/enums/Unit.java rename to src/main/java/com/artemis/the/gr8/playerstats/api/enums/Unit.java index ed07595..71cef78 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/enums/Unit.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/api/enums/Unit.java @@ -1,4 +1,4 @@ -package com.artemis.the.gr8.playerstats.enums; +package com.artemis.the.gr8.playerstats.api.enums; import org.bukkit.Statistic; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/Main.java b/src/main/java/com/artemis/the/gr8/playerstats/core/Main.java similarity index 83% rename from src/main/java/com/artemis/the/gr8/playerstats/Main.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/Main.java index ccdb8b3..b456dc6 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/Main.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/Main.java @@ -1,18 +1,20 @@ -package com.artemis.the.gr8.playerstats; +package com.artemis.the.gr8.playerstats.core; import com.artemis.the.gr8.playerstats.api.PlayerStats; -import com.artemis.the.gr8.playerstats.api.StatFormatter; +import com.artemis.the.gr8.playerstats.api.StatNumberFormatter; +import com.artemis.the.gr8.playerstats.api.StatTextFormatter; import com.artemis.the.gr8.playerstats.api.StatManager; -import com.artemis.the.gr8.playerstats.commands.*; -import com.artemis.the.gr8.playerstats.multithreading.ThreadManager; -import com.artemis.the.gr8.playerstats.statistic.RequestManager; -import com.artemis.the.gr8.playerstats.msg.OutputManager; -import com.artemis.the.gr8.playerstats.config.ConfigHandler; -import com.artemis.the.gr8.playerstats.listeners.JoinListener; -import com.artemis.the.gr8.playerstats.msg.msgutils.LanguageKeyHandler; -import com.artemis.the.gr8.playerstats.share.ShareManager; -import com.artemis.the.gr8.playerstats.utils.MyLogger; -import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; +import com.artemis.the.gr8.playerstats.core.commands.*; +import com.artemis.the.gr8.playerstats.core.msg.msgutils.NumberFormatter; +import com.artemis.the.gr8.playerstats.core.multithreading.ThreadManager; +import com.artemis.the.gr8.playerstats.core.statrequest.RequestManager; +import com.artemis.the.gr8.playerstats.core.msg.OutputManager; +import com.artemis.the.gr8.playerstats.core.config.ConfigHandler; +import com.artemis.the.gr8.playerstats.core.listeners.JoinListener; +import com.artemis.the.gr8.playerstats.core.msg.msgutils.LanguageKeyHandler; +import com.artemis.the.gr8.playerstats.core.sharing.ShareManager; +import com.artemis.the.gr8.playerstats.core.utils.MyLogger; +import com.artemis.the.gr8.playerstats.core.utils.OfflinePlayerHandler; import me.clip.placeholderapi.PlaceholderAPIPlugin; import me.clip.placeholderapi.expansion.PlaceholderExpansion; import net.kyori.adventure.platform.bukkit.BukkitAudiences; @@ -176,7 +178,13 @@ public final class Main extends JavaPlugin implements PlayerStats { } @Override - public StatFormatter getFormatter() { + public StatTextFormatter getStatTextFormatter() { return outputManager.getMainMessageBuilder(); } + + @Contract(" -> new") + @Override + public @NotNull StatNumberFormatter getStatNumberFormatter() { + return new NumberFormatter(); + } } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/ExcludeCommand.java b/src/main/java/com/artemis/the/gr8/playerstats/core/commands/ExcludeCommand.java similarity index 92% rename from src/main/java/com/artemis/the/gr8/playerstats/commands/ExcludeCommand.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/commands/ExcludeCommand.java index 60fc7c1..8e462d8 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/ExcludeCommand.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/commands/ExcludeCommand.java @@ -1,8 +1,8 @@ -package com.artemis.the.gr8.playerstats.commands; +package com.artemis.the.gr8.playerstats.core.commands; -import com.artemis.the.gr8.playerstats.msg.OutputManager; -import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; +import com.artemis.the.gr8.playerstats.core.msg.OutputManager; +import com.artemis.the.gr8.playerstats.core.utils.OfflinePlayerHandler; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/ReloadCommand.java b/src/main/java/com/artemis/the/gr8/playerstats/core/commands/ReloadCommand.java similarity index 82% rename from src/main/java/com/artemis/the/gr8/playerstats/commands/ReloadCommand.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/commands/ReloadCommand.java index 4f2d869..e3f0036 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/ReloadCommand.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/commands/ReloadCommand.java @@ -1,6 +1,6 @@ -package com.artemis.the.gr8.playerstats.commands; +package com.artemis.the.gr8.playerstats.core.commands; -import com.artemis.the.gr8.playerstats.multithreading.ThreadManager; +import com.artemis.the.gr8.playerstats.core.multithreading.ThreadManager; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/ShareCommand.java b/src/main/java/com/artemis/the/gr8/playerstats/core/commands/ShareCommand.java similarity index 83% rename from src/main/java/com/artemis/the/gr8/playerstats/commands/ShareCommand.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/commands/ShareCommand.java index 6b09b1a..ffcd633 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/ShareCommand.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/commands/ShareCommand.java @@ -1,10 +1,10 @@ -package com.artemis.the.gr8.playerstats.commands; +package com.artemis.the.gr8.playerstats.core.commands; -import com.artemis.the.gr8.playerstats.share.ShareManager; -import com.artemis.the.gr8.playerstats.enums.StandardMessage; -import com.artemis.the.gr8.playerstats.msg.OutputManager; -import com.artemis.the.gr8.playerstats.share.StoredResult; -import com.artemis.the.gr8.playerstats.utils.MyLogger; +import com.artemis.the.gr8.playerstats.core.sharing.ShareManager; +import com.artemis.the.gr8.playerstats.core.enums.StandardMessage; +import com.artemis.the.gr8.playerstats.core.msg.OutputManager; +import com.artemis.the.gr8.playerstats.core.sharing.StoredResult; +import com.artemis.the.gr8.playerstats.core.utils.MyLogger; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java b/src/main/java/com/artemis/the/gr8/playerstats/core/commands/StatCommand.java similarity index 92% rename from src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/commands/StatCommand.java index 9e921ac..c885ea6 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/StatCommand.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/commands/StatCommand.java @@ -1,14 +1,17 @@ -package com.artemis.the.gr8.playerstats.commands; +package com.artemis.the.gr8.playerstats.core.commands; -import com.artemis.the.gr8.playerstats.multithreading.ThreadManager; +import com.artemis.the.gr8.playerstats.api.StatRequest; +import com.artemis.the.gr8.playerstats.core.multithreading.ThreadManager; import com.artemis.the.gr8.playerstats.api.RequestGenerator; -import com.artemis.the.gr8.playerstats.config.ConfigHandler; -import com.artemis.the.gr8.playerstats.enums.StandardMessage; -import com.artemis.the.gr8.playerstats.enums.Target; -import com.artemis.the.gr8.playerstats.msg.OutputManager; -import com.artemis.the.gr8.playerstats.statistic.*; -import com.artemis.the.gr8.playerstats.utils.EnumHandler; -import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; +import com.artemis.the.gr8.playerstats.core.config.ConfigHandler; +import com.artemis.the.gr8.playerstats.core.enums.StandardMessage; +import com.artemis.the.gr8.playerstats.api.enums.Target; +import com.artemis.the.gr8.playerstats.core.msg.OutputManager; +import com.artemis.the.gr8.playerstats.core.statrequest.PlayerStatRequest; +import com.artemis.the.gr8.playerstats.core.statrequest.ServerStatRequest; +import com.artemis.the.gr8.playerstats.core.statrequest.TopStatRequest; +import com.artemis.the.gr8.playerstats.core.utils.EnumHandler; +import com.artemis.the.gr8.playerstats.core.utils.OfflinePlayerHandler; import org.bukkit.Material; import org.bukkit.Statistic; import org.bukkit.command.Command; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/TabCompleter.java b/src/main/java/com/artemis/the/gr8/playerstats/core/commands/TabCompleter.java similarity index 97% rename from src/main/java/com/artemis/the/gr8/playerstats/commands/TabCompleter.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/commands/TabCompleter.java index 836688e..9187146 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/TabCompleter.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/commands/TabCompleter.java @@ -1,7 +1,7 @@ -package com.artemis.the.gr8.playerstats.commands; +package com.artemis.the.gr8.playerstats.core.commands; -import com.artemis.the.gr8.playerstats.utils.EnumHandler; -import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; +import com.artemis.the.gr8.playerstats.core.utils.EnumHandler; +import com.artemis.the.gr8.playerstats.core.utils.OfflinePlayerHandler; import org.bukkit.Material; import org.bukkit.Statistic; import org.bukkit.command.Command; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/config/ConfigHandler.java b/src/main/java/com/artemis/the/gr8/playerstats/core/config/ConfigHandler.java similarity index 98% rename from src/main/java/com/artemis/the/gr8/playerstats/config/ConfigHandler.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/config/ConfigHandler.java index 6da522d..68ca9f5 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/config/ConfigHandler.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/config/ConfigHandler.java @@ -1,9 +1,9 @@ -package com.artemis.the.gr8.playerstats.config; +package com.artemis.the.gr8.playerstats.core.config; -import com.artemis.the.gr8.playerstats.enums.Target; -import com.artemis.the.gr8.playerstats.enums.Unit; -import com.artemis.the.gr8.playerstats.utils.FileHandler; -import com.artemis.the.gr8.playerstats.utils.MyLogger; +import com.artemis.the.gr8.playerstats.api.enums.Target; +import com.artemis.the.gr8.playerstats.api.enums.Unit; +import com.artemis.the.gr8.playerstats.core.utils.FileHandler; +import com.artemis.the.gr8.playerstats.core.utils.MyLogger; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/config/DefaultValueGetter.java b/src/main/java/com/artemis/the/gr8/playerstats/core/config/DefaultValueGetter.java similarity index 97% rename from src/main/java/com/artemis/the/gr8/playerstats/config/DefaultValueGetter.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/config/DefaultValueGetter.java index c2761c1..19b56d8 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/config/DefaultValueGetter.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/config/DefaultValueGetter.java @@ -1,4 +1,4 @@ -package com.artemis.the.gr8.playerstats.config; +package com.artemis.the.gr8.playerstats.core.config; import org.bukkit.configuration.file.FileConfiguration; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/enums/DebugLevel.java b/src/main/java/com/artemis/the/gr8/playerstats/core/enums/DebugLevel.java similarity index 85% rename from src/main/java/com/artemis/the/gr8/playerstats/enums/DebugLevel.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/enums/DebugLevel.java index 34e76ce..55db286 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/enums/DebugLevel.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/enums/DebugLevel.java @@ -1,4 +1,4 @@ -package com.artemis.the.gr8.playerstats.enums; +package com.artemis.the.gr8.playerstats.core.enums; /** * Represents the debugging level that PlayerStats can use. diff --git a/src/main/java/com/artemis/the/gr8/playerstats/enums/PluginColor.java b/src/main/java/com/artemis/the/gr8/playerstats/core/enums/PluginColor.java similarity index 97% rename from src/main/java/com/artemis/the/gr8/playerstats/enums/PluginColor.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/enums/PluginColor.java index ac70cbb..9bfdab3 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/enums/PluginColor.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/enums/PluginColor.java @@ -1,4 +1,4 @@ -package com.artemis.the.gr8.playerstats.enums; +package com.artemis.the.gr8.playerstats.core.enums; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.TextColor; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/enums/StandardMessage.java b/src/main/java/com/artemis/the/gr8/playerstats/core/enums/StandardMessage.java similarity index 89% rename from src/main/java/com/artemis/the/gr8/playerstats/enums/StandardMessage.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/enums/StandardMessage.java index dd43f03..6f90bad 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/enums/StandardMessage.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/enums/StandardMessage.java @@ -1,4 +1,4 @@ -package com.artemis.the.gr8.playerstats.enums; +package com.artemis.the.gr8.playerstats.core.enums; /** * All standard messages PlayerStats can send as feedback. diff --git a/src/main/java/com/artemis/the/gr8/playerstats/listeners/JoinListener.java b/src/main/java/com/artemis/the/gr8/playerstats/core/listeners/JoinListener.java similarity index 83% rename from src/main/java/com/artemis/the/gr8/playerstats/listeners/JoinListener.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/listeners/JoinListener.java index d7c2d11..8719b33 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/listeners/JoinListener.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/listeners/JoinListener.java @@ -1,6 +1,6 @@ -package com.artemis.the.gr8.playerstats.listeners; +package com.artemis.the.gr8.playerstats.core.listeners; -import com.artemis.the.gr8.playerstats.multithreading.ThreadManager; +import com.artemis.the.gr8.playerstats.core.multithreading.ThreadManager; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/MessageBuilder.java similarity index 95% rename from src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/msg/MessageBuilder.java index 67d4f3f..86d65e2 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/MessageBuilder.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/MessageBuilder.java @@ -1,14 +1,14 @@ -package com.artemis.the.gr8.playerstats.msg; +package com.artemis.the.gr8.playerstats.core.msg; -import com.artemis.the.gr8.playerstats.api.StatFormatter; -import com.artemis.the.gr8.playerstats.msg.components.*; -import com.artemis.the.gr8.playerstats.msg.msgutils.*; -import com.artemis.the.gr8.playerstats.statistic.StatRequest; -import com.artemis.the.gr8.playerstats.utils.EnumHandler; -import com.artemis.the.gr8.playerstats.utils.MyLogger; -import com.artemis.the.gr8.playerstats.enums.Target; -import com.artemis.the.gr8.playerstats.config.ConfigHandler; -import com.artemis.the.gr8.playerstats.enums.Unit; +import com.artemis.the.gr8.playerstats.api.StatTextFormatter; +import com.artemis.the.gr8.playerstats.core.msg.components.*; +import com.artemis.the.gr8.playerstats.core.msg.msgutils.*; +import com.artemis.the.gr8.playerstats.api.StatRequest; +import com.artemis.the.gr8.playerstats.core.utils.EnumHandler; +import com.artemis.the.gr8.playerstats.core.utils.MyLogger; +import com.artemis.the.gr8.playerstats.api.enums.Target; +import com.artemis.the.gr8.playerstats.core.config.ConfigHandler; +import com.artemis.the.gr8.playerstats.api.enums.Unit; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.TextComponent; @@ -34,11 +34,10 @@ import static net.kyori.adventure.text.Component.*; * @see PrideComponentFactory * @see BukkitConsoleComponentFactory */ -public final class MessageBuilder implements StatFormatter { +public final class MessageBuilder implements StatTextFormatter { private final ConfigHandler config; - private boolean useHoverText; - private boolean isConsoleBuilder; + private final boolean useHoverText; private final ComponentFactory componentFactory; private final LanguageKeyHandler languageKeyHandler; @@ -50,7 +49,11 @@ public final class MessageBuilder implements StatFormatter { languageKeyHandler = LanguageKeyHandler.getInstance(); componentFactory = factory; - useHoverText = config.useHoverText(); + if (componentFactory.isConsoleFactory()) { + useHoverText = false; + } else { + useHoverText = config.useHoverText(); + } formatter = new NumberFormatter(); serializer = new ComponentSerializer(); } @@ -65,18 +68,6 @@ public final class MessageBuilder implements StatFormatter { return new MessageBuilder(factory); } - /** - * Set whether this {@link MessageBuilder} should use hoverText. - * By default, this follows the setting specified in the {@link ConfigHandler}. - */ - public void toggleHoverUse(boolean desiredSetting) { - useHoverText = desiredSetting; - } - - public void setConsoleBuilder(boolean isConsoleBuilder) { - this.isConsoleBuilder = isConsoleBuilder; - } - @Override public @NotNull String textComponentToString(TextComponent component) { return serializer.getTranslatableComponentSerializer().serialize(component); @@ -186,7 +177,7 @@ public final class MessageBuilder implements StatFormatter { public TextComponent helpMsg() { int listSize = config.getTopListMaxSize(); - if (!isConsoleBuilder && useHoverText) { + if (useHoverText) { return HelpMessage.constructHoverMsg(componentFactory, listSize); } else { return HelpMessage.constructPlainMsg(componentFactory, listSize); @@ -638,16 +629,10 @@ public final class MessageBuilder implements StatFormatter { */ private @NotNull TextComponent getDamageUnitComponent(Unit unit, Target target) { if (unit == Unit.HEART) { - TextComponent heartUnit; - if (isConsoleBuilder) { - heartUnit = componentFactory.consoleHeart(); - } else if (useHoverText) { - heartUnit = componentFactory.clientHeartWithHoverText(); - } else { - heartUnit = componentFactory.clientHeart(false); - } - return Component.space() - .append(heartUnit); + TextComponent heartUnit = useHoverText ? + componentFactory.heartBetweenBracketsWithHoverText() : + componentFactory.heartBetweenBrackets(); + return Component.space().append(heartUnit); } return Component.space() .append(componentFactory.statUnit(unit.getLabel(), target)); @@ -702,7 +687,7 @@ public final class MessageBuilder implements StatFormatter { } private int getNumberOfDotsToAlign(String displayText) { - if (isConsoleBuilder) { + if (componentFactory.isConsoleFactory()) { return FontUtils.getNumberOfDotsToAlignForConsole(displayText); } else if (config.playerNameIsBold()) { return FontUtils.getNumberOfDotsToAlignForBoldText(displayText); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/OutputManager.java similarity index 88% rename from src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/msg/OutputManager.java index 931bcb5..14e7b5e 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/OutputManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/OutputManager.java @@ -1,13 +1,14 @@ -package com.artemis.the.gr8.playerstats.msg; +package com.artemis.the.gr8.playerstats.core.msg; -import com.artemis.the.gr8.playerstats.api.StatFormatter; -import com.artemis.the.gr8.playerstats.config.ConfigHandler; -import com.artemis.the.gr8.playerstats.enums.StandardMessage; -import com.artemis.the.gr8.playerstats.msg.components.BukkitConsoleComponentFactory; -import com.artemis.the.gr8.playerstats.msg.components.HalloweenComponentFactory; -import com.artemis.the.gr8.playerstats.msg.components.PrideComponentFactory; -import com.artemis.the.gr8.playerstats.msg.msgutils.FormattingFunction; -import com.artemis.the.gr8.playerstats.statistic.StatRequest; +import com.artemis.the.gr8.playerstats.api.StatTextFormatter; +import com.artemis.the.gr8.playerstats.core.config.ConfigHandler; +import com.artemis.the.gr8.playerstats.core.enums.StandardMessage; +import com.artemis.the.gr8.playerstats.core.msg.components.ConsoleComponentFactory; +import com.artemis.the.gr8.playerstats.core.msg.components.PrideComponentFactory; +import com.artemis.the.gr8.playerstats.core.msg.components.BukkitConsoleComponentFactory; +import com.artemis.the.gr8.playerstats.core.msg.components.HalloweenComponentFactory; +import com.artemis.the.gr8.playerstats.core.msg.msgutils.FormattingFunction; +import com.artemis.the.gr8.playerstats.api.StatRequest; import net.kyori.adventure.platform.bukkit.BukkitAudiences; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.TextComponent; @@ -24,7 +25,7 @@ import java.util.EnumMap; import java.util.LinkedHashMap; import java.util.function.Function; -import static com.artemis.the.gr8.playerstats.enums.StandardMessage.*; +import static com.artemis.the.gr8.playerstats.core.enums.StandardMessage.*; /** * This class manages all PlayerStats output. It is the only @@ -54,7 +55,7 @@ public final class OutputManager { getMessageBuilders(); } - public StatFormatter getMainMessageBuilder() { + public StatTextFormatter getMainMessageBuilder() { return messageBuilder; } @@ -169,10 +170,8 @@ public final class OutputManager { if (isBukkit()) { consoleBuilder = MessageBuilder.fromComponentFactory(new BukkitConsoleComponentFactory()); } else { - consoleBuilder = getClientMessageBuilder(); + consoleBuilder = MessageBuilder.fromComponentFactory(new ConsoleComponentFactory()); } - consoleBuilder.setConsoleBuilder(true); - consoleBuilder.toggleHoverUse(false); return consoleBuilder; } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/BukkitConsoleComponentFactory.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/BukkitConsoleComponentFactory.java similarity index 80% rename from src/main/java/com/artemis/the/gr8/playerstats/msg/components/BukkitConsoleComponentFactory.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/BukkitConsoleComponentFactory.java index 5cfd5de..0cb35df 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/BukkitConsoleComponentFactory.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/BukkitConsoleComponentFactory.java @@ -1,6 +1,6 @@ -package com.artemis.the.gr8.playerstats.msg.components; +package com.artemis.the.gr8.playerstats.core.msg.components; -import com.artemis.the.gr8.playerstats.enums.PluginColor; +import com.artemis.the.gr8.playerstats.core.enums.PluginColor; import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.format.TextColor; @@ -40,6 +40,29 @@ public class BukkitConsoleComponentFactory extends ComponentFactory { MSG_HOVER_ACCENT = PluginColor.LIGHT_GOLD.getConsoleColor(); } + @Override + public boolean isConsoleFactory() { + return true; + } + + @Override + public TextComponent heart() { + return text() + .content(String.valueOf('\u2665')) + .color(HEARTS) + .build(); + } + + @Override + public TextComponent arrow() { + return text("->").color(INFO_MSG); + } + + @Override + public TextComponent bulletPoint() { + return text("*").color(INFO_MSG); + } + @Override protected TextComponent getComponent(String content, @NotNull TextColor color, @Nullable TextDecoration style) { return getComponentBuilder(content, NamedTextColor.nearestTo(color), style).build(); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentFactory.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ComponentFactory.java similarity index 93% rename from src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentFactory.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ComponentFactory.java index 16dd0ce..ec0ea2b 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ComponentFactory.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ComponentFactory.java @@ -1,11 +1,11 @@ -package com.artemis.the.gr8.playerstats.msg.components; +package com.artemis.the.gr8.playerstats.core.msg.components; -import com.artemis.the.gr8.playerstats.config.ConfigHandler; -import com.artemis.the.gr8.playerstats.enums.PluginColor; -import com.artemis.the.gr8.playerstats.enums.Target; -import com.artemis.the.gr8.playerstats.enums.Unit; -import com.artemis.the.gr8.playerstats.msg.MessageBuilder; -import com.artemis.the.gr8.playerstats.msg.msgutils.LanguageKeyHandler; +import com.artemis.the.gr8.playerstats.core.config.ConfigHandler; +import com.artemis.the.gr8.playerstats.core.enums.PluginColor; +import com.artemis.the.gr8.playerstats.api.enums.Target; +import com.artemis.the.gr8.playerstats.api.enums.Unit; +import com.artemis.the.gr8.playerstats.core.msg.msgutils.LanguageKeyHandler; +import com.artemis.the.gr8.playerstats.core.msg.MessageBuilder; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.TranslatableComponent; @@ -83,6 +83,10 @@ public class ComponentFactory { .build(); } + public boolean isConsoleFactory() { + return false; + } + public TextComponent getExampleName() { return text("Artemis_the_gr8").color(INFO_MSG_ACCENT_2); } @@ -271,7 +275,7 @@ public class ComponentFactory { } public TextComponent damageNumberWithHeartUnitInHoverText(String mainNumber, String hoverNumber, Target target) { - return statNumberWithHoverText(mainNumber, hoverNumber, null, null, clientHeart(true), target); + return statNumberWithHoverText(mainNumber, hoverNumber, null, null, heart(), target); } public TextComponent distanceNumber(String prettyNumber, Target target) { @@ -304,35 +308,33 @@ public class ComponentFactory { return surroundWithBrackets(statUnit); } - public TextComponent clientHeart(boolean isDisplayedInHoverText) { - TextComponent basicHeartComponent = basicHeartComponent('\u2764'); - if (isDisplayedInHoverText) { - return basicHeartComponent; - } - return surroundWithBrackets(basicHeartComponent); + public TextComponent heart() { + return text() + .content(String.valueOf('\u2764')) + .color(HEARTS) + .build(); } - public TextComponent clientHeartWithHoverText() { - TextComponent basicHeartComponent = basicHeartComponent('\u2764') + public TextComponent heartBetweenBrackets() { + return surroundWithBrackets(heart()); + } + + public TextComponent heartBetweenBracketsWithHoverText() { + TextComponent heart = heart() .toBuilder() .hoverEvent(HoverEvent.showText( text(Unit.HEART.getLabel()) .color(MSG_HOVER_ACCENT))) .build(); - return surroundWithBrackets(basicHeartComponent); + return surroundWithBrackets(heart); } - public TextComponent consoleHeart() { - return surroundWithBrackets(basicHeartComponent('\u2665')); + public TextComponent arrow() { + return text("→").color(INFO_MSG); //alt + 26 } - //console can do u2665, u2764 looks better in-game - @Contract("_ -> new") - private @NotNull TextComponent basicHeartComponent(char heartChar) { - return Component.text() - .content(String.valueOf(heartChar)) - .color(HEARTS) - .build(); + public TextComponent bulletPoint() { + return text("•").color(INFO_MSG); //alt + 7 } /** diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ConsoleComponentFactory.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ConsoleComponentFactory.java new file mode 100644 index 0000000..38bdb01 --- /dev/null +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ConsoleComponentFactory.java @@ -0,0 +1,24 @@ +package com.artemis.the.gr8.playerstats.core.msg.components; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.TextComponent; + +public class ConsoleComponentFactory extends ComponentFactory { + + public ConsoleComponentFactory() { + super(); + } + + @Override + public boolean isConsoleFactory() { + return true; + } + + @Override + public TextComponent heart() { + return Component.text() + .content(String.valueOf('\u2665')) + .color(HEARTS) + .build(); + } +} diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ExampleMessage.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ExampleMessage.java similarity index 86% rename from src/main/java/com/artemis/the/gr8/playerstats/msg/components/ExampleMessage.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ExampleMessage.java index 25c0afa..5f8b877 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ExampleMessage.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ExampleMessage.java @@ -1,4 +1,4 @@ -package com.artemis.the.gr8.playerstats.msg.components; +package com.artemis.the.gr8.playerstats.core.msg.components; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.ComponentLike; @@ -29,25 +29,27 @@ public final class ExampleMessage implements TextComponent { } private @NotNull TextComponent buildMessage(@NotNull ComponentFactory factory) { - String arrowString = factory instanceof BukkitConsoleComponentFactory ? " -> " : " → "; //4 spaces, alt + 26, 1 space - TextComponent arrow = text(arrowString).color(factory.INFO_MSG); + TextComponent spaces = text(" "); //4 spaces return Component.newline() .append(factory.pluginPrefixAsTitle()) .append(Component.newline()) .append(factory.subTitle("Examples: ")) .append(Component.newline()) - .append(arrow) + .append(spaces).append( + factory.arrow()).append(Component.space()) .append(text("/stat ").color(factory.INFO_MSG) .append(text("animals_bred ").color(factory.INFO_MSG_ACCENT_1) .append(text("top").color(factory.INFO_MSG_ACCENT_2)))) .append(Component.newline()) - .append(arrow) + .append(spaces).append( + factory.arrow()).append(Component.space()) .append(text("/stat ").color(factory.INFO_MSG) .append(text("mine_block diorite ").color(factory.INFO_MSG_ACCENT_1) .append(text("me").color(factory.INFO_MSG_ACCENT_2)))) .append(Component.newline()) - .append(arrow) + .append(spaces).append( + factory.arrow()).append(Component.space()) .append(text("/stat ").color(factory.INFO_MSG) .append(text("deaths ").color(factory.INFO_MSG_ACCENT_1) .append(text("player ").color(factory.INFO_MSG_ACCENT_2) diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ExcludeInfoMessage.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ExcludeInfoMessage.java similarity index 75% rename from src/main/java/com/artemis/the/gr8/playerstats/msg/components/ExcludeInfoMessage.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ExcludeInfoMessage.java index 322a4bd..44f21df 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/ExcludeInfoMessage.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ExcludeInfoMessage.java @@ -1,4 +1,4 @@ -package com.artemis.the.gr8.playerstats.msg.components; +package com.artemis.the.gr8.playerstats.core.msg.components; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.ComponentLike; @@ -26,8 +26,7 @@ public final class ExcludeInfoMessage implements TextComponent { } private @NotNull TextComponent buildMessage(@NotNull ComponentFactory factory) { - String arrowString = factory instanceof BukkitConsoleComponentFactory ? " -> " : " → "; //4 spaces, alt + 26, 1 space - TextComponent arrow = text(arrowString).color(factory.INFO_MSG); + TextComponent spaces = text(" "); return Component.newline() .append(factory.pluginPrefixAsTitle()) @@ -36,11 +35,18 @@ public final class ExcludeInfoMessage implements TextComponent { .append(Component.newline()) .append(factory.subTitle("specific players' results from /stat lookups")) .append(Component.newline()) - .append(text("Excluded players are:").color(factory.INFO_MSG)) + .append(text("Excluded players are:") + .color(factory.INFO_MSG)) .append(Component.newline()) - .append(arrow).append(text("not visible in the top 10").color(factory.INFO_MSG_ACCENT_1)) + .append(spaces).append( + factory.arrow()).append(Component.space()) + .append(text("not visible in the top 10") + .color(factory.INFO_MSG_ACCENT_1)) .append(Component.newline()) - .append(arrow).append(text("not counted for the server total").color(factory.INFO_MSG_ACCENT_1)); + .append(spaces).append( + factory.arrow()).append(Component.space()) + .append(text("not counted for the server total") + .color(factory.INFO_MSG_ACCENT_1)); } @Override diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/HalloweenComponentFactory.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/HalloweenComponentFactory.java similarity index 91% rename from src/main/java/com/artemis/the/gr8/playerstats/msg/components/HalloweenComponentFactory.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/HalloweenComponentFactory.java index 915400a..4393efa 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/HalloweenComponentFactory.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/HalloweenComponentFactory.java @@ -1,4 +1,4 @@ -package com.artemis.the.gr8.playerstats.msg.components; +package com.artemis.the.gr8.playerstats.core.msg.components; import net.kyori.adventure.text.TextComponent; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/HelpMessage.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/HelpMessage.java similarity index 85% rename from src/main/java/com/artemis/the/gr8/playerstats/msg/components/HelpMessage.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/HelpMessage.java index 179dda8..9a070d0 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/HelpMessage.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/HelpMessage.java @@ -1,4 +1,4 @@ -package com.artemis.the.gr8.playerstats.msg.components; +package com.artemis.the.gr8.playerstats.core.msg.components; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.ComponentLike; @@ -40,16 +40,7 @@ public final class HelpMessage implements TextComponent { } private @NotNull TextComponent buildPlainMsg(ComponentFactory factory, int listSize) { - String arrowSymbol = "→"; //alt + 26 - String bulletSymbol = "•"; //alt + 7 - - if (factory instanceof BukkitConsoleComponentFactory) { - arrowSymbol = "->"; - bulletSymbol = "*"; - } TextComponent spaces = text(" "); //4 spaces - TextComponent arrow = text(arrowSymbol).color(factory.INFO_MSG); - TextComponent bullet = text(bulletSymbol).color(factory.INFO_MSG); return Component.newline() .append(factory.pluginPrefixAsTitle()) @@ -59,39 +50,46 @@ public final class HelpMessage implements TextComponent { .append(text("Usage:").color(factory.INFO_MSG)).append(space()) .append(text("/statistic").color(factory.MSG_HOVER_ACCENT)) .append(newline()) - .append(spaces).append(arrow).append(space()) + .append(spaces).append( + factory.arrow()).append(space()) .append(text("name").color(factory.MSG_HOVER_ACCENT)) .append(newline()) - .append(spaces).append(arrow).append(space()) + .append(spaces).append( + factory.arrow()).append(space()) .append(text("{sub-statistic}").color(factory.MSG_HOVER_ACCENT)).append(space()) .append(text("(a block, item or entity)").color(factory.BRACKETS)) .append(newline()) - .append(spaces).append(arrow).append(space()) + .append(spaces).append( + factory.arrow()).append(space()) .append(text("me | player | server | top").color(factory.MSG_HOVER_ACCENT)) .append(newline()) - .append(spaces).append(spaces).append(bullet).append(space()) + .append(spaces).append(spaces).append( + factory.bulletPoint()).append(space()) .append(text("me:").color(factory.INFO_MSG_ACCENT_1)).append(space()) .append(text("your own statistic").color(factory.BRACKETS)) .append(newline()) - .append(spaces).append(spaces).append(bullet).append(space()) + .append(spaces).append(spaces).append( + factory.bulletPoint()).append(space()) .append(text("player:").color(factory.INFO_MSG_ACCENT_1)).append(space()) .append(text("choose a player").color(factory.BRACKETS)) .append(newline()) - .append(spaces).append(spaces).append(bullet).append(space()) + .append(spaces).append(spaces).append( + factory.bulletPoint()).append(space()) .append(text("server:").color(factory.INFO_MSG_ACCENT_1)).append(space()) .append(text("everyone on the server combined").color(factory.BRACKETS)) .append(newline()) - .append(spaces).append(spaces).append(bullet).append(space()) + .append(spaces).append(spaces).append( + factory.bulletPoint()).append(space()) .append(text("top:").color(factory.INFO_MSG_ACCENT_1)).append(space()) .append(text("the top").color(factory.BRACKETS).append(space()).append(text(listSize))) .append(newline()) - .append(spaces).append(arrow).append(space()) + .append(spaces).append( + factory.arrow()).append(space()) .append(text("{player-name}").color(factory.MSG_HOVER_ACCENT)); } private @NotNull TextComponent buildHoverMsg(@NotNull ComponentFactory factory, int listSize) { TextComponent spaces = text(" "); - TextComponent arrow = text("→").color(factory.INFO_MSG); return Component.newline() .append(factory.pluginPrefixAsTitle()) @@ -101,14 +99,14 @@ public final class HelpMessage implements TextComponent { .append(text("Usage:").color(factory.INFO_MSG)).append(space()) .append(text("/statistic").color(factory.MSG_HOVER_ACCENT)) .append(newline()) - .append(spaces).append(arrow).append(space()) + .append(spaces).append(factory.arrow()).append(space()) .append(text("name").color(factory.MSG_HOVER_ACCENT) .hoverEvent(HoverEvent.showText(text("The name that describes the statistic").color(factory.MSG_HOVER) .append(newline()) .append(text("Example: ").color(factory.INFO_MSG)) .append(text("\"animals_bred\"").color(factory.MSG_HOVER_ACCENT))))) .append(newline()) - .append(spaces).append(arrow).append(space()) + .append(spaces).append(factory.arrow()).append(space()) .append(text("sub-statistic").color(factory.MSG_HOVER_ACCENT) .hoverEvent(HoverEvent.showText( text("Some statistics need an item, block or entity as extra input").color(factory.MSG_HOVER) @@ -116,9 +114,10 @@ public final class HelpMessage implements TextComponent { .append(text("Example: ").color(factory.INFO_MSG) .append(text("\"mine_block diorite\"").color(factory.MSG_HOVER_ACCENT)))))) .append(newline()) - .append(spaces).append(arrow + .append(spaces).append(factory.arrow() .hoverEvent(HoverEvent.showText( - text("Choose one").color(factory.MSG_CLICKED)))).append(space()) + text("Choose one").color(factory.MSG_CLICKED)))) + .append(space()) .append(text("me").color(factory.MSG_HOVER_ACCENT) .hoverEvent(HoverEvent.showText( text("See your own statistic").color(factory.MSG_HOVER)))) @@ -136,7 +135,7 @@ public final class HelpMessage implements TextComponent { text("See the top").color(factory.MSG_HOVER).append(space()) .append(text(listSize))))) .append(newline()) - .append(spaces).append(arrow).append(space()) + .append(spaces).append(factory.arrow()).append(space()) .append(text("player-name").color(factory.MSG_HOVER_ACCENT) .hoverEvent(HoverEvent.showText( text("In case you typed").color(factory.MSG_HOVER).append(space()) diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/PrideComponentFactory.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/PrideComponentFactory.java similarity index 98% rename from src/main/java/com/artemis/the/gr8/playerstats/msg/components/PrideComponentFactory.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/PrideComponentFactory.java index 19cb4ac..37cdcde 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/components/PrideComponentFactory.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/PrideComponentFactory.java @@ -1,4 +1,4 @@ -package com.artemis.the.gr8.playerstats.msg.components; +package com.artemis.the.gr8.playerstats.core.msg.components; import net.kyori.adventure.text.TextComponent; import org.jetbrains.annotations.Contract; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/ComponentSerializer.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/msgutils/ComponentSerializer.java similarity index 98% rename from src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/ComponentSerializer.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/msg/msgutils/ComponentSerializer.java index 80f6c03..b4453fb 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/ComponentSerializer.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/msgutils/ComponentSerializer.java @@ -1,4 +1,4 @@ -package com.artemis.the.gr8.playerstats.msg.msgutils; +package com.artemis.the.gr8.playerstats.core.msg.msgutils; import net.kyori.adventure.text.*; import net.kyori.adventure.text.flattener.ComponentFlattener; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/EasterEggProvider.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/msgutils/EasterEggProvider.java similarity index 98% rename from src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/EasterEggProvider.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/msg/msgutils/EasterEggProvider.java index c908020..3a3c510 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/EasterEggProvider.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/msgutils/EasterEggProvider.java @@ -1,4 +1,4 @@ -package com.artemis.the.gr8.playerstats.msg.msgutils; +package com.artemis.the.gr8.playerstats.core.msg.msgutils; import me.clip.placeholderapi.PlaceholderAPI; import net.kyori.adventure.text.Component; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/FontUtils.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/msgutils/FontUtils.java similarity index 92% rename from src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/FontUtils.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/msg/msgutils/FontUtils.java index 8d3cc6c..17dae0b 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/FontUtils.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/msgutils/FontUtils.java @@ -1,4 +1,4 @@ -package com.artemis.the.gr8.playerstats.msg.msgutils; +package com.artemis.the.gr8.playerstats.core.msg.msgutils; import org.bukkit.map.MinecraftFont; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/FormattingFunction.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/msgutils/FormattingFunction.java similarity index 93% rename from src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/FormattingFunction.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/msg/msgutils/FormattingFunction.java index c231ef9..b368003 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/FormattingFunction.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/msgutils/FormattingFunction.java @@ -1,4 +1,4 @@ -package com.artemis.the.gr8.playerstats.msg.msgutils; +package com.artemis.the.gr8.playerstats.core.msg.msgutils; import net.kyori.adventure.text.TextComponent; import org.bukkit.command.CommandSender; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/LanguageKeyHandler.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/msgutils/LanguageKeyHandler.java similarity index 97% rename from src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/LanguageKeyHandler.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/msg/msgutils/LanguageKeyHandler.java index 6204694..a96a664 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/LanguageKeyHandler.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/msgutils/LanguageKeyHandler.java @@ -1,8 +1,8 @@ -package com.artemis.the.gr8.playerstats.msg.msgutils; +package com.artemis.the.gr8.playerstats.core.msg.msgutils; -import com.artemis.the.gr8.playerstats.utils.EnumHandler; -import com.artemis.the.gr8.playerstats.utils.FileHandler; -import com.artemis.the.gr8.playerstats.enums.Unit; +import com.artemis.the.gr8.playerstats.core.utils.EnumHandler; +import com.artemis.the.gr8.playerstats.core.utils.FileHandler; +import com.artemis.the.gr8.playerstats.api.enums.Unit; import org.bukkit.Material; import org.bukkit.Statistic; import org.bukkit.entity.EntityType; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/NumberFormatter.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/msgutils/NumberFormatter.java similarity index 85% rename from src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/NumberFormatter.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/msg/msgutils/NumberFormatter.java index 74ff77a..efdb677 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/NumberFormatter.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/msgutils/NumberFormatter.java @@ -1,6 +1,8 @@ -package com.artemis.the.gr8.playerstats.msg.msgutils; +package com.artemis.the.gr8.playerstats.core.msg.msgutils; -import com.artemis.the.gr8.playerstats.enums.Unit; +import com.artemis.the.gr8.playerstats.api.StatNumberFormatter; +import com.artemis.the.gr8.playerstats.api.enums.Unit; +import org.jetbrains.annotations.NotNull; import java.text.DecimalFormat; @@ -10,7 +12,7 @@ import java.text.DecimalFormat; * that are easier to understand (for example: from ticks to hours) and adds commas * to break up large numbers. */ -public final class NumberFormatter { +public final class NumberFormatter implements StatNumberFormatter { private final DecimalFormat format; @@ -21,11 +23,9 @@ public final class NumberFormatter { } /** - * Turns the input number into a more readable format depending on its type - * (number-of-times, time-, damage- or distance-based) according to the - * corresponding config settings, and adds commas in groups of 3. + * Adds commas in groups of 3. */ - public String formatNumber(long number) { + public @NotNull String formatNumber(long number) { return format.format(number); } @@ -33,7 +33,8 @@ public final class NumberFormatter { * The unit of damage-based statistics is half a heart by default. * This method turns the number into hearts. */ - public String formatDamageNumber(long number, Unit statUnit) { //7 statistics + @Override + public @NotNull String formatDamageNumber(long number, @NotNull Unit statUnit) { //7 statistics if (statUnit == Unit.HEART) { return format.format(Math.round(number / 2.0)); } else { @@ -47,7 +48,8 @@ public final class NumberFormatter { * and turns it into km or leaves it as cm otherwise, * depending on the config settings. */ - public String formatDistanceNumber(long number, Unit statUnit) { //15 statistics + @Override + public @NotNull String formatDistanceNumber(long number, @NotNull Unit statUnit) { //15 statistics switch (statUnit) { case CM -> { return format.format(number); @@ -69,6 +71,7 @@ public final class NumberFormatter { * @return a String with the form "1D 2H 3M 4S" * (depending on the Unit range selected) */ + @Override public String formatTimeNumber(long number, Unit biggestUnit, Unit smallestUnit) { //5 statistics if (number <= 0) { return "-"; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/StringUtils.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/msgutils/StringUtils.java similarity index 92% rename from src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/StringUtils.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/msg/msgutils/StringUtils.java index 8db7f71..e4f2223 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/StringUtils.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/msgutils/StringUtils.java @@ -1,6 +1,6 @@ -package com.artemis.the.gr8.playerstats.msg.msgutils; +package com.artemis.the.gr8.playerstats.core.msg.msgutils; -import com.artemis.the.gr8.playerstats.utils.MyLogger; +import com.artemis.the.gr8.playerstats.core.utils.MyLogger; import java.util.regex.Matcher; import java.util.regex.Pattern; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/multithreading/PlayerLoadAction.java b/src/main/java/com/artemis/the/gr8/playerstats/core/multithreading/PlayerLoadAction.java similarity index 89% rename from src/main/java/com/artemis/the/gr8/playerstats/multithreading/PlayerLoadAction.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/multithreading/PlayerLoadAction.java index 0d9e7f1..603fd95 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/multithreading/PlayerLoadAction.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/multithreading/PlayerLoadAction.java @@ -1,9 +1,9 @@ -package com.artemis.the.gr8.playerstats.multithreading; +package com.artemis.the.gr8.playerstats.core.multithreading; -import com.artemis.the.gr8.playerstats.config.ConfigHandler; -import com.artemis.the.gr8.playerstats.utils.MyLogger; -import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; -import com.artemis.the.gr8.playerstats.utils.UnixTimeHandler; +import com.artemis.the.gr8.playerstats.core.config.ConfigHandler; +import com.artemis.the.gr8.playerstats.core.utils.MyLogger; +import com.artemis.the.gr8.playerstats.core.utils.OfflinePlayerHandler; +import com.artemis.the.gr8.playerstats.core.utils.UnixTimeHandler; import org.bukkit.OfflinePlayer; import java.util.UUID; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/multithreading/ReloadThread.java b/src/main/java/com/artemis/the/gr8/playerstats/core/multithreading/ReloadThread.java similarity index 84% rename from src/main/java/com/artemis/the/gr8/playerstats/multithreading/ReloadThread.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/multithreading/ReloadThread.java index b259bd6..4ff2ca5 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/multithreading/ReloadThread.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/multithreading/ReloadThread.java @@ -1,9 +1,9 @@ -package com.artemis.the.gr8.playerstats.multithreading; +package com.artemis.the.gr8.playerstats.core.multithreading; -import com.artemis.the.gr8.playerstats.Main; -import com.artemis.the.gr8.playerstats.enums.StandardMessage; -import com.artemis.the.gr8.playerstats.msg.OutputManager; -import com.artemis.the.gr8.playerstats.utils.MyLogger; +import com.artemis.the.gr8.playerstats.core.Main; +import com.artemis.the.gr8.playerstats.core.enums.StandardMessage; +import com.artemis.the.gr8.playerstats.core.msg.OutputManager; +import com.artemis.the.gr8.playerstats.core.utils.MyLogger; import org.bukkit.command.CommandSender; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/multithreading/StatAction.java b/src/main/java/com/artemis/the/gr8/playerstats/core/multithreading/StatAction.java similarity index 93% rename from src/main/java/com/artemis/the/gr8/playerstats/multithreading/StatAction.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/multithreading/StatAction.java index 5a9b50d..df62967 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/multithreading/StatAction.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/multithreading/StatAction.java @@ -1,8 +1,8 @@ -package com.artemis.the.gr8.playerstats.multithreading; +package com.artemis.the.gr8.playerstats.core.multithreading; -import com.artemis.the.gr8.playerstats.statistic.StatRequest; -import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; -import com.artemis.the.gr8.playerstats.utils.MyLogger; +import com.artemis.the.gr8.playerstats.api.StatRequest; +import com.artemis.the.gr8.playerstats.core.utils.OfflinePlayerHandler; +import com.artemis.the.gr8.playerstats.core.utils.MyLogger; import com.google.common.collect.ImmutableList; import org.bukkit.OfflinePlayer; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/multithreading/StatThread.java b/src/main/java/com/artemis/the/gr8/playerstats/core/multithreading/StatThread.java similarity index 83% rename from src/main/java/com/artemis/the/gr8/playerstats/multithreading/StatThread.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/multithreading/StatThread.java index f0ee179..0c46665 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/multithreading/StatThread.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/multithreading/StatThread.java @@ -1,11 +1,11 @@ -package com.artemis.the.gr8.playerstats.multithreading; +package com.artemis.the.gr8.playerstats.core.multithreading; -import com.artemis.the.gr8.playerstats.msg.OutputManager; -import com.artemis.the.gr8.playerstats.statistic.RequestManager; -import com.artemis.the.gr8.playerstats.statistic.StatRequest; -import com.artemis.the.gr8.playerstats.statistic.StatResult; -import com.artemis.the.gr8.playerstats.utils.MyLogger; -import com.artemis.the.gr8.playerstats.enums.StandardMessage; +import com.artemis.the.gr8.playerstats.core.msg.OutputManager; +import com.artemis.the.gr8.playerstats.core.statrequest.RequestManager; +import com.artemis.the.gr8.playerstats.api.StatRequest; +import com.artemis.the.gr8.playerstats.api.StatResult; +import com.artemis.the.gr8.playerstats.core.utils.MyLogger; +import com.artemis.the.gr8.playerstats.core.enums.StandardMessage; import org.bukkit.command.CommandSender; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/multithreading/ThreadManager.java b/src/main/java/com/artemis/the/gr8/playerstats/core/multithreading/ThreadManager.java similarity index 89% rename from src/main/java/com/artemis/the/gr8/playerstats/multithreading/ThreadManager.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/multithreading/ThreadManager.java index 377b071..f16dcc6 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/multithreading/ThreadManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/multithreading/ThreadManager.java @@ -1,12 +1,12 @@ -package com.artemis.the.gr8.playerstats.multithreading; +package com.artemis.the.gr8.playerstats.core.multithreading; -import com.artemis.the.gr8.playerstats.Main; -import com.artemis.the.gr8.playerstats.msg.OutputManager; -import com.artemis.the.gr8.playerstats.config.ConfigHandler; -import com.artemis.the.gr8.playerstats.enums.StandardMessage; -import com.artemis.the.gr8.playerstats.statistic.StatRequest; -import com.artemis.the.gr8.playerstats.utils.MyLogger; -import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; +import com.artemis.the.gr8.playerstats.core.Main; +import com.artemis.the.gr8.playerstats.core.msg.OutputManager; +import com.artemis.the.gr8.playerstats.core.config.ConfigHandler; +import com.artemis.the.gr8.playerstats.core.enums.StandardMessage; +import com.artemis.the.gr8.playerstats.api.StatRequest; +import com.artemis.the.gr8.playerstats.core.utils.MyLogger; +import com.artemis.the.gr8.playerstats.core.utils.OfflinePlayerHandler; import com.google.common.collect.ImmutableList; import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandSender; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/share/ShareManager.java b/src/main/java/com/artemis/the/gr8/playerstats/core/sharing/ShareManager.java similarity index 97% rename from src/main/java/com/artemis/the/gr8/playerstats/share/ShareManager.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/sharing/ShareManager.java index a2eb460..0af4aad 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/share/ShareManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/sharing/ShareManager.java @@ -1,7 +1,7 @@ -package com.artemis.the.gr8.playerstats.share; +package com.artemis.the.gr8.playerstats.core.sharing; -import com.artemis.the.gr8.playerstats.config.ConfigHandler; -import com.artemis.the.gr8.playerstats.utils.MyLogger; +import com.artemis.the.gr8.playerstats.core.config.ConfigHandler; +import com.artemis.the.gr8.playerstats.core.utils.MyLogger; import net.kyori.adventure.text.TextComponent; import org.bukkit.command.CommandSender; import org.bukkit.command.ConsoleCommandSender; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/share/StoredResult.java b/src/main/java/com/artemis/the/gr8/playerstats/core/sharing/StoredResult.java similarity index 82% rename from src/main/java/com/artemis/the/gr8/playerstats/share/StoredResult.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/sharing/StoredResult.java index afbb940..9080bd2 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/share/StoredResult.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/sharing/StoredResult.java @@ -1,4 +1,4 @@ -package com.artemis.the.gr8.playerstats.share; +package com.artemis.the.gr8.playerstats.core.sharing; import net.kyori.adventure.text.TextComponent; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/PlayerStatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/core/statrequest/PlayerStatRequest.java similarity index 75% rename from src/main/java/com/artemis/the/gr8/playerstats/statistic/PlayerStatRequest.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/statrequest/PlayerStatRequest.java index c8f9bc2..abaf24f 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/PlayerStatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/statrequest/PlayerStatRequest.java @@ -1,6 +1,7 @@ -package com.artemis.the.gr8.playerstats.statistic; +package com.artemis.the.gr8.playerstats.core.statrequest; import com.artemis.the.gr8.playerstats.api.RequestGenerator; +import com.artemis.the.gr8.playerstats.api.StatRequest; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Statistic; @@ -16,24 +17,24 @@ public final class PlayerStatRequest extends StatRequest implements Req public PlayerStatRequest(CommandSender sender, String playerName) { super(sender); - super.getSettings().configureForPlayer(playerName); + super.configureForPlayer(playerName); } @Override public StatRequest untyped(@NotNull Statistic statistic) { - super.getSettings().configureUntyped(statistic); + super.configureUntyped(statistic); return this; } @Override public StatRequest blockOrItemType(@NotNull Statistic statistic, @NotNull Material material) { - super.getSettings().configureBlockOrItemType(statistic, material); + super.configureBlockOrItemType(statistic, material); return this; } @Override public StatRequest entityType(@NotNull Statistic statistic, @NotNull EntityType entityType) { - super.getSettings().configureEntityType(statistic, entityType); + super.configureEntityType(statistic, entityType); return this; } } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/RequestManager.java b/src/main/java/com/artemis/the/gr8/playerstats/core/statrequest/RequestManager.java similarity index 83% rename from src/main/java/com/artemis/the/gr8/playerstats/statistic/RequestManager.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/statrequest/RequestManager.java index c70e88f..7723439 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/RequestManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/statrequest/RequestManager.java @@ -1,17 +1,20 @@ -package com.artemis.the.gr8.playerstats.statistic; +package com.artemis.the.gr8.playerstats.core.statrequest; import com.artemis.the.gr8.playerstats.api.RequestGenerator; import com.artemis.the.gr8.playerstats.api.StatManager; -import com.artemis.the.gr8.playerstats.msg.msgutils.FormattingFunction; -import com.artemis.the.gr8.playerstats.msg.OutputManager; -import com.artemis.the.gr8.playerstats.multithreading.ThreadManager; -import com.artemis.the.gr8.playerstats.share.ShareManager; -import com.artemis.the.gr8.playerstats.utils.MyLogger; -import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; +import com.artemis.the.gr8.playerstats.api.StatRequest; +import com.artemis.the.gr8.playerstats.api.StatResult; +import com.artemis.the.gr8.playerstats.core.msg.msgutils.FormattingFunction; +import com.artemis.the.gr8.playerstats.core.msg.OutputManager; +import com.artemis.the.gr8.playerstats.core.multithreading.ThreadManager; +import com.artemis.the.gr8.playerstats.core.sharing.ShareManager; +import com.artemis.the.gr8.playerstats.core.utils.MyLogger; +import com.artemis.the.gr8.playerstats.core.utils.OfflinePlayerHandler; import net.kyori.adventure.text.TextComponent; import org.bukkit.OfflinePlayer; import org.bukkit.command.CommandSender; import org.bukkit.command.ConsoleCommandSender; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import java.util.*; @@ -41,39 +44,42 @@ public final class RequestManager implements StatManager { }; } + @Contract("_ -> new") @Override - public RequestGenerator createPlayerStatRequest(String playerName) { + public @NotNull RequestGenerator createPlayerStatRequest(String playerName) { return new PlayerStatRequest(playerName); } @Override - public StatResult executePlayerStatRequest(StatRequest request) { + public @NotNull StatResult executePlayerStatRequest(@NotNull StatRequest request) { return processor.processPlayerRequest(request.getSettings()); } + @Contract(" -> new") @Override - public RequestGenerator createServerStatRequest() { + public @NotNull RequestGenerator createServerStatRequest() { return new ServerStatRequest(); } @Override - public StatResult executeServerStatRequest(StatRequest request) { + public @NotNull StatResult executeServerStatRequest(@NotNull StatRequest request) { return processor.processServerRequest(request.getSettings()); } + @Contract("_ -> new") @Override - public RequestGenerator> createTopStatRequest(int topListSize) { + public @NotNull RequestGenerator> createTopStatRequest(int topListSize) { return new TopStatRequest(topListSize); } @Override - public RequestGenerator> createTotalTopStatRequest() { + public @NotNull RequestGenerator> createTotalTopStatRequest() { int playerCount = offlinePlayerHandler.getOfflinePlayerCount(); return createTopStatRequest(playerCount); } @Override - public StatResult> executeTopRequest(StatRequest> request) { + public @NotNull StatResult> executeTopRequest(@NotNull StatRequest> request) { return processor.processTopRequest(request.getSettings()); } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/ServerStatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/core/statrequest/ServerStatRequest.java similarity index 74% rename from src/main/java/com/artemis/the/gr8/playerstats/statistic/ServerStatRequest.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/statrequest/ServerStatRequest.java index 239ef57..a50a5f8 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/ServerStatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/statrequest/ServerStatRequest.java @@ -1,6 +1,7 @@ -package com.artemis.the.gr8.playerstats.statistic; +package com.artemis.the.gr8.playerstats.core.statrequest; import com.artemis.the.gr8.playerstats.api.RequestGenerator; +import com.artemis.the.gr8.playerstats.api.StatRequest; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Statistic; @@ -17,24 +18,24 @@ public final class ServerStatRequest extends StatRequest implements Reques public ServerStatRequest(CommandSender sender) { super(sender); - super.getSettings().configureForServer(); + super.configureForServer(); } @Override public StatRequest untyped(@NotNull Statistic statistic) { - super.getSettings().configureUntyped(statistic); + super.configureUntyped(statistic); return this; } @Override public StatRequest blockOrItemType(@NotNull Statistic statistic, @NotNull Material material) { - super.getSettings().configureBlockOrItemType(statistic, material); + super.configureBlockOrItemType(statistic, material); return this; } @Override public StatRequest entityType(@NotNull Statistic statistic, @NotNull EntityType entityType) { - super.getSettings().configureEntityType(statistic, entityType); + super.configureEntityType(statistic, entityType); return this; } } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/statistic/TopStatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/core/statrequest/TopStatRequest.java similarity index 77% rename from src/main/java/com/artemis/the/gr8/playerstats/statistic/TopStatRequest.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/statrequest/TopStatRequest.java index 32a6dec..0ef49bb 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/statistic/TopStatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/statrequest/TopStatRequest.java @@ -1,6 +1,7 @@ -package com.artemis.the.gr8.playerstats.statistic; +package com.artemis.the.gr8.playerstats.core.statrequest; import com.artemis.the.gr8.playerstats.api.RequestGenerator; +import com.artemis.the.gr8.playerstats.api.StatRequest; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Statistic; @@ -18,24 +19,24 @@ public final class TopStatRequest extends StatRequest> untyped(@NotNull Statistic statistic) { - super.getSettings().configureUntyped(statistic); + super.configureUntyped(statistic); return this; } @Override public StatRequest> blockOrItemType(@NotNull Statistic statistic, @NotNull Material material) { - super.getSettings().configureBlockOrItemType(statistic, material); + super.configureBlockOrItemType(statistic, material); return this; } @Override public StatRequest> entityType(@NotNull Statistic statistic, @NotNull EntityType entityType) { - super.getSettings().configureEntityType(statistic, entityType); + super.configureEntityType(statistic, entityType); return this; } } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/utils/EnumHandler.java b/src/main/java/com/artemis/the/gr8/playerstats/core/utils/EnumHandler.java similarity index 99% rename from src/main/java/com/artemis/the/gr8/playerstats/utils/EnumHandler.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/utils/EnumHandler.java index b44953d..c58eb01 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/utils/EnumHandler.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/utils/EnumHandler.java @@ -1,4 +1,4 @@ -package com.artemis.the.gr8.playerstats.utils; +package com.artemis.the.gr8.playerstats.core.utils; import org.bukkit.Material; import org.bukkit.Statistic; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/utils/FileHandler.java b/src/main/java/com/artemis/the/gr8/playerstats/core/utils/FileHandler.java similarity index 96% rename from src/main/java/com/artemis/the/gr8/playerstats/utils/FileHandler.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/utils/FileHandler.java index 24de82e..7ea1837 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/utils/FileHandler.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/utils/FileHandler.java @@ -1,6 +1,6 @@ -package com.artemis.the.gr8.playerstats.utils; +package com.artemis.the.gr8.playerstats.core.utils; -import com.artemis.the.gr8.playerstats.Main; +import com.artemis.the.gr8.playerstats.core.Main; import com.tchristofferson.configupdater.ConfigUpdater; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/utils/MyLogger.java b/src/main/java/com/artemis/the/gr8/playerstats/core/utils/MyLogger.java similarity index 97% rename from src/main/java/com/artemis/the/gr8/playerstats/utils/MyLogger.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/utils/MyLogger.java index 4ab5838..e2ec061 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/utils/MyLogger.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/utils/MyLogger.java @@ -1,6 +1,6 @@ -package com.artemis.the.gr8.playerstats.utils; +package com.artemis.the.gr8.playerstats.core.utils; -import com.artemis.the.gr8.playerstats.enums.DebugLevel; +import com.artemis.the.gr8.playerstats.core.enums.DebugLevel; import org.bukkit.Bukkit; import org.bukkit.plugin.Plugin; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/utils/OfflinePlayerHandler.java b/src/main/java/com/artemis/the/gr8/playerstats/core/utils/OfflinePlayerHandler.java similarity index 97% rename from src/main/java/com/artemis/the/gr8/playerstats/utils/OfflinePlayerHandler.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/utils/OfflinePlayerHandler.java index 1dae341..3cff6ab 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/utils/OfflinePlayerHandler.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/utils/OfflinePlayerHandler.java @@ -1,7 +1,7 @@ -package com.artemis.the.gr8.playerstats.utils; +package com.artemis.the.gr8.playerstats.core.utils; -import com.artemis.the.gr8.playerstats.config.ConfigHandler; -import com.artemis.the.gr8.playerstats.multithreading.ThreadManager; +import com.artemis.the.gr8.playerstats.core.config.ConfigHandler; +import com.artemis.the.gr8.playerstats.core.multithreading.ThreadManager; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.jetbrains.annotations.Contract; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/utils/UnixTimeHandler.java b/src/main/java/com/artemis/the/gr8/playerstats/core/utils/UnixTimeHandler.java similarity index 94% rename from src/main/java/com/artemis/the/gr8/playerstats/utils/UnixTimeHandler.java rename to src/main/java/com/artemis/the/gr8/playerstats/core/utils/UnixTimeHandler.java index cf6e9a0..fa7f4d4 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/utils/UnixTimeHandler.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/utils/UnixTimeHandler.java @@ -1,4 +1,4 @@ -package com.artemis.the.gr8.playerstats.utils; +package com.artemis.the.gr8.playerstats.core.utils; /** * A small utility class that calculates with unix time. diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 0c90827..1e43d0f 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,4 +1,4 @@ -main: com.artemis.the.gr8.playerstats.Main +main: com.artemis.the.gr8.playerstats.core.Main name: PlayerStats version: 2.0 api-version: 1.13 From 7a48e590496ae6be9e081e87933fec80dd4c686e Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Wed, 2 Nov 2022 13:33:31 +0100 Subject: [PATCH 28/43] Added formatDefaultNumber to StatNumberFormatter for API --- pom.xml | 6 +++--- .../the/gr8/playerstats/api/StatNumberFormatter.java | 2 ++ .../the/gr8/playerstats/core/msg/MessageBuilder.java | 4 ++-- .../gr8/playerstats/core/msg/msgutils/NumberFormatter.java | 3 ++- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index 50b63fd..5e70d4a 100644 --- a/pom.xml +++ b/pom.xml @@ -200,7 +200,7 @@ attach-sources - deploy + deploy jar-no-fork @@ -214,7 +214,7 @@ sign-artifacts - deploy + deploy sign @@ -228,7 +228,7 @@ attach-javadocs - deploy + deploy jar diff --git a/src/main/java/com/artemis/the/gr8/playerstats/api/StatNumberFormatter.java b/src/main/java/com/artemis/the/gr8/playerstats/api/StatNumberFormatter.java index a6c2453..3d871af 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/api/StatNumberFormatter.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/api/StatNumberFormatter.java @@ -4,6 +4,8 @@ import com.artemis.the.gr8.playerstats.api.enums.Unit; public interface StatNumberFormatter { + String formatDefaultNumber(long number); + String formatDamageNumber(long number, Unit statUnit); String formatDistanceNumber(long number, Unit statUnit); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/MessageBuilder.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/MessageBuilder.java index 86d65e2..76eeb53 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/MessageBuilder.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/MessageBuilder.java @@ -564,7 +564,7 @@ public final class MessageBuilder implements StatTextFormatter { ArrayList unitRange = getTimeUnitRange(statNumber); if (unitRange.size() <= 1 || (useHoverText && unitRange.size() <= 3)) { MyLogger.logWarning("There is something wrong with the time-units you specified, please check your config!"); - return componentFactory.timeNumber(formatter.formatNumber(statNumber), target); + return componentFactory.timeNumber(formatter.formatDefaultNumber(statNumber), target); } else { String mainNumber = formatter.formatTimeNumber(statNumber, unitRange.get(0), unitRange.get(1)); @@ -586,7 +586,7 @@ public final class MessageBuilder implements StatTextFormatter { } private TextComponent getDefaultNumberComponent(long statNumber, Target target) { - return componentFactory.statNumber(formatter.formatNumber(statNumber), target); + return componentFactory.statNumber(formatter.formatDefaultNumber(statNumber), target); } /** diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/msgutils/NumberFormatter.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/msgutils/NumberFormatter.java index efdb677..09c4d29 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/msgutils/NumberFormatter.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/msgutils/NumberFormatter.java @@ -25,7 +25,8 @@ public final class NumberFormatter implements StatNumberFormatter { /** * Adds commas in groups of 3. */ - public @NotNull String formatNumber(long number) { + @Override + public @NotNull String formatDefaultNumber(long number) { return format.format(number); } From a12521e529cb1250808e12f92071e773f8a88928 Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Thu, 3 Nov 2022 16:35:45 +0100 Subject: [PATCH 29/43] Added more festive decorations and wrote test method to see and compare them in-game --- .../playerstats/api/StatNumberFormatter.java | 2 +- .../core/commands/ExcludeCommand.java | 43 +++++---- .../core/commands/TabCompleter.java | 38 +++++--- .../playerstats/core/msg/MessageBuilder.java | 6 +- .../playerstats/core/msg/OutputManager.java | 92 ++++++++++++++----- .../components/BirthdayComponentFactory.java | 18 ++++ .../BukkitConsoleComponentFactory.java | 6 +- .../core/msg/components/ComponentFactory.java | 23 +++-- .../core/msg/components/ExampleMessage.java | 12 +-- .../msg/components/ExcludeInfoMessage.java | 39 +++++++- .../components/HalloweenComponentFactory.java | 22 +++++ .../core/msg/components/HelpMessage.java | 46 +++++----- .../msg/components/PrideComponentFactory.java | 53 +++-------- .../components/WinterComponentFactory.java | 24 +++++ src/main/resources/excluded_players.yml | 4 +- 15 files changed, 280 insertions(+), 148 deletions(-) create mode 100644 src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/BirthdayComponentFactory.java create mode 100644 src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/WinterComponentFactory.java diff --git a/src/main/java/com/artemis/the/gr8/playerstats/api/StatNumberFormatter.java b/src/main/java/com/artemis/the/gr8/playerstats/api/StatNumberFormatter.java index 3d871af..ea50549 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/api/StatNumberFormatter.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/api/StatNumberFormatter.java @@ -11,4 +11,4 @@ public interface StatNumberFormatter { String formatDistanceNumber(long number, Unit statUnit); String formatTimeNumber(long number, Unit biggestTimeUnit, Unit smallestTimeUnit); -} +} \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/commands/ExcludeCommand.java b/src/main/java/com/artemis/the/gr8/playerstats/core/commands/ExcludeCommand.java index 8e462d8..1ca867b 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/commands/ExcludeCommand.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/commands/ExcludeCommand.java @@ -1,6 +1,5 @@ package com.artemis.the.gr8.playerstats.core.commands; - import com.artemis.the.gr8.playerstats.core.msg.OutputManager; import com.artemis.the.gr8.playerstats.core.utils.OfflinePlayerHandler; import org.bukkit.command.Command; @@ -9,8 +8,6 @@ import org.bukkit.command.CommandSender; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; public final class ExcludeCommand implements CommandExecutor { @@ -24,7 +21,7 @@ public final class ExcludeCommand implements CommandExecutor { @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { - if (args.length == 1) { + if (args.length >= 1) { switch (args[0]) { case "list" -> { ArrayList excludedPlayers = offlinePlayerHandler.getExcludedPlayerNames(); @@ -35,28 +32,36 @@ public final class ExcludeCommand implements CommandExecutor { outputManager.sendExcludeInfo(sender); return true; } - } - } - else if (args.length >= 2) { - String playerName = args[1]; - switch (args[0]) { case "test" -> { - List converted = new ArrayList<>(List.copyOf(Arrays.asList(args))); - converted.remove(0); - outputManager.sendTest(sender, converted.toArray(new String[0])); + if (args.length >= 3) { + switch (args[1]) { + case "help" -> outputManager.sendHelpTest(sender, args[2]); + case "examples" -> outputManager.sendExampleTest(sender, args[2]); + case "exclude" -> outputManager.sendExcludeTest(sender, args[2]); + case "prefix" -> outputManager.sendPrefixTest(sender, args[2]); + case "title" -> outputManager.sendPrefixTitleTest(sender, args[2]); + case "name" -> { + if (args.length >= 4) { + outputManager.sendNameTest(sender, args[2], args[3]); + } + } + } + } return true; } case "add" -> { - if (offlinePlayerHandler.isLoadedPlayer(playerName)) { - offlinePlayerHandler.addLoadedPlayerToExcludeList(playerName); - sender.sendMessage("Excluded " + playerName + "!"); + if (args.length >= 2 && + offlinePlayerHandler.isLoadedPlayer(args[1])) { + offlinePlayerHandler.addLoadedPlayerToExcludeList(args[1]); + sender.sendMessage("Excluded " + args[1] + "!"); return true; } } case "remove" -> { - if (offlinePlayerHandler.isExcludedPlayer(playerName)) { - offlinePlayerHandler.addExcludedPlayerToLoadedList(playerName); - sender.sendMessage("Removed " + playerName + " from the exclude list again!"); + if (args.length >= 2 && + offlinePlayerHandler.isExcludedPlayer(args[1])) { + offlinePlayerHandler.addExcludedPlayerToLoadedList(args[1]); + sender.sendMessage("Removed " + args[1] + " from the exclude list again!"); return true; } } @@ -64,4 +69,4 @@ public final class ExcludeCommand implements CommandExecutor { } return false; } -} +} \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/commands/TabCompleter.java b/src/main/java/com/artemis/the/gr8/playerstats/core/commands/TabCompleter.java index 9187146..ce39f9d 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/commands/TabCompleter.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/commands/TabCompleter.java @@ -7,12 +7,16 @@ import org.bukkit.Statistic; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.entity.EntityType; +import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.Unmodifiable; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; public final class TabCompleter implements org.bukkit.command.TabCompleter { @@ -60,12 +64,33 @@ public final class TabCompleter implements org.bukkit.command.TabCompleter { loadedPlayers.addAll(offlinePlayerHandler.getExcludedPlayerNames()); yield loadedPlayers; } + case "test" -> getTestSuggestions(); default -> tabSuggestions; }; } + else if (args.length == 3) { + Pattern testPattern = Pattern.compile("help|examples|exclude|prefix|title|name"); + Matcher matcher = testPattern.matcher(args[1]); + if (matcher.find()) { + tabSuggestions = getSecondTestSuggestions(); + } + } + else if (args.length == 4 && args[1].equalsIgnoreCase("name")) { + tabSuggestions = offlinePlayerHandler.getLoadedOfflinePlayerNames(); + } return getDynamicTabSuggestions(tabSuggestions, args[args.length-1]); } + @Contract(pure = true) + private @Unmodifiable List getTestSuggestions() { + return List.of("help", "examples", "exclude", "prefix", "title", "name"); + } + + @Contract(pure = true) + private @Unmodifiable List getSecondTestSuggestions() { + return List.of("halloween", "pride", "bukkit", "console", "default", "winter"); + } + private @Nullable List getStatCommandSuggestions(@NotNull String[] args) { if (args.length == 0) { return null; @@ -143,17 +168,8 @@ public final class TabCompleter implements org.bukkit.command.TabCompleter { } private void prepareLists() { - statCommandTargets = new ArrayList<>(); - statCommandTargets.add("top"); - statCommandTargets.add("player"); - statCommandTargets.add("server"); - statCommandTargets.add("me"); - - excludeCommandOptions = new ArrayList<>(); - excludeCommandOptions.add("add"); - excludeCommandOptions.add("list"); - excludeCommandOptions.add("remove"); - excludeCommandOptions.add("info"); + statCommandTargets = List.of("top", "player", "server", "me"); + excludeCommandOptions = List.of("add", "list", "remove", "info"); //breaking an item means running its durability negative itemsThatCanBreak = Arrays.stream(Material.values()) diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/MessageBuilder.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/MessageBuilder.java index 76eeb53..657fbdb 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/MessageBuilder.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/MessageBuilder.java @@ -81,7 +81,7 @@ public final class MessageBuilder implements StatTextFormatter { @Override public TextComponent getRainbowPluginPrefix() { PrideComponentFactory pride = new PrideComponentFactory(); - return pride.rainbowPrefix(); + return pride.pluginPrefix(); } @Override @@ -95,6 +95,10 @@ public final class MessageBuilder implements StatTextFormatter { return pride.pluginPrefixAsTitle(); } + public TextComponent getSharerName(String name) { + return componentFactory.sharerName(name); + } + public @NotNull TextComponent reloadedConfig() { return composePluginMessage("Config reloaded!"); } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/OutputManager.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/OutputManager.java index 14e7b5e..9703370 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/OutputManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/OutputManager.java @@ -3,16 +3,11 @@ package com.artemis.the.gr8.playerstats.core.msg; import com.artemis.the.gr8.playerstats.api.StatTextFormatter; import com.artemis.the.gr8.playerstats.core.config.ConfigHandler; import com.artemis.the.gr8.playerstats.core.enums.StandardMessage; -import com.artemis.the.gr8.playerstats.core.msg.components.ConsoleComponentFactory; -import com.artemis.the.gr8.playerstats.core.msg.components.PrideComponentFactory; -import com.artemis.the.gr8.playerstats.core.msg.components.BukkitConsoleComponentFactory; -import com.artemis.the.gr8.playerstats.core.msg.components.HalloweenComponentFactory; +import com.artemis.the.gr8.playerstats.core.msg.components.*; import com.artemis.the.gr8.playerstats.core.msg.msgutils.FormattingFunction; import com.artemis.the.gr8.playerstats.api.StatRequest; import net.kyori.adventure.platform.bukkit.BukkitAudiences; -import net.kyori.adventure.text.Component; import net.kyori.adventure.text.TextComponent; -import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.command.ConsoleCommandSender; @@ -20,7 +15,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.time.LocalDate; -import java.time.Month; import java.util.EnumMap; import java.util.LinkedHashMap; import java.util.function.Function; @@ -129,14 +123,50 @@ public final class OutputManager { .excludeInfoMsg()); } - public void sendTest(@NotNull CommandSender sender, String[] args) { - StringBuilder msg = new StringBuilder(); - for (String arg : args) { - char text = (char) Integer.parseInt(arg, 16); - msg.append(text); + public void sendPrefixTest(@NotNull CommandSender sender, String arg) { + adventure.sender(sender).sendMessage(getTestBuilder(arg) + .getPluginPrefix()); + } + + public void sendPrefixTitleTest(@NotNull CommandSender sender, String arg) { + adventure.sender(sender).sendMessage(getTestBuilder(arg) + .getPluginPrefixAsTitle()); + } + + public void sendHelpTest(@NotNull CommandSender sender, String arg) { + adventure.sender(sender).sendMessage(getTestBuilder(arg) + .helpMsg()); + } + + public void sendExcludeTest(@NotNull CommandSender sender, String arg) { + adventure.sender(sender).sendMessage(getTestBuilder(arg) + .excludeInfoMsg()); + } + + public void sendExampleTest(@NotNull CommandSender sender, String arg) { + adventure.sender(sender).sendMessage(getTestBuilder(arg) + .usageExamples()); + } + + public void sendNameTest(@NotNull CommandSender sender, String arg, String playerName) { + adventure.sender(sender).sendMessage(getTestBuilder(arg) + .getSharerName(playerName)); + } + + private MessageBuilder getTestBuilder(String arg) { + if (arg == null) { + return MessageBuilder.defaultBuilder(); + } else { + ComponentFactory factory = switch (arg) { + case "halloween" -> new HalloweenComponentFactory(); + case "pride" -> new PrideComponentFactory(); + case "bukkit" -> new BukkitConsoleComponentFactory(); + case "console" -> new ConsoleComponentFactory(); + case "winter" -> new WinterComponentFactory(); + default -> new ComponentFactory(); + }; + return MessageBuilder.fromComponentFactory(factory); } - Component test = MiniMessage.miniMessage().deserialize(msg.toString()); - adventure.sender(sender).sendMessage(test); } public void sendToAllPlayers(@NotNull TextComponent component) { @@ -157,12 +187,11 @@ public final class OutputManager { } private MessageBuilder getClientMessageBuilder() { - if (useRainbowStyle()) { - return MessageBuilder.fromComponentFactory(new PrideComponentFactory()); - } else if (useHalloweenStyle()) { - return MessageBuilder.fromComponentFactory(new HalloweenComponentFactory()); + ComponentFactory festiveFactory = getFestiveFactory(); + if (festiveFactory == null) { + return MessageBuilder.defaultBuilder(); } - return MessageBuilder.defaultBuilder(); + return MessageBuilder.fromComponentFactory(festiveFactory); } private @NotNull MessageBuilder getConsoleMessageBuilder() { @@ -175,12 +204,25 @@ public final class OutputManager { return consoleBuilder; } - private boolean useRainbowStyle() { - return config.useRainbowMode() || (config.useFestiveFormatting() && LocalDate.now().getMonth().equals(Month.JUNE)); - } - - private boolean useHalloweenStyle() { - return config.useFestiveFormatting() && LocalDate.now().getMonth().equals(Month.OCTOBER); + private @Nullable ComponentFactory getFestiveFactory() { + if (config.useRainbowMode()) { + return new PrideComponentFactory(); + } + else if (config.useFestiveFormatting()) { + return switch (LocalDate.now().getMonth()) { + case JUNE -> new PrideComponentFactory(); + case OCTOBER -> new HalloweenComponentFactory(); + case SEPTEMBER -> { + if (LocalDate.now().getDayOfMonth() == 12) { + yield new BirthdayComponentFactory(); + } + yield null; + } + case DECEMBER -> new WinterComponentFactory(); + default -> null; + }; + } + return null; } private boolean isBukkit() { diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/BirthdayComponentFactory.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/BirthdayComponentFactory.java new file mode 100644 index 0000000..062dc96 --- /dev/null +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/BirthdayComponentFactory.java @@ -0,0 +1,18 @@ +package com.artemis.the.gr8.playerstats.core.msg.components; + +import net.kyori.adventure.text.TextComponent; + +public class BirthdayComponentFactory extends ComponentFactory { + + public BirthdayComponentFactory() { + super(); + } + + @Override + public TextComponent pluginPrefixAsTitle() { + return miniMessageToComponent( + "" + + "\ud83d\udd25 __________ [PlayerStats] __________ " + + "\ud83d\udd25"); + } +} diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/BukkitConsoleComponentFactory.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/BukkitConsoleComponentFactory.java index 0cb35df..ddb4c66 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/BukkitConsoleComponentFactory.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/BukkitConsoleComponentFactory.java @@ -32,12 +32,12 @@ public class BukkitConsoleComponentFactory extends ComponentFactory { FEEDBACK_MSG_ACCENT = PluginColor.LIGHT_BLUE.getConsoleColor(); INFO_MSG = PluginColor.GOLD.getConsoleColor(); - INFO_MSG_ACCENT_1 = PluginColor.MEDIUM_GOLD.getConsoleColor(); - INFO_MSG_ACCENT_2 = PluginColor.LIGHT_YELLOW.getConsoleColor(); + INFO_MSG_ACCENT_DARKEST = PluginColor.MEDIUM_GOLD.getConsoleColor(); + INFO_MSG_ACCENT_MEDIUM = PluginColor.LIGHT_GOLD.getConsoleColor(); + INFO_MSG_ACCENT_LIGHTEST = PluginColor.LIGHT_YELLOW.getConsoleColor(); MSG_HOVER = PluginColor.LIGHTEST_BLUE.getConsoleColor(); MSG_CLICKED = PluginColor.LIGHT_PURPLE.getConsoleColor(); - MSG_HOVER_ACCENT = PluginColor.LIGHT_GOLD.getConsoleColor(); } @Override diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ComponentFactory.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ComponentFactory.java index ec0ea2b..8cb205e 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ComponentFactory.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ComponentFactory.java @@ -45,11 +45,11 @@ public class ComponentFactory { protected TextColor FEEDBACK_MSG_ACCENT; //light_blue protected TextColor INFO_MSG; //gold - protected TextColor INFO_MSG_ACCENT_1; //medium_gold - protected TextColor INFO_MSG_ACCENT_2; //light_yellow + protected TextColor INFO_MSG_ACCENT_DARKEST; //medium_gold + protected TextColor INFO_MSG_ACCENT_MEDIUM; //light_gold + protected TextColor INFO_MSG_ACCENT_LIGHTEST; //light_yellow protected TextColor MSG_HOVER; //lightest_blue - protected TextColor MSG_HOVER_ACCENT; //light_gold protected TextColor MSG_CLICKED; //light_purple @@ -68,11 +68,11 @@ public class ComponentFactory { FEEDBACK_MSG_ACCENT = PluginColor.LIGHT_BLUE.getColor(); INFO_MSG = PluginColor.GOLD.getColor(); - INFO_MSG_ACCENT_1 = PluginColor.MEDIUM_GOLD.getColor(); - INFO_MSG_ACCENT_2 = PluginColor.LIGHT_YELLOW.getColor(); + INFO_MSG_ACCENT_DARKEST = PluginColor.MEDIUM_GOLD.getColor(); + INFO_MSG_ACCENT_MEDIUM = PluginColor.LIGHT_GOLD.getColor(); + INFO_MSG_ACCENT_LIGHTEST = PluginColor.LIGHT_YELLOW.getColor(); MSG_HOVER = PluginColor.LIGHTEST_BLUE.getColor(); - MSG_HOVER_ACCENT = PluginColor.LIGHT_GOLD.getColor(); MSG_CLICKED = PluginColor.LIGHT_PURPLE.getColor(); } @@ -88,7 +88,7 @@ public class ComponentFactory { } public TextComponent getExampleName() { - return text("Artemis_the_gr8").color(INFO_MSG_ACCENT_2); + return text("Artemis_the_gr8").color(INFO_MSG_ACCENT_LIGHTEST); } /** @@ -105,11 +105,10 @@ public class ComponentFactory { * Returns [PlayerStats] surrounded by underscores on both sides. */ public TextComponent pluginPrefixAsTitle() { - //12 underscores for both console and in-game - return text("____________").color(UNDERSCORE) + return text("____________").color(UNDERSCORE) //12 underscores .append(text(" ")) //4 spaces .append(pluginPrefix()) - .append(text(" ")) //4 spaces + .append(text(" ")) .append(text("____________")); } @@ -183,7 +182,7 @@ public class ComponentFactory { .color(FEEDBACK_MSG_ACCENT) .clickEvent(ClickEvent.runCommand("/statshare " + shareCode)) .hoverEvent(HoverEvent.showText(text("Click here to share this statistic in chat!") - .color(MSG_HOVER_ACCENT)))); + .color(INFO_MSG_ACCENT_MEDIUM)))); } public TextComponent sharedByMessage(Component playerName) { @@ -324,7 +323,7 @@ public class ComponentFactory { .toBuilder() .hoverEvent(HoverEvent.showText( text(Unit.HEART.getLabel()) - .color(MSG_HOVER_ACCENT))) + .color(INFO_MSG_ACCENT_MEDIUM))) .build(); return surroundWithBrackets(heart); } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ExampleMessage.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ExampleMessage.java index 5f8b877..25201a8 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ExampleMessage.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ExampleMessage.java @@ -39,20 +39,20 @@ public final class ExampleMessage implements TextComponent { .append(spaces).append( factory.arrow()).append(Component.space()) .append(text("/stat ").color(factory.INFO_MSG) - .append(text("animals_bred ").color(factory.INFO_MSG_ACCENT_1) - .append(text("top").color(factory.INFO_MSG_ACCENT_2)))) + .append(text("animals_bred ").color(factory.INFO_MSG_ACCENT_MEDIUM) + .append(text("top").color(factory.INFO_MSG_ACCENT_LIGHTEST)))) .append(Component.newline()) .append(spaces).append( factory.arrow()).append(Component.space()) .append(text("/stat ").color(factory.INFO_MSG) - .append(text("mine_block diorite ").color(factory.INFO_MSG_ACCENT_1) - .append(text("me").color(factory.INFO_MSG_ACCENT_2)))) + .append(text("mine_block diorite ").color(factory.INFO_MSG_ACCENT_MEDIUM) + .append(text("me").color(factory.INFO_MSG_ACCENT_LIGHTEST)))) .append(Component.newline()) .append(spaces).append( factory.arrow()).append(Component.space()) .append(text("/stat ").color(factory.INFO_MSG) - .append(text("deaths ").color(factory.INFO_MSG_ACCENT_1) - .append(text("player ").color(factory.INFO_MSG_ACCENT_2) + .append(text("deaths ").color(factory.INFO_MSG_ACCENT_MEDIUM) + .append(text("player ").color(factory.INFO_MSG_ACCENT_LIGHTEST) .append(factory.getExampleName())))); } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ExcludeInfoMessage.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ExcludeInfoMessage.java index 44f21df..ff04d1e 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ExcludeInfoMessage.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ExcludeInfoMessage.java @@ -3,7 +3,9 @@ package com.artemis.the.gr8.playerstats.core.msg.components; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.ComponentLike; import net.kyori.adventure.text.TextComponent; +import net.kyori.adventure.text.event.HoverEvent; import net.kyori.adventure.text.format.Style; +import net.kyori.adventure.text.format.TextDecoration; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Unmodifiable; @@ -31,9 +33,7 @@ public final class ExcludeInfoMessage implements TextComponent { return Component.newline() .append(factory.pluginPrefixAsTitle()) .append(Component.newline()) - .append(factory.subTitle("The /statexclude command is used to hide")) - .append(Component.newline()) - .append(factory.subTitle("specific players' results from /stat lookups")) + .append(factory.subTitle("Hide a player's statistics from /stat results")) .append(Component.newline()) .append(text("Excluded players are:") .color(factory.INFO_MSG)) @@ -41,12 +41,41 @@ public final class ExcludeInfoMessage implements TextComponent { .append(spaces).append( factory.arrow()).append(Component.space()) .append(text("not visible in the top 10") - .color(factory.INFO_MSG_ACCENT_1)) + .color(factory.INFO_MSG_ACCENT_MEDIUM)) .append(Component.newline()) .append(spaces).append( factory.arrow()).append(Component.space()) .append(text("not counted for the server total") - .color(factory.INFO_MSG_ACCENT_1)); + .color(factory.INFO_MSG_ACCENT_MEDIUM)) + .append(Component.newline()) + .append(spaces).append( + factory.arrow()).append(Component.space()) + .append(text("hidden") + .decorate(TextDecoration.BOLD) + .color(factory.INFO_MSG_ACCENT_MEDIUM) + .hoverEvent(HoverEvent.showText(text("All data is still stored by the server,") + .append(Component.newline()) + .append(text("and excluded players can still look up")) + .append(Component.newline()) + .append(text("their own statistics in the in-game menu")) + .color(factory.FEEDBACK_MSG)))) + .append(text(", not removed") + .decorations(TextDecoration.NAMES.values(), false) + .color(factory.INFO_MSG_ACCENT_MEDIUM)) + .append(Component.newline()) + .append(Component.newline()) + .append(text("Usage: ").color(factory.INFO_MSG) + .append(text("/statexclude").color(factory.INFO_MSG_ACCENT_MEDIUM))) + .append(Component.newline()) + .append(spaces).append(spaces).append( + factory.bulletPoint()).append(Component.space()) + .append(text("add ").color(factory.INFO_MSG_ACCENT_DARKEST)) + .append(text("player-name").color(factory.INFO_MSG_ACCENT_MEDIUM)) + .append(Component.newline()) + .append(spaces).append(spaces).append( + factory.bulletPoint()).append(Component.space()) + .append(text("remove ").color(factory.INFO_MSG_ACCENT_DARKEST)) + .append(text("player-name").color(factory.INFO_MSG_ACCENT_MEDIUM)); } @Override diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/HalloweenComponentFactory.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/HalloweenComponentFactory.java index 4393efa..1a1371e 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/HalloweenComponentFactory.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/HalloweenComponentFactory.java @@ -1,6 +1,9 @@ package com.artemis.the.gr8.playerstats.core.msg.components; import net.kyori.adventure.text.TextComponent; +import org.jetbrains.annotations.NotNull; + +import java.util.Random; public class HalloweenComponentFactory extends ComponentFactory { @@ -22,4 +25,23 @@ public class HalloweenComponentFactory extends ComponentFactory { return miniMessageToComponent( "[PlayerStats]"); } + + @Override + public TextComponent sharerName(String sharerName) { + return miniMessageToComponent(decorateWithRandomGradient(sharerName)); + } + + private @NotNull String decorateWithRandomGradient(@NotNull String input) { + Random random = new Random(); + String colorString = switch (random.nextInt(6)) { + case 0 -> ""; + case 1 -> ""; + case 2 -> ""; + case 3 -> ""; + case 4 -> ""; + case 5 -> ""; + default -> ""; + }; + return colorString + input + ""; + } } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/HelpMessage.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/HelpMessage.java index 9a070d0..5e7f765 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/HelpMessage.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/HelpMessage.java @@ -48,44 +48,44 @@ public final class HelpMessage implements TextComponent { .append(text("Type \"/statistic examples\" to see examples!").color(factory.BRACKETS).decorate(TextDecoration.ITALIC)) .append(newline()) .append(text("Usage:").color(factory.INFO_MSG)).append(space()) - .append(text("/statistic").color(factory.MSG_HOVER_ACCENT)) + .append(text("/statistic").color(factory.INFO_MSG_ACCENT_MEDIUM)) .append(newline()) .append(spaces).append( factory.arrow()).append(space()) - .append(text("name").color(factory.MSG_HOVER_ACCENT)) + .append(text("name").color(factory.INFO_MSG_ACCENT_MEDIUM)) .append(newline()) .append(spaces).append( factory.arrow()).append(space()) - .append(text("{sub-statistic}").color(factory.MSG_HOVER_ACCENT)).append(space()) + .append(text("{sub-statistic}").color(factory.INFO_MSG_ACCENT_MEDIUM)).append(space()) .append(text("(a block, item or entity)").color(factory.BRACKETS)) .append(newline()) .append(spaces).append( factory.arrow()).append(space()) - .append(text("me | player | server | top").color(factory.MSG_HOVER_ACCENT)) + .append(text("me | player | server | top").color(factory.INFO_MSG_ACCENT_MEDIUM)) .append(newline()) .append(spaces).append(spaces).append( factory.bulletPoint()).append(space()) - .append(text("me:").color(factory.INFO_MSG_ACCENT_1)).append(space()) + .append(text("me:").color(factory.INFO_MSG_ACCENT_DARKEST)).append(space()) .append(text("your own statistic").color(factory.BRACKETS)) .append(newline()) .append(spaces).append(spaces).append( factory.bulletPoint()).append(space()) - .append(text("player:").color(factory.INFO_MSG_ACCENT_1)).append(space()) + .append(text("player:").color(factory.INFO_MSG_ACCENT_DARKEST)).append(space()) .append(text("choose a player").color(factory.BRACKETS)) .append(newline()) .append(spaces).append(spaces).append( factory.bulletPoint()).append(space()) - .append(text("server:").color(factory.INFO_MSG_ACCENT_1)).append(space()) + .append(text("server:").color(factory.INFO_MSG_ACCENT_DARKEST)).append(space()) .append(text("everyone on the server combined").color(factory.BRACKETS)) .append(newline()) .append(spaces).append(spaces).append( factory.bulletPoint()).append(space()) - .append(text("top:").color(factory.INFO_MSG_ACCENT_1)).append(space()) + .append(text("top:").color(factory.INFO_MSG_ACCENT_DARKEST)).append(space()) .append(text("the top").color(factory.BRACKETS).append(space()).append(text(listSize))) .append(newline()) .append(spaces).append( factory.arrow()).append(space()) - .append(text("{player-name}").color(factory.MSG_HOVER_ACCENT)); + .append(text("{player-name}").color(factory.INFO_MSG_ACCENT_MEDIUM)); } private @NotNull TextComponent buildHoverMsg(@NotNull ComponentFactory factory, int listSize) { @@ -97,49 +97,49 @@ public final class HelpMessage implements TextComponent { .append(factory.subTitle("Hover over the arguments for more information!")) .append(newline()) .append(text("Usage:").color(factory.INFO_MSG)).append(space()) - .append(text("/statistic").color(factory.MSG_HOVER_ACCENT)) + .append(text("/statistic").color(factory.INFO_MSG_ACCENT_MEDIUM)) .append(newline()) .append(spaces).append(factory.arrow()).append(space()) - .append(text("name").color(factory.MSG_HOVER_ACCENT) + .append(text("name").color(factory.INFO_MSG_ACCENT_MEDIUM) .hoverEvent(HoverEvent.showText(text("The name that describes the statistic").color(factory.MSG_HOVER) .append(newline()) .append(text("Example: ").color(factory.INFO_MSG)) - .append(text("\"animals_bred\"").color(factory.MSG_HOVER_ACCENT))))) + .append(text("\"animals_bred\"").color(factory.INFO_MSG_ACCENT_MEDIUM))))) .append(newline()) .append(spaces).append(factory.arrow()).append(space()) - .append(text("sub-statistic").color(factory.MSG_HOVER_ACCENT) + .append(text("sub-statistic").color(factory.INFO_MSG_ACCENT_MEDIUM) .hoverEvent(HoverEvent.showText( text("Some statistics need an item, block or entity as extra input").color(factory.MSG_HOVER) .append(newline()) .append(text("Example: ").color(factory.INFO_MSG) - .append(text("\"mine_block diorite\"").color(factory.MSG_HOVER_ACCENT)))))) + .append(text("\"mine_block diorite\"").color(factory.INFO_MSG_ACCENT_MEDIUM)))))) .append(newline()) .append(spaces).append(factory.arrow() .hoverEvent(HoverEvent.showText( text("Choose one").color(factory.MSG_CLICKED)))) .append(space()) - .append(text("me").color(factory.MSG_HOVER_ACCENT) + .append(text("me").color(factory.INFO_MSG_ACCENT_MEDIUM) .hoverEvent(HoverEvent.showText( text("See your own statistic").color(factory.MSG_HOVER)))) - .append(text(" | ").color(factory.MSG_HOVER_ACCENT)) - .append(text("player").color(factory.MSG_HOVER_ACCENT) + .append(text(" | ").color(factory.INFO_MSG_ACCENT_MEDIUM)) + .append(text("player").color(factory.INFO_MSG_ACCENT_MEDIUM) .hoverEvent(HoverEvent.showText( text("Choose any player that has played on your server").color(factory.MSG_HOVER)))) - .append(text(" | ").color(factory.MSG_HOVER_ACCENT)) - .append(text("server").color(factory.MSG_HOVER_ACCENT) + .append(text(" | ").color(factory.INFO_MSG_ACCENT_MEDIUM)) + .append(text("server").color(factory.INFO_MSG_ACCENT_MEDIUM) .hoverEvent(HoverEvent.showText( text("See the combined total for everyone on your server").color(factory.MSG_HOVER)))) - .append(text(" | ").color(factory.MSG_HOVER_ACCENT)) - .append(text("top").color(factory.MSG_HOVER_ACCENT) + .append(text(" | ").color(factory.INFO_MSG_ACCENT_MEDIUM)) + .append(text("top").color(factory.INFO_MSG_ACCENT_MEDIUM) .hoverEvent(HoverEvent.showText( text("See the top").color(factory.MSG_HOVER).append(space()) .append(text(listSize))))) .append(newline()) .append(spaces).append(factory.arrow()).append(space()) - .append(text("player-name").color(factory.MSG_HOVER_ACCENT) + .append(text("player-name").color(factory.INFO_MSG_ACCENT_MEDIUM) .hoverEvent(HoverEvent.showText( text("In case you typed").color(factory.MSG_HOVER).append(space()) - .append(text("\"player\"").color(factory.MSG_HOVER_ACCENT)) + .append(text("\"player\"").color(factory.INFO_MSG_ACCENT_MEDIUM)) .append(text(", add the player's name"))))); } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/PrideComponentFactory.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/PrideComponentFactory.java index 37cdcde..242e5d1 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/PrideComponentFactory.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/PrideComponentFactory.java @@ -1,7 +1,6 @@ package com.artemis.the.gr8.playerstats.core.msg.components; import net.kyori.adventure.text.TextComponent; -import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import java.util.Random; @@ -11,11 +10,8 @@ import java.util.Random; */ public class PrideComponentFactory extends ComponentFactory { - private final Random random; - public PrideComponentFactory() { super(); - random = new Random(); } @Override @@ -36,46 +32,23 @@ public class PrideComponentFactory extends ComponentFactory { @Override public TextComponent pluginPrefix() { - if (random.nextBoolean()) { - return backwardsPluginPrefixComponent(); - } - return rainbowPrefix(); - } - - public TextComponent rainbowPrefix() { return miniMessageToComponent("<#f74040>[" + - "<#F54D39>P" + - "<#F16E28>l" + - "<#ee8a19>a" + - "<#EEA019>y" + - "<#F7C522>e" + - "<#C1DA15>r" + - "<#84D937>S" + - "<#46D858>t" + - "<#01c1a7>a" + - "<#1F8BEB>t" + - "<#3341E6>s" + - "<#631ae6>]"); - } - - @Contract(" -> new") - private @NotNull TextComponent backwardsPluginPrefixComponent() { - return miniMessageToComponent("<#631ae6>[" + - "<#3341E6>P" + - "<#1F8BEB>l" + - "<#01c1a7>a" + - "<#46D858>y" + - "<#84D937>e" + - "<#C1DA15>r" + - "<#F7C522>S" + - "<#EEA019>t" + - "<#ee8a19>a" + - "<#f67824>t" + - "<#f76540>s" + - "<#f74040>]"); + "<#F54D39>P" + + "<#F16E28>l" + + "<#ee8a19>a" + + "<#EEA019>y" + + "<#F7C522>e" + + "<#C1DA15>r" + + "<#84D937>S" + + "<#46D858>t" + + "<#01c1a7>a" + + "<#1F8BEB>t" + + "<#3341E6>s" + + "<#631ae6>]"); } private @NotNull String decorateWithRandomGradient(@NotNull String input) { + Random random = new Random(); String colorString = switch (random.nextInt(8)) { case 0 -> ""; case 1 -> ""; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/WinterComponentFactory.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/WinterComponentFactory.java new file mode 100644 index 0000000..51d4ec4 --- /dev/null +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/WinterComponentFactory.java @@ -0,0 +1,24 @@ +package com.artemis.the.gr8.playerstats.core.msg.components; + +import net.kyori.adventure.text.TextComponent; + +public class WinterComponentFactory extends ComponentFactory { + + public WinterComponentFactory() { + super(); + } + + @Override + public TextComponent pluginPrefixAsTitle() { + return miniMessageToComponent( + "" + + "\u2744 __________ [PlayerStats] __________ " + + "\u2744"); + } + + @Override + public TextComponent pluginPrefix() { + return miniMessageToComponent( + "[PlayerStats]"); + } +} diff --git a/src/main/resources/excluded_players.yml b/src/main/resources/excluded_players.yml index 1dc7bc9..011efa6 100644 --- a/src/main/resources/excluded_players.yml +++ b/src/main/resources/excluded_players.yml @@ -7,7 +7,7 @@ # For more general filtering settings, see the config.yml (section 'General') # Format: -# - playerUUID-1 -# - playerUUID-2 +# - player1UUID +# - player2UUID excluded: - \ No newline at end of file From 9b62828c040bc6e6b01a646ded811df338da519b Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Wed, 9 Nov 2022 13:11:41 +0100 Subject: [PATCH 30/43] Refined and completed the new decorations --- .../playerstats/core/commands/TabCompleter.java | 2 +- .../gr8/playerstats/core/msg/OutputManager.java | 1 + .../msg/components/BirthdayComponentFactory.java | 16 +++++++++++----- .../BukkitConsoleComponentFactory.java | 2 +- .../msg/components/ConsoleComponentFactory.java | 4 ++-- .../components/HalloweenComponentFactory.java | 4 ++-- .../msg/components/PrideComponentFactory.java | 2 +- .../msg/components/WinterComponentFactory.java | 10 +++++----- 8 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/commands/TabCompleter.java b/src/main/java/com/artemis/the/gr8/playerstats/core/commands/TabCompleter.java index ce39f9d..f26512e 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/commands/TabCompleter.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/commands/TabCompleter.java @@ -88,7 +88,7 @@ public final class TabCompleter implements org.bukkit.command.TabCompleter { @Contract(pure = true) private @Unmodifiable List getSecondTestSuggestions() { - return List.of("halloween", "pride", "bukkit", "console", "default", "winter"); + return List.of("halloween", "pride", "bukkit", "console", "default", "winter", "birthday"); } private @Nullable List getStatCommandSuggestions(@NotNull String[] args) { diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/OutputManager.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/OutputManager.java index 9703370..653d8f1 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/OutputManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/OutputManager.java @@ -163,6 +163,7 @@ public final class OutputManager { case "bukkit" -> new BukkitConsoleComponentFactory(); case "console" -> new ConsoleComponentFactory(); case "winter" -> new WinterComponentFactory(); + case "birthday" -> new BirthdayComponentFactory(); default -> new ComponentFactory(); }; return MessageBuilder.fromComponentFactory(factory); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/BirthdayComponentFactory.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/BirthdayComponentFactory.java index 062dc96..44315a1 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/BirthdayComponentFactory.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/BirthdayComponentFactory.java @@ -2,7 +2,7 @@ package com.artemis.the.gr8.playerstats.core.msg.components; import net.kyori.adventure.text.TextComponent; -public class BirthdayComponentFactory extends ComponentFactory { +public final class BirthdayComponentFactory extends ComponentFactory { public BirthdayComponentFactory() { super(); @@ -11,8 +11,14 @@ public class BirthdayComponentFactory extends ComponentFactory { @Override public TextComponent pluginPrefixAsTitle() { return miniMessageToComponent( - "" + - "\ud83d\udd25 __________ [PlayerStats] __________ " + - "\ud83d\udd25"); + "" + + "<#FF9300>\ud83d\udd25 __________ [PlayerStats] __________ " + + "<#FF9300>\ud83d\udd25"); } -} + + @Override + public TextComponent pluginPrefix() { + return miniMessageToComponent( + "[PlayerStats]"); + } +} \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/BukkitConsoleComponentFactory.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/BukkitConsoleComponentFactory.java index ddb4c66..0cce2df 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/BukkitConsoleComponentFactory.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/BukkitConsoleComponentFactory.java @@ -15,7 +15,7 @@ import static net.kyori.adventure.text.Component.text; * a Bukkit Console. Bukkit consoles don't support hex colors, * unlike Paper consoles. */ -public class BukkitConsoleComponentFactory extends ComponentFactory { +public final class BukkitConsoleComponentFactory extends ComponentFactory { public BukkitConsoleComponentFactory() { super(); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ConsoleComponentFactory.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ConsoleComponentFactory.java index 38bdb01..2a9c78a 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ConsoleComponentFactory.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ConsoleComponentFactory.java @@ -3,7 +3,7 @@ package com.artemis.the.gr8.playerstats.core.msg.components; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.TextComponent; -public class ConsoleComponentFactory extends ComponentFactory { +public final class ConsoleComponentFactory extends ComponentFactory { public ConsoleComponentFactory() { super(); @@ -21,4 +21,4 @@ public class ConsoleComponentFactory extends ComponentFactory { .color(HEARTS) .build(); } -} +} \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/HalloweenComponentFactory.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/HalloweenComponentFactory.java index 1a1371e..60effbc 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/HalloweenComponentFactory.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/HalloweenComponentFactory.java @@ -5,7 +5,7 @@ import org.jetbrains.annotations.NotNull; import java.util.Random; -public class HalloweenComponentFactory extends ComponentFactory { +public final class HalloweenComponentFactory extends ComponentFactory { public HalloweenComponentFactory() { @@ -15,7 +15,7 @@ public class HalloweenComponentFactory extends ComponentFactory { @Override public TextComponent pluginPrefixAsTitle() { return miniMessageToComponent( - "" + + "" + "\u2620 __________ [PlayerStats] __________ " + "\u2620"); } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/PrideComponentFactory.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/PrideComponentFactory.java index 242e5d1..7821683 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/PrideComponentFactory.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/PrideComponentFactory.java @@ -8,7 +8,7 @@ import java.util.Random; /** * A festive version of the {@link ComponentFactory} */ -public class PrideComponentFactory extends ComponentFactory { +public final class PrideComponentFactory extends ComponentFactory { public PrideComponentFactory() { super(); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/WinterComponentFactory.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/WinterComponentFactory.java index 51d4ec4..d15e915 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/WinterComponentFactory.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/WinterComponentFactory.java @@ -2,7 +2,7 @@ package com.artemis.the.gr8.playerstats.core.msg.components; import net.kyori.adventure.text.TextComponent; -public class WinterComponentFactory extends ComponentFactory { +public final class WinterComponentFactory extends ComponentFactory { public WinterComponentFactory() { super(); @@ -12,13 +12,13 @@ public class WinterComponentFactory extends ComponentFactory { public TextComponent pluginPrefixAsTitle() { return miniMessageToComponent( "" + - "\u2744 __________ [PlayerStats] __________ " + - "\u2744"); + "<#D6F1FE>\u2744 __________ [PlayerStats] __________ " + + "<#D6F1FE>\u2744"); } @Override public TextComponent pluginPrefix() { return miniMessageToComponent( - "[PlayerStats]"); + "[PlayerStats]"); } -} +} \ No newline at end of file From 11185468ffe1012c1a3201f18a7619ddeb6c9f2f Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Wed, 9 Nov 2022 16:41:56 +0100 Subject: [PATCH 31/43] Removed test command (#127) --- .../core/commands/ExcludeCommand.java | 17 ------- .../core/commands/TabCompleter.java | 30 ------------ .../playerstats/core/msg/OutputManager.java | 47 ------------------- 3 files changed, 94 deletions(-) diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/commands/ExcludeCommand.java b/src/main/java/com/artemis/the/gr8/playerstats/core/commands/ExcludeCommand.java index 1ca867b..e6ab8a4 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/commands/ExcludeCommand.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/commands/ExcludeCommand.java @@ -32,23 +32,6 @@ public final class ExcludeCommand implements CommandExecutor { outputManager.sendExcludeInfo(sender); return true; } - case "test" -> { - if (args.length >= 3) { - switch (args[1]) { - case "help" -> outputManager.sendHelpTest(sender, args[2]); - case "examples" -> outputManager.sendExampleTest(sender, args[2]); - case "exclude" -> outputManager.sendExcludeTest(sender, args[2]); - case "prefix" -> outputManager.sendPrefixTest(sender, args[2]); - case "title" -> outputManager.sendPrefixTitleTest(sender, args[2]); - case "name" -> { - if (args.length >= 4) { - outputManager.sendNameTest(sender, args[2], args[3]); - } - } - } - } - return true; - } case "add" -> { if (args.length >= 2 && offlinePlayerHandler.isLoadedPlayer(args[1])) { diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/commands/TabCompleter.java b/src/main/java/com/artemis/the/gr8/playerstats/core/commands/TabCompleter.java index f26512e..ffb0ff4 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/commands/TabCompleter.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/commands/TabCompleter.java @@ -7,16 +7,12 @@ import org.bukkit.Statistic; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.entity.EntityType; -import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.Unmodifiable; import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import java.util.stream.Collectors; public final class TabCompleter implements org.bukkit.command.TabCompleter { @@ -59,38 +55,12 @@ public final class TabCompleter implements org.bukkit.command.TabCompleter { tabSuggestions = switch (args[0]) { case "add" -> offlinePlayerHandler.getLoadedOfflinePlayerNames(); case "remove" -> offlinePlayerHandler.getExcludedPlayerNames(); - case "info" -> { - ArrayList loadedPlayers = offlinePlayerHandler.getLoadedOfflinePlayerNames(); - loadedPlayers.addAll(offlinePlayerHandler.getExcludedPlayerNames()); - yield loadedPlayers; - } - case "test" -> getTestSuggestions(); default -> tabSuggestions; }; } - else if (args.length == 3) { - Pattern testPattern = Pattern.compile("help|examples|exclude|prefix|title|name"); - Matcher matcher = testPattern.matcher(args[1]); - if (matcher.find()) { - tabSuggestions = getSecondTestSuggestions(); - } - } - else if (args.length == 4 && args[1].equalsIgnoreCase("name")) { - tabSuggestions = offlinePlayerHandler.getLoadedOfflinePlayerNames(); - } return getDynamicTabSuggestions(tabSuggestions, args[args.length-1]); } - @Contract(pure = true) - private @Unmodifiable List getTestSuggestions() { - return List.of("help", "examples", "exclude", "prefix", "title", "name"); - } - - @Contract(pure = true) - private @Unmodifiable List getSecondTestSuggestions() { - return List.of("halloween", "pride", "bukkit", "console", "default", "winter", "birthday"); - } - private @Nullable List getStatCommandSuggestions(@NotNull String[] args) { if (args.length == 0) { return null; diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/OutputManager.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/OutputManager.java index 653d8f1..3b6fa1e 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/OutputManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/OutputManager.java @@ -123,53 +123,6 @@ public final class OutputManager { .excludeInfoMsg()); } - public void sendPrefixTest(@NotNull CommandSender sender, String arg) { - adventure.sender(sender).sendMessage(getTestBuilder(arg) - .getPluginPrefix()); - } - - public void sendPrefixTitleTest(@NotNull CommandSender sender, String arg) { - adventure.sender(sender).sendMessage(getTestBuilder(arg) - .getPluginPrefixAsTitle()); - } - - public void sendHelpTest(@NotNull CommandSender sender, String arg) { - adventure.sender(sender).sendMessage(getTestBuilder(arg) - .helpMsg()); - } - - public void sendExcludeTest(@NotNull CommandSender sender, String arg) { - adventure.sender(sender).sendMessage(getTestBuilder(arg) - .excludeInfoMsg()); - } - - public void sendExampleTest(@NotNull CommandSender sender, String arg) { - adventure.sender(sender).sendMessage(getTestBuilder(arg) - .usageExamples()); - } - - public void sendNameTest(@NotNull CommandSender sender, String arg, String playerName) { - adventure.sender(sender).sendMessage(getTestBuilder(arg) - .getSharerName(playerName)); - } - - private MessageBuilder getTestBuilder(String arg) { - if (arg == null) { - return MessageBuilder.defaultBuilder(); - } else { - ComponentFactory factory = switch (arg) { - case "halloween" -> new HalloweenComponentFactory(); - case "pride" -> new PrideComponentFactory(); - case "bukkit" -> new BukkitConsoleComponentFactory(); - case "console" -> new ConsoleComponentFactory(); - case "winter" -> new WinterComponentFactory(); - case "birthday" -> new BirthdayComponentFactory(); - default -> new ComponentFactory(); - }; - return MessageBuilder.fromComponentFactory(factory); - } - } - public void sendToAllPlayers(@NotNull TextComponent component) { adventure.players().sendMessage(component); } From 520f83bb6049c8f8e8dbcb881c0552c2b5ce9a6a Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Wed, 23 Nov 2022 17:37:19 +0100 Subject: [PATCH 32/43] Added output for /statexclude list command, and feedback for add/remove (#88) --- .../core/commands/ExcludeCommand.java | 38 ++++----- .../core/enums/StandardMessage.java | 2 + .../playerstats/core/msg/MessageBuilder.java | 48 ++++++++++-- .../playerstats/core/msg/OutputManager.java | 18 +++++ .../BukkitConsoleComponentFactory.java | 9 ++- .../core/msg/components/ComponentFactory.java | 12 ++- .../core/msg/components/ExampleMessage.java | 11 +-- .../msg/components/ExcludeInfoMessage.java | 78 +++++++++---------- .../core/msg/components/HelpMessage.java | 36 +++------ .../core/utils/OfflinePlayerHandler.java | 33 ++++---- src/main/resources/excluded_players.yml | 7 +- src/main/resources/plugin.yml | 8 +- 12 files changed, 179 insertions(+), 121 deletions(-) diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/commands/ExcludeCommand.java b/src/main/java/com/artemis/the/gr8/playerstats/core/commands/ExcludeCommand.java index e6ab8a4..9132278 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/commands/ExcludeCommand.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/commands/ExcludeCommand.java @@ -1,5 +1,6 @@ package com.artemis.the.gr8.playerstats.core.commands; +import com.artemis.the.gr8.playerstats.core.enums.StandardMessage; import com.artemis.the.gr8.playerstats.core.msg.OutputManager; import com.artemis.the.gr8.playerstats.core.utils.OfflinePlayerHandler; import org.bukkit.command.Command; @@ -21,35 +22,36 @@ public final class ExcludeCommand implements CommandExecutor { @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { - if (args.length >= 1) { + if (args.length == 0) { + outputManager.sendExcludeInfo(sender); + } + else if (args.length == 1) { switch (args[0]) { + case "info" -> outputManager.sendExcludeInfo(sender); case "list" -> { ArrayList excludedPlayers = offlinePlayerHandler.getExcludedPlayerNames(); - sender.sendMessage(String.valueOf(excludedPlayers)); - return true; - } - case "info" -> { - outputManager.sendExcludeInfo(sender); - return true; + outputManager.sendExcludedList(sender, excludedPlayers); } + } + } + else { + switch (args[0]) { case "add" -> { - if (args.length >= 2 && - offlinePlayerHandler.isLoadedPlayer(args[1])) { - offlinePlayerHandler.addLoadedPlayerToExcludeList(args[1]); - sender.sendMessage("Excluded " + args[1] + "!"); - return true; + if (offlinePlayerHandler.addLoadedPlayerToExcludeList(args[1])) { + outputManager.sendFeedbackMsgPlayerExcluded(sender, args[1]); + } else { + outputManager.sendFeedbackMsg(sender, StandardMessage.EXCLUDE_FAILED); } } case "remove" -> { - if (args.length >= 2 && - offlinePlayerHandler.isExcludedPlayer(args[1])) { - offlinePlayerHandler.addExcludedPlayerToLoadedList(args[1]); - sender.sendMessage("Removed " + args[1] + " from the exclude list again!"); - return true; + if (offlinePlayerHandler.addExcludedPlayerToLoadedList(args[1])) { + outputManager.sendFeedbackMsgPlayerIncluded(sender, args[1]); + } else { + outputManager.sendFeedbackMsg(sender, StandardMessage.INCLUDE_FAILED); } } } } - return false; + return true; } } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/enums/StandardMessage.java b/src/main/java/com/artemis/the/gr8/playerstats/core/enums/StandardMessage.java index 6f90bad..64d1407 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/enums/StandardMessage.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/enums/StandardMessage.java @@ -8,6 +8,8 @@ package com.artemis.the.gr8.playerstats.core.enums; public enum StandardMessage { RELOADED_CONFIG, STILL_RELOADING, + EXCLUDE_FAILED, + INCLUDE_FAILED, MISSING_STAT_NAME, MISSING_PLAYER_NAME, WAIT_A_MOMENT, diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/MessageBuilder.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/MessageBuilder.java index 657fbdb..8a92dec 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/MessageBuilder.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/MessageBuilder.java @@ -79,7 +79,7 @@ public final class MessageBuilder implements StatTextFormatter { } @Override - public TextComponent getRainbowPluginPrefix() { + public @NotNull TextComponent getRainbowPluginPrefix() { PrideComponentFactory pride = new PrideComponentFactory(); return pride.pluginPrefix(); } @@ -90,15 +90,11 @@ public final class MessageBuilder implements StatTextFormatter { } @Override - public TextComponent getRainbowPluginPrefixAsTitle() { + public @NotNull TextComponent getRainbowPluginPrefixAsTitle() { PrideComponentFactory pride = new PrideComponentFactory(); return pride.pluginPrefixAsTitle(); } - public TextComponent getSharerName(String name) { - return componentFactory.sharerName(name); - } - public @NotNull TextComponent reloadedConfig() { return composePluginMessage("Config reloaded!"); } @@ -107,6 +103,30 @@ public final class MessageBuilder implements StatTextFormatter { return composePluginMessage("The plugin is (re)loading, your request will be processed when it is done!"); } + public @NotNull TextComponent excludeSuccess(String playerName) { + return componentFactory.pluginPrefix() + .append(space()) + .append(componentFactory.message().content("Excluded ") + .append(componentFactory.messageAccent().content(playerName)) + .append(text("!"))); + } + + public @NotNull TextComponent excludeFailed() { + return composePluginMessage("This player is already hidden from /stat results!"); + } + + public @NotNull TextComponent includeSuccess(String playerName) { + return componentFactory.pluginPrefix() + .append(space()) + .append(componentFactory.message().content("Removed ") + .append(componentFactory.messageAccent().content(playerName)) + .append(text(" from the exclude-list!"))); + } + + public @NotNull TextComponent includeFailed() { + return composePluginMessage("This is not a player that has been excluded with the /statexclude command!"); + } + public @NotNull TextComponent waitAMinute() { return composePluginMessage("Calculating statistics, this may take a minute..."); } @@ -192,6 +212,22 @@ public final class MessageBuilder implements StatTextFormatter { return ExcludeInfoMessage.construct(componentFactory); } + public @NotNull TextComponent excludedList(@NotNull ArrayList excludedPlayerNames) { + TextComponent.Builder excludedList = text() + .append(newline()) + .append(getPluginPrefixAsTitle() + .append(newline()) + .append(componentFactory.subTitle("All players that are currently excluded: "))); + + excludedPlayerNames.forEach(playerName -> excludedList + .append(newline()) + .append(componentFactory.arrow() + .append(space()) + .append(componentFactory.infoMessageAccent().content(playerName)))); + + return excludedList.build(); + } + @Override public @NotNull TextComponent getStatTitle(Statistic statistic, @Nullable String subStatName) { return getTopStatTitleComponent(0, statistic, subStatName, null); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/OutputManager.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/OutputManager.java index 3b6fa1e..ee6caf2 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/OutputManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/OutputManager.java @@ -15,6 +15,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.time.LocalDate; +import java.util.ArrayList; import java.util.EnumMap; import java.util.LinkedHashMap; import java.util.function.Function; @@ -94,6 +95,16 @@ public final class OutputManager { } } + public void sendFeedbackMsgPlayerExcluded(@NotNull CommandSender sender, String playerName) { + adventure.sender(sender).sendMessage(getMessageBuilder(sender) + .excludeSuccess(playerName)); + } + + public void sendFeedbackMsgPlayerIncluded(@NotNull CommandSender sender, String playerName) { + adventure.sender(sender).sendMessage(getMessageBuilder(sender) + .includeSuccess(playerName)); + } + public void sendFeedbackMsgMissingSubStat(@NotNull CommandSender sender, String statType) { adventure.sender(sender).sendMessage(getMessageBuilder(sender) .missingSubStatName(statType)); @@ -123,6 +134,11 @@ public final class OutputManager { .excludeInfoMsg()); } + public void sendExcludedList(@NotNull CommandSender sender, ArrayList excludedPlayerNames) { + adventure.sender(sender).sendMessage(getMessageBuilder(sender) + .excludedList(excludedPlayerNames)); + } + public void sendToAllPlayers(@NotNull TextComponent component) { adventure.players().sendMessage(component); } @@ -188,6 +204,8 @@ public final class OutputManager { standardMessages.put(RELOADED_CONFIG, MessageBuilder::reloadedConfig); standardMessages.put(STILL_RELOADING, MessageBuilder::stillReloading); + standardMessages.put(EXCLUDE_FAILED, MessageBuilder::excludeFailed); + standardMessages.put(INCLUDE_FAILED, MessageBuilder::includeFailed); standardMessages.put(MISSING_STAT_NAME, MessageBuilder::missingStatName); standardMessages.put(MISSING_PLAYER_NAME, MessageBuilder::missingPlayerName); standardMessages.put(WAIT_A_MOMENT, MessageBuilder::waitAMoment); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/BukkitConsoleComponentFactory.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/BukkitConsoleComponentFactory.java index 0cce2df..21122ff 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/BukkitConsoleComponentFactory.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/BukkitConsoleComponentFactory.java @@ -55,12 +55,17 @@ public final class BukkitConsoleComponentFactory extends ComponentFactory { @Override public TextComponent arrow() { - return text("->").color(INFO_MSG); + return text(" ->").color(INFO_MSG); } @Override public TextComponent bulletPoint() { - return text("*").color(INFO_MSG); + return text(" *").color(INFO_MSG); + } + + @Override + public TextComponent bulletPointIndented() { + return text(" *").color(INFO_MSG); } @Override diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ComponentFactory.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ComponentFactory.java index 8cb205e..92a9774 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ComponentFactory.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ComponentFactory.java @@ -132,6 +132,10 @@ public class ComponentFactory { return text().color(FEEDBACK_MSG_ACCENT).build(); } + public TextComponent infoMessageAccent() { + return text().color(INFO_MSG_ACCENT_MEDIUM).build(); + } + public TextComponent title(String content, Target target) { return getComponent(content, getColorFromString(config.getTitleDecoration(target, false)), @@ -329,11 +333,15 @@ public class ComponentFactory { } public TextComponent arrow() { - return text("→").color(INFO_MSG); //alt + 26 + return text(" →").color(INFO_MSG); //4 spaces, alt + 26 } public TextComponent bulletPoint() { - return text("•").color(INFO_MSG); //alt + 7 + return text(" •").color(INFO_MSG); //4 spaces, alt + 7 + } + + public TextComponent bulletPointIndented() { + return text(" •").color(INFO_MSG); //8 spaces, alt + 7 } /** diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ExampleMessage.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ExampleMessage.java index 25201a8..7fd0338 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ExampleMessage.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ExampleMessage.java @@ -29,27 +29,22 @@ public final class ExampleMessage implements TextComponent { } private @NotNull TextComponent buildMessage(@NotNull ComponentFactory factory) { - TextComponent spaces = text(" "); //4 spaces - return Component.newline() .append(factory.pluginPrefixAsTitle()) .append(Component.newline()) .append(factory.subTitle("Examples: ")) .append(Component.newline()) - .append(spaces).append( - factory.arrow()).append(Component.space()) + .append(factory.arrow()).append(Component.space()) .append(text("/stat ").color(factory.INFO_MSG) .append(text("animals_bred ").color(factory.INFO_MSG_ACCENT_MEDIUM) .append(text("top").color(factory.INFO_MSG_ACCENT_LIGHTEST)))) .append(Component.newline()) - .append(spaces).append( - factory.arrow()).append(Component.space()) + .append(factory.arrow()).append(Component.space()) .append(text("/stat ").color(factory.INFO_MSG) .append(text("mine_block diorite ").color(factory.INFO_MSG_ACCENT_MEDIUM) .append(text("me").color(factory.INFO_MSG_ACCENT_LIGHTEST)))) .append(Component.newline()) - .append(spaces).append( - factory.arrow()).append(Component.space()) + .append(factory.arrow()).append(Component.space()) .append(text("/stat ").color(factory.INFO_MSG) .append(text("deaths ").color(factory.INFO_MSG_ACCENT_MEDIUM) .append(text("player ").color(factory.INFO_MSG_ACCENT_LIGHTEST) diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ExcludeInfoMessage.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ExcludeInfoMessage.java index ff04d1e..7b0848d 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ExcludeInfoMessage.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ExcludeInfoMessage.java @@ -5,7 +5,6 @@ import net.kyori.adventure.text.ComponentLike; import net.kyori.adventure.text.TextComponent; import net.kyori.adventure.text.event.HoverEvent; import net.kyori.adventure.text.format.Style; -import net.kyori.adventure.text.format.TextDecoration; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Unmodifiable; @@ -28,54 +27,51 @@ public final class ExcludeInfoMessage implements TextComponent { } private @NotNull TextComponent buildMessage(@NotNull ComponentFactory factory) { - TextComponent spaces = text(" "); - return Component.newline() .append(factory.pluginPrefixAsTitle()) .append(Component.newline()) - .append(factory.subTitle("Hide a player's statistics from /stat results")) - .append(Component.newline()) - .append(text("Excluded players are:") - .color(factory.INFO_MSG)) - .append(Component.newline()) - .append(spaces).append( - factory.arrow()).append(Component.space()) - .append(text("not visible in the top 10") - .color(factory.INFO_MSG_ACCENT_MEDIUM)) - .append(Component.newline()) - .append(spaces).append( - factory.arrow()).append(Component.space()) - .append(text("not counted for the server total") - .color(factory.INFO_MSG_ACCENT_MEDIUM)) - .append(Component.newline()) - .append(spaces).append( - factory.arrow()).append(Component.space()) - .append(text("hidden") - .decorate(TextDecoration.BOLD) - .color(factory.INFO_MSG_ACCENT_MEDIUM) - .hoverEvent(HoverEvent.showText(text("All data is still stored by the server,") - .append(Component.newline()) - .append(text("and excluded players can still look up")) - .append(Component.newline()) - .append(text("their own statistics in the in-game menu")) - .color(factory.FEEDBACK_MSG)))) - .append(text(", not removed") - .decorations(TextDecoration.NAMES.values(), false) - .color(factory.INFO_MSG_ACCENT_MEDIUM)) - .append(Component.newline()) + .append(factory.subTitle("Hover over the arguments for more information!")) .append(Component.newline()) .append(text("Usage: ").color(factory.INFO_MSG) .append(text("/statexclude").color(factory.INFO_MSG_ACCENT_MEDIUM))) .append(Component.newline()) - .append(spaces).append(spaces).append( - factory.bulletPoint()).append(Component.space()) - .append(text("add ").color(factory.INFO_MSG_ACCENT_DARKEST)) - .append(text("player-name").color(factory.INFO_MSG_ACCENT_MEDIUM)) + .append(factory.bulletPoint()).append(Component.space()) + .append(text("add ").color(factory.INFO_MSG_ACCENT_DARKEST) + .append(text("{player-name}").color(factory.INFO_MSG_ACCENT_MEDIUM)) + .hoverEvent(HoverEvent.showText( + text("Excludes this player from /stat results").color(factory.FEEDBACK_MSG)))) .append(Component.newline()) - .append(spaces).append(spaces).append( - factory.bulletPoint()).append(Component.space()) - .append(text("remove ").color(factory.INFO_MSG_ACCENT_DARKEST)) - .append(text("player-name").color(factory.INFO_MSG_ACCENT_MEDIUM)); + .append(factory.bulletPoint()).append(Component.space()) + .append(text("remove ").color(factory.INFO_MSG_ACCENT_DARKEST) + .append(text("{player-name}").color(factory.INFO_MSG_ACCENT_MEDIUM)) + .hoverEvent(HoverEvent.showText(text("Removes this player from the excluded-players file,") + .append(Component.newline()) + .append(text("so their stats show up in /stat results again")) + .color(factory.FEEDBACK_MSG)))) + .append(Component.newline()) + .append(factory.bulletPoint()).append(Component.space()) + .append(text("list").color(factory.INFO_MSG_ACCENT_DARKEST) + .hoverEvent(HoverEvent.showText( + text("See a list of all currently excluded players").color(factory.FEEDBACK_MSG)))) + .append(Component.newline()) + .append(Component.newline()) + .append(text("Excluded players are:") + .color(factory.INFO_MSG)) + .append(Component.newline()) + .append(factory.arrow()).append(Component.space()) + .append(text("not visible in the top 10").color(factory.INFO_MSG_ACCENT_MEDIUM)) + .append(Component.newline()) + .append(factory.arrow()).append(Component.space()) + .append(text("not counted for the server total").color(factory.INFO_MSG_ACCENT_MEDIUM)) + .append(Component.newline()) + .append(factory.arrow()).append(Component.space()) + .append(text("hidden") + .hoverEvent(HoverEvent.showText(text("All statistics are still stored and tracked by the server, ") + .append(Component.newline()) + .append(text("this command does not delete anything")) + .color(factory.FEEDBACK_MSG)))) + .append(text(", not removed") + .color(factory.INFO_MSG_ACCENT_MEDIUM)); } @Override diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/HelpMessage.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/HelpMessage.java index 5e7f765..592d885 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/HelpMessage.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/HelpMessage.java @@ -40,8 +40,6 @@ public final class HelpMessage implements TextComponent { } private @NotNull TextComponent buildPlainMsg(ComponentFactory factory, int listSize) { - TextComponent spaces = text(" "); //4 spaces - return Component.newline() .append(factory.pluginPrefixAsTitle()) .append(newline()) @@ -50,47 +48,37 @@ public final class HelpMessage implements TextComponent { .append(text("Usage:").color(factory.INFO_MSG)).append(space()) .append(text("/statistic").color(factory.INFO_MSG_ACCENT_MEDIUM)) .append(newline()) - .append(spaces).append( - factory.arrow()).append(space()) + .append(factory.arrow()).append(space()) .append(text("name").color(factory.INFO_MSG_ACCENT_MEDIUM)) .append(newline()) - .append(spaces).append( - factory.arrow()).append(space()) + .append(factory.arrow()).append(space()) .append(text("{sub-statistic}").color(factory.INFO_MSG_ACCENT_MEDIUM)).append(space()) .append(text("(a block, item or entity)").color(factory.BRACKETS)) .append(newline()) - .append(spaces).append( - factory.arrow()).append(space()) + .append(factory.arrow()).append(space()) .append(text("me | player | server | top").color(factory.INFO_MSG_ACCENT_MEDIUM)) .append(newline()) - .append(spaces).append(spaces).append( - factory.bulletPoint()).append(space()) + .append(factory.bulletPointIndented()).append(space()) .append(text("me:").color(factory.INFO_MSG_ACCENT_DARKEST)).append(space()) .append(text("your own statistic").color(factory.BRACKETS)) .append(newline()) - .append(spaces).append(spaces).append( - factory.bulletPoint()).append(space()) + .append(factory.bulletPointIndented()).append(space()) .append(text("player:").color(factory.INFO_MSG_ACCENT_DARKEST)).append(space()) .append(text("choose a player").color(factory.BRACKETS)) .append(newline()) - .append(spaces).append(spaces).append( - factory.bulletPoint()).append(space()) + .append(factory.bulletPointIndented()).append(space()) .append(text("server:").color(factory.INFO_MSG_ACCENT_DARKEST)).append(space()) .append(text("everyone on the server combined").color(factory.BRACKETS)) .append(newline()) - .append(spaces).append(spaces).append( - factory.bulletPoint()).append(space()) + .append(factory.bulletPointIndented()).append(space()) .append(text("top:").color(factory.INFO_MSG_ACCENT_DARKEST)).append(space()) .append(text("the top").color(factory.BRACKETS).append(space()).append(text(listSize))) .append(newline()) - .append(spaces).append( - factory.arrow()).append(space()) + .append(factory.arrow()).append(space()) .append(text("{player-name}").color(factory.INFO_MSG_ACCENT_MEDIUM)); } private @NotNull TextComponent buildHoverMsg(@NotNull ComponentFactory factory, int listSize) { - TextComponent spaces = text(" "); - return Component.newline() .append(factory.pluginPrefixAsTitle()) .append(newline()) @@ -99,14 +87,14 @@ public final class HelpMessage implements TextComponent { .append(text("Usage:").color(factory.INFO_MSG)).append(space()) .append(text("/statistic").color(factory.INFO_MSG_ACCENT_MEDIUM)) .append(newline()) - .append(spaces).append(factory.arrow()).append(space()) + .append(factory.arrow()).append(space()) .append(text("name").color(factory.INFO_MSG_ACCENT_MEDIUM) .hoverEvent(HoverEvent.showText(text("The name that describes the statistic").color(factory.MSG_HOVER) .append(newline()) .append(text("Example: ").color(factory.INFO_MSG)) .append(text("\"animals_bred\"").color(factory.INFO_MSG_ACCENT_MEDIUM))))) .append(newline()) - .append(spaces).append(factory.arrow()).append(space()) + .append(factory.arrow()).append(space()) .append(text("sub-statistic").color(factory.INFO_MSG_ACCENT_MEDIUM) .hoverEvent(HoverEvent.showText( text("Some statistics need an item, block or entity as extra input").color(factory.MSG_HOVER) @@ -114,7 +102,7 @@ public final class HelpMessage implements TextComponent { .append(text("Example: ").color(factory.INFO_MSG) .append(text("\"mine_block diorite\"").color(factory.INFO_MSG_ACCENT_MEDIUM)))))) .append(newline()) - .append(spaces).append(factory.arrow() + .append(factory.arrow() .hoverEvent(HoverEvent.showText( text("Choose one").color(factory.MSG_CLICKED)))) .append(space()) @@ -135,7 +123,7 @@ public final class HelpMessage implements TextComponent { text("See the top").color(factory.MSG_HOVER).append(space()) .append(text(listSize))))) .append(newline()) - .append(spaces).append(factory.arrow()).append(space()) + .append(factory.arrow()).append(space()) .append(text("player-name").color(factory.INFO_MSG_ACCENT_MEDIUM) .hoverEvent(HoverEvent.showText( text("In case you typed").color(factory.MSG_HOVER).append(space()) diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/utils/OfflinePlayerHandler.java b/src/main/java/com/artemis/the/gr8/playerstats/core/utils/OfflinePlayerHandler.java index 3cff6ab..4f02db9 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/utils/OfflinePlayerHandler.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/utils/OfflinePlayerHandler.java @@ -72,24 +72,29 @@ public final class OfflinePlayerHandler extends FileHandler { return excludedPlayerUUIDs.containsValue(uniqueID); } - public void addLoadedPlayerToExcludeList(String playerName) throws IllegalArgumentException { - UUID uuid = includedPlayerUUIDs.get(playerName); - if (uuid == null) { - throw new IllegalArgumentException("This player is not loaded, and therefore cannot be excluded!"); + public boolean addLoadedPlayerToExcludeList(String playerName) { + if (isLoadedPlayer(playerName)) { + UUID uuid = includedPlayerUUIDs.get(playerName); + + super.writeEntryToList("excluded", uuid.toString()); + includedPlayerUUIDs.remove(playerName); + excludedPlayerUUIDs.put(playerName, uuid); + return true; } - super.writeEntryToList("excluded", uuid.toString()); - includedPlayerUUIDs.remove(playerName); - excludedPlayerUUIDs.put(playerName, uuid); + return false; } - public void addExcludedPlayerToLoadedList(String playerName) { - UUID uuid = excludedPlayerUUIDs.get(playerName); - if (uuid == null) { - throw new IllegalArgumentException("This player is not excluded, and therefore cannot be un-excluded!"); + public boolean addExcludedPlayerToLoadedList(String playerName) { + //this only includes explicitly excluded players + if (isExcludedPlayer(playerName)) { + UUID uuid = excludedPlayerUUIDs.get(playerName); + + super.removeEntryFromList("excluded", uuid.toString()); + excludedPlayerUUIDs.remove(playerName); + includedPlayerUUIDs.put(playerName, uuid); + return true; } - super.removeEntryFromList("excluded", uuid.toString()); - excludedPlayerUUIDs.remove(playerName); - includedPlayerUUIDs.put(playerName, uuid); + return false; } @Contract(" -> new") diff --git a/src/main/resources/excluded_players.yml b/src/main/resources/excluded_players.yml index 011efa6..b2cc778 100644 --- a/src/main/resources/excluded_players.yml +++ b/src/main/resources/excluded_players.yml @@ -2,10 +2,11 @@ # PlayerStats Excluded Players # # ------------------------------------------------------------------------------------------------------ # -# Players whose UUIDs are stored in this file, will not be included in /statistic results. -# This can be used for more fine-grained filtering, for example to exclude alt accounts. -# For more general filtering settings, see the config.yml (section 'General') +# Players whose UUIDs are stored in this file, will be hidden from /statistic results. +# This can be used to exclude alt accounts, for example. +# To exclude groups of players (such as banned players), see the config.yml (section 'General') +# UUIDs can be added directly to this file, or through the /statexclude command in game. # Format: # - player1UUID # - player2UUID diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 1e43d0f..3c9988d 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -12,27 +12,29 @@ commands: - stat - stats description: show player statistics in private chat + usage: "§6/stat info" permission: playerstats.stat statisticshare: aliases: - statshare - statsshare description: share last stat lookup in chat - usage: "§b/statshare" + usage: "§6/This command can only be executed by clicking the \"share\" button in /stat results. + If you don't see this button, you don't have share-permission, or sharing is turned off." permission: playerstats.share statisticreload: aliases: - statreload - statsreload description: reloads the config - usage: "§a/statreload" + usage: "§6/statreload" permission: playerstats.reload statisticexclude: aliases: - statexclude - statsexclude description: hide this player's statistics from /stat results - usage: "§c/statexclude" + usage: "§6/statexclude info" permission: playerstats.exclude permissions: playerstats.stat: From 89c2a0f85f5f5891ddbb310c74422ac72b6e1045 Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Fri, 25 Nov 2022 14:14:53 +0100 Subject: [PATCH 33/43] Small formatting fix --- .../core/msg/components/ExcludeInfoMessage.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ExcludeInfoMessage.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ExcludeInfoMessage.java index 7b0848d..fdec736 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ExcludeInfoMessage.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ExcludeInfoMessage.java @@ -44,10 +44,8 @@ public final class ExcludeInfoMessage implements TextComponent { .append(factory.bulletPoint()).append(Component.space()) .append(text("remove ").color(factory.INFO_MSG_ACCENT_DARKEST) .append(text("{player-name}").color(factory.INFO_MSG_ACCENT_MEDIUM)) - .hoverEvent(HoverEvent.showText(text("Removes this player from the excluded-players file,") - .append(Component.newline()) - .append(text("so their stats show up in /stat results again")) - .color(factory.FEEDBACK_MSG)))) + .hoverEvent(HoverEvent.showText( + text("Includes this player in /stat results again").color(factory.FEEDBACK_MSG)))) .append(Component.newline()) .append(factory.bulletPoint()).append(Component.space()) .append(text("list").color(factory.INFO_MSG_ACCENT_DARKEST) @@ -65,7 +63,7 @@ public final class ExcludeInfoMessage implements TextComponent { .append(text("not counted for the server total").color(factory.INFO_MSG_ACCENT_MEDIUM)) .append(Component.newline()) .append(factory.arrow()).append(Component.space()) - .append(text("hidden") + .append(text("hidden").color(factory.INFO_MSG_ACCENT_MEDIUM) .hoverEvent(HoverEvent.showText(text("All statistics are still stored and tracked by the server, ") .append(Component.newline()) .append(text("this command does not delete anything")) From a6e15828c12aa1f73bcaf67efa46f04e6d5be48f Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Mon, 5 Dec 2022 15:43:49 +0100 Subject: [PATCH 34/43] Changed accent color for exclude-info-msg and removed unnecessary plugincolor --- .../gr8/playerstats/core/enums/PluginColor.java | 5 ----- .../BukkitConsoleComponentFactory.java | 2 +- .../core/msg/components/ComponentFactory.java | 6 +++--- .../core/msg/components/ExcludeInfoMessage.java | 16 ++++++++-------- 4 files changed, 12 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/enums/PluginColor.java b/src/main/java/com/artemis/the/gr8/playerstats/core/enums/PluginColor.java index 9bfdab3..5087d07 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/enums/PluginColor.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/enums/PluginColor.java @@ -52,11 +52,6 @@ public enum PluginColor { */ LIGHT_GOLD (TextColor.fromHexString("#FFEA40")), - /** - * A Light Yellow that is used for final accents in the example message (#FFFF8E). - */ - LIGHT_YELLOW (TextColor.fromHexString("#FFFF8E")), - /** * The color of vanilla Minecraft hearts (#FF1313). */ diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/BukkitConsoleComponentFactory.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/BukkitConsoleComponentFactory.java index 21122ff..41d65f6 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/BukkitConsoleComponentFactory.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/BukkitConsoleComponentFactory.java @@ -34,7 +34,7 @@ public final class BukkitConsoleComponentFactory extends ComponentFactory { INFO_MSG = PluginColor.GOLD.getConsoleColor(); INFO_MSG_ACCENT_DARKEST = PluginColor.MEDIUM_GOLD.getConsoleColor(); INFO_MSG_ACCENT_MEDIUM = PluginColor.LIGHT_GOLD.getConsoleColor(); - INFO_MSG_ACCENT_LIGHTEST = PluginColor.LIGHT_YELLOW.getConsoleColor(); + INFO_MSG_ACCENT_LIGHTEST = PluginColor.LIGHTEST_BLUE.getConsoleColor(); MSG_HOVER = PluginColor.LIGHTEST_BLUE.getConsoleColor(); MSG_CLICKED = PluginColor.LIGHT_PURPLE.getConsoleColor(); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ComponentFactory.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ComponentFactory.java index 92a9774..94f6f84 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ComponentFactory.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ComponentFactory.java @@ -47,7 +47,7 @@ public class ComponentFactory { protected TextColor INFO_MSG; //gold protected TextColor INFO_MSG_ACCENT_DARKEST; //medium_gold protected TextColor INFO_MSG_ACCENT_MEDIUM; //light_gold - protected TextColor INFO_MSG_ACCENT_LIGHTEST; //light_yellow + protected TextColor INFO_MSG_ACCENT_LIGHTEST; //lightest_blue protected TextColor MSG_HOVER; //lightest_blue protected TextColor MSG_CLICKED; //light_purple @@ -70,7 +70,7 @@ public class ComponentFactory { INFO_MSG = PluginColor.GOLD.getColor(); INFO_MSG_ACCENT_DARKEST = PluginColor.MEDIUM_GOLD.getColor(); INFO_MSG_ACCENT_MEDIUM = PluginColor.LIGHT_GOLD.getColor(); - INFO_MSG_ACCENT_LIGHTEST = PluginColor.LIGHT_YELLOW.getColor(); + INFO_MSG_ACCENT_LIGHTEST = PluginColor.LIGHTEST_BLUE.getColor(); MSG_HOVER = PluginColor.LIGHTEST_BLUE.getColor(); MSG_CLICKED = PluginColor.LIGHT_PURPLE.getColor(); @@ -88,7 +88,7 @@ public class ComponentFactory { } public TextComponent getExampleName() { - return text("Artemis_the_gr8").color(INFO_MSG_ACCENT_LIGHTEST); + return text("Artemis_the_gr8").color(FEEDBACK_MSG); } /** diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ExcludeInfoMessage.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ExcludeInfoMessage.java index fdec736..eb2f35a 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ExcludeInfoMessage.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/components/ExcludeInfoMessage.java @@ -39,18 +39,18 @@ public final class ExcludeInfoMessage implements TextComponent { .append(text("add ").color(factory.INFO_MSG_ACCENT_DARKEST) .append(text("{player-name}").color(factory.INFO_MSG_ACCENT_MEDIUM)) .hoverEvent(HoverEvent.showText( - text("Excludes this player from /stat results").color(factory.FEEDBACK_MSG)))) + text("Excludes this player from /stat results").color(factory.INFO_MSG_ACCENT_LIGHTEST)))) .append(Component.newline()) .append(factory.bulletPoint()).append(Component.space()) .append(text("remove ").color(factory.INFO_MSG_ACCENT_DARKEST) .append(text("{player-name}").color(factory.INFO_MSG_ACCENT_MEDIUM)) .hoverEvent(HoverEvent.showText( - text("Includes this player in /stat results again").color(factory.FEEDBACK_MSG)))) + text("Includes this player in /stat results again").color(factory.INFO_MSG_ACCENT_LIGHTEST)))) .append(Component.newline()) .append(factory.bulletPoint()).append(Component.space()) .append(text("list").color(factory.INFO_MSG_ACCENT_DARKEST) .hoverEvent(HoverEvent.showText( - text("See a list of all currently excluded players").color(factory.FEEDBACK_MSG)))) + text("See a list of all currently excluded players").color(factory.INFO_MSG_ACCENT_LIGHTEST)))) .append(Component.newline()) .append(Component.newline()) .append(text("Excluded players are:") @@ -63,12 +63,12 @@ public final class ExcludeInfoMessage implements TextComponent { .append(text("not counted for the server total").color(factory.INFO_MSG_ACCENT_MEDIUM)) .append(Component.newline()) .append(factory.arrow()).append(Component.space()) - .append(text("hidden").color(factory.INFO_MSG_ACCENT_MEDIUM) - .hoverEvent(HoverEvent.showText(text("All statistics are still stored and tracked by the server, ") + .append(text("hidden").color(factory.INFO_MSG_ACCENT_LIGHTEST) + .hoverEvent(HoverEvent.showText(text("All statistics are still stored and tracked by the") .append(Component.newline()) - .append(text("this command does not delete anything")) - .color(factory.FEEDBACK_MSG)))) - .append(text(", not removed") + .append(text("server, this command does not delete anything!")) + .color(factory.INFO_MSG_ACCENT_LIGHTEST)))) + .append(text(" - not removed") .color(factory.INFO_MSG_ACCENT_MEDIUM)); } From bf35582b1317c765a0e6c4d86ffa91795b6f6744 Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Tue, 6 Dec 2022 20:29:04 +0100 Subject: [PATCH 35/43] Added way to get excluded player with corresponding config setting (#128, #129) --- .../gr8/playerstats/core/commands/StatCommand.java | 1 + .../gr8/playerstats/core/config/ConfigHandler.java | 10 +++++++++- .../playerstats/core/multithreading/StatAction.java | 2 +- .../playerstats/core/statrequest/RequestManager.java | 11 ++++++++++- .../playerstats/core/utils/OfflinePlayerHandler.java | 11 +++++++++-- src/main/resources/config.yml | 7 ++++++- 6 files changed, 36 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/commands/StatCommand.java b/src/main/java/com/artemis/the/gr8/playerstats/core/commands/StatCommand.java index c885ea6..91f7844 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/commands/StatCommand.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/commands/StatCommand.java @@ -170,6 +170,7 @@ public final class StatCommand implements CommandExecutor { switch (targetArg) { case "me" -> { if (sender instanceof Player) { + //TODO this is where an excluded player can sneak in target = Target.PLAYER; playerName = sender.getName(); } else { diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/config/ConfigHandler.java b/src/main/java/com/artemis/the/gr8/playerstats/core/config/ConfigHandler.java index 68ca9f5..d64de0b 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/config/ConfigHandler.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/config/ConfigHandler.java @@ -21,7 +21,7 @@ public final class ConfigHandler extends FileHandler { super("config.yml"); config = super.getFileConfiguration(); - configVersion = 6; + configVersion = 7; checkAndUpdateConfigVersion(); MyLogger.setDebugLevel(getDebugLevel()); } @@ -132,6 +132,14 @@ public final class ConfigHandler extends FileHandler { return config.getInt("number-of-days-since-last-joined", 0); } + /** + * Whether to allow the /stat player command for excluded players. + * @return the config setting (default: true) + */ + public boolean allowPlayerLookupsForExcludedPlayers() { + return config.getBoolean("allow-player-lookups-for-excluded-players", true); + } + /** * Whether to use TranslatableComponents wherever possible. * diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/multithreading/StatAction.java b/src/main/java/com/artemis/the/gr8/playerstats/core/multithreading/StatAction.java index df62967..e0e5c9b 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/multithreading/StatAction.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/multithreading/StatAction.java @@ -64,7 +64,7 @@ final class StatAction extends RecursiveTask> do { String playerName = iterator.next(); MyLogger.actionRunning(Thread.currentThread().getName()); - OfflinePlayer player = offlinePlayerHandler.getOfflinePlayer(playerName); + OfflinePlayer player = offlinePlayerHandler.getLoadedOfflinePlayer(playerName); int statistic = 0; switch (requestSettings.getStatistic().getType()) { case UNTYPED -> statistic = player.getStatistic(requestSettings.getStatistic()); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/statrequest/RequestManager.java b/src/main/java/com/artemis/the/gr8/playerstats/core/statrequest/RequestManager.java index 7723439..d83d15e 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/statrequest/RequestManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/statrequest/RequestManager.java @@ -4,6 +4,7 @@ import com.artemis.the.gr8.playerstats.api.RequestGenerator; import com.artemis.the.gr8.playerstats.api.StatManager; import com.artemis.the.gr8.playerstats.api.StatRequest; import com.artemis.the.gr8.playerstats.api.StatResult; +import com.artemis.the.gr8.playerstats.core.config.ConfigHandler; import com.artemis.the.gr8.playerstats.core.msg.msgutils.FormattingFunction; import com.artemis.the.gr8.playerstats.core.msg.OutputManager; import com.artemis.the.gr8.playerstats.core.multithreading.ThreadManager; @@ -85,10 +86,12 @@ public final class RequestManager implements StatManager { private final class RequestProcessor { + private static ConfigHandler config; private static OutputManager outputManager; private static ShareManager shareManager; public RequestProcessor(OutputManager outputManager) { + RequestProcessor.config = ConfigHandler.getInstance(); RequestProcessor.outputManager = outputManager; RequestProcessor.shareManager = ShareManager.getInstance(); } @@ -121,7 +124,13 @@ public final class RequestManager implements StatManager { } private int getPlayerStat(@NotNull StatRequest.Settings requestSettings) { - OfflinePlayer player = offlinePlayerHandler.getOfflinePlayer(requestSettings.getPlayerName()); + OfflinePlayer player; + if (offlinePlayerHandler.isExcludedPlayer(requestSettings.getPlayerName()) && + config.allowPlayerLookupsForExcludedPlayers()) { + player = offlinePlayerHandler.getExcludedOfflinePlayer(requestSettings.getPlayerName()); + } else { + player = offlinePlayerHandler.getLoadedOfflinePlayer(requestSettings.getPlayerName()); + } return switch (requestSettings.getStatistic().getType()) { case UNTYPED -> player.getStatistic(requestSettings.getStatistic()); case ENTITY -> player.getStatistic(requestSettings.getStatistic(), requestSettings.getEntity()); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/utils/OfflinePlayerHandler.java b/src/main/java/com/artemis/the/gr8/playerstats/core/utils/OfflinePlayerHandler.java index 4f02db9..b22da42 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/utils/OfflinePlayerHandler.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/utils/OfflinePlayerHandler.java @@ -132,7 +132,7 @@ public final class OfflinePlayerHandler extends FileHandler { * @throws IllegalArgumentException if this player is not on the list * of players that should be included in statistic calculations */ - public @NotNull OfflinePlayer getOfflinePlayer(String playerName) throws IllegalArgumentException { + public @NotNull OfflinePlayer getLoadedOfflinePlayer(String playerName) throws IllegalArgumentException { if (includedPlayerUUIDs.get(playerName) != null) { return Bukkit.getOfflinePlayer(includedPlayerUUIDs.get(playerName)); } @@ -140,10 +140,17 @@ public final class OfflinePlayerHandler extends FileHandler { 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"); - throw new IllegalArgumentException("Cannot convert this player-name into a valid Player to calculate statistics for"); + throw new IllegalArgumentException("PlayerStats does not know a player by this name"); } } + public @NotNull OfflinePlayer getExcludedOfflinePlayer(String playerName) throws IllegalArgumentException { + if (excludedPlayerUUIDs.get(playerName) != null) { + return Bukkit.getOfflinePlayer(excludedPlayerUUIDs.get(playerName)); + } + throw new IllegalArgumentException("There is no player on the exclude-list with this name"); + } + private void loadOfflinePlayers() { Executors.newSingleThreadExecutor().execute(() -> { loadExcludedPlayerNames(); diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 27c6b78..9065560 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,7 +1,7 @@ # ------------------------------------------------------------------------------------------------------ # # PlayerStats Configuration # # ------------------------------------------------------------------------------------------------------ # -config-version: 6 +config-version: 7 # # ------------------------------- # # @@ -33,6 +33,11 @@ exclude-banned-players: false # Leave this on 0 to include all players number-of-days-since-last-joined: 0 +# Players that are excluded through the previous settings or the excluded-players-file will not +# show up in top or server statistics. This setting controls whether you can still see their stats with +# the /stat player command +allow-player-lookups-for-excluded-players: true + # # ------------------------------- # # # # Format & Display # # From 6298bf075c506654e7dc3c544d875ed8839e0057 Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Mon, 6 Feb 2023 12:16:34 +0100 Subject: [PATCH 36/43] Merged locale-bugfix into v2.0 --- .../playerstats/commands/TabCompleter.java | 116 ------------------ .../commands/cmdutils/TabCompleteHelper.java | 58 --------- .../core/commands/TabCompleter.java | 7 +- .../core/msg/msgutils/StringUtils.java | 3 +- .../playerstats/msg/msgutils/StringUtils.java | 34 ----- 5 files changed, 6 insertions(+), 212 deletions(-) delete mode 100644 src/main/java/com/artemis/the/gr8/playerstats/commands/TabCompleter.java delete mode 100644 src/main/java/com/artemis/the/gr8/playerstats/commands/cmdutils/TabCompleteHelper.java delete mode 100644 src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/StringUtils.java diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/TabCompleter.java b/src/main/java/com/artemis/the/gr8/playerstats/commands/TabCompleter.java deleted file mode 100644 index deab6a8..0000000 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/TabCompleter.java +++ /dev/null @@ -1,116 +0,0 @@ -package com.artemis.the.gr8.playerstats.commands; - -import com.artemis.the.gr8.playerstats.utils.EnumHandler; -import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; -import com.artemis.the.gr8.playerstats.commands.cmdutils.TabCompleteHelper; -import org.bukkit.Statistic; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; -import java.util.stream.Collectors; - -public final class TabCompleter implements org.bukkit.command.TabCompleter { - - private final EnumHandler enumHandler; - private final OfflinePlayerHandler offlinePlayerHandler; - private final TabCompleteHelper tabCompleteHelper; - - private final List commandOptions; - - public TabCompleter(EnumHandler enumHandler, OfflinePlayerHandler offlinePlayerHandler) { - this.enumHandler = enumHandler; - this.offlinePlayerHandler = offlinePlayerHandler; - tabCompleteHelper = new TabCompleteHelper(enumHandler); - - commandOptions = new ArrayList<>(); - commandOptions.add("top"); - commandOptions.add("player"); - commandOptions.add("server"); - commandOptions.add("me"); - - } - - //args[0] = statistic (length = 1) - //args[1] = commandOption (top/player/me) OR substatistic (block/item/entitytype) (length = 2) - //args[2] = executorName OR commandOption (top/player/me) (length = 3) - //args[3] = executorName (length = 4) - - @Override - public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { - List tabSuggestions = new ArrayList<>(); - - if (args.length >= 1) { - String currentArg = args[args.length -1]; - - if (args.length == 1) { //after typing "stat", suggest a list of viable statistics - tabSuggestions = getFirstArgSuggestions(args[0]); - } - - else { //after checking if args[0] is a viable statistic, suggest substatistic OR commandOptions - String previousArg = args[args.length -2]; - - if (enumHandler.isStatistic(previousArg)) { - Statistic stat = EnumHandler.getStatEnum(previousArg); - if (stat != null) { - tabSuggestions = getTabSuggestions(getRelevantList(stat), currentArg); - } - } - - //if previous arg = "player" - else if (previousArg.equalsIgnoreCase("player")) { - - 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 - tabSuggestions = getTabSuggestions(offlinePlayerHandler.getOfflinePlayerNames(), currentArg); - } - } - - //after a substatistic, suggest commandOptions - else if (enumHandler.isSubStatEntry(previousArg)) { - tabSuggestions = commandOptions; - } - } - } - return tabSuggestions; - } - - private List getFirstArgSuggestions(String currentArg) { - List suggestions = enumHandler.getStatNames(); - suggestions.add("examples"); - suggestions.add("help"); - return getTabSuggestions(suggestions, currentArg); - } - - private List getTabSuggestions(List completeList, String currentArg) { - return completeList.stream() - .filter(item -> item.toLowerCase(Locale.ENGLISH).contains(currentArg.toLowerCase(Locale.ENGLISH))) - .collect(Collectors.toList()); - } - - private List getRelevantList(Statistic stat) { - switch (stat.getType()) { - case BLOCK -> { - return tabCompleteHelper.getAllBlockNames(); - } - case ITEM -> { - if (stat == Statistic.BREAK_ITEM) { - return tabCompleteHelper.getItemBrokenSuggestions(); - } else { - return tabCompleteHelper.getAllItemNames(); - } - } - case ENTITY -> { - return tabCompleteHelper.getEntitySuggestions(); - } - default -> { - return commandOptions; - } - } - } -} \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/commands/cmdutils/TabCompleteHelper.java b/src/main/java/com/artemis/the/gr8/playerstats/commands/cmdutils/TabCompleteHelper.java deleted file mode 100644 index ab4f00a..0000000 --- a/src/main/java/com/artemis/the/gr8/playerstats/commands/cmdutils/TabCompleteHelper.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.artemis.the.gr8.playerstats.commands.cmdutils; - -import com.artemis.the.gr8.playerstats.utils.EnumHandler; -import org.bukkit.Material; -import org.bukkit.entity.EntityType; - -import java.util.Arrays; -import java.util.List; -import java.util.Locale; -import java.util.stream.Collectors; - -public final class TabCompleteHelper { - - private final EnumHandler enumHandler; - private static List itemBrokenSuggestions; - private static List entitySuggestions; - - public TabCompleteHelper(EnumHandler enumHandler) { - this.enumHandler = enumHandler; - prepareLists(); - } - - public List getAllItemNames() { - return enumHandler.getItemNames(); - } - - public List getItemBrokenSuggestions() { - return itemBrokenSuggestions; - } - - public List getAllBlockNames() { - return enumHandler.getBlockNames(); - } - - public List getEntitySuggestions() { - return entitySuggestions; - } - - - private static void prepareLists() { - //breaking an item means running its durability negative - itemBrokenSuggestions = Arrays.stream(Material.values()) - .parallel() - .filter(Material::isItem) - .filter(item -> item.getMaxDurability() != 0) - .map(Material::toString) - .map(string -> string.toLowerCase(Locale.ENGLISH)) - .collect(Collectors.toList()); - - //the only statistics dealing with entities are killed_entity and entity_killed_by - entitySuggestions = Arrays.stream(EntityType.values()) - .parallel() - .filter(EntityType::isAlive) - .map(EntityType::toString) - .map(string -> string.toLowerCase(Locale.ENGLISH)) - .collect(Collectors.toList()); - } -} \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/commands/TabCompleter.java b/src/main/java/com/artemis/the/gr8/playerstats/core/commands/TabCompleter.java index ffb0ff4..4d5f9d0 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/commands/TabCompleter.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/commands/TabCompleter.java @@ -13,6 +13,7 @@ import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Locale; import java.util.stream.Collectors; public final class TabCompleter implements org.bukkit.command.TabCompleter { @@ -104,7 +105,7 @@ public final class TabCompleter implements org.bukkit.command.TabCompleter { */ private List getDynamicTabSuggestions(@NotNull List completeList, String currentArg) { return completeList.stream() - .filter(item -> item.toLowerCase().contains(currentArg.toLowerCase())) + .filter(item -> item.toLowerCase(Locale.ENGLISH).contains(currentArg.toLowerCase(Locale.ENGLISH))) .collect(Collectors.toList()); } @@ -147,7 +148,7 @@ public final class TabCompleter implements org.bukkit.command.TabCompleter { .filter(Material::isItem) .filter(item -> item.getMaxDurability() != 0) .map(Material::toString) - .map(String::toLowerCase) + .map(string -> string.toLowerCase(Locale.ENGLISH)) .collect(Collectors.toList()); //the only statistics dealing with entities are killed_entity and entity_killed_by @@ -155,7 +156,7 @@ public final class TabCompleter implements org.bukkit.command.TabCompleter { .parallel() .filter(EntityType::isAlive) .map(EntityType::toString) - .map(String::toLowerCase) + .map(string -> string.toLowerCase(Locale.ENGLISH)) .collect(Collectors.toList()); } } \ No newline at end of file diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/msgutils/StringUtils.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/msgutils/StringUtils.java index e4f2223..017385d 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/msgutils/StringUtils.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/msgutils/StringUtils.java @@ -2,6 +2,7 @@ package com.artemis.the.gr8.playerstats.core.msg.msgutils; import com.artemis.the.gr8.playerstats.core.utils.MyLogger; +import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -29,7 +30,7 @@ public final class StringUtils { if (input == null) return null; MyLogger.logHighLevelMsg("Prettifying [" + input + "]"); - StringBuilder capitals = new StringBuilder(input.toLowerCase()); + StringBuilder capitals = new StringBuilder(input.toLowerCase(Locale.ENGLISH)); capitals.setCharAt(0, Character.toUpperCase(capitals.charAt(0))); while (capitals.indexOf("_") != -1) { diff --git a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/StringUtils.java b/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/StringUtils.java deleted file mode 100644 index 79cc7cf..0000000 --- a/src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/StringUtils.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.artemis.the.gr8.playerstats.msg.msgutils; - -import com.artemis.the.gr8.playerstats.utils.MyLogger; - -import java.util.Locale; - -/** - * A small utility class that helps make enum constant - * names prettier for output in stat-messages. - */ -public final class StringUtils { - - private StringUtils() { - } - - /** - * Replace "_" with " " and capitalize each first letter of the input. - * - * @param input String to prettify, case-insensitive - */ - public static String prettify(String input) { - if (input == null) return null; - StringBuilder capitals = new StringBuilder(input.toLowerCase(Locale.ENGLISH)); - capitals.setCharAt(0, Character.toUpperCase(capitals.charAt(0))); - while (capitals.indexOf("_") != -1) { - MyLogger.logHighLevelMsg("Replacing underscores and capitalizing names..."); - - int index = capitals.indexOf("_"); - capitals.setCharAt(index + 1, Character.toUpperCase(capitals.charAt(index + 1))); - capitals.setCharAt(index, ' '); - } - return capitals.toString(); - } -} \ No newline at end of file From 3dd43d3a8df425d0b6c55b7fce86702d471af181 Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Mon, 6 Feb 2023 12:26:03 +0100 Subject: [PATCH 37/43] Finished clean-up after merging the updated main branch into v2.0 --- .../playerstats/core/msg/msgutils/LanguageKeyHandler.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/msgutils/LanguageKeyHandler.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/msgutils/LanguageKeyHandler.java index 2f13bc4..2fb6c3a 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/msgutils/LanguageKeyHandler.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/msgutils/LanguageKeyHandler.java @@ -12,9 +12,9 @@ import org.jetbrains.annotations.Nullable; import java.util.Arrays; import java.util.HashMap; +import java.util.Locale; import java.util.regex.Matcher; import java.util.regex.Pattern; -import java.util.Locale; /** * @@ -45,7 +45,6 @@ public final class LanguageKeyHandler extends FileHandler { } return instance; } - languageKeys = YamlConfiguration.loadConfiguration(languageKeyFile); } @Contract(pure = true) @@ -239,7 +238,7 @@ public final class LanguageKeyHandler extends FileHandler { if (block == null) return null; else if (block.toString().toLowerCase(Locale.ENGLISH).contains("wall_banner")) { //replace wall_banner with regular banner, since there is no key for wall banners String blockName = block.toString().toLowerCase(Locale.ENGLISH).replace("wall_", ""); - Material newBlock = EnumHandler.getBlockEnum(blockName); + Material newBlock = EnumHandler.getInstance().getBlockEnum(blockName); return (newBlock != null) ? "block.minecraft." + newBlock.getKey().getKey() : null; } else { From e8cf9ade47b776e89f4a64e475833b2449be9ab6 Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Mon, 6 Feb 2023 15:50:02 +0100 Subject: [PATCH 38/43] Added feedback for /stat commands with excluded player targets (#88), fixed bug (#128) --- .../the/gr8/playerstats/api/StatRequest.java | 28 +++++++++++++++---- .../core/commands/ExcludeCommand.java | 4 +-- .../core/commands/StatCommand.java | 19 +++++++------ .../core/commands/TabCompleter.java | 4 +-- .../core/enums/StandardMessage.java | 1 + .../playerstats/core/msg/MessageBuilder.java | 4 +++ .../playerstats/core/msg/OutputManager.java | 1 + .../core/multithreading/StatAction.java | 2 +- .../core/multithreading/ThreadManager.java | 2 +- .../core/statrequest/RequestManager.java | 4 +-- .../core/utils/OfflinePlayerHandler.java | 15 +++++----- 11 files changed, 54 insertions(+), 30 deletions(-) diff --git a/src/main/java/com/artemis/the/gr8/playerstats/api/StatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/api/StatRequest.java index 2d506cb..6d701a9 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/api/StatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/api/StatRequest.java @@ -1,6 +1,8 @@ package com.artemis.the.gr8.playerstats.api; import com.artemis.the.gr8.playerstats.api.enums.Target; +import com.artemis.the.gr8.playerstats.core.config.ConfigHandler; +import com.artemis.the.gr8.playerstats.core.utils.OfflinePlayerHandler; import org.bukkit.Material; import org.bukkit.Statistic; import org.bukkit.command.CommandSender; @@ -33,14 +35,10 @@ public abstract class StatRequest { public boolean isValid() { if (settings.statistic == null) { return false; - } else if (settings.target == Target.PLAYER && settings.playerName == null) { + } else if (!hasValidTarget()) { return false; - } else if (settings.statistic.getType() != Statistic.Type.UNTYPED && - settings.subStatEntryName == null) { - return false; - } else { - return hasMatchingSubStat(); } + return hasMatchingSubStat(); } protected void configureForPlayer(String playerName) { @@ -88,6 +86,24 @@ public abstract class StatRequest { this.settings.subStatEntryName = entityType.toString(); } + private boolean hasValidTarget() { + if (settings.target == null) { + return false; + } + else if (settings.target == Target.PLAYER) { + OfflinePlayerHandler offlinePlayerHandler = OfflinePlayerHandler.getInstance(); + + if (settings.playerName == null) { + return false; + } else if (offlinePlayerHandler.isExcludedPlayer(settings.playerName)) { + return ConfigHandler.getInstance().allowPlayerLookupsForExcludedPlayers(); + } else { + return (offlinePlayerHandler.isIncludedPlayer(settings.playerName)); + } + } + return true; + } + private boolean hasMatchingSubStat() { switch (settings.statistic.getType()) { case BLOCK -> { diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/commands/ExcludeCommand.java b/src/main/java/com/artemis/the/gr8/playerstats/core/commands/ExcludeCommand.java index 9132278..8b756a6 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/commands/ExcludeCommand.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/commands/ExcludeCommand.java @@ -37,14 +37,14 @@ public final class ExcludeCommand implements CommandExecutor { else { switch (args[0]) { case "add" -> { - if (offlinePlayerHandler.addLoadedPlayerToExcludeList(args[1])) { + if (offlinePlayerHandler.addPlayerToExcludeList(args[1])) { outputManager.sendFeedbackMsgPlayerExcluded(sender, args[1]); } else { outputManager.sendFeedbackMsg(sender, StandardMessage.EXCLUDE_FAILED); } } case "remove" -> { - if (offlinePlayerHandler.addExcludedPlayerToLoadedList(args[1])) { + if (offlinePlayerHandler.removePlayerFromExcludeList(args[1])) { outputManager.sendFeedbackMsgPlayerIncluded(sender, args[1]); } else { outputManager.sendFeedbackMsg(sender, StandardMessage.INCLUDE_FAILED); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/commands/StatCommand.java b/src/main/java/com/artemis/the/gr8/playerstats/core/commands/StatCommand.java index 91f7844..ee88433 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/commands/StatCommand.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/commands/StatCommand.java @@ -37,6 +37,7 @@ public final class StatCommand implements CommandExecutor { private static OutputManager outputManager; private final ConfigHandler config; private final EnumHandler enumHandler; + private final OfflinePlayerHandler offlinePlayerHandler; public StatCommand(OutputManager outputManager, ThreadManager threadManager) { StatCommand.threadManager = threadManager; @@ -44,6 +45,7 @@ public final class StatCommand implements CommandExecutor { config = ConfigHandler.getInstance(); enumHandler = EnumHandler.getInstance(); + offlinePlayerHandler = OfflinePlayerHandler.getInstance(); } @Override @@ -59,11 +61,10 @@ public final class StatCommand implements CommandExecutor { } else { ArgProcessor processor = new ArgProcessor(sender, args); - if (processor.request != null) { + if (processor.request != null && processor.request.isValid()) { threadManager.startStatThread(processor.request); } else { sendFeedback(sender, processor); - return false; } } return true; @@ -89,8 +90,13 @@ public final class StatCommand implements CommandExecutor { if (processor.statistic == null) { outputManager.sendFeedbackMsg(sender, StandardMessage.MISSING_STAT_NAME); } - else if (processor.target == Target.PLAYER && processor.playerName == null) { - outputManager.sendFeedbackMsg(sender, StandardMessage.MISSING_PLAYER_NAME); + else if (processor.target == Target.PLAYER) { + if (processor.playerName == null) { + outputManager.sendFeedbackMsg(sender, StandardMessage.MISSING_PLAYER_NAME); + } else if (offlinePlayerHandler.isExcludedPlayer(processor.playerName) && + !config.allowPlayerLookupsForExcludedPlayers()) { + outputManager.sendFeedbackMsg(sender, StandardMessage.PLAYER_IS_EXCLUDED); + } } else { Statistic.Type type = processor.statistic.getType(); @@ -170,7 +176,6 @@ public final class StatCommand implements CommandExecutor { switch (targetArg) { case "me" -> { if (sender instanceof Player) { - //TODO this is where an excluded player can sneak in target = Target.PLAYER; playerName = sender.getName(); } else { @@ -248,10 +253,8 @@ public final class StatCommand implements CommandExecutor { @Contract(pure = true) private @Nullable String tryToFindPlayerName(@NotNull String[] args) { - OfflinePlayerHandler offlinePlayerHandler = OfflinePlayerHandler.getInstance(); - for (String arg : args) { - if (offlinePlayerHandler.isLoadedPlayer(arg)) { + if (offlinePlayerHandler.isIncludedPlayer(arg) || offlinePlayerHandler.isExcludedPlayer(arg)) { return arg; } } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/commands/TabCompleter.java b/src/main/java/com/artemis/the/gr8/playerstats/core/commands/TabCompleter.java index 4d5f9d0..688852f 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/commands/TabCompleter.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/commands/TabCompleter.java @@ -54,7 +54,7 @@ public final class TabCompleter implements org.bukkit.command.TabCompleter { } else if (args.length == 2) { tabSuggestions = switch (args[0]) { - case "add" -> offlinePlayerHandler.getLoadedOfflinePlayerNames(); + case "add" -> offlinePlayerHandler.getIncludedOfflinePlayerNames(); case "remove" -> offlinePlayerHandler.getExcludedPlayerNames(); default -> tabSuggestions; }; @@ -86,7 +86,7 @@ public final class TabCompleter implements org.bukkit.command.TabCompleter { tabSuggestions = statCommandTargets; //if arg before "player" was entity-sub-stat, suggest targets } else { //otherwise "player" is the target: suggest playerNames - tabSuggestions = offlinePlayerHandler.getLoadedOfflinePlayerNames(); + tabSuggestions = offlinePlayerHandler.getIncludedOfflinePlayerNames(); } } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/enums/StandardMessage.java b/src/main/java/com/artemis/the/gr8/playerstats/core/enums/StandardMessage.java index 64d1407..011956f 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/enums/StandardMessage.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/enums/StandardMessage.java @@ -12,6 +12,7 @@ public enum StandardMessage { INCLUDE_FAILED, MISSING_STAT_NAME, MISSING_PLAYER_NAME, + PLAYER_IS_EXCLUDED, WAIT_A_MOMENT, WAIT_A_MINUTE, REQUEST_ALREADY_RUNNING, diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/MessageBuilder.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/MessageBuilder.java index 8a92dec..1a6bbff 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/MessageBuilder.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/MessageBuilder.java @@ -147,6 +147,10 @@ public final class MessageBuilder implements StatTextFormatter { return composePluginMessage("Please specify a valid player-name!"); } + public @NotNull TextComponent playerIsExcluded() { + return composePluginMessage("This player is excluded from /stat results!"); + } + public @NotNull TextComponent wrongSubStatType(String statType, String subStatName) { return componentFactory.pluginPrefix() .append(space()) diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/OutputManager.java b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/OutputManager.java index ee6caf2..cbac752 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/msg/OutputManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/msg/OutputManager.java @@ -208,6 +208,7 @@ public final class OutputManager { standardMessages.put(INCLUDE_FAILED, MessageBuilder::includeFailed); standardMessages.put(MISSING_STAT_NAME, MessageBuilder::missingStatName); standardMessages.put(MISSING_PLAYER_NAME, MessageBuilder::missingPlayerName); + standardMessages.put(PLAYER_IS_EXCLUDED, MessageBuilder::playerIsExcluded); standardMessages.put(WAIT_A_MOMENT, MessageBuilder::waitAMoment); standardMessages.put(WAIT_A_MINUTE, MessageBuilder::waitAMinute); standardMessages.put(REQUEST_ALREADY_RUNNING, MessageBuilder::requestAlreadyRunning); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/multithreading/StatAction.java b/src/main/java/com/artemis/the/gr8/playerstats/core/multithreading/StatAction.java index e0e5c9b..f276bb4 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/multithreading/StatAction.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/multithreading/StatAction.java @@ -64,7 +64,7 @@ final class StatAction extends RecursiveTask> do { String playerName = iterator.next(); MyLogger.actionRunning(Thread.currentThread().getName()); - OfflinePlayer player = offlinePlayerHandler.getLoadedOfflinePlayer(playerName); + OfflinePlayer player = offlinePlayerHandler.getIncludedOfflinePlayer(playerName); int statistic = 0; switch (requestSettings.getStatistic().getType()) { case UNTYPED -> statistic = player.getStatistic(requestSettings.getStatistic()); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/multithreading/ThreadManager.java b/src/main/java/com/artemis/the/gr8/playerstats/core/multithreading/ThreadManager.java index f16dcc6..9acbe7e 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/multithreading/ThreadManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/multithreading/ThreadManager.java @@ -58,7 +58,7 @@ public final class ThreadManager { public static @NotNull StatAction getStatAction(StatRequest.Settings requestSettings) { OfflinePlayerHandler offlinePlayerHandler = OfflinePlayerHandler.getInstance(); - ImmutableList relevantPlayerNames = ImmutableList.copyOf(offlinePlayerHandler.getLoadedOfflinePlayerNames()); + ImmutableList relevantPlayerNames = ImmutableList.copyOf(offlinePlayerHandler.getIncludedOfflinePlayerNames()); ConcurrentHashMap resultingStatNumbers = new ConcurrentHashMap<>(relevantPlayerNames.size()); StatAction task = new StatAction(relevantPlayerNames, requestSettings, resultingStatNumbers); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/statrequest/RequestManager.java b/src/main/java/com/artemis/the/gr8/playerstats/core/statrequest/RequestManager.java index d83d15e..33f8fd9 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/statrequest/RequestManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/statrequest/RequestManager.java @@ -75,7 +75,7 @@ public final class RequestManager implements StatManager { @Override public @NotNull RequestGenerator> createTotalTopStatRequest() { - int playerCount = offlinePlayerHandler.getOfflinePlayerCount(); + int playerCount = offlinePlayerHandler.getIncludedPlayerCount(); return createTopStatRequest(playerCount); } @@ -129,7 +129,7 @@ public final class RequestManager implements StatManager { config.allowPlayerLookupsForExcludedPlayers()) { player = offlinePlayerHandler.getExcludedOfflinePlayer(requestSettings.getPlayerName()); } else { - player = offlinePlayerHandler.getLoadedOfflinePlayer(requestSettings.getPlayerName()); + player = offlinePlayerHandler.getIncludedOfflinePlayer(requestSettings.getPlayerName()); } return switch (requestSettings.getStatistic().getType()) { case UNTYPED -> player.getStatistic(requestSettings.getStatistic()); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/utils/OfflinePlayerHandler.java b/src/main/java/com/artemis/the/gr8/playerstats/core/utils/OfflinePlayerHandler.java index b22da42..78ed96e 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/utils/OfflinePlayerHandler.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/utils/OfflinePlayerHandler.java @@ -60,7 +60,7 @@ public final class OfflinePlayerHandler extends FileHandler { * @param playerName String (case-sensitive) * @return true if this player is included */ - public boolean isLoadedPlayer(String playerName) { + public boolean isIncludedPlayer(String playerName) { return includedPlayerUUIDs.containsKey(playerName); } @@ -72,8 +72,8 @@ public final class OfflinePlayerHandler extends FileHandler { return excludedPlayerUUIDs.containsValue(uniqueID); } - public boolean addLoadedPlayerToExcludeList(String playerName) { - if (isLoadedPlayer(playerName)) { + public boolean addPlayerToExcludeList(String playerName) { + if (isIncludedPlayer(playerName)) { UUID uuid = includedPlayerUUIDs.get(playerName); super.writeEntryToList("excluded", uuid.toString()); @@ -84,8 +84,7 @@ public final class OfflinePlayerHandler extends FileHandler { return false; } - public boolean addExcludedPlayerToLoadedList(String playerName) { - //this only includes explicitly excluded players + public boolean removePlayerFromExcludeList(String playerName) { if (isExcludedPlayer(playerName)) { UUID uuid = excludedPlayerUUIDs.get(playerName); @@ -109,7 +108,7 @@ public final class OfflinePlayerHandler extends FileHandler { * @return the ArrayList */ @Contract(" -> new") - public @NotNull ArrayList getLoadedOfflinePlayerNames() { + public @NotNull ArrayList getIncludedOfflinePlayerNames() { return Collections.list(includedPlayerUUIDs.keys()); } @@ -119,7 +118,7 @@ public final class OfflinePlayerHandler extends FileHandler { * * @return the number of included OfflinePlayers */ - public int getOfflinePlayerCount() { + public int getIncludedPlayerCount() { return includedPlayerUUIDs.size(); } @@ -132,7 +131,7 @@ public final class OfflinePlayerHandler extends FileHandler { * @throws IllegalArgumentException if this player is not on the list * of players that should be included in statistic calculations */ - public @NotNull OfflinePlayer getLoadedOfflinePlayer(String playerName) throws IllegalArgumentException { + public @NotNull OfflinePlayer getIncludedOfflinePlayer(String playerName) throws IllegalArgumentException { if (includedPlayerUUIDs.get(playerName) != null) { return Bukkit.getOfflinePlayer(includedPlayerUUIDs.get(playerName)); } From 4a67dfef10069077795cb89ee231d6685ab6bfe5 Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Fri, 10 Feb 2023 12:53:04 +0100 Subject: [PATCH 39/43] Moved some logic out of StatRequest to keep API and core separated --- .../the/gr8/playerstats/api/StatRequest.java | 32 +++---------------- .../core/statrequest/PlayerStatRequest.java | 24 ++++++++++++++ .../core/statrequest/ServerStatRequest.java | 5 +++ .../core/statrequest/TopStatRequest.java | 5 +++ 4 files changed, 38 insertions(+), 28 deletions(-) diff --git a/src/main/java/com/artemis/the/gr8/playerstats/api/StatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/api/StatRequest.java index 6d701a9..2f2093b 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/api/StatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/api/StatRequest.java @@ -1,8 +1,6 @@ package com.artemis.the.gr8.playerstats.api; import com.artemis.the.gr8.playerstats.api.enums.Target; -import com.artemis.the.gr8.playerstats.core.config.ConfigHandler; -import com.artemis.the.gr8.playerstats.core.utils.OfflinePlayerHandler; import org.bukkit.Material; import org.bukkit.Statistic; import org.bukkit.command.CommandSender; @@ -24,6 +22,8 @@ public abstract class StatRequest { settings = new Settings(requester); } + public abstract boolean isValid(); + /** * Use this method to view the settings that have * been configured for this StatRequest. @@ -32,15 +32,6 @@ public abstract class StatRequest { return settings; } - public boolean isValid() { - if (settings.statistic == null) { - return false; - } else if (!hasValidTarget()) { - return false; - } - return hasMatchingSubStat(); - } - protected void configureForPlayer(String playerName) { this.settings.target = Target.PLAYER; this.settings.playerName = playerName; @@ -86,25 +77,11 @@ public abstract class StatRequest { this.settings.subStatEntryName = entityType.toString(); } - private boolean hasValidTarget() { - if (settings.target == null) { + protected boolean hasMatchingSubStat() { + if (settings.statistic == null) { return false; } - else if (settings.target == Target.PLAYER) { - OfflinePlayerHandler offlinePlayerHandler = OfflinePlayerHandler.getInstance(); - if (settings.playerName == null) { - return false; - } else if (offlinePlayerHandler.isExcludedPlayer(settings.playerName)) { - return ConfigHandler.getInstance().allowPlayerLookupsForExcludedPlayers(); - } else { - return (offlinePlayerHandler.isIncludedPlayer(settings.playerName)); - } - } - return true; - } - - private boolean hasMatchingSubStat() { switch (settings.statistic.getType()) { case BLOCK -> { return settings.block != null; @@ -141,7 +118,6 @@ public abstract class StatRequest { this.sender = sender; } - public @NotNull CommandSender getCommandSender() { return sender; } diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/statrequest/PlayerStatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/core/statrequest/PlayerStatRequest.java index abaf24f..17c4cd9 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/statrequest/PlayerStatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/statrequest/PlayerStatRequest.java @@ -2,6 +2,8 @@ package com.artemis.the.gr8.playerstats.core.statrequest; import com.artemis.the.gr8.playerstats.api.RequestGenerator; import com.artemis.the.gr8.playerstats.api.StatRequest; +import com.artemis.the.gr8.playerstats.core.config.ConfigHandler; +import com.artemis.the.gr8.playerstats.core.utils.OfflinePlayerHandler; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Statistic; @@ -20,6 +22,28 @@ public final class PlayerStatRequest extends StatRequest implements Req super.configureForPlayer(playerName); } + @Override + public boolean isValid() { + if (!hasValidTarget()) { + return false; + } + return super.hasMatchingSubStat(); + } + + private boolean hasValidTarget() { + StatRequest.Settings settings = super.getSettings(); + if (settings.getPlayerName() == null) { + return false; + } + + OfflinePlayerHandler offlinePlayerHandler = OfflinePlayerHandler.getInstance(); + if (offlinePlayerHandler.isExcludedPlayer(settings.getPlayerName())) { + return ConfigHandler.getInstance().allowPlayerLookupsForExcludedPlayers(); + } else { + return offlinePlayerHandler.isIncludedPlayer(settings.getPlayerName()); + } + } + @Override public StatRequest untyped(@NotNull Statistic statistic) { super.configureUntyped(statistic); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/statrequest/ServerStatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/core/statrequest/ServerStatRequest.java index a50a5f8..3d47394 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/statrequest/ServerStatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/statrequest/ServerStatRequest.java @@ -21,6 +21,11 @@ public final class ServerStatRequest extends StatRequest implements Reques super.configureForServer(); } + @Override + public boolean isValid() { + return super.hasMatchingSubStat(); + } + @Override public StatRequest untyped(@NotNull Statistic statistic) { super.configureUntyped(statistic); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/statrequest/TopStatRequest.java b/src/main/java/com/artemis/the/gr8/playerstats/core/statrequest/TopStatRequest.java index 0ef49bb..09e9f43 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/statrequest/TopStatRequest.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/statrequest/TopStatRequest.java @@ -22,6 +22,11 @@ public final class TopStatRequest extends StatRequest> untyped(@NotNull Statistic statistic) { super.configureUntyped(statistic); From 18ac4ecf0004661b890fa27e48a9ec6229c15cae Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Thu, 23 Feb 2023 13:49:23 +0100 Subject: [PATCH 40/43] Updated version number in plugin.yml, and made API #getVersion read the value from the plugin description and return the major version number only --- dependency-reduced-pom.xml | 2 +- pom.xml | 2 +- .../artemis/the/gr8/playerstats/api/PlayerStats.java | 12 ++++++------ .../com/artemis/the/gr8/playerstats/core/Main.java | 3 +-- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml index 1ca85c8..244c296 100644 --- a/dependency-reduced-pom.xml +++ b/dependency-reduced-pom.xml @@ -4,7 +4,7 @@ io.github.ithotl PlayerStats PlayerStats - 2.0-SNAPSHOT + 2.0 Statistics Plugin https://www.spigotmc.org/resources/playerstats.102347/ diff --git a/pom.xml b/pom.xml index 5e70d4a..f9fb434 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.ithotl PlayerStats - 2.0-SNAPSHOT + 2.0 PlayerStats Statistics Plugin diff --git a/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStats.java b/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStats.java index 0a91708..43a6323 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStats.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/api/PlayerStats.java @@ -29,13 +29,13 @@ public interface PlayerStats { } /** - * Gets the current version of PlayerStatsAPI. - * Use this method to ensure the correct version of - * PlayerStats is running on the server before - * accessing further API methods, to prevent - * ClassDefNotFoundExceptions. + * Gets the version number of the PlayerStats API + * that's present for this instance of PlayerStats. + * This number equals the major version number + * of PlayerStats. For v1.7.2, for example, + * the API version will be 1. * - * @return the version of PlayerStatsAPI present on the server + * @return the API version number */ String getVersion(); diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/Main.java b/src/main/java/com/artemis/the/gr8/playerstats/core/Main.java index b456dc6..5eaa9d6 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/Main.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/Main.java @@ -166,10 +166,9 @@ public final class Main extends JavaPlugin implements PlayerStats { }.runTaskLaterAsynchronously(this, 200); } - @Contract(pure = true) @Override public @NotNull String getVersion() { - return "1.8"; + return String.valueOf(this.getDescription().getVersion().charAt(0)); } @Override From 18bf8a56a7e72f2b6f0dd32728cdabbdf21677f8 Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Sat, 25 Feb 2023 14:32:36 +0100 Subject: [PATCH 41/43] Added method to API to check whether a player is on the exclude-list --- dependency-reduced-pom.xml | 6 +++--- .../artemis/the/gr8/playerstats/api/StatManager.java | 10 ++++++++++ .../playerstats/core/statrequest/RequestManager.java | 7 ++++++- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/dependency-reduced-pom.xml b/dependency-reduced-pom.xml index 244c296..5ef58c2 100644 --- a/dependency-reduced-pom.xml +++ b/dependency-reduced-pom.xml @@ -107,7 +107,7 @@ attach-sources - deploy + verify jar-no-fork @@ -120,7 +120,7 @@ sign-artifacts - deploy + verify sign @@ -133,7 +133,7 @@ attach-javadocs - deploy + verify jar diff --git a/src/main/java/com/artemis/the/gr8/playerstats/api/StatManager.java b/src/main/java/com/artemis/the/gr8/playerstats/api/StatManager.java index 0317fc3..33eae8c 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/api/StatManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/api/StatManager.java @@ -4,6 +4,16 @@ import java.util.LinkedHashMap; public interface StatManager { + /** Checks if the player belonging to this name + * is on PlayerStats' exclude-list (meaning this + * player is not counted for the server total, and + * does not show in top results). + * + * @param playerName the name of the player to check + * @return true if this player is on the exclude-list + */ + boolean isExcludedPlayer(String playerName); + /** Gets a RequestGenerator that can be used to create a PlayerStatRequest. * This RequestGenerator will make sure all default settings * for a player-statistic-lookup are configured. diff --git a/src/main/java/com/artemis/the/gr8/playerstats/core/statrequest/RequestManager.java b/src/main/java/com/artemis/the/gr8/playerstats/core/statrequest/RequestManager.java index 33f8fd9..3373cc9 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/core/statrequest/RequestManager.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/core/statrequest/RequestManager.java @@ -25,7 +25,7 @@ import java.util.stream.Collectors; /** * Turns user input into a {@link StatRequest} that can be - * used to get statistic data. + * executed to get statistic data. */ public final class RequestManager implements StatManager { @@ -45,6 +45,11 @@ public final class RequestManager implements StatManager { }; } + @Override + public boolean isExcludedPlayer(String playerName) { + return offlinePlayerHandler.isExcludedPlayer(playerName); + } + @Contract("_ -> new") @Override public @NotNull RequestGenerator createPlayerStatRequest(String playerName) { From fa0667f26a54f2946c4f148330883e8368273710 Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Sun, 26 Feb 2023 12:40:48 +0100 Subject: [PATCH 42/43] Updated documentation --- .../com/artemis/the/gr8/playerstats/api/enums/Unit.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/artemis/the/gr8/playerstats/api/enums/Unit.java b/src/main/java/com/artemis/the/gr8/playerstats/api/enums/Unit.java index 7e29621..0a63e10 100644 --- a/src/main/java/com/artemis/the/gr8/playerstats/api/enums/Unit.java +++ b/src/main/java/com/artemis/the/gr8/playerstats/api/enums/Unit.java @@ -185,10 +185,12 @@ public enum Unit { } /** - * Gets the most suitable Unit for this number. + * Gets the largest Unit this number can be expressed in as a whole number. + * For example, for Type TIME a value of 80.000 would return Unit.HOUR + * (80.000 ticks equals 4.000 seconds, 67 minutes, or 1 hour) * - * @param type the Unit.Type of the statistic this number belongs to - * @param number the statistic number as returned by Player.getStatistic() + * @param type the Unit.Type of this statistic + * @param number the statistic value in ticks as returned by Player.getStatistic() * @return the Unit */ public static Unit getMostSuitableUnit(Unit.Type type, long number) { From 0653228a98216384c25f41b7c67e4f8ac8b44ba3 Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Tue, 28 Feb 2023 12:12:36 +0100 Subject: [PATCH 43/43] Updated version number, ready for release v2.0! --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index f9fb434..1547ebd 100644 --- a/pom.xml +++ b/pom.xml @@ -200,7 +200,7 @@ attach-sources - deploy + verify jar-no-fork @@ -214,7 +214,7 @@ sign-artifacts - deploy + verify sign @@ -228,7 +228,7 @@ attach-javadocs - deploy + verify jar