Added output for /statexclude list command, and feedback for add/remove (#88)

This commit is contained in:
Artemis-the-gr8 2022-11-23 17:37:19 +01:00
parent 11185468ff
commit 520f83bb60
12 changed files with 179 additions and 121 deletions

View File

@ -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<String> 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;
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -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
}
/**

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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