Blacksmith/src/main/java/net/knarcraft/blacksmith/command/BlackSmithConfigCommand.java

258 lines
12 KiB
Java

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.ItemType;
import net.knarcraft.blacksmith.formatting.TranslatableMessage;
import net.knarcraft.blacksmith.formatting.Translator;
import net.knarcraft.blacksmith.util.InputParsingHelper;
import net.knarcraft.blacksmith.util.TypeValidationHelper;
import net.md_5.bungee.api.ChatColor;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
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.StringFormatter.displayErrorMessage;
import static net.knarcraft.blacksmith.formatting.StringFormatter.displaySuccessMessage;
/**
* 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())) {
displayErrorMessage(sender,
Translator.getTranslatedMessage(TranslatableMessage.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
return changeValue(args, detectedGlobalSetting, detectedNPCSetting, settings, sender);
}
/**
* Changes the value of the setting defined in the user's input
*
* @param args <p>The arguments given by the user</p>
* @param detectedGlobalSetting <p>The global setting recognized from the input, if any</p>
* @param detectedNPCSetting <p>The NPC setting recognized from the input, if any</p>
* @param settings <p>The global settings object to get settings from</p>
* @param sender <p>The command sender to display any output to</p>
* @return <p>True if the value was successfully changed</p>
*/
private boolean changeValue(String[] args, GlobalSetting detectedGlobalSetting, NPCSetting detectedNPCSetting,
GlobalSettings settings, CommandSender sender) {
String newValue = args[1];
if (detectedGlobalSetting != null) {
settings.changeValue(detectedGlobalSetting, newValue);
displaySuccessMessage(sender, TranslatableMessage.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);
displaySuccessMessage(sender, TranslatableMessage.getValueChangedMessage(detectedNPCSetting.getNodeName(), newValue));
return true;
} else {
return false;
}
}
/**
* Displays the current value of the selected setting
*
* @param detectedGlobalSetting <p>The global setting recognized from the input, if any</p>
* @param detectedNPCSetting <p>The NPC setting recognized from the input, if any</p>
* @param settings <p>The global settings object to get settings from</p>
* @param sender <p>The command sender to display any output to</p>
* @return <p>True if a settings was successfully displayed</p>
*/
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
displaySuccessMessage(sender, TranslatableMessage.getCurrentValueMessage(correctCommandName, settingValue));
//Print the value with any colors displayed as &a-f0-9
if (printRawValue) {
sender.sendMessage(TranslatableMessage.getRawValueMessage(
settingValue.replace(ChatColor.COLOR_CHAR, '&')));
}
return true;
}
/**
* Displays the current value of a special-case configuration value
*
* @param selector <p>The selector specifying which material/enchantment to display information about</p>
* @param sender <p>The sender to display the value to</p>
* @param setting <p>The setting to display</p>
* @param settings <p>The settings object to query</p>
* @return <p>True if the value was successfully displayed</p>
*/
private boolean displaySpecialCaseValue(String selector, CommandSender sender, GlobalSetting setting,
GlobalSettings settings) {
if (setting == GlobalSetting.BASE_PRICE || setting == GlobalSetting.PRICE_PER_DURABILITY_POINT) {
Material material = Material.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));
}
displaySuccessMessage(sender, TranslatableMessage.getItemCurrentValueMessage(setting.getCommandName(), ItemType.MATERIAL,
material.name(), currentValue));
return true;
} else if (setting == GlobalSetting.ENCHANTMENT_COST) {
Enchantment enchantment = Enchantment.getByKey(NamespacedKey.minecraft(selector));
if (enchantment == null) {
return false;
}
displaySuccessMessage(sender, TranslatableMessage.getItemCurrentValueMessage(setting.getCommandName(), ItemType.ENCHANTMENT,
enchantment.toString(), String.valueOf(settings.getEnchantmentCost(enchantment))));
return true;
} else {
return false;
}
}
/**
* Gets whether a command name matches a special case command
*
* @param commandName <p>The command specified</p>
* @return <p>True if the command is a special case</p>
*/
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 settings <p>The settings to modify</p>
* @param detectedGlobalSetting <p>The global setting specified</p>
* @param args <p>All arguments given</p>
* @param sender <p>The command sender to notify if successful</p>
* @return <p>True if already handled as a special case</p>
*/
private boolean updateSpecialCase(GlobalSettings settings, GlobalSetting detectedGlobalSetting, String[] args,
CommandSender sender) {
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.toString();
settings.setEnchantmentCost(enchantment, newPrice);
} else {
return false;
}
displaySuccessMessage(sender, TranslatableMessage.getItemValueChangedMessage(detectedGlobalSetting.getCommandName(),
itemType, itemChanged, newValue));
return true;
}
}