Reworked MessageFactory to work with a StatRequest, and reworked LanguageKeyHandler to only work with Enums. Now the only place a String is converted into an Enum is inside the StatCommand. Also added method isValid to StatRequest and changed selection to SERVER for "me" in console

This commit is contained in:
Artemis-the-gr8 2022-06-27 13:54:14 +02:00
parent fcb5283982
commit 6253627846
6 changed files with 121 additions and 101 deletions

View File

@ -73,22 +73,25 @@ public class StatCommand implements CommandExecutor {
}
}
//check for selection
else if (request.getSelection() == null) {
if (arg.equalsIgnoreCase("top")) {
request.setSelection(Target.TOP);
}
else if (arg.equalsIgnoreCase("server")) {
request.setSelection(Target.SERVER);
}
else if (arg.equalsIgnoreCase("me") && sender instanceof Player) {
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 (OfflinePlayerHandler.isRelevantPlayer(arg) && request.getPlayerName() == null) {
request.setPlayerName(arg);
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;
@ -105,6 +108,9 @@ public class StatCommand implements CommandExecutor {
if (type == Statistic.Type.ENTITY && request.getSubStatEntry() == null) {
request.setSubStatEntry("player");
}
else {
request.setSelection(Target.PLAYER);
}
}
String subStatEntry = request.getSubStatEntry();
@ -125,10 +131,6 @@ public class StatCommand implements CommandExecutor {
if (subStatEntry != null) request.setSubStatEntry(null);
}
}
if (request.getSelection() == null) { //assume top as default
request.setSelection(Target.TOP);
}
}
}

View File

@ -28,39 +28,39 @@ public class LanguageKeyHandler {
}
}
/** Get the official Key from the NameSpacedKey for the entityType corresponding to this entityName,
or return null if no enum constant can be retrieved.*/
public @Nullable String getEntityKey(@NotNull String entityName) {
if (entityName.equalsIgnoreCase("UNKNOWN")) {
return null;
/** Get the official Key from the NameSpacedKey for this entityType,
or return null if no enum constant can be retrieved or entityType is UNKNOWN.*/
public @Nullable String getEntityKey(EntityType entity) {
if (entity == null || entity == EntityType.UNKNOWN) return null;
else {
return "entity.minecraft." + entity.getKey().getKey();
}
EntityType entity = EnumHandler.getEntityEnum(entityName);
return (entity != null) ? "entity.minecraft." + entity.getKey().getKey() : null;
}
/** Get the official Key from the NameSpacedKey for the Material corresponding to this itemName,
/** Get the official Key from the NameSpacedKey for this item Material,
or return null if no enum constant can be retrieved.*/
public @Nullable String getItemKey(@NotNull String itemName) {
Material item = EnumHandler.getItemEnum(itemName);
if (item == null) {
return null;
}
if (item.isBlock()) {
return "block.minecraft." + item.getKey().getKey();
public @Nullable String getItemKey(Material item) {
if (item == null) return null;
else if (item.isBlock()) {
return getBlockKey(item);
}
else {
return "item.minecraft." + item.getKey().getKey();
}
}
/** Get the official Key from the NameSpacedKey for the Material corresponding to this blockName,
/** Returns the official Key from the NameSpacedKey for the block Material provided,
or return null if no enum constant can be retrieved.*/
public @Nullable String getBlockKey(@NotNull String blockName) {
if (blockName.toLowerCase().contains("wall_banner")) {
blockName = blockName.replace("wall_", "");
public @Nullable String getBlockKey(Material block) {
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);
return (newBlock != null) ? "block.minecraft." + newBlock.getKey().getKey() : null;
}
else {
return "block.minecraft." + block.getKey().getKey();
}
Material block = EnumHandler.getBlockEnum(blockName);
return (block != null) ? "block.minecraft." + block.getKey().getKey() : null;
}
private void generateDefaultKeys() {

View File

@ -2,6 +2,7 @@ package com.gmail.artemis.the.gr8.playerstats.msg;
import com.gmail.artemis.the.gr8.playerstats.enums.Target;
import com.gmail.artemis.the.gr8.playerstats.config.ConfigHandler;
import com.gmail.artemis.the.gr8.playerstats.statistic.StatRequest;
import com.gmail.artemis.the.gr8.playerstats.utils.MyLogger;
import com.gmail.artemis.the.gr8.playerstats.utils.NumberFormatter;
import net.kyori.adventure.text.Component;
@ -157,19 +158,22 @@ public class MessageFactory {
.append(newline());
}
public TextComponent formatPlayerStat(String playerName, Statistic statistic, String subStatEntry, int stat) {
public TextComponent formatPlayerStat(int stat, @NotNull StatRequest request) {
if (!request.isValid()) return unknownError(request.isConsoleSender());
return Component.text()
.append(playerNameComponent(Target.PLAYER, playerName + ": "))
.append(playerNameComponent(Target.PLAYER, request.getPlayerName() + ": "))
.append(statNumberComponent(Target.PLAYER, stat))
.append(space())
.append(statNameComponent(Target.PLAYER, statistic, subStatEntry))
.append(statNameComponent(request))
.append(space())
.build();
}
public TextComponent formatTopStats(@NotNull LinkedHashMap<String, Integer> topStats, Statistic statistic, String subStatEntry, boolean isConsoleSender) {
public TextComponent formatTopStats(@NotNull LinkedHashMap<String, Integer> topStats, @NotNull StatRequest request) {
if (!request.isValid()) return unknownError(request.isConsoleSender());
TextComponent.Builder topList = Component.text();
topList.append(getTopStatTitle(topStats.size(), statistic, subStatEntry, isConsoleSender));
topList.append(getTopStatTitle(topStats.size(), request));
boolean useDots = config.useDots();
Set<String> playerNames = topStats.keySet();
@ -187,7 +191,7 @@ public class MessageFactory {
topList.append(space());
int dots = (int) Math.round((130.0 - font.getWidth(count + ". " + playerName))/2);
if (isConsoleSender) {
if (request.isConsoleSender()) {
dots = (int) Math.round((130.0 - font.getWidth(count + ". " + playerName))/6) + 7;
}
else if (config.playerNameIsBold()) {
@ -205,7 +209,8 @@ public class MessageFactory {
return topList.build();
}
public TextComponent formatServerStat(Statistic statistic, String subStatEntry, long stat) {
public TextComponent formatServerStat(long stat, @NotNull StatRequest request) {
if (!request.isValid()) return unknownError(request.isConsoleSender());
return Component.text()
.append(titleComponent(Target.SERVER, config.getServerTitle()))
.append(space())
@ -213,7 +218,7 @@ public class MessageFactory {
.append(space())
.append(statNumberComponent(Target.SERVER, stat))
.append(space())
.append(statNameComponent(Target.SERVER, statistic, subStatEntry))
.append(statNameComponent(request))
.append(space())
.build();
}
@ -233,15 +238,15 @@ public class MessageFactory {
.append(text(underscores));
}
protected TextComponent getTopStatTitle(int topLength, @NotNull Statistic statistic, String subStatEntry, boolean isConsoleSender) {
protected TextComponent getTopStatTitle(int topLength, @NotNull StatRequest request) {
return Component.text()
.append(newline())
.append(pluginPrefix(isConsoleSender))
.append(pluginPrefix(request.isConsoleSender()))
.append(titleComponent(Target.TOP, config.getTopStatsTitle()))
.append(space())
.append(titleNumberComponent(topLength))
.append(space())
.append(statNameComponent(Target.TOP, statistic, subStatEntry))
.append(statNameComponent(request))
.append(space())
.build();
}
@ -252,26 +257,28 @@ public class MessageFactory {
getStyleFromString(config.getPlayerNameFormatting(selection, true)));
}
protected TranslatableComponent statNameComponent(Target selection, @NotNull Statistic statistic, String subStatName) {
TextColor statNameColor = getColorFromString(config.getStatNameFormatting(selection, false));
TextDecoration statNameStyle = getStyleFromString(config.getStatNameFormatting(selection, true));
protected TranslatableComponent statNameComponent(@NotNull StatRequest request) {
if (request.getStatistic() == null) return null;
TextColor statNameColor = getColorFromString(config.getStatNameFormatting(request.getSelection(), false));
TextDecoration statNameStyle = getStyleFromString(config.getStatNameFormatting(request.getSelection(), true));
String statName;
String statName = request.getStatistic().name();
String subStatName = request.getSubStatEntry();
if (!config.useTranslatableComponents()) {
statName = getPrettyName(statistic.name().toLowerCase());
statName = getPrettyName(statName);
subStatName = getPrettyName(subStatName);
}
else {
statName = language.getStatKey(statistic);
switch (statistic.getType()) {
case BLOCK -> subStatName = language.getBlockKey(subStatName);
case ENTITY -> subStatName = language.getEntityKey(subStatName);
case ITEM -> subStatName = language.getItemKey(subStatName);
statName = language.getStatKey(request.getStatistic());
switch (request.getStatistic().getType()) {
case BLOCK -> subStatName = language.getBlockKey(request.getBlock());
case ENTITY -> subStatName = language.getEntityKey(request.getEntity());
case ITEM -> subStatName = language.getItemKey(request.getItem());
case UNTYPED -> {
}
}
}
TextComponent subStat = subStatNameComponent(selection, subStatName);
TextComponent subStat = subStatNameComponent(request.getSelection(), subStatName);
TranslatableComponent.Builder totalName;
if (statName.equalsIgnoreCase("stat_type.minecraft.killed") && subStat != null) {
@ -291,22 +298,24 @@ public class MessageFactory {
.build();
}
/** Construct a custom translation for kill_entity */
private TranslatableComponent.@NotNull Builder killEntityComponent(TextComponent subStat) {
TranslatableComponent.Builder totalName = translatable()
.key("commands.kill.success.single"); //"Killed %s"
if (subStat != null) totalName.args(subStat);
return totalName;
/** Construct a custom translation for kill_entity with the language key for commands.kill.success.single ("Killed %s").
@return a TranslatableComponent Builder with the subStat Component as args.*/
private TranslatableComponent.Builder killEntityComponent(@NotNull TextComponent subStat) {
return translatable()
.key("commands.kill.success.single") //"Killed %s"
.args(subStat);
}
/** Construct a custom translation for entity_killed_by */
private TranslatableComponent.@NotNull Builder entityKilledByComponent(@NotNull TextComponent subStat) {
/** Construct a custom translation for entity_killed_by with the language keys for stat.minecraft.deaths
("Number of Deaths") and book.byAuthor ("by %s").
@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 entityKilledByComponent(@NotNull TextComponent subStat) {
return translatable()
.key("stat.minecraft.deaths") //"Number of Deaths"
.append(space())
.append(translatable()
.key("book.byAuthor")
.key("book.byAuthor") //"by %s"
.args(subStat));
}
@ -371,10 +380,11 @@ public class MessageFactory {
return style == null ? text(content).color(color) : text(content).color(color).decoration(style, TextDecoration.State.TRUE);
}
/** Replace "_" with " " and capitalize each first letter of the input.*/
/** Replace "_" with " " and capitalize each first letter of the input.
@param input String to prettify, case-insensitive*/
private String getPrettyName(String input) {
if (input == null) return null;
StringBuilder capitals = new StringBuilder(input);
StringBuilder capitals = new StringBuilder(input.toLowerCase());
capitals.setCharAt(0, Character.toUpperCase(capitals.charAt(0)));
while (capitals.indexOf("_") != -1) {
MyLogger.replacingUnderscores();

View File

@ -4,6 +4,7 @@ import com.gmail.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;
@ -21,16 +22,41 @@ public class StatRequest {
private Material item;
private boolean playerFlag;
//playerFlag is set to false by default, will be set to true if "player" is in the args
//make a StatRequest for a given CommandSender with some default values
public StatRequest(@NotNull CommandSender s) {
sender = s;
selection = Target.TOP;
playerFlag = false;
}
public CommandSender getCommandSender() {
/** Returns true if this StatRequest has all the information needed for a Statistic lookup to succeed.*/
public boolean isValid() {
if (statistic == null) return false;
switch (statistic.getType()) {
case BLOCK -> {
if (block == null) return false;
}
case ENTITY -> {
if (entity == null) return false;
}
case ITEM -> {
if (item == null) return false;
}
case UNTYPED -> {
if (subStatEntry != null) return false;
}
} //if target = PLAYER and playerName = null, return false, otherwise return true
return selection != Target.PLAYER || playerName != null;
}
public @NotNull CommandSender getCommandSender() {
return sender;
}
public boolean isConsoleSender() {
return sender instanceof ConsoleCommandSender;
}
public void setStatistic(Statistic statistic) {
this.statistic = statistic;
}
@ -73,7 +99,7 @@ public class StatRequest {
this.selection = selection;
}
public Target getSelection() {
public @NotNull Target getSelection() {
return selection;
}

View File

@ -76,9 +76,6 @@ public class StatThread extends Thread {
CommandSender sender = request.getCommandSender();
boolean isConsoleSencer = sender instanceof ConsoleCommandSender;
Statistic statistic = request.getStatistic();
String playerName = request.getPlayerName();
String subStatEntry = request.getSubStatEntry();
Target selection = request.getSelection();
if (selection == Target.TOP || selection == Target.SERVER) {
@ -91,12 +88,10 @@ public class StatThread extends Thread {
try {
if (selection == Target.TOP) {
adventure.sender(sender).sendMessage(messageFactory.formatTopStats(
getTopStats(), statistic, subStatEntry, sender instanceof ConsoleCommandSender));
adventure.sender(sender).sendMessage(messageFactory.formatTopStats(getTopStats(), request));
}
else {
adventure.sender(sender).sendMessage(messageFactory.formatServerStat(
statistic, subStatEntry, getServerTotal()));
adventure.sender(sender).sendMessage(messageFactory.formatServerStat(getServerTotal(), request));
}
} catch (ConcurrentModificationException e) {
@ -112,8 +107,7 @@ public class StatThread extends Thread {
else if (selection == Target.PLAYER) {
try {
adventure.sender(sender).sendMessage(
messageFactory.formatPlayerStat(
playerName, statistic, subStatEntry, getIndividualStat()));
messageFactory.formatPlayerStat(getIndividualStat(), request));
} catch (UnsupportedOperationException | NullPointerException e) {
adventure.sender(sender).sendMessage(messageFactory.formatExceptions(e.toString(), isConsoleSencer));

View File

@ -59,12 +59,6 @@ public class EnumHandler {
private EnumHandler() {
}
/** Checks whether the provided string is a valid item
@param itemName String, case-insensitive */
public static boolean isItem(@NotNull String itemName) {
return itemNames.contains(itemName.toLowerCase());
}
/** Returns all item names in lowercase */
public static List<String> getItemNames() {
return itemNames;
@ -74,12 +68,10 @@ public class EnumHandler {
@param itemName String, case-insensitive
@return Material enum constant, uppercase */
public static @Nullable Material getItemEnum(String itemName) {
return Material.matchMaterial(itemName);
}
if (itemName == null) return null;
/** Checks whether the provided string is a valid entity */
public static boolean isEntity(@NotNull String entityName) {
return entityNames.contains(entityName.toLowerCase());
Material item = Material.matchMaterial(itemName);
return (item != null && item.isItem()) ? item : null;
}
/** Returns all entitytype names in lowercase */
@ -99,12 +91,6 @@ public class EnumHandler {
}
}
/** Checks whether the provided string is a valid block
@param materialName String, case-insensitive */
public static boolean isBlock(@NotNull String materialName) {
return blockNames.contains(materialName.toLowerCase());
}
/** Returns all block names in lowercase */
public static List<String> getBlockNames() {
return blockNames;
@ -114,8 +100,10 @@ public class EnumHandler {
@param materialName String, case-insensitive
@return Material enum constant, uppercase */
public static @Nullable Material getBlockEnum(String materialName) {
return Material.matchMaterial(materialName);
if (materialName == null) return null;
Material block = Material.matchMaterial(materialName);
return (block != null && block.isBlock()) ? block : null;
}
/** Checks if string is a valid statistic
@ -150,4 +138,4 @@ public class EnumHandler {
public static List<String> getEntitySubStatNames() {
return entitySubStatNames;
}
}
}