From 003c9e836771addd9c7876805254bb10cd39195a Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 11 Jul 2023 16:36:19 +0200 Subject: [PATCH] Finishes the reward tab completer --- .../net/knarcraft/minigames/MiniGames.java | 5 + .../minigames/arena/reward/CommandReward.java | 14 +- .../minigames/arena/reward/ItemReward.java | 2 +- .../minigames/arena/reward/RewardType.java | 31 +--- .../command/JoinArenaTabCompleter.java | 2 +- .../command/SetArenaRewardTabCompleter.java | 149 +++++++++++++++++- .../dropper/DropperGroupListCommand.java | 2 +- .../dropper/DropperGroupSetCommand.java | 2 +- .../dropper/DropperGroupSwapCommand.java | 2 +- .../dropper/EditDropperArenaTabCompleter.java | 2 +- .../RemoveDropperArenaTabCompleter.java | 2 +- .../parkour/EditParkourArenaTabCompleter.java | 2 +- .../parkour/ParkourGroupListCommand.java | 2 +- .../parkour/ParkourGroupSetCommand.java | 2 +- .../parkour/ParkourGroupSwapCommand.java | 2 +- .../RemoveParkourArenaTabCompleter.java | 2 +- .../minigames/util/TabCompleteHelper.java | 84 ++++++++-- 17 files changed, 247 insertions(+), 60 deletions(-) diff --git a/src/main/java/net/knarcraft/minigames/MiniGames.java b/src/main/java/net/knarcraft/minigames/MiniGames.java index 40e97c7..7521db5 100644 --- a/src/main/java/net/knarcraft/minigames/MiniGames.java +++ b/src/main/java/net/knarcraft/minigames/MiniGames.java @@ -325,6 +325,11 @@ public final class MiniGames extends JavaPlugin { log(Level.WARNING, "Unable to register PlaceholderAPI parkour expansion!"); } } + if (Bukkit.getPluginManager().getPlugin("Vault") != null) { + setupVault(); + } else { + log(Level.WARNING, "Vault not found. Economy and Permission rewards are unavailable."); + } } /** diff --git a/src/main/java/net/knarcraft/minigames/arena/reward/CommandReward.java b/src/main/java/net/knarcraft/minigames/arena/reward/CommandReward.java index c246dda..a810022 100644 --- a/src/main/java/net/knarcraft/minigames/arena/reward/CommandReward.java +++ b/src/main/java/net/knarcraft/minigames/arena/reward/CommandReward.java @@ -27,8 +27,7 @@ public class CommandReward implements Reward { @Override public boolean grant(@NotNull Player player) { - return Bukkit.dispatchCommand(Bukkit.getServer().getConsoleSender(), - command.replaceAll("[<%(\\[]player(_|-name)?[>%)\\]]", player.getName())); + return Bukkit.dispatchCommand(Bukkit.getServer().getConsoleSender(), replaceNamePlaceholder(player, command)); } @Override @@ -45,6 +44,17 @@ public class CommandReward implements Reward { return data; } + /** + * Replaces the name placeholder in the given input with the given player's name + * + * @param player

The player whose name should be used

+ * @param input

The input containing a name placeholder

+ * @return

The input with the placeholder replaced

+ */ + private String replaceNamePlaceholder(@NotNull Player player, @NotNull String input) { + return input.replaceAll("[<%(\\[{]player[_\\-]?(name)?[>%)\\]}]", player.getName()); + } + /** * Deserializes the command reward defined in the given data * diff --git a/src/main/java/net/knarcraft/minigames/arena/reward/ItemReward.java b/src/main/java/net/knarcraft/minigames/arena/reward/ItemReward.java index 2247fc9..fde135b 100644 --- a/src/main/java/net/knarcraft/minigames/arena/reward/ItemReward.java +++ b/src/main/java/net/knarcraft/minigames/arena/reward/ItemReward.java @@ -45,7 +45,7 @@ public class ItemReward implements Reward { public @NotNull String getGrantMessage() { return MiniGames.getInstance().getStringFormatter().replacePlaceholders(MiniGameMessage.SUCCESS_ITEM_REWARDED, new String[]{"{amount}", "{item}"}, new String[]{String.valueOf(item.getAmount()), - item.getType().getKey().getKey()}); + item.getType().getKey().getKey().replace("_", " ")}); } @NotNull diff --git a/src/main/java/net/knarcraft/minigames/arena/reward/RewardType.java b/src/main/java/net/knarcraft/minigames/arena/reward/RewardType.java index 0da99c9..c3778ca 100644 --- a/src/main/java/net/knarcraft/minigames/arena/reward/RewardType.java +++ b/src/main/java/net/knarcraft/minigames/arena/reward/RewardType.java @@ -1,7 +1,6 @@ package net.knarcraft.minigames.arena.reward; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; /** * The type of a specific reward @@ -11,46 +10,24 @@ public enum RewardType { /** * A command reward */ - COMMAND(CommandReward.class), + COMMAND, /** * An economy reward */ - ECONOMY(EconomyReward.class), + ECONOMY, /** * An item reward */ - ITEM(ItemReward.class), + ITEM, /** * A permission reward */ - PERMISSION(PermissionReward.class), + PERMISSION, ; - private final Class classType; - - RewardType(Class classType) { - this.classType = classType; - } - - /** - * Gets the type of reward the given object represents - * - * @param object

A reward object

- * @return

The reward type of the given object, or null if not recognized

- */ - public static @Nullable RewardType getFromObject(@NotNull K object) { - for (RewardType rewardType : RewardType.values()) { - if (object.getClass() == rewardType.classType) { - return rewardType; - } - } - - return null; - } - /** * Gets a reward type from the given string * diff --git a/src/main/java/net/knarcraft/minigames/command/JoinArenaTabCompleter.java b/src/main/java/net/knarcraft/minigames/command/JoinArenaTabCompleter.java index d33828e..a6f592c 100644 --- a/src/main/java/net/knarcraft/minigames/command/JoinArenaTabCompleter.java +++ b/src/main/java/net/knarcraft/minigames/command/JoinArenaTabCompleter.java @@ -11,7 +11,7 @@ import java.util.ArrayList; import java.util.List; import java.util.function.Supplier; -import static net.knarcraft.minigames.util.TabCompleteHelper.filterMatchingContains; +import static net.knarcraft.knarlib.util.TabCompletionHelper.filterMatchingContains; /** * An abstract class for an arena joining tab-completer diff --git a/src/main/java/net/knarcraft/minigames/command/SetArenaRewardTabCompleter.java b/src/main/java/net/knarcraft/minigames/command/SetArenaRewardTabCompleter.java index 2537618..e96a50a 100644 --- a/src/main/java/net/knarcraft/minigames/command/SetArenaRewardTabCompleter.java +++ b/src/main/java/net/knarcraft/minigames/command/SetArenaRewardTabCompleter.java @@ -1,23 +1,168 @@ package net.knarcraft.minigames.command; +import net.knarcraft.knarlib.util.MaterialHelper; +import net.knarcraft.knarlib.util.TabCompletionHelper; +import net.knarcraft.minigames.MiniGames; +import net.knarcraft.minigames.arena.Arena; +import net.knarcraft.minigames.arena.reward.RewardCondition; +import net.knarcraft.minigames.arena.reward.RewardType; +import net.knarcraft.minigames.util.TabCompleteHelper; +import org.bukkit.Material; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.command.TabCompleter; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.EnumSet; import java.util.List; +import java.util.Set; + +import static net.knarcraft.knarlib.util.TabCompletionHelper.filterMatchingContains; +import static net.knarcraft.knarlib.util.TabCompletionHelper.filterMatchingStartsWith; /** * The tab completer for the reward setting command */ public class SetArenaRewardTabCompleter implements TabCompleter { + private static final List materials = getMaterials(); + @Nullable @Override public List onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, - @NotNull String[] strings) { - return null; + @NotNull String[] arguments) { + if (arguments.length == 1) { + // The first argument is either clear or add + return TabCompletionHelper.filterMatchingStartsWith(Arrays.asList("add", "clear"), arguments[0]); + } + if (arguments.length >= 2) { + // If the first argument is invalid, stop further tab completion + if (!arguments[0].equalsIgnoreCase("add") && !arguments[0].equalsIgnoreCase("clear")) { + return new ArrayList<>(); + } + } + if (arguments.length == 2) { + // The second argument is the type of arena to change rewards for + return TabCompletionHelper.filterMatchingStartsWith(Arrays.asList("dropper", "parkour"), arguments[1]); + } else if (arguments.length == 3) { + // The third argument is the name of the arena to change rewards for + if (arguments[1].equalsIgnoreCase("dropper")) { + return filterMatchingContains(TabCompleteHelper.getDropperArenas(), arguments[2]); + } else if (arguments[1].equalsIgnoreCase("parkour")) { + return filterMatchingContains(TabCompleteHelper.getParkourArenas(), arguments[2]); + } + } + if (arguments.length >= 4) { + // Make sure a valid dropper or arena name has been given + Arena arena = null; + if (arguments[1].equalsIgnoreCase("dropper")) { + arena = MiniGames.getInstance().getDropperArenaHandler().getArena(arguments[2]); + } else if (arguments[1].equalsIgnoreCase("parkour")) { + arena = MiniGames.getInstance().getParkourArenaHandler().getArena(arguments[2]); + } + if (arena == null) { + return new ArrayList<>(); + } + } + if (arguments.length == 4) { + // The fourth argument is the condition to change the reward for + return filterMatchingContains(getRewardConditions(), arguments[3]); + } + if (arguments.length >= 5) { + // If the condition is invalid, or it's the clear action, stop tab-completion + if (RewardCondition.getFromString(arguments[3]) == null || + arguments[0].equalsIgnoreCase("clear")) { + return new ArrayList<>(); + } + } + if (arguments.length == 5) { + // The fifth argument is the type of reward to grant + return filterMatchingContains(getRewardTypes(), arguments[4]); + } + if (arguments.length >= 6) { + // Make sure a valid reward type has been given + RewardType rewardType = RewardType.getFromString(arguments[4]); + if (rewardType == null) { + return new ArrayList<>(); + } + + if (arguments.length == 6) { + return switch (rewardType) { + case ITEM -> filterMatchingContains(materials, arguments[5]); + case PERMISSION -> TabCompleteHelper.tabCompletePermission(arguments[5]); + case ECONOMY -> filterMatchingStartsWith(Arrays.asList("1", "5", "10", "25", "50"), arguments[5]); + case COMMAND -> filterMatchingStartsWith(getCommands(), arguments[5]); + }; + } + + if (rewardType == RewardType.ITEM && arguments.length == 7) { + // If a valid item material has been given, give potential amounts + if (MaterialHelper.loadMaterialString(arguments[5], MiniGames.getInstance().getLogger()) == null) { + return new ArrayList<>(); + } + return Arrays.asList("1", "5", "10", "16", "32", "48", "64"); + } + } + return new ArrayList<>(); + } + + /** + * Gets example command rewards + * + * @return

Example command rewards

+ */ + private static List getCommands() { + List commands = new ArrayList<>(); + commands.add("f powerboost player add %player% 1"); + commands.add("minecraft:xp give (player_name) 1000"); + return commands; + } + + /** + * Gets all materials grant-able as item rewards + * + * @return

All grant-able materials

+ */ + private static List getMaterials() { + List materials = new ArrayList<>(); + Set invalid = EnumSet.of(Material.WATER, Material.LAVA, Material.POWDER_SNOW); + for (Material material : Material.values()) { + if (material.isAir() || invalid.contains(material) || (material.isBlock() && + (material.getHardness() == -1 || material.getHardness() == Double.MAX_VALUE))) { + continue; + } + materials.add(material.name()); + } + return materials; + } + + /** + * Gets a list of all reward types + * + * @return

All reward types

+ */ + private List getRewardTypes() { + List types = new ArrayList<>(); + for (RewardType rewardType : RewardType.values()) { + types.add(rewardType.name()); + } + return types; + } + + /** + * Gets a list of all reward conditions + * + * @return

All reward conditions

+ */ + private List getRewardConditions() { + List conditions = new ArrayList<>(); + for (RewardCondition rewardCondition : RewardCondition.values()) { + conditions.add(rewardCondition.name()); + } + return conditions; } } diff --git a/src/main/java/net/knarcraft/minigames/command/dropper/DropperGroupListCommand.java b/src/main/java/net/knarcraft/minigames/command/dropper/DropperGroupListCommand.java index fe654d8..7435921 100644 --- a/src/main/java/net/knarcraft/minigames/command/dropper/DropperGroupListCommand.java +++ b/src/main/java/net/knarcraft/minigames/command/dropper/DropperGroupListCommand.java @@ -16,7 +16,7 @@ import java.util.ArrayList; import java.util.List; import java.util.UUID; -import static net.knarcraft.minigames.util.TabCompleteHelper.filterMatchingContains; +import static net.knarcraft.knarlib.util.TabCompletionHelper.filterMatchingContains; /** * The command for listing groups and the stages within diff --git a/src/main/java/net/knarcraft/minigames/command/dropper/DropperGroupSetCommand.java b/src/main/java/net/knarcraft/minigames/command/dropper/DropperGroupSetCommand.java index d1bfb4d..db67695 100644 --- a/src/main/java/net/knarcraft/minigames/command/dropper/DropperGroupSetCommand.java +++ b/src/main/java/net/knarcraft/minigames/command/dropper/DropperGroupSetCommand.java @@ -16,7 +16,7 @@ import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; -import static net.knarcraft.minigames.util.TabCompleteHelper.filterMatchingContains; +import static net.knarcraft.knarlib.util.TabCompletionHelper.filterMatchingContains; /** * The command for setting the group of an arena diff --git a/src/main/java/net/knarcraft/minigames/command/dropper/DropperGroupSwapCommand.java b/src/main/java/net/knarcraft/minigames/command/dropper/DropperGroupSwapCommand.java index 404018b..9097a7b 100644 --- a/src/main/java/net/knarcraft/minigames/command/dropper/DropperGroupSwapCommand.java +++ b/src/main/java/net/knarcraft/minigames/command/dropper/DropperGroupSwapCommand.java @@ -16,7 +16,7 @@ import java.util.ArrayList; import java.util.List; import java.util.UUID; -import static net.knarcraft.minigames.util.TabCompleteHelper.filterMatchingContains; +import static net.knarcraft.knarlib.util.TabCompletionHelper.filterMatchingContains; /** * The command for swapping the order of two arenas in a group diff --git a/src/main/java/net/knarcraft/minigames/command/dropper/EditDropperArenaTabCompleter.java b/src/main/java/net/knarcraft/minigames/command/dropper/EditDropperArenaTabCompleter.java index 2488606..52d4951 100644 --- a/src/main/java/net/knarcraft/minigames/command/dropper/EditDropperArenaTabCompleter.java +++ b/src/main/java/net/knarcraft/minigames/command/dropper/EditDropperArenaTabCompleter.java @@ -11,7 +11,7 @@ import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; -import static net.knarcraft.minigames.util.TabCompleteHelper.filterMatchingContains; +import static net.knarcraft.knarlib.util.TabCompletionHelper.filterMatchingContains; /** * The tab-completer for the edit arena command diff --git a/src/main/java/net/knarcraft/minigames/command/dropper/RemoveDropperArenaTabCompleter.java b/src/main/java/net/knarcraft/minigames/command/dropper/RemoveDropperArenaTabCompleter.java index 1143e3e..7a90a1f 100644 --- a/src/main/java/net/knarcraft/minigames/command/dropper/RemoveDropperArenaTabCompleter.java +++ b/src/main/java/net/knarcraft/minigames/command/dropper/RemoveDropperArenaTabCompleter.java @@ -10,7 +10,7 @@ import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; -import static net.knarcraft.minigames.util.TabCompleteHelper.filterMatchingContains; +import static net.knarcraft.knarlib.util.TabCompletionHelper.filterMatchingContains; /** * The tab-completer for the remove arena command diff --git a/src/main/java/net/knarcraft/minigames/command/parkour/EditParkourArenaTabCompleter.java b/src/main/java/net/knarcraft/minigames/command/parkour/EditParkourArenaTabCompleter.java index 3a0a7f0..3aff671 100644 --- a/src/main/java/net/knarcraft/minigames/command/parkour/EditParkourArenaTabCompleter.java +++ b/src/main/java/net/knarcraft/minigames/command/parkour/EditParkourArenaTabCompleter.java @@ -11,7 +11,7 @@ import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; -import static net.knarcraft.minigames.util.TabCompleteHelper.filterMatchingContains; +import static net.knarcraft.knarlib.util.TabCompletionHelper.filterMatchingContains; /** * The tab-completer for the edit arena command diff --git a/src/main/java/net/knarcraft/minigames/command/parkour/ParkourGroupListCommand.java b/src/main/java/net/knarcraft/minigames/command/parkour/ParkourGroupListCommand.java index 915a861..2101887 100644 --- a/src/main/java/net/knarcraft/minigames/command/parkour/ParkourGroupListCommand.java +++ b/src/main/java/net/knarcraft/minigames/command/parkour/ParkourGroupListCommand.java @@ -17,7 +17,7 @@ import java.util.List; import java.util.Set; import java.util.UUID; -import static net.knarcraft.minigames.util.TabCompleteHelper.filterMatchingContains; +import static net.knarcraft.knarlib.util.TabCompletionHelper.filterMatchingContains; /** * The command for listing groups and the stages within diff --git a/src/main/java/net/knarcraft/minigames/command/parkour/ParkourGroupSetCommand.java b/src/main/java/net/knarcraft/minigames/command/parkour/ParkourGroupSetCommand.java index e97081e..81dc3ae 100644 --- a/src/main/java/net/knarcraft/minigames/command/parkour/ParkourGroupSetCommand.java +++ b/src/main/java/net/knarcraft/minigames/command/parkour/ParkourGroupSetCommand.java @@ -17,7 +17,7 @@ import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; -import static net.knarcraft.minigames.util.TabCompleteHelper.filterMatchingContains; +import static net.knarcraft.knarlib.util.TabCompletionHelper.filterMatchingContains; /** * The command for setting the group of an arena diff --git a/src/main/java/net/knarcraft/minigames/command/parkour/ParkourGroupSwapCommand.java b/src/main/java/net/knarcraft/minigames/command/parkour/ParkourGroupSwapCommand.java index f272017..83bd74d 100644 --- a/src/main/java/net/knarcraft/minigames/command/parkour/ParkourGroupSwapCommand.java +++ b/src/main/java/net/knarcraft/minigames/command/parkour/ParkourGroupSwapCommand.java @@ -16,7 +16,7 @@ import java.util.ArrayList; import java.util.List; import java.util.UUID; -import static net.knarcraft.minigames.util.TabCompleteHelper.filterMatchingContains; +import static net.knarcraft.knarlib.util.TabCompletionHelper.filterMatchingContains; /** * The command for swapping the order of two arenas in a group diff --git a/src/main/java/net/knarcraft/minigames/command/parkour/RemoveParkourArenaTabCompleter.java b/src/main/java/net/knarcraft/minigames/command/parkour/RemoveParkourArenaTabCompleter.java index 87c0787..88b4530 100644 --- a/src/main/java/net/knarcraft/minigames/command/parkour/RemoveParkourArenaTabCompleter.java +++ b/src/main/java/net/knarcraft/minigames/command/parkour/RemoveParkourArenaTabCompleter.java @@ -10,7 +10,7 @@ import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; -import static net.knarcraft.minigames.util.TabCompleteHelper.filterMatchingContains; +import static net.knarcraft.knarlib.util.TabCompletionHelper.filterMatchingContains; /** * The tab-completer for the remove arena command diff --git a/src/main/java/net/knarcraft/minigames/util/TabCompleteHelper.java b/src/main/java/net/knarcraft/minigames/util/TabCompleteHelper.java index fee509a..8153c6e 100644 --- a/src/main/java/net/knarcraft/minigames/util/TabCompleteHelper.java +++ b/src/main/java/net/knarcraft/minigames/util/TabCompleteHelper.java @@ -1,18 +1,22 @@ package net.knarcraft.minigames.util; +import net.knarcraft.knarlib.util.TabCompletionHelper; import net.knarcraft.minigames.MiniGames; import net.knarcraft.minigames.arena.Arena; import net.knarcraft.minigames.arena.ArenaHandler; import net.knarcraft.minigames.arena.EditablePropertyType; import net.knarcraft.minigames.arena.dropper.DropperArenaEditableProperty; import net.knarcraft.minigames.arena.parkour.ParkourArenaEditableProperty; +import org.bukkit.Bukkit; import org.bukkit.Material; +import org.bukkit.permissions.Permission; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.StringJoiner; /** * A helper-class for common tab-completions @@ -20,6 +24,8 @@ import java.util.Map; public final class TabCompleteHelper { private static Map> tabCompleteSuggestions; + private static List plugins; + private static Map> permissions; private TabCompleteHelper() { @@ -82,23 +88,6 @@ public final class TabCompleteHelper { return arenaProperties; } - /** - * Finds tab complete values that contain the typed text - * - * @param values

The values to filter

- * @param typedText

The text the player has started typing

- * @return

The given string values that contain the player's typed text

- */ - public static List filterMatchingContains(@NotNull List values, @NotNull String typedText) { - List configValues = new ArrayList<>(); - for (String value : values) { - if (value.toLowerCase().contains(typedText.toLowerCase())) { - configValues.add(value); - } - } - return configValues; - } - /** * Gets tab-complete suggestions for the given property type * @@ -215,4 +204,65 @@ public final class TabCompleteHelper { return locations; } + /** + * Gets the tab complete value for the permission typed + * + * @param typedNode

The full permission node typed by the player

+ * @return

All known valid auto-complete options

+ */ + public static List tabCompletePermission(String typedNode) { + if (plugins == null) { + loadAvailablePermissions(); + } + List output; + if (typedNode.contains(".")) { + List matchingPermissions = permissions.get(typedNode.substring(0, typedNode.lastIndexOf("."))); + if (matchingPermissions == null) { + output = new ArrayList<>(); + } else { + //Filter by the typed text + output = TabCompletionHelper.filterMatchingStartsWith(matchingPermissions, typedNode); + } + } else { + output = plugins; + } + + //Add previous permissions in the comma-separated lists as a prefix + return output; + } + + /** + * Loads all permissions available from bukkit plugins + */ + private static void loadAvailablePermissions() { + plugins = new ArrayList<>(); + permissions = new HashMap<>(); + + for (Permission permission : Bukkit.getPluginManager().getPermissions()) { + loadPermission(permission.getName()); + } + } + + /** + * Loads a given permission into the proper lists and maps + * + * @param permissionName

The permission to load

+ */ + private static void loadPermission(String permissionName) { + String[] permissionParts = permissionName.split("\\."); + if (permissionParts.length == 1 && !plugins.contains(permissionParts[0])) { + plugins.add(permissionParts[0]); + } else if (permissionParts.length > 1) { + StringJoiner pathJoiner = new StringJoiner("."); + for (int j = 0; j < permissionParts.length - 1; j++) { + pathJoiner.add(permissionParts[j]); + } + String path = pathJoiner.toString(); + List permissionList = permissions.computeIfAbsent(path, k -> new ArrayList<>()); + permissionList.add(permissionName); + + loadPermission(path); + } + } + }