Merge branch 'main' into v2.0

# Conflicts:
#	src/main/java/com/artemis/the/gr8/playerstats/commands/TabCompleter.java
#	src/main/java/com/artemis/the/gr8/playerstats/commands/cmdutils/TabCompleteHelper.java
#	src/main/java/com/artemis/the/gr8/playerstats/core/msg/msgutils/LanguageKeyHandler.java
#	src/main/java/com/artemis/the/gr8/playerstats/msg/msgutils/StringUtils.java
This commit is contained in:
Artemis-the-gr8 2023-02-06 12:10:16 +01:00
commit 991ab06f9f
6 changed files with 227 additions and 14 deletions

View File

@ -3,6 +3,8 @@ package com.artemis.the.gr8.playerstats.api.enums;
import org.bukkit.Statistic;
import org.jetbrains.annotations.NotNull;
import java.util.Locale;
/**
* All the units PlayerStats can display statistics in, separated
* by {@link Unit.Type}.
@ -146,7 +148,7 @@ public enum Unit {
match exactly (it can be "day" or "days", for example), and is case-insensitive.
@param unitName an approximation of the name belonging to the desired Unit, case-insensitive */
public static @NotNull Unit fromString(@NotNull String unitName) {
return switch (unitName.toLowerCase()) {
return switch (unitName.toLowerCase(Locale.ENGLISH)) {
case "cm" -> Unit.CM;
case "m", "block", "blocks" -> Unit.BLOCK;
case "mile", "miles" -> Unit.MILE;
@ -170,7 +172,7 @@ public enum Unit {
* @return the Type of this Unit
*/
public static @NotNull Type getTypeFromStatistic(Statistic statistic) {
String name = statistic.toString().toLowerCase();
String name = statistic.toString().toLowerCase(Locale.ENGLISH);
if (name.contains("one_cm")) {
return Type.DISTANCE;
} else if (name.contains("damage")) {

View File

@ -0,0 +1,116 @@
package com.artemis.the.gr8.playerstats.commands;
import com.artemis.the.gr8.playerstats.utils.EnumHandler;
import com.artemis.the.gr8.playerstats.utils.OfflinePlayerHandler;
import com.artemis.the.gr8.playerstats.commands.cmdutils.TabCompleteHelper;
import org.bukkit.Statistic;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
public final class TabCompleter implements org.bukkit.command.TabCompleter {
private final EnumHandler enumHandler;
private final OfflinePlayerHandler offlinePlayerHandler;
private final TabCompleteHelper tabCompleteHelper;
private final List<String> commandOptions;
public TabCompleter(EnumHandler enumHandler, OfflinePlayerHandler offlinePlayerHandler) {
this.enumHandler = enumHandler;
this.offlinePlayerHandler = offlinePlayerHandler;
tabCompleteHelper = new TabCompleteHelper(enumHandler);
commandOptions = new ArrayList<>();
commandOptions.add("top");
commandOptions.add("player");
commandOptions.add("server");
commandOptions.add("me");
}
//args[0] = statistic (length = 1)
//args[1] = commandOption (top/player/me) OR substatistic (block/item/entitytype) (length = 2)
//args[2] = executorName OR commandOption (top/player/me) (length = 3)
//args[3] = executorName (length = 4)
@Override
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
List<String> tabSuggestions = new ArrayList<>();
if (args.length >= 1) {
String currentArg = args[args.length -1];
if (args.length == 1) { //after typing "stat", suggest a list of viable statistics
tabSuggestions = getFirstArgSuggestions(args[0]);
}
else { //after checking if args[0] is a viable statistic, suggest substatistic OR commandOptions
String previousArg = args[args.length -2];
if (enumHandler.isStatistic(previousArg)) {
Statistic stat = EnumHandler.getStatEnum(previousArg);
if (stat != null) {
tabSuggestions = getTabSuggestions(getRelevantList(stat), currentArg);
}
}
//if previous arg = "player"
else if (previousArg.equalsIgnoreCase("player")) {
if (args.length >= 3 && enumHandler.isEntityStatistic(args[args.length-3])) {
tabSuggestions = commandOptions; //if arg before "player" was entity-stat, suggest commandOptions
}
else { //otherwise "player" is target-flag: suggest playerNames
tabSuggestions = getTabSuggestions(offlinePlayerHandler.getOfflinePlayerNames(), currentArg);
}
}
//after a substatistic, suggest commandOptions
else if (enumHandler.isSubStatEntry(previousArg)) {
tabSuggestions = commandOptions;
}
}
}
return tabSuggestions;
}
private List<String> getFirstArgSuggestions(String currentArg) {
List<String> suggestions = enumHandler.getStatNames();
suggestions.add("examples");
suggestions.add("help");
return getTabSuggestions(suggestions, currentArg);
}
private List<String> getTabSuggestions(List<String> completeList, String currentArg) {
return completeList.stream()
.filter(item -> item.toLowerCase(Locale.ENGLISH).contains(currentArg.toLowerCase(Locale.ENGLISH)))
.collect(Collectors.toList());
}
private List<String> getRelevantList(Statistic stat) {
switch (stat.getType()) {
case BLOCK -> {
return tabCompleteHelper.getAllBlockNames();
}
case ITEM -> {
if (stat == Statistic.BREAK_ITEM) {
return tabCompleteHelper.getItemBrokenSuggestions();
} else {
return tabCompleteHelper.getAllItemNames();
}
}
case ENTITY -> {
return tabCompleteHelper.getEntitySuggestions();
}
default -> {
return commandOptions;
}
}
}
}

View File

@ -0,0 +1,58 @@
package com.artemis.the.gr8.playerstats.commands.cmdutils;
import com.artemis.the.gr8.playerstats.utils.EnumHandler;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
public final class TabCompleteHelper {
private final EnumHandler enumHandler;
private static List<String> itemBrokenSuggestions;
private static List<String> entitySuggestions;
public TabCompleteHelper(EnumHandler enumHandler) {
this.enumHandler = enumHandler;
prepareLists();
}
public List<String> getAllItemNames() {
return enumHandler.getItemNames();
}
public List<String> getItemBrokenSuggestions() {
return itemBrokenSuggestions;
}
public List<String> getAllBlockNames() {
return enumHandler.getBlockNames();
}
public List<String> getEntitySuggestions() {
return entitySuggestions;
}
private static void prepareLists() {
//breaking an item means running its durability negative
itemBrokenSuggestions = Arrays.stream(Material.values())
.parallel()
.filter(Material::isItem)
.filter(item -> item.getMaxDurability() != 0)
.map(Material::toString)
.map(string -> string.toLowerCase(Locale.ENGLISH))
.collect(Collectors.toList());
//the only statistics dealing with entities are killed_entity and entity_killed_by
entitySuggestions = Arrays.stream(EntityType.values())
.parallel()
.filter(EntityType::isAlive)
.map(EntityType::toString)
.map(string -> string.toLowerCase(Locale.ENGLISH))
.collect(Collectors.toList());
}
}

View File

@ -14,6 +14,7 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.Locale;
/**
*
@ -44,6 +45,7 @@ public final class LanguageKeyHandler extends FileHandler {
}
return instance;
}
languageKeys = YamlConfiguration.loadConfiguration(languageKeyFile);
}
@Contract(pure = true)
@ -235,9 +237,9 @@ public final class LanguageKeyHandler extends FileHandler {
*/
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.getInstance().getBlockEnum(blockName);
else if (block.toString().toLowerCase(Locale.ENGLISH).contains("wall_banner")) { //replace wall_banner with regular banner, since there is no key for wall banners
String blockName = block.toString().toLowerCase(Locale.ENGLISH).replace("wall_", "");
Material newBlock = EnumHandler.getBlockEnum(blockName);
return (newBlock != null) ? "block.minecraft." + newBlock.getKey().getKey() : null;
}
else {
@ -260,7 +262,7 @@ public final class LanguageKeyHandler extends FileHandler {
private @NotNull HashMap<Statistic, String> generateStatisticKeys() {
//get the enum names for all statistics first
HashMap<Statistic, String> statNames = new HashMap<>(Statistic.values().length);
Arrays.stream(Statistic.values()).forEach(statistic -> statNames.put(statistic, statistic.toString().toLowerCase()));
Arrays.stream(Statistic.values()).forEach(statistic -> statNames.put(statistic, statistic.toString().toLowerCase(Locale.ENGLISH)));
//replace the ones for which the language key is different from the enum name
statNames.put(Statistic.ARMOR_CLEANED, "clean_armor");

View File

@ -9,6 +9,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -95,7 +96,7 @@ public final class EnumHandler {
*/
public @Nullable EntityType getEntityEnum(String entityName) {
try {
return EntityType.valueOf(entityName.toUpperCase());
return EntityType.valueOf(entityName.toUpperCase(Locale.ENGLISH));
}
catch (IllegalArgumentException | NullPointerException e) {
return null;
@ -124,7 +125,7 @@ public final class EnumHandler {
*/
public @Nullable Statistic getStatEnum(@NotNull String statName) {
try {
return Statistic.valueOf(statName.toUpperCase());
return Statistic.valueOf(statName.toUpperCase(Locale.ENGLISH));
}
catch (IllegalArgumentException e) {
return null;
@ -138,7 +139,7 @@ public final class EnumHandler {
* @return true if this String is a valid Statistic
*/
public boolean isStatistic(@NotNull String statName) {
return statNames.contains(statName.toLowerCase());
return statNames.contains(statName.toLowerCase(Locale.ENGLISH));
}
/**
@ -162,7 +163,7 @@ public final class EnumHandler {
* of Type.Untyped
*/
public boolean isSubStatEntry(@NotNull String statName) {
return subStatNames.contains(statName.toLowerCase());
return subStatNames.contains(statName.toLowerCase(Locale.ENGLISH));
}
/**
@ -186,20 +187,20 @@ public final class EnumHandler {
private void prepareLists() {
List<String> entityNames = Arrays.stream(EntityType.values())
.map(EntityType::toString)
.map(String::toLowerCase)
.map(string -> string.toLowerCase(Locale.ENGLISH))
.filter(entityName -> !entityName.equalsIgnoreCase("unknown"))
.collect(Collectors.toList());
blockNames = Arrays.stream(Material.values())
.filter(Material::isBlock)
.map(Material::toString)
.map(String::toLowerCase)
.map(string -> string.toLowerCase(Locale.ENGLISH))
.collect(Collectors.toList());
itemNames = Arrays.stream(Material.values())
.filter(Material::isItem)
.map(Material::toString)
.map(String::toLowerCase)
.map(string -> string.toLowerCase(Locale.ENGLISH))
.collect(Collectors.toList());
subStatNames = Stream.of(blockNames, entityNames, itemNames)
@ -209,7 +210,7 @@ public final class EnumHandler {
statNames = Arrays.stream(Statistic.values())
.map(Statistic::toString)
.map(String::toLowerCase)
.map(string -> string.toLowerCase(Locale.ENGLISH))
.collect(Collectors.toList());
}
}

View File

@ -0,0 +1,34 @@
package com.artemis.the.gr8.playerstats.msg.msgutils;
import com.artemis.the.gr8.playerstats.utils.MyLogger;
import java.util.Locale;
/**
* A small utility class that helps make enum constant
* names prettier for output in stat-messages.
*/
public final class StringUtils {
private StringUtils() {
}
/**
* Replace "_" with " " and capitalize each first letter of the input.
*
* @param input String to prettify, case-insensitive
*/
public static String prettify(String input) {
if (input == null) return null;
StringBuilder capitals = new StringBuilder(input.toLowerCase(Locale.ENGLISH));
capitals.setCharAt(0, Character.toUpperCase(capitals.charAt(0)));
while (capitals.indexOf("_") != -1) {
MyLogger.logHighLevelMsg("Replacing underscores and capitalizing names...");
int index = capitals.indexOf("_");
capitals.setCharAt(index + 1, Character.toUpperCase(capitals.charAt(index + 1)));
capitals.setCharAt(index, ' ');
}
return capitals.toString();
}
}