From 096bb8960767cd3f4e30c59d4d5065ef1eb533a9 Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Sun, 24 Jul 2022 13:44:34 +0200 Subject: [PATCH] Messing with API structure some more --- .../artemis/the/gr8/playerstats/Main.java | 9 +- .../the/gr8/playerstats/api/PlayerStats.java | 21 +-- .../gr8/playerstats/api/PlayerStatsAPI.java | 77 ++++++-- .../gr8/playerstats/api/RequestGenerator.java | 22 --- .../gr8/playerstats/api/SimpleRequest.java | 37 ++++ .../gr8/playerstats/api/StatFormatter.java | 19 +- .../gr8/playerstats/commands/StatCommand.java | 15 +- .../gr8/playerstats/models/StatRequest.java | 19 +- .../gr8/playerstats/msg/OutputManager.java | 33 ++-- .../playerstats/statistic/RequestManager.java | 165 ++++++++++++++++++ .../playerstats/statistic/StatManager.java | 140 +-------------- .../statistic/StatRequestGenerator.java | 4 - .../gr8/playerstats/statistic/StatThread.java | 8 +- 13 files changed, 318 insertions(+), 251 deletions(-) delete mode 100644 src/main/java/com/gmail/artemis/the/gr8/playerstats/api/RequestGenerator.java create mode 100644 src/main/java/com/gmail/artemis/the/gr8/playerstats/api/SimpleRequest.java create mode 100644 src/main/java/com/gmail/artemis/the/gr8/playerstats/statistic/RequestManager.java delete mode 100644 src/main/java/com/gmail/artemis/the/gr8/playerstats/statistic/StatRequestGenerator.java diff --git a/src/main/java/com/gmail/artemis/the/gr8/playerstats/Main.java b/src/main/java/com/gmail/artemis/the/gr8/playerstats/Main.java index 4a49ced..9f990f9 100644 --- a/src/main/java/com/gmail/artemis/the/gr8/playerstats/Main.java +++ b/src/main/java/com/gmail/artemis/the/gr8/playerstats/Main.java @@ -9,6 +9,7 @@ import com.gmail.artemis.the.gr8.playerstats.commands.TabCompleter; import com.gmail.artemis.the.gr8.playerstats.config.ConfigHandler; import com.gmail.artemis.the.gr8.playerstats.listeners.JoinListener; import com.gmail.artemis.the.gr8.playerstats.msg.OutputManager; +import com.gmail.artemis.the.gr8.playerstats.statistic.RequestManager; import com.gmail.artemis.the.gr8.playerstats.statistic.StatManager; import com.gmail.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; import net.kyori.adventure.platform.bukkit.BukkitAudiences; @@ -22,6 +23,7 @@ public class Main extends JavaPlugin { private static BukkitAudiences adventure; private static PlayerStats playerStatsAPI; private static OutputManager outputManager; + private static RequestManager requestManager; private static ShareManager shareManager; private static StatManager statManager; private static ThreadManager threadManager; @@ -39,7 +41,7 @@ public class Main extends JavaPlugin { //register all commands and the tabCompleter PluginCommand statcmd = this.getCommand("statistic"); if (statcmd != null) { - statcmd.setExecutor(new StatCommand(outputManager, threadManager, statManager)); + statcmd.setExecutor(new StatCommand(outputManager, threadManager, requestManager)); statcmd.setTabCompleter(new TabCompleter(offlinePlayerHandler)); } PluginCommand reloadcmd = this.getCommand("statisticreload"); @@ -109,10 +111,11 @@ public class Main extends JavaPlugin { adventure = BukkitAudiences.create(this); shareManager = new ShareManager(config); + statManager = new StatManager(offlinePlayerHandler, config.getTopListMaxSize()); outputManager = new OutputManager(getAdventure(), config, shareManager); - statManager = new StatManager(outputManager, offlinePlayerHandler, config.getTopListMaxSize()); + requestManager = new RequestManager(offlinePlayerHandler, outputManager); threadManager = new ThreadManager(config, statManager, outputManager, offlinePlayerHandler); - playerStatsAPI = PlayerStatsAPI.load(statManager, outputManager); + playerStatsAPI = new PlayerStatsAPI(requestManager, statManager, outputManager); } } \ No newline at end of file diff --git a/src/main/java/com/gmail/artemis/the/gr8/playerstats/api/PlayerStats.java b/src/main/java/com/gmail/artemis/the/gr8/playerstats/api/PlayerStats.java index 8497d05..fa15787 100644 --- a/src/main/java/com/gmail/artemis/the/gr8/playerstats/api/PlayerStats.java +++ b/src/main/java/com/gmail/artemis/the/gr8/playerstats/api/PlayerStats.java @@ -12,10 +12,11 @@ import org.jetbrains.annotations.NotNull; /** This Interface is the outgoing API that provides access to the core functionality of PlayerStats. To work with it, you can call PlayerStats.{@link #getAPI()} to get an instance of {@link PlayerStatsAPI}. - You can then use this object to call any of the below methods. Since calculating a - top or server statistics can take some time, it is recommended to call any of the + You can then use this object to get formatted statistics. + +

Since calculating a top or server statistics can take some time, it is recommended to call any of the getServerStat() or getTopStats() methods asynchronously. Otherwise, the main Thread will have - to wait until all calculations are done, and this might cause lag spikes on the server. + to wait until all calculations are done, and this might cause lag spikes on the server.

The result of the methods in PlayerStats' API are returned in the form of a TextComponent, which can be sent directly to a Minecraft client with the Adventure library, @@ -29,20 +30,6 @@ public interface PlayerStats { return Main.getPlayerStatsAPI(); } - /** Returns a stat-result as if the caller ran the /stat command in Minecraft chat. Since calculating the - top or server statistics can take some time, it is recommended to call this method asynchronously - (otherwise the main Thread will have to wait until the calculations are done). - - @param args an Array of args very similar to the input a CommandSender would put in Minecraft chat: -

- a stat-name (example: "mine_block")

-

- if applicable, a sub-stat-name (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 player-name

- @param sender the CommandSender that requested this specific statistic - @throws IllegalArgumentException if the args do not result in a valid statistic look-up*/ - TextComponent getFancyStat(CommandSender sender, String[] args) throws IllegalArgumentException; - - /** Get a formatted player-statistic of Statistic.Type UNTYPED.*/ TextComponent getPlayerStat(@NotNull Statistic statistic, @NotNull OfflinePlayer player); diff --git a/src/main/java/com/gmail/artemis/the/gr8/playerstats/api/PlayerStatsAPI.java b/src/main/java/com/gmail/artemis/the/gr8/playerstats/api/PlayerStatsAPI.java index 12880d9..5da5b6c 100644 --- a/src/main/java/com/gmail/artemis/the/gr8/playerstats/api/PlayerStatsAPI.java +++ b/src/main/java/com/gmail/artemis/the/gr8/playerstats/api/PlayerStatsAPI.java @@ -1,13 +1,15 @@ package com.gmail.artemis.the.gr8.playerstats.api; -import com.gmail.artemis.the.gr8.playerstats.enums.Target; import com.gmail.artemis.the.gr8.playerstats.models.StatRequest; +import com.gmail.artemis.the.gr8.playerstats.statistic.RequestManager; import com.gmail.artemis.the.gr8.playerstats.statistic.StatManager; import net.kyori.adventure.text.TextComponent; +import org.bukkit.Material; import org.bukkit.OfflinePlayer; import org.bukkit.Statistic; import org.bukkit.command.CommandSender; -import org.jetbrains.annotations.Nullable; +import org.bukkit.entity.EntityType; +import org.jetbrains.annotations.NotNull; import java.util.LinkedHashMap; @@ -17,44 +19,85 @@ import static org.jetbrains.annotations.ApiStatus.Internal; /** The implementation of the API Interface */ public final class PlayerStatsAPI implements PlayerStats { + private static RequestManager requestManager; private static StatFormatter statFormatter; private static StatManager statManager; @Internal - private PlayerStatsAPI(StatManager stat, StatFormatter format) { + public PlayerStatsAPI(RequestManager request, StatManager stat, StatFormatter format) { + requestManager = request; statFormatter = format; statManager = stat; } - @Internal - public static PlayerStatsAPI load(StatManager statManager, StatFormatter statFormatter) { - return new PlayerStatsAPI(statManager, statFormatter); - } - - - @Override - public TextComponent getFancyStat(CommandSender sender, String[] args) throws IllegalArgumentException { - StatRequest request = statManager.generateRequest(sender, args); - if (statManager.requestIsValid(request)) { + private TextComponent getFancyStat(CommandSender sender, String[] args) throws IllegalArgumentException { + StatRequest request = requestManager.generateRequest(sender, args); + if (requestManager.requestIsValid(request)) { switch (request.getSelection()) { case PLAYER -> { int stat = statManager.getPlayerStat(request); - return statFormatter.formatPlayerStat(request, stat); + return statFormatter.formatPlayerStat(request, stat, true); } case SERVER -> { long stat = statManager.getServerStat(request); - return statFormatter.formatServerStat(request, stat); + return statFormatter.formatServerStat(request, stat, true); } case TOP -> { LinkedHashMap stats = statManager.getTopStats(request); - return statFormatter.formatTopStat(request, stats); + return statFormatter.formatTopStat(request, stats, true); } } } throw new IllegalArgumentException("This is not a valid stat-request!"); } + @Override + public TextComponent getPlayerStat(@NotNull Statistic statistic, @NotNull OfflinePlayer player) { + return null; + } + + @Override + public TextComponent getPlayerStat(@NotNull Statistic statistic, @NotNull Material material, @NotNull OfflinePlayer player) { + return null; + } + + @Override + public TextComponent getPlayerStat(@NotNull Statistic statistic, @NotNull EntityType entity, @NotNull OfflinePlayer player) { + return null; + } + + @Override + public TextComponent getServerStat(@NotNull Statistic statistic) { + return null; + } + + @Override + public TextComponent getServerStat(@NotNull Statistic statistic, @NotNull Material material) { + return null; + } + + @Override + public TextComponent getServerStat(@NotNull Statistic statistic, @NotNull EntityType entity) { + return null; + } + + @Override + public TextComponent getTopStats(@NotNull Statistic statistic) { + return null; + } + + @Override + public TextComponent getTopStats(@NotNull Statistic statistic, @NotNull Material material) { + return null; + } + + @Override + public TextComponent getTopStats(@NotNull Statistic statistic, @NotNull EntityType entity) { + return null; + } + + @Override public String statResultComponentToString(TextComponent component) { - return statFormatter.toString(component); + return statFormatter.statResultToString(component); } } \ No newline at end of file diff --git a/src/main/java/com/gmail/artemis/the/gr8/playerstats/api/RequestGenerator.java b/src/main/java/com/gmail/artemis/the/gr8/playerstats/api/RequestGenerator.java deleted file mode 100644 index 0ece032..0000000 --- a/src/main/java/com/gmail/artemis/the/gr8/playerstats/api/RequestGenerator.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.gmail.artemis.the.gr8.playerstats.api; - -import com.gmail.artemis.the.gr8.playerstats.enums.Target; -import com.gmail.artemis.the.gr8.playerstats.models.StatRequest; -import org.bukkit.command.CommandSender; -import org.jetbrains.annotations.Nullable; - -/** The {@link RequestGenerator} will help you turn a String (such as "stat animals_bred") into a specific {@link StatRequest} - with all the information {@link PlayerStatsAPI} needs to work with. You'll need this StatRequest Object to get the statistic - data that you want, and to format this data into a fancy Component or String, so you can output it somewhere.*/ -public interface RequestGenerator { - - /** This will create a {@link StatRequest} from the provided args, with the requesting Player (or Console) - as CommandSender. This CommandSender will receive feedback messages if the StatRequest could not be created. - @param args an Array of args corresponding to a Statistic, a potential Sub-Statistic, and a Target - (exactly as they are typed in Minecraft chat when using PlayerStatsAPI' /stat command - - for example "/stat kill_entity bee top") - @param sender the CommandSender that requested this specific statistic*/ - StatRequest generateRequest(CommandSender sender, String[] args); - - StatRequest generateRequest(CommandSender sender, String statName, @Nullable String subStatName, Target selection, @Nullable String PlayerName); -} diff --git a/src/main/java/com/gmail/artemis/the/gr8/playerstats/api/SimpleRequest.java b/src/main/java/com/gmail/artemis/the/gr8/playerstats/api/SimpleRequest.java new file mode 100644 index 0000000..95dfe42 --- /dev/null +++ b/src/main/java/com/gmail/artemis/the/gr8/playerstats/api/SimpleRequest.java @@ -0,0 +1,37 @@ +package com.gmail.artemis.the.gr8.playerstats.api; + +import com.gmail.artemis.the.gr8.playerstats.enums.Target; +import org.bukkit.Material; +import org.bukkit.Statistic; +import org.bukkit.entity.EntityType; + +public interface SimpleRequest { + + void setStatistic(Statistic statistic); + + Statistic getStatistic(); + + void setSubStatEntry(String subStatEntry); + + String getSubStatEntry(); + + void setPlayerName(String playerName); + + String getPlayerName(); + + void setSelection(Target selection); + + Target getSelection(); + + void setEntity(EntityType entity); + + EntityType getEntity(); + + void setBlock(Material material); + + Material getBlock(); + + void setItem(Material item); + + Material getItem(); +} \ No newline at end of file diff --git a/src/main/java/com/gmail/artemis/the/gr8/playerstats/api/StatFormatter.java b/src/main/java/com/gmail/artemis/the/gr8/playerstats/api/StatFormatter.java index 184ca42..61329cf 100644 --- a/src/main/java/com/gmail/artemis/the/gr8/playerstats/api/StatFormatter.java +++ b/src/main/java/com/gmail/artemis/the/gr8/playerstats/api/StatFormatter.java @@ -2,8 +2,7 @@ package com.gmail.artemis.the.gr8.playerstats.api; import com.gmail.artemis.the.gr8.playerstats.models.StatRequest; import net.kyori.adventure.text.TextComponent; - -import static org.jetbrains.annotations.ApiStatus.Internal; +import net.kyori.adventure.text.minimessage.MiniMessage; import java.util.LinkedHashMap; @@ -11,19 +10,13 @@ import java.util.LinkedHashMap; This is meant for an outgoing API - for internal use, more output functionality may exist. */ public interface StatFormatter { - default String toString(TextComponent component) { - return component.content(); + default String statResultToString(TextComponent statResult) { + return MiniMessage.miniMessage().serialize(statResult); } - /** Returns the setting for whether TextComponents should be saved internally for later stat-sharing by players. - Make this method return "false" if you only want to get a fancy stat-result, and don't want to send it - to players in chat with a clickable "share"-button. */ - @Internal - boolean saveOutputForSharing(); + TextComponent formatPlayerStat(StatRequest request, int playerStat, boolean isAPIRequest); - TextComponent formatPlayerStat(StatRequest request, int playerStat); + TextComponent formatServerStat(StatRequest request, long serverStat, boolean isAPIRequest); - TextComponent formatServerStat(StatRequest request, long serverStat); - - TextComponent formatTopStat(StatRequest request, LinkedHashMap topStats); + TextComponent formatTopStat(StatRequest request, LinkedHashMap topStats, boolean isAPIRequest); } \ No newline at end of file diff --git a/src/main/java/com/gmail/artemis/the/gr8/playerstats/commands/StatCommand.java b/src/main/java/com/gmail/artemis/the/gr8/playerstats/commands/StatCommand.java index 229631c..cf1b6c1 100644 --- a/src/main/java/com/gmail/artemis/the/gr8/playerstats/commands/StatCommand.java +++ b/src/main/java/com/gmail/artemis/the/gr8/playerstats/commands/StatCommand.java @@ -1,25 +1,30 @@ package com.gmail.artemis.the.gr8.playerstats.commands; import com.gmail.artemis.the.gr8.playerstats.ThreadManager; +import com.gmail.artemis.the.gr8.playerstats.enums.StandardMessage; import com.gmail.artemis.the.gr8.playerstats.msg.OutputManager; +import com.gmail.artemis.the.gr8.playerstats.statistic.RequestManager; import com.gmail.artemis.the.gr8.playerstats.statistic.StatManager; import com.gmail.artemis.the.gr8.playerstats.models.StatRequest; +import net.kyori.adventure.text.TextComponent; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.jetbrains.annotations.NotNull; +import java.awt.*; + public class StatCommand implements CommandExecutor { private static ThreadManager threadManager; private static OutputManager outputManager; - private final StatManager statManager; + private final RequestManager requestManager; - public StatCommand(OutputManager m, ThreadManager t, StatManager s) { + public StatCommand(OutputManager m, ThreadManager t, RequestManager r) { threadManager = t; outputManager = m; - statManager = s; + requestManager = r; } @Override @@ -32,8 +37,8 @@ public class StatCommand implements CommandExecutor { outputManager.sendExamples(sender); } else { - StatRequest request = statManager.generateRequest(sender, args); - if (statManager.requestIsValid(request)) { + StatRequest request = requestManager.generateRequest(sender, args); + if (requestManager.requestIsValid(request)) { threadManager.startStatThread(request); } else { return false; diff --git a/src/main/java/com/gmail/artemis/the/gr8/playerstats/models/StatRequest.java b/src/main/java/com/gmail/artemis/the/gr8/playerstats/models/StatRequest.java index 742629a..c2df9ac 100644 --- a/src/main/java/com/gmail/artemis/the/gr8/playerstats/models/StatRequest.java +++ b/src/main/java/com/gmail/artemis/the/gr8/playerstats/models/StatRequest.java @@ -1,5 +1,6 @@ package com.gmail.artemis.the.gr8.playerstats.models; +import com.gmail.artemis.the.gr8.playerstats.api.SimpleRequest; import com.gmail.artemis.the.gr8.playerstats.enums.Target; import org.bukkit.Material; import org.bukkit.Statistic; @@ -12,9 +13,9 @@ import org.jetbrains.annotations.NotNull; It is generated from the args provided by a CommandSender when /stat is called, and always contains this CommandSender. By default, {@link #getSelection()} will return {@link Target#TOP}, unless another selection is specified in the args.*/ -public final class StatRequest { +public final class StatRequest implements SimpleRequest { - private final CommandSender sender; + private CommandSender sender; private Statistic statistic; private String playerName; private Target selection; @@ -25,13 +26,19 @@ public final class StatRequest { private Material item; private boolean playerFlag; - //make a StatRequest for a given CommandSender with some default values - public StatRequest(@NotNull CommandSender s) { - sender = s; + //make a SimpleRequest for a given CommandSender with some default values + public StatRequest(CommandSender s) { + if (s != null) { + setCommandSender(s); + } selection = Target.TOP; playerFlag = false; } + public void setCommandSender(@NotNull CommandSender sender) { + this.sender = sender; + } + public @NotNull CommandSender getCommandSender() { return sender; } @@ -74,7 +81,7 @@ public final class StatRequest { /** The "player" arg is a special case, because it could either be a valid subStatEntry, or indicate that the lookup action should target a specific player. This is why the playerFlag exists - if this is true, and playerName is null, subStatEntry should be set to "player". */ - public boolean playerFlag() { + public boolean getPlayerFlag() { return playerFlag; } diff --git a/src/main/java/com/gmail/artemis/the/gr8/playerstats/msg/OutputManager.java b/src/main/java/com/gmail/artemis/the/gr8/playerstats/msg/OutputManager.java index 4f36d0b..2822a39 100644 --- a/src/main/java/com/gmail/artemis/the/gr8/playerstats/msg/OutputManager.java +++ b/src/main/java/com/gmail/artemis/the/gr8/playerstats/msg/OutputManager.java @@ -24,7 +24,6 @@ import java.util.UUID; import java.util.function.BiFunction; import java.util.function.Function; -import static org.jetbrains.annotations.ApiStatus.Internal; import static com.gmail.artemis.the.gr8.playerstats.enums.StandardMessage.*; /** This class manages all PlayerStats output. It is the only place where messages are sent. @@ -51,14 +50,8 @@ public final class OutputManager implements StatFormatter { getMessageWriters(config); } - @Internal @Override - public boolean saveOutputForSharing() { - return true; - } - - @Override - public TextComponent formatPlayerStat(@NotNull StatRequest request, int playerStat) { + public TextComponent formatPlayerStat(@NotNull StatRequest request, int playerStat, boolean isAPIRequest) { CommandSender sender = request.getCommandSender(); BiFunction playerStatFunction = getWriter(sender).formattedPlayerStatFunction(playerStat, request); @@ -67,7 +60,7 @@ public final class OutputManager implements StatFormatter { } @Override - public TextComponent formatServerStat(@NotNull StatRequest request, long serverStat) { + public TextComponent formatServerStat(@NotNull StatRequest request, long serverStat, boolean isAPIRequest) { CommandSender sender = request.getCommandSender(); BiFunction serverStatFunction = getWriter(sender).formattedServerStatFunction(serverStat, request); @@ -76,7 +69,7 @@ public final class OutputManager implements StatFormatter { } @Override - public TextComponent formatTopStat(@NotNull StatRequest request, LinkedHashMap topStats) { + public TextComponent formatTopStat(@NotNull StatRequest request, @NotNull LinkedHashMap topStats, boolean isAPIRequest) { CommandSender sender = request.getCommandSender(); BiFunction topStatFunction = getWriter(sender).formattedTopStatFunction(topStats, request); @@ -84,24 +77,24 @@ public final class OutputManager implements StatFormatter { return processBuildFunction(sender, topStatFunction); } - public void sendFeedbackMsg(CommandSender sender, StandardMessage message) { + public void sendFeedbackMsg(@NotNull CommandSender sender, StandardMessage message) { if (message != null) { adventure.sender(sender).sendMessage(standardMessages.get(message) .apply(getWriter(sender))); } } - public void sendFeedbackMsgWaitAMoment(CommandSender sender, boolean longWait) { + public void sendFeedbackMsgWaitAMoment(@NotNull CommandSender sender, boolean longWait) { adventure.sender(sender).sendMessage(getWriter(sender) .waitAMoment(longWait)); } - public void sendFeedbackMsgMissingSubStat(CommandSender sender, Statistic.Type statType) { + public void sendFeedbackMsgMissingSubStat(@NotNull CommandSender sender, Statistic.Type statType) { adventure.sender(sender).sendMessage(getWriter(sender) .missingSubStatName(statType)); } - public void sendFeedbackMsgWrongSubStat(CommandSender sender, Statistic.Type statType, String subStatName) { + public void sendFeedbackMsgWrongSubStat(@NotNull CommandSender sender, Statistic.Type statType, @Nullable String subStatName) { if (subStatName == null) { sendFeedbackMsgMissingSubStat(sender, statType); } else { @@ -110,12 +103,12 @@ public final class OutputManager implements StatFormatter { } } - public void sendExamples(CommandSender sender) { + public void sendExamples(@NotNull CommandSender sender) { adventure.sender(sender).sendMessage(getWriter(sender) .usageExamples()); } - public void sendHelp(CommandSender sender) { + public void sendHelp(@NotNull CommandSender sender) { adventure.sender(sender).sendMessage(getWriter(sender) .helpMsg(sender instanceof ConsoleCommandSender)); } @@ -124,13 +117,12 @@ public final class OutputManager implements StatFormatter { adventure.players().sendMessage(component); } - public void sendToCommandSender(CommandSender sender, TextComponent component) { + public void sendToCommandSender(@NotNull CommandSender sender, @NotNull TextComponent component) { adventure.sender(sender).sendMessage(component); } - private TextComponent processBuildFunction(@Nullable CommandSender sender, BiFunction buildFunction) { - boolean saveOutput = saveOutputForSharing() && - sender != null && + private TextComponent processBuildFunction(@Nullable CommandSender sender, @NotNull BiFunction buildFunction) { + boolean saveOutput = sender != null && ShareManager.isEnabled() && shareManager.senderHasPermission(sender); @@ -144,6 +136,7 @@ public final class OutputManager implements StatFormatter { } } + /** If sender == null, this will return the regular writer*/ private MessageBuilder getWriter(CommandSender sender) { return sender instanceof ConsoleCommandSender ? consoleWriter : writer; } diff --git a/src/main/java/com/gmail/artemis/the/gr8/playerstats/statistic/RequestManager.java b/src/main/java/com/gmail/artemis/the/gr8/playerstats/statistic/RequestManager.java new file mode 100644 index 0000000..c0fcb74 --- /dev/null +++ b/src/main/java/com/gmail/artemis/the/gr8/playerstats/statistic/RequestManager.java @@ -0,0 +1,165 @@ +package com.gmail.artemis.the.gr8.playerstats.statistic; + +import com.gmail.artemis.the.gr8.playerstats.enums.StandardMessage; +import com.gmail.artemis.the.gr8.playerstats.enums.Target; +import com.gmail.artemis.the.gr8.playerstats.models.StatRequest; +import com.gmail.artemis.the.gr8.playerstats.msg.OutputManager; +import com.gmail.artemis.the.gr8.playerstats.utils.EnumHandler; +import com.gmail.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; +import org.bukkit.Material; +import org.bukkit.OfflinePlayer; +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 class RequestManager { + + private final OfflinePlayerHandler offlinePlayerHandler; + private static OutputManager outputManager; + + public RequestManager(OfflinePlayerHandler offlinePlayerHandler, OutputManager outputManager) { + this.offlinePlayerHandler = offlinePlayerHandler; + RequestManager.outputManager = outputManager; + } + + /** This will create a {@link StatRequest} from the provided args, with the requesting Player (or Console) + as CommandSender. This CommandSender will receive feedback messages if the SimpleRequest could not be created. + @param args an Array of args such as a CommandSender would put in Minecraft chat: +

- a stat-name (example: "mine_block")

+

- if applicable, a sub-stat-name (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 player-name

+ @param sender the CommandSender that requested this specific statistic + @throws IllegalArgumentException if the args do not result in a valid statistic look-up*/ + public StatRequest generateRequest(CommandSender sender, String[] args) { + StatRequest request = new StatRequest(sender); + for (String arg : args) { + //check for statName + if (EnumHandler.isStatistic(arg) && request.getStatistic() == null) { + request.setStatistic(EnumHandler.getStatEnum(arg)); + } + //check for subStatEntry and playerFlag + else if (EnumHandler.isSubStatEntry(arg)) { + if (arg.equalsIgnoreCase("player") && !request.getPlayerFlag()) { + request.setPlayerFlag(true); + } + else { + if (request.getSubStatEntry() == null) request.setSubStatEntry(arg); + } + } + //check for selection + else if (arg.equalsIgnoreCase("top")) { + request.setSelection(Target.TOP); + } + else if (arg.equalsIgnoreCase("server")) { + request.setSelection(Target.SERVER); + } + else if (arg.equalsIgnoreCase("me")) { + if (sender instanceof Player) { + request.setPlayerName(sender.getName()); + request.setSelection(Target.PLAYER); + } + else if (sender instanceof ConsoleCommandSender) { + request.setSelection(Target.SERVER); + } + } + else if (offlinePlayerHandler.isRelevantPlayer(arg) && request.getPlayerName() == null) { + request.setPlayerName(arg); + request.setSelection(Target.PLAYER); + } + } + patchRequest(request); + return request; + } + + public StatRequest generateRequest(@NotNull Target selection, @NotNull Statistic statistic, Material material, EntityType entity, OfflinePlayer player) { + return null; + } + + /** This method validates the {@link StatRequest} and returns a feedback message if the Request is invalid. + It checks the following: +

1. Is a Statistic set?

+

2. Is a subStat needed, and is a subStat Enum constant present? (block/entity/item)

+

3. If the target is PLAYER, is a valid PlayerName provided?

+ @return true if the SimpleRequest is valid, and false + an explanation message otherwise. */ + public boolean requestIsValid(StatRequest request) { + if (request.getStatistic() == null) { + outputManager.sendFeedbackMsg(request.getCommandSender(), StandardMessage.MISSING_STAT_NAME); + return false; + } + Statistic.Type type = request.getStatistic().getType(); + if (request.getSubStatEntry() == null && type != Statistic.Type.UNTYPED) { + outputManager.sendFeedbackMsgMissingSubStat(request.getCommandSender(), type); + return false; + } + else if (!hasMatchingSubStat(request)) { + outputManager.sendFeedbackMsgWrongSubStat(request.getCommandSender(), type, request.getSubStatEntry()); + return false; + } + else if (request.getSelection() == Target.PLAYER && request.getPlayerName() == null) { + outputManager.sendFeedbackMsg(request.getCommandSender(), StandardMessage.MISSING_PLAYER_NAME); + return false; + } + else { + return true; + } + } + + /** Adjust the SimpleRequest 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(StatRequest request) { + if (request.getStatistic() != null) { + Statistic.Type type = request.getStatistic().getType(); + + if (request.getPlayerFlag()) { //unpack the playerFlag + if (type == Statistic.Type.ENTITY && request.getSubStatEntry() == null) { + request.setSubStatEntry("player"); + } + else { + request.setSelection(Target.PLAYER); + } + } + + String subStatEntry = request.getSubStatEntry(); + switch (type) { //attempt to convert relevant subStatEntries into their corresponding Enum Constant + case BLOCK -> { + Material block = EnumHandler.getBlockEnum(subStatEntry); + if (block != null) request.setBlock(block); + } + case ENTITY -> { + EntityType entity = EnumHandler.getEntityEnum(subStatEntry); + if (entity != null) request.setEntity(entity); + } + case ITEM -> { + Material item = EnumHandler.getItemEnum(subStatEntry); + if (item != null) request.setItem(item); + } + case UNTYPED -> { //remove unnecessary subStatEntries + if (subStatEntry != null) request.setSubStatEntry(null); + } + } + } + } + + private boolean hasMatchingSubStat(StatRequest request) { + Statistic.Type type = request.getStatistic().getType(); + switch (type) { + case BLOCK -> { + return request.getBlock() != null; + } + case ENTITY -> { + return request.getEntity() != null; + } + case ITEM -> { + return request.getItem() != null; + } + default -> { + return true; + } + } + } +} \ No newline at end of file diff --git a/src/main/java/com/gmail/artemis/the/gr8/playerstats/statistic/StatManager.java b/src/main/java/com/gmail/artemis/the/gr8/playerstats/statistic/StatManager.java index 6165107..176bac3 100644 --- a/src/main/java/com/gmail/artemis/the/gr8/playerstats/statistic/StatManager.java +++ b/src/main/java/com/gmail/artemis/the/gr8/playerstats/statistic/StatManager.java @@ -1,23 +1,13 @@ package com.gmail.artemis.the.gr8.playerstats.statistic; import com.gmail.artemis.the.gr8.playerstats.ThreadManager; -import com.gmail.artemis.the.gr8.playerstats.api.RequestGenerator; import com.gmail.artemis.the.gr8.playerstats.api.StatGetter; -import com.gmail.artemis.the.gr8.playerstats.enums.StandardMessage; -import com.gmail.artemis.the.gr8.playerstats.enums.Target; import com.gmail.artemis.the.gr8.playerstats.models.StatRequest; import com.gmail.artemis.the.gr8.playerstats.msg.OutputManager; -import com.gmail.artemis.the.gr8.playerstats.utils.EnumHandler; import com.gmail.artemis.the.gr8.playerstats.utils.MyLogger; import com.gmail.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; import com.google.common.collect.ImmutableList; -import org.bukkit.Material; import org.bukkit.OfflinePlayer; -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; import java.util.*; @@ -28,12 +18,10 @@ import java.util.stream.Collectors; public final class StatManager implements StatGetter { private final OfflinePlayerHandler offlinePlayerHandler; - private static OutputManager outputManager; private static int topListMaxSize; - public StatManager(OutputManager outputManager, OfflinePlayerHandler offlinePlayerHandler, int topListMaxSize) { + public StatManager(OfflinePlayerHandler offlinePlayerHandler, int topListMaxSize) { this.offlinePlayerHandler = offlinePlayerHandler; - StatManager.outputManager = outputManager; StatManager.topListMaxSize = topListMaxSize; } @@ -41,132 +29,6 @@ public final class StatManager implements StatGetter { StatManager.topListMaxSize = topListMaxSize; } - public StatRequest generateRequest(CommandSender sender, String[] args) { - StatRequest request = new StatRequest(sender); - for (String arg : args) { - //check for statName - if (EnumHandler.isStatistic(arg) && request.getStatistic() == null) { - request.setStatistic(EnumHandler.getStatEnum(arg)); - } - //check for subStatEntry and playerFlag - else if (EnumHandler.isSubStatEntry(arg)) { - if (arg.equalsIgnoreCase("player") && !request.playerFlag()) { - request.setPlayerFlag(true); - } - else { - if (request.getSubStatEntry() == null) request.setSubStatEntry(arg); - } - } - //check for selection - else if (arg.equalsIgnoreCase("top")) { - request.setSelection(Target.TOP); - } - else if (arg.equalsIgnoreCase("server")) { - request.setSelection(Target.SERVER); - } - else if (arg.equalsIgnoreCase("me")) { - if (sender instanceof Player) { - request.setPlayerName(sender.getName()); - request.setSelection(Target.PLAYER); - } - else if (sender instanceof ConsoleCommandSender) { - request.setSelection(Target.SERVER); - } - } - else if (offlinePlayerHandler.isRelevantPlayer(arg) && request.getPlayerName() == null) { - request.setPlayerName(arg); - request.setSelection(Target.PLAYER); - } - } - patchRequest(request); - return request; - } - - - /** Adjust the StatRequest 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(StatRequest request) { - if (request.getStatistic() != null) { - Statistic.Type type = request.getStatistic().getType(); - - if (request.playerFlag()) { //unpack the playerFlag - if (type == Statistic.Type.ENTITY && request.getSubStatEntry() == null) { - request.setSubStatEntry("player"); - } - else { - request.setSelection(Target.PLAYER); - } - } - - String subStatEntry = request.getSubStatEntry(); - switch (type) { //attempt to convert relevant subStatEntries into their corresponding Enum Constant - case BLOCK -> { - Material block = EnumHandler.getBlockEnum(subStatEntry); - if (block != null) request.setBlock(block); - } - case ENTITY -> { - EntityType entity = EnumHandler.getEntityEnum(subStatEntry); - if (entity != null) request.setEntity(entity); - } - case ITEM -> { - Material item = EnumHandler.getItemEnum(subStatEntry); - if (item != null) request.setItem(item); - } - case UNTYPED -> { //remove unnecessary subStatEntries - if (subStatEntry != null) request.setSubStatEntry(null); - } - } - } - } - - /** This method validates the {@link StatRequest} and returns feedback to the player if it returns false. - It checks the following: -

1. Is a Statistic set?

-

2. Is a subStat needed, and is a subStat Enum constant present? (block/entity/item)

-

3. If the target is PLAYER, is a valid PlayerName provided?

- @return true if the StatRequest is valid, and false + an explanation message otherwise. */ - public boolean requestIsValid(StatRequest request) { - if (request.getStatistic() == null) { - outputManager.sendFeedbackMsg(request.getCommandSender(), StandardMessage.MISSING_STAT_NAME); - return false; - } - Statistic.Type type = request.getStatistic().getType(); - if (request.getSubStatEntry() == null && type != Statistic.Type.UNTYPED) { - outputManager.sendFeedbackMsgMissingSubStat(request.getCommandSender(), type); - return false; - } - else if (!hasMatchingSubStat(request)) { - outputManager.sendFeedbackMsgWrongSubStat(request.getCommandSender(), type, request.getSubStatEntry()); - return false; - } - else if (request.getSelection() == Target.PLAYER && request.getPlayerName() == null) { - outputManager.sendFeedbackMsg(request.getCommandSender(), StandardMessage.MISSING_PLAYER_NAME); - return false; - } - else { - return true; - } - } - - private boolean hasMatchingSubStat(StatRequest request) { - Statistic.Type type = request.getStatistic().getType(); - switch (type) { - case BLOCK -> { - return request.getBlock() != null; - } - case ENTITY -> { - return request.getEntity() != null; - } - case ITEM -> { - return request.getItem() != null; - } - default -> { - return true; - } - } - } - /** Gets the statistic data for an individual player. If somehow the player cannot be found, this returns 0.*/ public int getPlayerStat(StatRequest request) { diff --git a/src/main/java/com/gmail/artemis/the/gr8/playerstats/statistic/StatRequestGenerator.java b/src/main/java/com/gmail/artemis/the/gr8/playerstats/statistic/StatRequestGenerator.java deleted file mode 100644 index 725139b..0000000 --- a/src/main/java/com/gmail/artemis/the/gr8/playerstats/statistic/StatRequestGenerator.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.gmail.artemis.the.gr8.playerstats.statistic; - -public class StatRequestGenerator { -} diff --git a/src/main/java/com/gmail/artemis/the/gr8/playerstats/statistic/StatThread.java b/src/main/java/com/gmail/artemis/the/gr8/playerstats/statistic/StatThread.java index 832c78b..44fef08 100644 --- a/src/main/java/com/gmail/artemis/the/gr8/playerstats/statistic/StatThread.java +++ b/src/main/java/com/gmail/artemis/the/gr8/playerstats/statistic/StatThread.java @@ -6,9 +6,7 @@ import com.gmail.artemis.the.gr8.playerstats.models.StatRequest; import com.gmail.artemis.the.gr8.playerstats.msg.OutputManager; import com.gmail.artemis.the.gr8.playerstats.reload.ReloadThread; import com.gmail.artemis.the.gr8.playerstats.ThreadManager; -import com.gmail.artemis.the.gr8.playerstats.config.ConfigHandler; import com.gmail.artemis.the.gr8.playerstats.utils.MyLogger; -import com.gmail.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler; import net.kyori.adventure.text.TextComponent; import org.jetbrains.annotations.Nullable; @@ -61,9 +59,9 @@ public class StatThread extends Thread { Target selection = request.getSelection(); try { TextComponent statResult = switch (selection) { - case PLAYER -> outputManager.formatPlayerStat(request, statManager.getPlayerStat(request)); - case TOP -> outputManager.formatTopStat(request, statManager.getTopStats(request)); - case SERVER -> outputManager.formatServerStat(request, statManager.getServerStat(request)); + case PLAYER -> outputManager.formatPlayerStat(request, statManager.getPlayerStat(request), false); + case TOP -> outputManager.formatTopStat(request, statManager.getTopStats(request), false); + case SERVER -> outputManager.formatServerStat(request, statManager.getServerStat(request), false); }; outputManager.sendToCommandSender(request.getCommandSender(), statResult); }