diff --git a/src/main/java/net/knarcraft/paidsigns/command/AddCommand.java b/src/main/java/net/knarcraft/paidsigns/command/AddCommand.java index f367e74..bc5da9d 100644 --- a/src/main/java/net/knarcraft/paidsigns/command/AddCommand.java +++ b/src/main/java/net/knarcraft/paidsigns/command/AddCommand.java @@ -30,7 +30,7 @@ public class AddCommand implements CommandExecutor { PaidSignManager manager = PaidSigns.getInstance().getSignManager(); List arguments = Tokenizer.tokenize(String.join(" ", args)); - String id = arguments.get(0); + String signName = arguments.get(0); double cost; try { cost = Double.parseDouble(arguments.get(2)); @@ -49,7 +49,7 @@ public class AddCommand implements CommandExecutor { } try { - PaidSign sign = new PaidSign(id, cost, permission, ignoreCase, ignoreColor); + PaidSign sign = new PaidSign(signName, cost, permission, ignoreCase, ignoreColor); /* TODO: Rewrite the method for comparing if paid signs are duplicated for (PaidSign similarSign : manager.getPaidSigns(sign.getCleanId(), sign.getLineIndex())) { if (sign.matches(similarSign)) { diff --git a/src/main/java/net/knarcraft/paidsigns/command/AddTabCompleter.java b/src/main/java/net/knarcraft/paidsigns/command/AddTabCompleter.java index bde8835..4e923b3 100644 --- a/src/main/java/net/knarcraft/paidsigns/command/AddTabCompleter.java +++ b/src/main/java/net/knarcraft/paidsigns/command/AddTabCompleter.java @@ -1,60 +1,136 @@ package net.knarcraft.paidsigns.command; import net.knarcraft.paidsigns.utility.Tokenizer; +import org.bukkit.Bukkit; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.command.TabCompleter; +import org.bukkit.permissions.Permission; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.StringJoiner; /** * The tab completer for the add paid sign command */ public class AddTabCompleter implements TabCompleter { - private static List ids; - private static List lines; + private static List names; private static List costs; + private static List plugins; + private static Map> permissions; private static List options; @Nullable @Override public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) { - if (ids == null) { + if (names == null) { initializeValues(); + loadAvailablePermissions(); } List arguments = Tokenizer.tokenize(String.join(" ", args)); if (arguments.size() < 1) { - return ids; + return names; } else if (arguments.size() < 2) { - return lines; - } else if (arguments.size() < 3) { return costs; + } else if (arguments.size() < 3) { + return tabCompletePermission(arguments.get(arguments.size() - 1)); } else if (arguments.size() < 5) { return options; } return new ArrayList<>(); } + /** + * 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

+ */ + private List tabCompletePermission(String typedNode) { + 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 = filterMatching(matchingPermissions, typedNode); + } + } else { + output = plugins; + } + + //Add previous permissions in the comma-separated lists as a prefix + return output; + } + + /** + * Find completable strings which match the text typed by the command's sender + * + * @param values

The values to filter

+ * @param typedText

The text the player has started typing

+ * @return

The given string values which start with the player's typed text

+ */ + private List filterMatching(List values, String typedText) { + List configValues = new ArrayList<>(); + for (String value : values) { + if (value.toLowerCase().startsWith(typedText.toLowerCase())) { + configValues.add(value); + } + } + return configValues; + } + + /** + * 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); + } + } + /** * Initializes the values available for tab completion */ private static void initializeValues() { - ids = new ArrayList<>(); - ids.add("[Gate]"); - ids.add("\"[Lift Up]\""); - ids.add("\"[Lift Down]\""); - - lines = new ArrayList<>(); - lines.add("1"); - lines.add("2"); - lines.add("3"); - lines.add("4"); + names = new ArrayList<>(); + names.add("sign1"); + names.add("\"lift up sign\""); + names.add("\"lift down sign\""); costs = new ArrayList<>(); costs.add("1"); diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 2006b56..de4fdaf 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -10,7 +10,11 @@ website: https://git.knarcraft.net commands: addpaidsign: description: Used to add a new paid sign - usage: / [ignore case] [ignore color] + usage: / [permission] [ignore case] [ignore color] + permission: paidsigns.add + addpaidsigncondition: + description: Used to add a new match condition for a paid sign + usage: / [executeRegEx] [ignoreCase] [ignoreColor] permission: paidsigns.add removepaidsign: description: Used to remove a paid sign