Adds various improvements, fixes and a new feature
Adds and option to match any paid sign condition instead of all conditions Adds checks for whether line indices are outside the allowed range Disallows any invalid regular expressions in sign conditions
This commit is contained in:
parent
664115b2b4
commit
9bb234169d
@ -13,7 +13,7 @@ As this plugin only listens to sign change events, there are some limitations:
|
||||
|
||||
## Commands
|
||||
|
||||
* /addpaidsign <name> <cost> \[permission] \[ignore case] \[ignore color]
|
||||
* /addpaidsign <name> <cost> \[permission] \[ignore case] \[ignore color] \[match any condition]
|
||||
* /addpaidsigncondition <name (of a paid sign)> <line number> <string to match> \[executeRegEx] \[ignoreCase]
|
||||
\[ignoreColor]
|
||||
* /listpaidsigns \[name (of a paid sign)] \[line number]
|
||||
@ -35,6 +35,8 @@ This command adds a new paid sign that does nothing until a condition is added.
|
||||
default uses the config file value).
|
||||
* ignore color - Whether any condition of the paid sign should ignore color by default, when matching against text (
|
||||
default uses the config file value).
|
||||
* match any condition - Whether to trigger a paid sign match if a single one of the sign's conditions is true. This is
|
||||
mainly useful if several lines may contain the match string, or if trying to match a word.
|
||||
|
||||
### /addpaidsigncondition
|
||||
|
||||
@ -79,6 +81,7 @@ Removes a registered paid sign
|
||||
|
||||
## Configuration options
|
||||
|
||||
* language - The language to use for all messages displayed to players
|
||||
* ignoreCase - Whether to ignore the case (lowercase/uppercase) of the paid sign text. The option can be set on a
|
||||
per-sign basis, but this value is used if not specified. The correct value depends on whether the plugin signs it
|
||||
should match are case-sensitive or not.
|
||||
|
@ -45,26 +45,31 @@ public class AddCommand extends TokenizedCommand {
|
||||
if (argumentSize > 4) {
|
||||
ignoreColor = OptionState.fromString(arguments.get(4));
|
||||
}
|
||||
boolean matchAnyCondition = false;
|
||||
if (argumentSize > 5) {
|
||||
matchAnyCondition = Boolean.parseBoolean(arguments.get(5));
|
||||
}
|
||||
|
||||
return createPaidSign(sender, signName, cost, permission, ignoreCase, ignoreColor);
|
||||
return createPaidSign(sender, signName, cost, permission, ignoreCase, ignoreColor, matchAnyCondition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new paid sign with the given user input
|
||||
*
|
||||
* @param sender <p>The command sender that called the add command</p>
|
||||
* @param signName <p>The name of the new paid sign</p>
|
||||
* @param cost <p>The cost of the new paid sign</p>
|
||||
* @param permission <p>The permission required for creating the sign represented by the paid sign</p>
|
||||
* @param ignoreCase <p>Whether to ignore case for the paid sign's conditions</p>
|
||||
* @param ignoreColor <p>Whether to ignore color for the paid sign's conditions</p>
|
||||
* @param sender <p>The command sender that called the add command</p>
|
||||
* @param signName <p>The name of the new paid sign</p>
|
||||
* @param cost <p>The cost of the new paid sign</p>
|
||||
* @param permission <p>The permission required for creating the sign represented by the paid sign</p>
|
||||
* @param ignoreCase <p>Whether to ignore case for the paid sign's conditions</p>
|
||||
* @param ignoreColor <p>Whether to ignore color for the paid sign's conditions</p>
|
||||
* @param matchAnyCondition <p>Whether to treat any matching condition as a sign match</p>
|
||||
* @return <p>True if the paid sign was successfully created and registered</p>
|
||||
*/
|
||||
private boolean createPaidSign(CommandSender sender, String signName, double cost, String permission,
|
||||
OptionState ignoreCase, OptionState ignoreColor) {
|
||||
OptionState ignoreCase, OptionState ignoreColor, boolean matchAnyCondition) {
|
||||
PaidSignManager manager = PaidSigns.getInstance().getSignManager();
|
||||
try {
|
||||
PaidSign sign = new PaidSign(signName, cost, permission, ignoreCase, ignoreColor);
|
||||
PaidSign sign = new PaidSign(signName, cost, permission, ignoreCase, ignoreColor, matchAnyCondition);
|
||||
if (manager.getPaidSign(signName) != null) {
|
||||
sender.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.ERROR_NAME_DUPLICATE));
|
||||
return false;
|
||||
|
@ -11,6 +11,8 @@ import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
|
||||
/**
|
||||
* A representation of the command for adding a new match condition for a sign
|
||||
@ -29,6 +31,10 @@ public class AddConditionCommand extends TokenizedCommand {
|
||||
short lineNumber;
|
||||
try {
|
||||
lineNumber = (short) (Short.parseShort(arguments.get(1)) - 1);
|
||||
if (lineNumber < 0 || lineNumber > 3) {
|
||||
sender.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.ERROR_INVALID_NUMBER));
|
||||
return false;
|
||||
}
|
||||
} catch (NumberFormatException exception) {
|
||||
sender.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.ERROR_INVALID_NUMBER));
|
||||
return false;
|
||||
@ -37,6 +43,9 @@ public class AddConditionCommand extends TokenizedCommand {
|
||||
boolean executeRegEx = false;
|
||||
if (argumentSize > 3) {
|
||||
executeRegEx = Boolean.parseBoolean(arguments.get(3));
|
||||
if (executeRegEx && !testRegEx(sender, stringToMatch)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
OptionState ignoreCase = OptionState.DEFAULT;
|
||||
if (argumentSize > 4) {
|
||||
@ -49,6 +58,24 @@ public class AddConditionCommand extends TokenizedCommand {
|
||||
return addCondition(name, lineNumber, stringToMatch, executeRegEx, ignoreCase, ignoreColor, sender);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether the given regular expression is valid
|
||||
*
|
||||
* @param sender <p>The command sender to notify if the regular expression is invalid</p>
|
||||
* @param regularExpression <p>The regular expression to test</p>
|
||||
* @return <p>True if the regular expression is valid</p>
|
||||
*/
|
||||
private boolean testRegEx(CommandSender sender, String regularExpression) {
|
||||
try {
|
||||
Pattern.compile(regularExpression);
|
||||
return true;
|
||||
} catch (PatternSyntaxException exception) {
|
||||
sender.sendMessage(StringFormatter.getTranslatedErrorMessage(
|
||||
TranslatableMessage.ERROR_INVALID_REGULAR_EXPRESSION));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the given input to add a paid sign condition
|
||||
*
|
||||
|
@ -24,6 +24,7 @@ public class AddTabCompleter extends TokenizedTabCompleter {
|
||||
private static List<String> plugins;
|
||||
private static Map<String, List<String>> permissions;
|
||||
private static List<String> options;
|
||||
private static List<String> booleans;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
@ -45,6 +46,8 @@ public class AddTabCompleter extends TokenizedTabCompleter {
|
||||
return TabCompleteHelper.filterMatchingStartsWith(options, arguments.get(3));
|
||||
} else if (argumentSize == 5) {
|
||||
return TabCompleteHelper.filterMatchingStartsWith(options, arguments.get(4));
|
||||
} else if (argumentSize == 6) {
|
||||
return TabCompleteHelper.filterMatchingStartsWith(booleans, arguments.get(5));
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
@ -131,6 +134,7 @@ public class AddTabCompleter extends TokenizedTabCompleter {
|
||||
names = TabCompleteHelper.getExamplePaidSignNames();
|
||||
costs = TabCompleteHelper.getCosts();
|
||||
options = TabCompleteHelper.getOptionStates();
|
||||
booleans = TabCompleteHelper.getBooleans();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -65,20 +65,24 @@ public class ListCommand extends TokenizedCommand {
|
||||
if (argumentSize < 2) {
|
||||
displayPaidSign(sender, paidSign);
|
||||
} else {
|
||||
short signLine;
|
||||
short lineNumber;
|
||||
try {
|
||||
signLine = (short) (Short.parseShort(arguments.get(1)) - 1);
|
||||
lineNumber = (short) (Short.parseShort(arguments.get(1)) - 1);
|
||||
if (lineNumber < 0 || lineNumber > 3) {
|
||||
sender.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.ERROR_INVALID_NUMBER));
|
||||
return false;
|
||||
}
|
||||
} catch (NumberFormatException exception) {
|
||||
sender.sendMessage(getTranslatedErrorMessage(TranslatableMessage.ERROR_INVALID_NUMBER));
|
||||
return false;
|
||||
}
|
||||
if (!paidSign.getConditions().containsKey(signLine)) {
|
||||
if (!paidSign.getConditions().containsKey(lineNumber)) {
|
||||
sender.sendMessage(replacePlaceholder(getTranslatedErrorMessage(
|
||||
TranslatableMessage.ERROR_NO_SUCH_CONDITION), "{line}", String.valueOf(signLine)));
|
||||
TranslatableMessage.ERROR_NO_SUCH_CONDITION), "{line}", String.valueOf(lineNumber)));
|
||||
return false;
|
||||
}
|
||||
PaidSignCondition condition = paidSign.getConditions().get(signLine);
|
||||
displayPaidSignCondition(sender, paidSign.getName(), signLine, condition);
|
||||
PaidSignCondition condition = paidSign.getConditions().get(lineNumber);
|
||||
displayPaidSignCondition(sender, paidSign.getName(), lineNumber, condition);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -117,9 +121,10 @@ public class ListCommand extends TokenizedCommand {
|
||||
|
||||
sender.sendMessage(replacePlaceholders(Translator.getTranslatedMessage(
|
||||
TranslatableMessage.PAID_SIGN_INFO), new String[]{"{name}", "{cost}", "{permission}", "{case}",
|
||||
"{color}", "{conditions}"}, new String[]{paidSign.getName(), String.valueOf(paidSign.getCost()),
|
||||
"{color}", "{any}", "{conditions}"}, new String[]{paidSign.getName(), String.valueOf(paidSign.getCost()),
|
||||
paidSign.getPermission(), translateBoolean(paidSign.getIgnoreCase()),
|
||||
translateBoolean(paidSign.getIgnoreColor()), conditions.toString()}));
|
||||
translateBoolean(paidSign.getIgnoreColor()), translateBoolean(paidSign.matchAnyCondition()),
|
||||
conditions.toString()}));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -24,9 +24,13 @@ public class RemoveConditionCommand extends TokenizedCommand {
|
||||
}
|
||||
|
||||
String name = arguments.get(0);
|
||||
short line;
|
||||
short lineNumber;
|
||||
try {
|
||||
line = (short) (Short.parseShort(arguments.get(1)) - 1);
|
||||
lineNumber = (short) (Short.parseShort(arguments.get(1)) - 1);
|
||||
if (lineNumber < 0 || lineNumber > 3) {
|
||||
sender.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.ERROR_INVALID_NUMBER));
|
||||
return false;
|
||||
}
|
||||
} catch (NumberFormatException exception) {
|
||||
sender.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.ERROR_INVALID_NUMBER));
|
||||
return false;
|
||||
@ -38,13 +42,13 @@ public class RemoveConditionCommand extends TokenizedCommand {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!sign.getConditions().containsKey(line)) {
|
||||
if (!sign.getConditions().containsKey(lineNumber)) {
|
||||
sender.sendMessage(StringFormatter.replacePlaceholder(StringFormatter.getTranslatedErrorMessage(
|
||||
TranslatableMessage.ERROR_NO_SUCH_CONDITION), "{line}", String.valueOf((line + 1))));
|
||||
TranslatableMessage.ERROR_NO_SUCH_CONDITION), "{line}", String.valueOf((lineNumber + 1))));
|
||||
return false;
|
||||
}
|
||||
|
||||
sign.removeCondition(line);
|
||||
sign.removeCondition(lineNumber);
|
||||
try {
|
||||
signManager.saveSigns();
|
||||
} catch (IOException e) {
|
||||
|
@ -5,8 +5,6 @@ import net.knarcraft.paidsigns.property.OptionState;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
|
||||
/**
|
||||
* A representation of a paid sign
|
||||
@ -18,18 +16,21 @@ public class PaidSign {
|
||||
private final String permission;
|
||||
private final OptionState ignoreCase;
|
||||
private final OptionState ignoreColor;
|
||||
private final boolean matchAnyCondition;
|
||||
private final Map<Short, PaidSignCondition> conditions = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Instantiates a new paid sign
|
||||
*
|
||||
* @param name <p>A recognizable, unique, name used to identify this paid sign</p>
|
||||
* @param cost <p>The cost of creating this paid sign</p>
|
||||
* @param permission <p>The permission required to create the sign this paid sign matches</p>
|
||||
* @param ignoreCase <p>Whether to ignore case when looking for this permission sign</p>
|
||||
* @param ignoreColor <p>Whether to ignore color when looking for this permission sign</p>
|
||||
* @param name <p>A recognizable, unique, name used to identify this paid sign</p>
|
||||
* @param cost <p>The cost of creating this paid sign</p>
|
||||
* @param permission <p>The permission required to create the sign this paid sign matches</p>
|
||||
* @param ignoreCase <p>Whether to ignore case when looking for this permission sign</p>
|
||||
* @param ignoreColor <p>Whether to ignore color when looking for this permission sign</p>
|
||||
* @param matchAnyCondition <p>Whether to treat a match for any condition as a sign match</p>
|
||||
*/
|
||||
public PaidSign(String name, double cost, String permission, OptionState ignoreCase, OptionState ignoreColor) {
|
||||
public PaidSign(String name, double cost, String permission, OptionState ignoreCase, OptionState ignoreColor,
|
||||
boolean matchAnyCondition) {
|
||||
if (name == null || name.trim().isBlank()) {
|
||||
throw new IllegalArgumentException("Name cannot be empty");
|
||||
}
|
||||
@ -44,6 +45,7 @@ public class PaidSign {
|
||||
this.permission = permission;
|
||||
this.ignoreCase = ignoreCase;
|
||||
this.ignoreColor = ignoreColor;
|
||||
this.matchAnyCondition = matchAnyCondition;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -100,6 +102,15 @@ public class PaidSign {
|
||||
return OptionState.getBooleanValue(this.ignoreColor, PaidSigns.getInstance().ignoreColor());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether to treat a match for any condition as a sign match
|
||||
*
|
||||
* @return <p>Whether to treat a match for any condition as a sign match</p>
|
||||
*/
|
||||
public boolean matchAnyCondition() {
|
||||
return this.matchAnyCondition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this paid sign matches the given set of sign lines
|
||||
*
|
||||
@ -111,17 +122,18 @@ public class PaidSign {
|
||||
if (this.conditions.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
boolean success = true;
|
||||
boolean matchAny = matchAnyCondition();
|
||||
boolean success = !matchAny;
|
||||
for (short i = 0; i < 4; i++) {
|
||||
PaidSignCondition condition = this.conditions.get(i);
|
||||
if (condition != null) {
|
||||
try {
|
||||
success = success && condition.test(lines[i]);
|
||||
} catch (PatternSyntaxException exception) {
|
||||
PaidSigns.getInstance().getLogger().log(Level.SEVERE, "The paid sign condition match string:" +
|
||||
" " + condition.getStringToMatch() + " belonging to sign: " + this.getName() +
|
||||
" is not a valid regular expression.");
|
||||
boolean conditionMatches = condition.test(lines[i]);
|
||||
if (matchAny) {
|
||||
success |= conditionMatches;
|
||||
} else {
|
||||
success &= conditionMatches;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return success;
|
||||
|
@ -115,4 +115,9 @@ public enum TranslatableMessage {
|
||||
*/
|
||||
ERROR_CANNOT_AFFORD,
|
||||
|
||||
/**
|
||||
* The error to display if an invalid regular expression is provided
|
||||
*/
|
||||
ERROR_INVALID_REGULAR_EXPRESSION,
|
||||
|
||||
}
|
||||
|
@ -98,7 +98,8 @@ public final class PaidSignManager {
|
||||
String permission = signSection.getString(name + ".permission");
|
||||
OptionState ignoreCase = OptionState.getFromBoolean(signSection.getBoolean(name + ".ignoreCase"));
|
||||
OptionState ignoreColor = OptionState.getFromBoolean(signSection.getBoolean(name + ".ignoreColor"));
|
||||
PaidSign sign = new PaidSign(name, cost, permission, ignoreCase, ignoreColor);
|
||||
boolean matchAnyCondition = signSection.getBoolean(name + ".matchAnyCondition");
|
||||
PaidSign sign = new PaidSign(name, cost, permission, ignoreCase, ignoreColor, matchAnyCondition);
|
||||
loadConditions(signSection, sign);
|
||||
paidSigns.put(name, sign);
|
||||
}
|
||||
@ -150,6 +151,7 @@ public final class PaidSignManager {
|
||||
signSection.set(name + ".permission", sign.getPermission());
|
||||
signSection.set(name + ".ignoreCase", sign.getIgnoreCase());
|
||||
signSection.set(name + ".ignoreColor", sign.getIgnoreColor());
|
||||
signSection.set(name + ".matchAnyCondition", sign.matchAnyCondition());
|
||||
ConfigurationSection conditionsSection = signSection.createSection(name + ".conditions");
|
||||
Map<Short, PaidSignCondition> signConditions = sign.getConditions();
|
||||
for (short lineIndex : signConditions.keySet()) {
|
||||
|
@ -10,7 +10,7 @@ website: https://git.knarcraft.net/EpicKnarvik97/PaidSigns
|
||||
commands:
|
||||
addpaidsign:
|
||||
description: Used to add a new paid sign
|
||||
usage: /<command> <name> <cost> [permission] [ignore case] [ignore color]
|
||||
usage: /<command> <name> <cost> [permission] [ignore case] [ignore color] [match any condition]
|
||||
permission: paidsigns.manage
|
||||
addpaidsigncondition:
|
||||
description: Used to add a new match condition for a paid sign
|
||||
|
@ -9,7 +9,7 @@ en:
|
||||
SUCCESS_REFUNDED: "&bYou were refunded &3{cost} {unit} &bfor your broken sign"
|
||||
PAID_SIGNS_INFO: "&f---&3Paid signs&f---{signs}\n&f-----------"
|
||||
PAID_SIGNS_INFO_FORMAT: "\n&f| &3{name}"
|
||||
PAID_SIGN_INFO: "&f---&3Paid sign&f---\n&f| &bName: &3{name}\n&f| &bCost: &3{cost}\n&f| &bPermission: &3{permission}\n&f| &bIgnore case: &3{case}\n&f| &bIgnore color: &3{color}\n&f| &bSign conditions: &3{conditions}\n&f---------------"
|
||||
PAID_SIGN_INFO: "&f---&3Paid sign&f---\n&f| &bName: &3{name}\n&f| &bCost: &3{cost}\n&f| &bPermission: &3{permission}\n&f| &bIgnore case: &3{case}\n&f| &bIgnore color: &3{color}\n&f| &bMatch any condition: &3{any}\n&f| &bSign conditions: &3{conditions}\n&f---------------"
|
||||
PAID_SIGN_INFO_CONDITION_FORMAT: "\n&f| &b{line}: &3{condition}"
|
||||
PAID_SIGN_CONDITION_INFO: "&f---&3Paid sign condition&f---\n&f| &bPaid sign name: &3{name}\n&f| &bCondition line: &3{line}\n&f| &bMatch string: &3{match}\n&f| &bExecute RegEx: &3{regex}\n&f| &bIgnore case: &3{case}\n&f| &bIgnore color: &3{color}\n&f---------------"
|
||||
BOOLEAN_TRUE: "&2true"
|
||||
@ -20,4 +20,5 @@ en:
|
||||
ERROR_INVALID_INPUT: "&bInvalid input: {input}"
|
||||
ERROR_PAID_SIGN_NOT_FOUND: "&bNo such paid sign exists"
|
||||
ERROR_NO_SUCH_CONDITION: "&bThe paid sign you specified has no condition for line {line}"
|
||||
ERROR_CANNOT_AFFORD: "&bYou cannot afford to create this sign"
|
||||
ERROR_CANNOT_AFFORD: "&bYou cannot afford to create this sign"
|
||||
ERROR_INVALID_REGULAR_EXPRESSION: "&bThe provided regular expression is invalid"
|
Loading…
Reference in New Issue
Block a user