package net.knarcraft.blacksmith.command; import net.knarcraft.blacksmith.BlacksmithPlugin; import net.knarcraft.blacksmith.config.GlobalSetting; import net.knarcraft.blacksmith.config.GlobalSettings; import net.knarcraft.blacksmith.config.NPCSetting; import net.knarcraft.blacksmith.config.SettingValueType; import net.knarcraft.blacksmith.formatting.BlacksmithTranslatableMessage; import net.knarcraft.blacksmith.formatting.ItemType; import net.knarcraft.blacksmith.util.InputParsingHelper; import net.knarcraft.blacksmith.util.TypeValidationHelper; import net.knarcraft.knarlib.formatting.StringFormatter; import net.md_5.bungee.api.ChatColor; import org.bukkit.Material; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.bukkit.enchantments.Enchantment; import org.jetbrains.annotations.NotNull; import java.util.Arrays; import static net.knarcraft.blacksmith.formatting.BlacksmithTranslatableMessage.getValueChangedMessage; /** * The command used for changing global configuration options */ public class BlackSmithConfigCommand implements CommandExecutor { @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { if (args.length == 0) { return false; } String commandName = args[0]; if (commandName.equalsIgnoreCase("reload")) { return new ReloadCommand().onCommand(sender, command, label, args); } GlobalSettings settings = BlacksmithPlugin.getInstance().getSettings(); //Changing reforge-able items' default isn't recommended if (commandName.equalsIgnoreCase(NPCSetting.REFORGE_ABLE_ITEMS.getCommandName())) { StringFormatter.displayErrorMessage(sender, BlacksmithTranslatableMessage.DEFAULT_REFORGE_ABLE_ITEMS_UNCHANGEABLE); return false; } //Find which global setting the user has specified, if any GlobalSetting detectedGlobalSetting = null; for (GlobalSetting globalSetting : GlobalSetting.values()) { if (commandName.equalsIgnoreCase(globalSetting.getCommandName())) { detectedGlobalSetting = globalSetting; break; } } //Find which npc setting the user has specified, if any NPCSetting detectedNPCSetting = null; for (NPCSetting npcSetting : NPCSetting.values()) { if (commandName.equalsIgnoreCase(npcSetting.getCommandName())) { detectedNPCSetting = npcSetting; break; } } //Display the current value of a setting if (args.length == 1) { return displayCurrentValue(detectedGlobalSetting, detectedNPCSetting, settings, sender); } else if (args.length == 2 && isSpecialCase(commandName)) { if (displaySpecialCaseValue(args[1], sender, detectedGlobalSetting, settings)) { return true; } } //Update the value of a special-case setting if (args.length == 3 && updateSpecialCase(settings, detectedGlobalSetting, args, sender)) { return true; } //Change the value of the specified setting if ((detectedGlobalSetting != null && TypeValidationHelper.isValid(detectedGlobalSetting.getValueType(), args[1], sender)) || (detectedNPCSetting != null && TypeValidationHelper.isValid(detectedNPCSetting.getValueType(), args[1], sender))) { return changeValue(args, detectedGlobalSetting, detectedNPCSetting, settings, sender); } else { return false; } } /** * Changes the value of the setting defined in the user's input * * @param args
The arguments given by the user
* @param detectedGlobalSettingThe global setting recognized from the input, if any
* @param detectedNPCSettingThe NPC setting recognized from the input, if any
* @param settingsThe global settings object to get settings from
* @param senderThe command sender to display any output to
* @returnTrue if the value was successfully changed
*/ private boolean changeValue(String[] args, GlobalSetting detectedGlobalSetting, NPCSetting detectedNPCSetting, GlobalSettings settings, CommandSender sender) { String newValue = args[1]; if (detectedGlobalSetting != null) { settings.changeValue(detectedGlobalSetting, newValue); StringFormatter.displaySuccessMessage(sender, getValueChangedMessage(detectedGlobalSetting.getCommandName(), newValue)); return true; } else if (detectedNPCSetting != null) { //This makes sure all arguments are treated as a sentence if (detectedNPCSetting.getValueType() == SettingValueType.STRING) { newValue = String.join(" ", Arrays.asList(args).subList(1, args.length)); } settings.changeValue(detectedNPCSetting, newValue); StringFormatter.displaySuccessMessage(sender, getValueChangedMessage(detectedNPCSetting.getCommandName(), newValue)); return true; } else { return false; } } /** * Displays the current value of the selected setting * * @param detectedGlobalSettingThe global setting recognized from the input, if any
* @param detectedNPCSettingThe NPC setting recognized from the input, if any
* @param settingsThe global settings object to get settings from
* @param senderThe command sender to display any output to
* @returnTrue if a settings was successfully displayed
*/ private boolean displayCurrentValue(GlobalSetting detectedGlobalSetting, NPCSetting detectedNPCSetting, GlobalSettings settings, CommandSender sender) { String settingValue; String correctCommandName; boolean printRawValue = false; //Find the value of the specified setting //TODO: See if there's a way to remove this duplication if (detectedGlobalSetting != null) { settingValue = String.valueOf(settings.getRawValue(detectedGlobalSetting)); correctCommandName = detectedGlobalSetting.getCommandName(); } else if (detectedNPCSetting != null) { settingValue = String.valueOf(settings.getRawValue(detectedNPCSetting)); correctCommandName = detectedNPCSetting.getCommandName(); //For messages, print an additional raw value showing which color codes are used if (detectedNPCSetting.getPath().startsWith("defaults.messages")) { printRawValue = true; } } else { return false; } //Display the current value of the setting StringFormatter.displaySuccessMessage(sender, BlacksmithTranslatableMessage.getCurrentValueMessage(correctCommandName, settingValue)); //Print the value with any colors displayed as &a-f0-9 if (printRawValue) { sender.sendMessage(BlacksmithTranslatableMessage.getRawValueMessage( settingValue.replace(ChatColor.COLOR_CHAR, '&'))); } return true; } /** * Displays the current value of a special-case configuration value * * @param selectorThe selector specifying which material/enchantment to display information about
* @param senderThe sender to display the value to
* @param settingThe setting to display
* @param settingsThe settings object to query
* @returnTrue if the value was successfully displayed
*/ private boolean displaySpecialCaseValue(String selector, CommandSender sender, GlobalSetting setting, GlobalSettings settings) { if (setting == GlobalSetting.BASE_PRICE || setting == GlobalSetting.PRICE_PER_DURABILITY_POINT) { Material material = InputParsingHelper.matchMaterial(selector); if (material == null) { return false; } String currentValue; if (setting == GlobalSetting.BASE_PRICE) { currentValue = String.valueOf(settings.getBasePrice(material)); } else { currentValue = String.valueOf(settings.getPricePerDurabilityPoint(material)); } StringFormatter.displaySuccessMessage(sender, BlacksmithTranslatableMessage.getItemCurrentValueMessage(setting.getCommandName(), ItemType.MATERIAL, material.name(), currentValue)); return true; } else if (setting == GlobalSetting.ENCHANTMENT_COST) { Enchantment enchantment = InputParsingHelper.matchEnchantment(selector); if (enchantment == null) { return false; } StringFormatter.displaySuccessMessage(sender, BlacksmithTranslatableMessage.getItemCurrentValueMessage(setting.getCommandName(), ItemType.ENCHANTMENT, enchantment.getKey().getKey(), String.valueOf(settings.getEnchantmentCost(enchantment)))); return true; } else { return false; } } /** * Gets whether a command name matches a special case command * * @param commandNameThe command specified
* @returnTrue if the command is a special case
*/ private boolean isSpecialCase(String commandName) { return commandName.equalsIgnoreCase(GlobalSetting.BASE_PRICE.getCommandName()) || commandName.equalsIgnoreCase(GlobalSetting.PRICE_PER_DURABILITY_POINT.getCommandName()) || commandName.equalsIgnoreCase(GlobalSetting.ENCHANTMENT_COST.getCommandName()); } /** * Updates a special-case configuration value if a special-case is encountered * * @param settingsThe settings to modify
* @param detectedGlobalSettingThe global setting specified
* @param argsAll arguments given
* @param senderThe command sender to notify if successful
* @returnTrue if already handled as a special case
*/ private boolean updateSpecialCase(GlobalSettings settings, GlobalSetting detectedGlobalSetting, String[] args, CommandSender sender) { if (InputParsingHelper.isEmpty(args[2])) { args[2] = "-1"; } else if (!TypeValidationHelper.isValid(SettingValueType.POSITIVE_DOUBLE, args[2], sender)) { return true; } double newPrice = Double.parseDouble(args[2]); String itemChanged; ItemType itemType; String newValue = String.valueOf(newPrice); if (detectedGlobalSetting == GlobalSetting.BASE_PRICE || detectedGlobalSetting == GlobalSetting.PRICE_PER_DURABILITY_POINT) { Material material = InputParsingHelper.matchMaterial(args[1]); if (material == null) { return false; } itemType = ItemType.MATERIAL; itemChanged = material.name(); if (detectedGlobalSetting == GlobalSetting.BASE_PRICE) { settings.setBasePrice(material, newPrice); } else { settings.setPricePerDurabilityPoint(material, newPrice); } } else if (detectedGlobalSetting == GlobalSetting.ENCHANTMENT_COST) { Enchantment enchantment = InputParsingHelper.matchEnchantment(args[1]); if (enchantment == null) { return false; } itemType = ItemType.ENCHANTMENT; itemChanged = enchantment.getKey().getKey(); settings.setEnchantmentCost(enchantment, newPrice); } else { return false; } StringFormatter.displaySuccessMessage(sender, BlacksmithTranslatableMessage.getItemValueChangedMessage( detectedGlobalSetting.getCommandName(), itemType, itemChanged, newValue)); return true; } }