Performs some necessary work required for the edit command

Adds an implementation for the edit tab completer
Adds an enum representing a paid sign property
Adds an enum representing a paid sign condition property
Adds aliases to all commands
This commit is contained in:
Kristian Knarvik 2022-03-14 16:20:42 +01:00
parent 3b5218cb98
commit 9c6921b4cd
8 changed files with 415 additions and 87 deletions

View File

@ -25,8 +25,8 @@
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version> <version>3.8.1</version>
<configuration> <configuration>
<source>17</source> <source>${java.version}</source>
<target>17</target> <target>${java.version}</target>
</configuration> </configuration>
</plugin> </plugin>
<plugin> <plugin>
@ -85,7 +85,7 @@
<dependency> <dependency>
<groupId>org.jetbrains</groupId> <groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId> <artifactId>annotations</artifactId>
<version>22.0.0</version> <version>23.0.0</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -1,18 +1,13 @@
package net.knarcraft.paidsigns.command; package net.knarcraft.paidsigns.command;
import net.knarcraft.paidsigns.utility.TabCompleteHelper; import net.knarcraft.paidsigns.utility.TabCompleteHelper;
import org.bukkit.Bukkit;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.permissions.Permission;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.StringJoiner;
/** /**
* The tab completer for the add paid sign command * The tab completer for the add paid sign command
@ -21,8 +16,6 @@ public class AddTabCompleter extends TokenizedTabCompleter {
private static List<String> names; private static List<String> names;
private static List<String> costs; private static List<String> costs;
private static List<String> plugins;
private static Map<String, List<String>> permissions;
private static List<String> options; private static List<String> options;
private static List<String> booleans; private static List<String> booleans;
@ -33,7 +26,6 @@ public class AddTabCompleter extends TokenizedTabCompleter {
super.onTabComplete(sender, command, alias, args); super.onTabComplete(sender, command, alias, args);
if (names == null) { if (names == null) {
initializeValues(); initializeValues();
loadAvailablePermissions();
} }
if (argumentSize == 1) { if (argumentSize == 1) {
@ -41,7 +33,7 @@ public class AddTabCompleter extends TokenizedTabCompleter {
} else if (argumentSize == 2) { } else if (argumentSize == 2) {
return TabCompleteHelper.filterMatchingStartsWith(costs, arguments.get(1)); return TabCompleteHelper.filterMatchingStartsWith(costs, arguments.get(1));
} else if (argumentSize == 3) { } else if (argumentSize == 3) {
return tabCompletePermission(arguments.get(arguments.size() - 1)); return TabCompleteHelper.tabCompletePermission(arguments.get(arguments.size() - 1));
} else if (argumentSize == 4) { } else if (argumentSize == 4) {
return TabCompleteHelper.filterMatchingStartsWith(options, arguments.get(3)); return TabCompleteHelper.filterMatchingStartsWith(options, arguments.get(3));
} else if (argumentSize == 5) { } else if (argumentSize == 5) {
@ -52,81 +44,6 @@ public class AddTabCompleter extends TokenizedTabCompleter {
return new ArrayList<>(); return new ArrayList<>();
} }
/**
* Gets the tab complete value for the permission typed
*
* @param typedNode <p>The full permission node typed by the player</p>
* @return <p>All known valid auto-complete options</p>
*/
private List<String> tabCompletePermission(String typedNode) {
List<String> output;
if (typedNode.contains(".")) {
List<String> 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 <p>The values to filter</p>
* @param typedText <p>The text the player has started typing</p>
* @return <p>The given string values which start with the player's typed text</p>
*/
private List<String> filterMatching(List<String> values, String typedText) {
List<String> 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 <p>The permission to load</p>
*/
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<String> permissionList = permissions.computeIfAbsent(path, k -> new ArrayList<>());
permissionList.add(permissionName);
loadPermission(path);
}
}
/** /**
* Initializes the values available for tab completion * Initializes the values available for tab completion
*/ */

View File

@ -0,0 +1,16 @@
package net.knarcraft.paidsigns.command;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
public class EditCommand extends TokenizedCommand {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label,
@NotNull String[] args) {
return false;
}
}

View File

@ -0,0 +1,172 @@
package net.knarcraft.paidsigns.command;
import net.knarcraft.paidsigns.PaidSigns;
import net.knarcraft.paidsigns.container.PaidSign;
import net.knarcraft.paidsigns.property.PaidSignConditionProperty;
import net.knarcraft.paidsigns.property.PaidSignProperty;
import net.knarcraft.paidsigns.utility.TabCompleteHelper;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
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;
public class EditTabCompleter extends TokenizedTabCompleter {
private static Map<PaidSignProperty, List<String>> propertyExampleValues;
private static Map<PaidSignConditionProperty, List<String>> conditionPropertyExampleValues;
@Nullable
@Override
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label,
@NotNull String[] args) {
if (propertyExampleValues == null) {
initializePropertyExampleValues();
initializeConditionPropertyExampleValues();
}
if (argumentSize == 1) {
return TabCompleteHelper.filterMatchingStartsWith(TabCompleteHelper.getPaidSignNames(), arguments.get(0));
} else if (argumentSize >= 2) {
PaidSign sign = PaidSigns.getInstance().getSignManager().getPaidSign(arguments.get(0));
if (sign != null) {
return tabCompleteForSign(sign);
}
}
return new ArrayList<>();
}
/**
* Returns tab completions for the given, non-null sign
*
* @param sign <p>The sign to tab complete for</p>
* @return <p>The tab complete options to give to users</p>
*/
private List<String> tabCompleteForSign(@NotNull PaidSign sign) {
if (argumentSize == 2) {
List<String> conditions = getAvailableSignConditions(sign);
conditions.addAll(getPaidSignProperties());
return TabCompleteHelper.filterMatchingStartsWith(conditions, arguments.get(1));
} else if (argumentSize >= 3) {
try {
return tabCompleteSignLine(sign);
} catch (NumberFormatException exception) {
if (argumentSize == 3) {
return tabCompleteProperty();
}
}
}
return new ArrayList<>();
}
/**
* Returns tab completions for the selected sign line
*
* @param sign <p>The paid sign the line belongs to</p>
* @return <p>The tab complete options to give to users</p>
*/
private List<String> tabCompleteSignLine(@NotNull PaidSign sign) {
short signLine = Short.parseShort(arguments.get(2));
//Refuse to autocomplete if invalid input is given
if (signLine < 0 || signLine > 3 || sign.getConditions().get(signLine) == null) {
return new ArrayList<>();
} else if (argumentSize == 3) {
return TabCompleteHelper.filterMatchingStartsWith(getPaidSignConditionProperties(), arguments.get(2));
} else if (argumentSize == 4) {
PaidSignConditionProperty property = PaidSignConditionProperty.getFromString(arguments.get(2));
if (property != null) {
return TabCompleteHelper.filterMatchingStartsWith(conditionPropertyExampleValues.get(property),
arguments.get(3));
}
}
return new ArrayList<>();
}
/**
* Returns tab completions for the selected property
*
* @return <p>The tab complete options to give to users</p>
*/
private List<String> tabCompleteProperty() {
PaidSignProperty paidSignProperty = PaidSignProperty.getFromString(arguments.get(1));
if (paidSignProperty != null) {
if (paidSignProperty == PaidSignProperty.PERMISSION) {
return TabCompleteHelper.tabCompletePermission(arguments.get(2));
} else {
return TabCompleteHelper.filterMatchingStartsWith(propertyExampleValues.get(paidSignProperty),
arguments.get(2));
}
} else {
return new ArrayList<>();
}
}
/**
* Gets all paid sign condition properties
*
* @return <p>All paid sign condition properties</p>
*/
private List<String> getPaidSignConditionProperties() {
List<String> properties = new ArrayList<>();
for (PaidSignConditionProperty property : PaidSignConditionProperty.values()) {
properties.add(property.getStringRepresentation());
}
return properties;
}
/**
* Gets all paid sign properties
*
* @return <p>All paid sign properties</p>
*/
private List<String> getPaidSignProperties() {
List<String> properties = new ArrayList<>();
for (PaidSignProperty property : PaidSignProperty.values()) {
properties.add(property.getStringRepresentation());
}
return properties;
}
/**
* Gets all sign conditions available for the given sign
*
* @param sign <p>The sign to get available sign conditions for</p>
* @return <p>The available sign conditions</p>
*/
private List<String> getAvailableSignConditions(PaidSign sign) {
List<String> availableConditions = new ArrayList<>();
for (Short signLine : sign.getConditions().keySet()) {
availableConditions.add(String.valueOf(signLine + 1));
}
return availableConditions;
}
/**
* Initializes the map for paid sign property example tab completions
*/
private void initializePropertyExampleValues() {
propertyExampleValues = new HashMap<>();
propertyExampleValues.put(PaidSignProperty.COST, TabCompleteHelper.getCosts());
propertyExampleValues.put(PaidSignProperty.NAME, TabCompleteHelper.getPaidSignNames());
propertyExampleValues.put(PaidSignProperty.IGNORE_CASE, TabCompleteHelper.getOptionStates());
propertyExampleValues.put(PaidSignProperty.IGNORE_COLOR, TabCompleteHelper.getOptionStates());
propertyExampleValues.put(PaidSignProperty.MATCH_ANY_CONDITION, TabCompleteHelper.getBooleans());
}
/**
* Initializes the map for paid sign condition property example tab completions
*/
private void initializeConditionPropertyExampleValues() {
conditionPropertyExampleValues = new HashMap<>();
conditionPropertyExampleValues.put(PaidSignConditionProperty.STRING_TO_MATCH,
TabCompleteHelper.getExampleConditionStrings());
conditionPropertyExampleValues.put(PaidSignConditionProperty.IGNORE_COLOR, TabCompleteHelper.getOptionStates());
conditionPropertyExampleValues.put(PaidSignConditionProperty.IGNORE_CASE, TabCompleteHelper.getOptionStates());
conditionPropertyExampleValues.put(PaidSignConditionProperty.EXECUTE_REG_EX, TabCompleteHelper.getBooleans());
}
}

View File

@ -0,0 +1,63 @@
package net.knarcraft.paidsigns.property;
/**
* A representation of a paid sign condition's editable properties
*/
public enum PaidSignConditionProperty {
/**
* The string used to trigger the paid sign condition
*/
STRING_TO_MATCH("stringToMatch"),
/**
* Whether to execute the match string as a regular expression
*/
EXECUTE_REG_EX("executeRegEx"),
/**
* Whether to ignore case for the sign condition
*/
IGNORE_CASE("ignoreCase"),
/**
* Whether to ignore color for the sign condition
*/
IGNORE_COLOR("ignoreColor");
private final String stringRepresentation;
/**
* Instantiates a new paid sign condition property
*
* @param stringRepresentation <p>The string representation of the paid sign condition property</p>
*/
PaidSignConditionProperty(String stringRepresentation) {
this.stringRepresentation = stringRepresentation;
}
/**
* Gets the string representation of this paid sign condition property
*
* @return <p>The string representation of this paid sign condition property</p>
*/
public String getStringRepresentation() {
return this.stringRepresentation;
}
/**
* Gets the paid sign property matching the given string
*
* @param propertyString <p>The string representing a paid sign condition property</p>
* @return <p>The matching paid sign condition property, or null if no such property exists</p>
*/
public static PaidSignConditionProperty getFromString(String propertyString) {
for (PaidSignConditionProperty paidSignProperty : PaidSignConditionProperty.values()) {
if (paidSignProperty.getStringRepresentation().equalsIgnoreCase(propertyString)) {
return paidSignProperty;
}
}
return null;
}
}

View File

@ -0,0 +1,73 @@
package net.knarcraft.paidsigns.property;
/**
* A representation of a paid sign's editable properties
*/
public enum PaidSignProperty {
/**
* The name of a paid sign
*/
NAME("name"),
/**
* The cost of creating a sign matching the paid sign
*/
COST("cost"),
/**
* The permission required to create the plugin sign matching the paid sign
*/
PERMISSION("permission"),
/**
* Whether to ignore case for any sign conditions added to the sign
*/
IGNORE_CASE("ignoreCase"),
/**
* Whether to ignore color for any sign conditions added to the sign
*/
IGNORE_COLOR("ignoreColor"),
/**
* Whether to treat a single condition match as a full match
*/
MATCH_ANY_CONDITION("matchAnyCondition");
private final String stringRepresentation;
/**
* Instantiates a new paid sign property
*
* @param stringRepresentation <p>The string representation of the paid sign property</p>
*/
PaidSignProperty(String stringRepresentation) {
this.stringRepresentation = stringRepresentation;
}
/**
* Gets the string representation of this paid sign property
*
* @return <p>The string representation of this paid sign property</p>
*/
public String getStringRepresentation() {
return this.stringRepresentation;
}
/**
* Gets the paid sign property matching the given string
*
* @param propertyString <p>The string representing a paid sign property</p>
* @return <p>The matching paid sign property, or null if no such property exists</p>
*/
public static PaidSignProperty getFromString(String propertyString) {
for (PaidSignProperty paidSignProperty : PaidSignProperty.values()) {
if (paidSignProperty.getStringRepresentation().equalsIgnoreCase(propertyString)) {
return paidSignProperty;
}
}
return null;
}
}

View File

@ -1,16 +1,24 @@
package net.knarcraft.paidsigns.utility; package net.knarcraft.paidsigns.utility;
import net.knarcraft.paidsigns.PaidSigns; import net.knarcraft.paidsigns.PaidSigns;
import org.bukkit.Bukkit;
import org.bukkit.permissions.Permission;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.StringJoiner;
/** /**
* A helper class for providing common tab complete options * A helper class for providing common tab complete options
*/ */
public final class TabCompleteHelper { public final class TabCompleteHelper {
private static List<String> plugins;
private static Map<String, List<String>> permissions;
private TabCompleteHelper() { private TabCompleteHelper() {
} }
@ -122,4 +130,65 @@ public final class TabCompleteHelper {
return conditionStrings; return conditionStrings;
} }
/**
* Gets the tab complete value for the permission typed
*
* @param typedNode <p>The full permission node typed by the player</p>
* @return <p>All known valid auto-complete options</p>
*/
public static List<String> tabCompletePermission(String typedNode) {
if (plugins == null) {
loadAvailablePermissions();
}
List<String> output;
if (typedNode.contains(".")) {
List<String> matchingPermissions = permissions.get(typedNode.substring(0, typedNode.lastIndexOf(".")));
if (matchingPermissions == null) {
output = new ArrayList<>();
} else {
//Filter by the typed text
output = TabCompleteHelper.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 <p>The permission to load</p>
*/
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<String> permissionList = permissions.computeIfAbsent(path, k -> new ArrayList<>());
permissionList.add(permissionName);
loadPermission(path);
}
}
} }

View File

@ -9,26 +9,44 @@ description: Add costs for creating plugin signs
website: https://git.knarcraft.net/EpicKnarvik97/PaidSigns website: https://git.knarcraft.net/EpicKnarvik97/PaidSigns
commands: commands:
addpaidsign: addpaidsign:
aliases:
- aps
description: Used to add a new paid sign description: Used to add a new paid sign
usage: /<command> <name> <cost> [permission] [ignore case] [ignore color] [match any condition] usage: /<command> <name> <cost> [permission] [ignore case] [ignore color] [match any condition]
permission: paidsigns.manage permission: paidsigns.manage
addpaidsigncondition: addpaidsigncondition:
aliases:
- apsc
description: Used to add a new match condition for a paid sign description: Used to add a new match condition for a paid sign
usage: /<command> <name (of a paid sign)> <line number> <string to match> [executeRegEx] [ignoreCase] [ignoreColor] usage: /<command> <name (of a paid sign)> <line number> <string to match> [executeRegEx] [ignoreCase] [ignoreColor]
permission: paidsigns.manage permission: paidsigns.manage
listpaidsigns: listpaidsigns:
aliases:
- lps
description: Lists all previously added paid signs description: Lists all previously added paid signs
usage: /<command> [sign name] [line number] usage: /<command> [sign name] [line number]
permission: paidsigns.manage permission: paidsigns.manage
editpaidsign:
aliases:
- eps
description: Edits a property of a paid sign or a paid sign condition
usage: /<ommand> <sign name> <property>/<line number> [new value]/<property> [new value]
permission: paidsigns.manage
removepaidsigncondition: removepaidsigncondition:
aliases:
- rpsc
description: Used to remove a match condition from a paid sign description: Used to remove a match condition from a paid sign
usage: /<command> <name (of a paid sign)> <line number> usage: /<command> <name (of a paid sign)> <line number>
permission: paidsigns.manage permission: paidsigns.manage
removepaidsign: removepaidsign:
aliases:
- rps
description: Used to remove a paid sign description: Used to remove a paid sign
usage: /<command> <name (of a paid sign)> usage: /<command> <name (of a paid sign)>
permission: paidsigns.manage permission: paidsigns.manage
reload: reload:
aliases:
- r
description: Reloads paid signs from disk description: Reloads paid signs from disk
usage: /<command> usage: /<command>
permision: paidsigns.reload permision: paidsigns.reload