Added feedback for /stat commands with excluded player targets (#88), fixed bug (#128)

This commit is contained in:
Artemis-the-gr8 2023-02-06 15:50:02 +01:00
parent 3dd43d3a8d
commit e8cf9ade47
11 changed files with 54 additions and 30 deletions

View File

@ -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<T> {
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<T> {
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 -> {

View File

@ -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);

View File

@ -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) {
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;
}
}

View File

@ -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();
}
}

View File

@ -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,

View File

@ -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())

View File

@ -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);

View File

@ -64,7 +64,7 @@ final class StatAction extends RecursiveTask<ConcurrentHashMap<String, Integer>>
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());

View File

@ -58,7 +58,7 @@ public final class ThreadManager {
public static @NotNull StatAction getStatAction(StatRequest.Settings requestSettings) {
OfflinePlayerHandler offlinePlayerHandler = OfflinePlayerHandler.getInstance();
ImmutableList<String> relevantPlayerNames = ImmutableList.copyOf(offlinePlayerHandler.getLoadedOfflinePlayerNames());
ImmutableList<String> relevantPlayerNames = ImmutableList.copyOf(offlinePlayerHandler.getIncludedOfflinePlayerNames());
ConcurrentHashMap<String, Integer> resultingStatNumbers = new ConcurrentHashMap<>(relevantPlayerNames.size());
StatAction task = new StatAction(relevantPlayerNames, requestSettings, resultingStatNumbers);

View File

@ -75,7 +75,7 @@ public final class RequestManager implements StatManager {
@Override
public @NotNull RequestGenerator<LinkedHashMap<String, Integer>> 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());

View File

@ -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<String> getLoadedOfflinePlayerNames() {
public @NotNull ArrayList<String> 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));
}