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) { 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

The paid sign the user is trying to edit

* @param sender

The command sender to notify of any errors

* @return

True if the command was executed successfully

* @throws NumberFormatException

If the given argument is not a number

*/ 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

The paid sign the user is trying to edit

* @param sender

The command sender to notify of any errors

* @return

True if the command was executed successfully

* @throws IOException

If unable to remove or save the sign

*/ 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

The command sender to notify of any errors or success

* @param sign

The sign to be updated

* @param property

The property to update

* @param newValue

The new value of the property

* @throws IOException

If unable to remove or save the sign

*/ 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

The command sender to notify of any errors or success

* @param sign

The sign the condition belongs to

* @param conditionIndex

The line index that identifies the sign condition

* @param property

The condition property to update

* @param newValue

The new value of the property

* @return

True if the property was successfully changed

*/ 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; } }