From e8cf9ade47b776e89f4a64e475833b2449be9ab6 Mon Sep 17 00:00:00 2001 From: Artemis-the-gr8 Date: Mon, 6 Feb 2023 15:50:02 +0100 Subject: [PATCH] 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)); }