Files
PaidSigns/src/main/java/net/knarcraft/paidsigns/command/EditCommand.java
EpicKnarvik97 38717a6b91 Improves behavior when signs share conditions
Makes sure that the paid sign matching the most conditions is always chosen as the matching paid sign
Makes sure to always choose the most expensive paid sign if two or more paid signs with the same amount of conditions are matching.
Changes some classes to records to reduce some boilerplate code
2022-07-20 18:09:09 +02:00

187 lines
8.9 KiB
Java

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;
import java.util.Map;
/**
* 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) {
super.onCommand(sender, command, label, args);
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();
Map<Short, PaidSignCondition> conditions = sign.getConditions();
PaidSignManager manager = PaidSigns.getInstance().getSignManager();
PaidSign updatedSign = new PaidSign(signName, cost, permission, ignoreCase, ignoreColor, matchAnyCondition);
for (short line : conditions.keySet()) {
PaidSignCondition condition = conditions.get(line);
updatedSign.addCondition(line, condition.stringToMatch(), condition.executeRegex(),
OptionState.getFromBoolean(condition.ignoreCase()),
OptionState.getFromBoolean(condition.ignoreColor()));
}
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.stringToMatch();
boolean executeRegEx = property == PaidSignConditionProperty.EXECUTE_REG_EX ? Boolean.parseBoolean(newValue) :
condition.executeRegex();
boolean ignoreCase = property == PaidSignConditionProperty.IGNORE_CASE ? OptionState.getBooleanValue(
OptionState.fromString(newValue), sign.getIgnoreCase()) : condition.ignoreCase();
boolean ignoreColor = property == PaidSignConditionProperty.IGNORE_COLOR ? OptionState.getBooleanValue(
OptionState.fromString(newValue), sign.getIgnoreColor()) : 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;
}
}