Implements the untested edit command

This commit is contained in:
Kristian Knarvik 2022-03-14 19:00:51 +01:00
parent 9c6921b4cd
commit 3e31c8c648
7 changed files with 213 additions and 25 deletions

View File

@ -4,6 +4,8 @@ import net.knarcraft.paidsigns.command.AddCommand;
import net.knarcraft.paidsigns.command.AddConditionCommand;
import net.knarcraft.paidsigns.command.AddConditionTabCompleter;
import net.knarcraft.paidsigns.command.AddTabCompleter;
import net.knarcraft.paidsigns.command.EditCommand;
import net.knarcraft.paidsigns.command.EditTabCompleter;
import net.knarcraft.paidsigns.command.ListCommand;
import net.knarcraft.paidsigns.command.ListTabCompleter;
import net.knarcraft.paidsigns.command.ReloadTabCommand;
@ -154,7 +156,9 @@ public final class PaidSigns extends JavaPlugin {
registerCommand("addPaidSign", new AddCommand(), new AddTabCompleter());
registerCommand("listPaidSigns", new ListCommand(), new ListTabCompleter());
registerCommand("addPaidSignCondition", new AddConditionCommand(), new AddConditionTabCompleter());
registerCommand("removePaidSignCondition", new RemoveConditionCommand(), new RemoveConditionTabCompleter());
registerCommand("removePaidSignCondition", new RemoveConditionCommand(),
new RemoveConditionTabCompleter());
registerCommand("editPaidSign", new EditCommand(), new EditTabCompleter());
TabExecutor removeTabExecutor = new RemoveTabCommand();
registerCommand("removePaidSign", removeTabExecutor, removeTabExecutor);

View File

@ -11,8 +11,6 @@ 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
@ -43,7 +41,7 @@ public class AddConditionCommand extends TokenizedCommand {
boolean executeRegEx = false;
if (argumentSize > 3) {
executeRegEx = Boolean.parseBoolean(arguments.get(3));
if (executeRegEx && !testRegEx(sender, stringToMatch)) {
if (executeRegEx && isRegExInvalid(sender, stringToMatch)) {
return false;
}
}
@ -58,24 +56,6 @@ 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
*

View File

@ -1,15 +1,176 @@
package net.knarcraft.paidsigns.command;
import net.knarcraft.paidsigns.PaidSigns;
import net.knarcraft.paidsigns.container.PaidSign;
import net.knarcraft.paidsigns.container.PaidSignCondition;
import net.knarcraft.paidsigns.formatting.StringFormatter;
import net.knarcraft.paidsigns.formatting.TranslatableMessage;
import net.knarcraft.paidsigns.manager.PaidSignManager;
import net.knarcraft.paidsigns.property.OptionState;
import net.knarcraft.paidsigns.property.PaidSignConditionProperty;
import net.knarcraft.paidsigns.property.PaidSignProperty;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
/**
* A representation of the command for editing a new paid sign
*/
public class EditCommand extends TokenizedCommand {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label,
@NotNull String[] args) {
return false;
if (argumentSize < 3) {
return false;
}
PaidSign sign = PaidSigns.getInstance().getSignManager().getPaidSign(arguments.get(0));
if (sign == null) {
sender.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.ERROR_PAID_SIGN_NOT_FOUND));
return false;
}
try {
try {
//First, assume a condition is changed
return parseGivenConditionLine(sign, sender);
} catch (NumberFormatException exception) {
//Fall back to assume a sign is changed
return parseGivenProperty(sign, sender);
}
} catch (IOException e) {
sender.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.ERROR_EXCEPTION_OCCURRED));
return false;
}
}
/**
* Parses the given condition line and the rest of the input
*
* @param sign <p>The paid sign the user is trying to edit</p>
* @param sender <p>The command sender to notify of any errors</p>
* @return <p>True if the command was executed successfully</p>
* @throws NumberFormatException <p>If the given argument is not a number</p>
*/
private boolean parseGivenConditionLine(@NotNull PaidSign sign,
@NotNull CommandSender sender) throws NumberFormatException {
short signLine = (short) (Short.parseShort(arguments.get(1)) - 1);
if (signLine < 0 || signLine > 3 || sign.getConditions().get(signLine) == null) {
sender.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.ERROR_NO_SUCH_CONDITION));
return false;
}
if (argumentSize < 4) {
return false;
}
PaidSignConditionProperty conditionProperty = PaidSignConditionProperty.getFromString(arguments.get(2));
if (conditionProperty == null) {
sender.sendMessage(StringFormatter.getTranslatedErrorMessage(
TranslatableMessage.ERROR_PROPERTY_NOT_RECOGNIZED));
return false;
}
String value = arguments.get(3);
return updateConditionProperty(sender, sign, signLine, conditionProperty, value);
}
/**
* Parses the given paid sign property and the rest of the input
*
* @param sign <p>The paid sign the user is trying to edit</p>
* @param sender <p>The command sender to notify of any errors</p>
* @return <p>True if the command was executed successfully</p>
* @throws IOException <p>If unable to remove or save the sign</p>
*/
private boolean parseGivenProperty(@NotNull PaidSign sign,
@NotNull CommandSender sender) throws IOException {
PaidSignProperty property = PaidSignProperty.getFromString(arguments.get(1));
if (property == null) {
sender.sendMessage(StringFormatter.getTranslatedErrorMessage(
TranslatableMessage.ERROR_PROPERTY_NOT_RECOGNIZED));
return false;
}
String value = arguments.get(2);
try {
updateProperty(sender, sign, property, value);
return true;
} catch (NumberFormatException exception) {
sender.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.ERROR_INVALID_NUMBER));
return false;
}
}
/**
* Updates a property for a paid sign
*
* @param sender <p>The command sender to notify of any errors or success</p>
* @param sign <p>The sign to be updated</p>
* @param property <p>The property to update</p>
* @param newValue <p>The new value of the property</p>
* @throws IOException <p>If unable to remove or save the sign</p>
*/
private void updateProperty(CommandSender sender, PaidSign sign, PaidSignProperty property,
String newValue) throws IOException {
String signName = property == PaidSignProperty.NAME ? newValue : sign.getName();
OptionState ignoreCase = property == PaidSignProperty.IGNORE_CASE ? OptionState.fromString(newValue) :
OptionState.getFromBoolean(sign.getIgnoreCase());
OptionState ignoreColor = property == PaidSignProperty.IGNORE_COLOR ? OptionState.fromString(newValue) :
OptionState.getFromBoolean(sign.getIgnoreColor());
boolean matchAnyCondition = property == PaidSignProperty.MATCH_ANY_CONDITION ? Boolean.parseBoolean(newValue) :
sign.matchAnyCondition();
double cost = property == PaidSignProperty.COST ? Double.parseDouble(newValue) : sign.getCost();
String permission = property == PaidSignProperty.PERMISSION ? newValue : sign.getPermission();
PaidSignManager manager = PaidSigns.getInstance().getSignManager();
PaidSign updatedSign = new PaidSign(signName, cost, permission, ignoreCase, ignoreColor, matchAnyCondition);
manager.removePaidSign(sign.getName());
manager.addPaidSign(updatedSign);
sender.sendMessage(StringFormatter.getTranslatedInfoMessage(TranslatableMessage.SUCCESS_UPDATED_PAID_SIGN));
}
/**
* Updates a property of a condition of a paid sign
*
* @param sender <p>The command sender to notify of any errors or success</p>
* @param sign <p>The sign the condition belongs to</p>
* @param conditionIndex <p>The line index that identifies the sign condition</p>
* @param property <p>The condition property to update</p>
* @param newValue <p>The new value of the property</p>
* @return <p>True if the property was successfully changed</p>
*/
private boolean updateConditionProperty(CommandSender sender, PaidSign sign, short conditionIndex,
PaidSignConditionProperty property, String newValue) {
PaidSignCondition condition = sign.getConditions().get(conditionIndex);
String stringToMatch = property == PaidSignConditionProperty.STRING_TO_MATCH ? newValue :
condition.getStringToMatch();
boolean executeRegEx = property == PaidSignConditionProperty.EXECUTE_REG_EX ? Boolean.parseBoolean(newValue) :
condition.executeRegex();
boolean ignoreCase = property == PaidSignConditionProperty.IGNORE_CASE ? Boolean.parseBoolean(newValue) :
condition.ignoreCase();
boolean ignoreColor = property == PaidSignConditionProperty.IGNORE_COLOR ? Boolean.parseBoolean(newValue) :
condition.ignoreColor();
//Make sure to test the regular expression in case anything changed
if (executeRegEx && isRegExInvalid(sender, stringToMatch)) {
return false;
}
sign.addCondition(conditionIndex, stringToMatch, executeRegEx, OptionState.getFromBoolean(ignoreCase),
OptionState.getFromBoolean(ignoreColor));
try {
PaidSigns.getInstance().getSignManager().saveSigns();
} catch (IOException e) {
sender.sendMessage(StringFormatter.getTranslatedErrorMessage(TranslatableMessage.ERROR_EXCEPTION_OCCURRED));
return false;
}
sender.sendMessage(StringFormatter.getTranslatedInfoMessage(
TranslatableMessage.SUCCESS_UPDATED_PAID_SIGN_CONDITION));
return true;
}
}

View File

@ -15,6 +15,9 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* The tab completer for the edit paid sign command
*/
public class EditTabCompleter extends TokenizedTabCompleter {
private static Map<PaidSignProperty, List<String>> propertyExampleValues;
@ -70,7 +73,7 @@ public class EditTabCompleter extends TokenizedTabCompleter {
* @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));
short signLine = (short) (Short.parseShort(arguments.get(2)) - 1);
//Refuse to autocomplete if invalid input is given
if (signLine < 0 || signLine > 3 || sign.getConditions().get(signLine) == null) {
return new ArrayList<>();

View File

@ -1,5 +1,7 @@
package net.knarcraft.paidsigns.command;
import net.knarcraft.paidsigns.formatting.StringFormatter;
import net.knarcraft.paidsigns.formatting.TranslatableMessage;
import net.knarcraft.paidsigns.utility.Tokenizer;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
@ -7,6 +9,8 @@ import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
/**
* A command executor with tokenized arguments
@ -23,4 +27,22 @@ public class TokenizedCommand implements CommandExecutor {
return true;
}
/**
* 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 invalid</p>
*/
protected boolean isRegExInvalid(CommandSender sender, String regularExpression) {
try {
Pattern.compile(regularExpression);
return false;
} catch (PatternSyntaxException exception) {
sender.sendMessage(StringFormatter.getTranslatedErrorMessage(
TranslatableMessage.ERROR_INVALID_REGULAR_EXPRESSION));
return true;
}
}
}

View File

@ -20,6 +20,16 @@ public enum TranslatableMessage {
*/
SUCCESS_ADDED_PAID_SIGN_CONDITION,
/**
* The message to display when a paid sign is successfully updated
*/
SUCCESS_UPDATED_PAID_SIGN,
/**
* The message to display when a paid sign condition is successfully updated
*/
SUCCESS_UPDATED_PAID_SIGN_CONDITION,
/**
* The message to display when a paid sign has been successfully removed
*/
@ -120,4 +130,9 @@ public enum TranslatableMessage {
*/
ERROR_INVALID_REGULAR_EXPRESSION,
/**
* The error to display if an invalid property is given to the edit command
*/
ERROR_PROPERTY_NOT_RECOGNIZED,
}

View File

@ -2,6 +2,8 @@ en:
PREFIX: "[PaidSigns]"
SUCCESS_ADDED_PAID_SIGN: "&bSuccessfully added new paid sign"
SUCCESS_ADDED_PAID_SIGN_CONDITION: "&bSuccessfully added new paid sign condition"
SUCCESS_UPDATED_PAID_SIGN: "&bSuccessfully updated the paid sign property"
SUCCESS_UPDATED_PAID_SIGN_CONDITION: "&bSuccessfully updated the paid sign condition property"
SUCCESS_REMOVED_PAID_SIGN: "&bSuccessfully removed paid sign"
SUCCESS_REMOVED_CONDITION: "&bSuccessfully removed paid sign condition"
SUCCESS_RELOADED: "&bSuccessfully reloaded configuration"
@ -21,4 +23,5 @@ en:
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_INVALID_REGULAR_EXPRESSION: "&bThe provided regular expression is invalid"
ERROR_INVALID_REGULAR_EXPRESSION: "&bThe provided regular expression is invalid"
ERROR_PROPERTY_NOT_RECOGNIZED: "&bThe property you tried to change was not recognized"