195 lines
8.1 KiB
Java
195 lines
8.1 KiB
Java
package net.knarcraft.blacksmith.command;
|
|
|
|
import net.citizensnpcs.api.CitizensAPI;
|
|
import net.citizensnpcs.api.npc.NPC;
|
|
import net.knarcraft.blacksmith.BlacksmithPlugin;
|
|
import net.knarcraft.blacksmith.config.Setting;
|
|
import net.knarcraft.blacksmith.config.SettingValueType;
|
|
import net.knarcraft.blacksmith.config.Settings;
|
|
import net.knarcraft.blacksmith.formatting.BlacksmithTranslatableMessage;
|
|
import net.knarcraft.blacksmith.trait.CustomTrait;
|
|
import net.knarcraft.blacksmith.util.ConfigCommandHelper;
|
|
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.command.Command;
|
|
import org.bukkit.command.CommandExecutor;
|
|
import org.bukkit.command.CommandSender;
|
|
import org.jetbrains.annotations.NotNull;
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
import java.util.Arrays;
|
|
import java.util.logging.Level;
|
|
|
|
import static net.knarcraft.blacksmith.formatting.BlacksmithTranslatableMessage.getCurrentValueMessage;
|
|
import static net.knarcraft.blacksmith.formatting.BlacksmithTranslatableMessage.getDefaultValueMessage;
|
|
import static net.knarcraft.blacksmith.formatting.BlacksmithTranslatableMessage.getValueChangedMessage;
|
|
|
|
/**
|
|
* A generic implementation of the edit command
|
|
*
|
|
* @param <K> <p>The type of trait to edit</p>
|
|
* @param <L> <p>The type of setting the trait uses</p>
|
|
*/
|
|
public abstract class EditCommand<K extends CustomTrait<L>, L extends Setting> implements CommandExecutor {
|
|
|
|
protected final Class<K> traitClass;
|
|
|
|
/**
|
|
* Instantiates a new edit command
|
|
*
|
|
* @param traitClass <p>The type of trait this command edits</p>
|
|
*/
|
|
public EditCommand(Class<K> traitClass) {
|
|
this.traitClass = traitClass;
|
|
}
|
|
|
|
/**
|
|
* Gets the setting corresponding to the given input
|
|
*
|
|
* @param input <p>The input given by the user</p>
|
|
* @return <p>The corresponding setting, or null if not recognized</p>
|
|
*/
|
|
public abstract L getSetting(String input);
|
|
|
|
/**
|
|
* Gets the global settings to use
|
|
*
|
|
* @return <p>The global settings</p>
|
|
*/
|
|
public abstract @NotNull Settings<L> getGlobalSettings();
|
|
|
|
@Override
|
|
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String s,
|
|
@NotNull String[] args) {
|
|
NPC npc = CitizensAPI.getDefaultNPCSelector().getSelected(sender);
|
|
if (npc == null || !npc.hasTrait(traitClass)) {
|
|
BlacksmithPlugin.getStringFormatter().displayErrorMessage(sender,
|
|
BlacksmithTranslatableMessage.NO_NPC_SELECTED);
|
|
return true;
|
|
}
|
|
|
|
if (args.length < 1) {
|
|
return false;
|
|
}
|
|
|
|
K trait = npc.getTraitNullable(traitClass);
|
|
if (trait == null) {
|
|
return false;
|
|
}
|
|
|
|
L setting = getSetting(args[0]);
|
|
if (setting != null) {
|
|
String newValue = args.length < 2 ? null : args[1];
|
|
//This makes sure all arguments are treated as a sentence
|
|
if (setting.getValueType() == SettingValueType.STRING && args.length > 2) {
|
|
newValue = String.join(" ", Arrays.asList(args).subList(1, args.length));
|
|
}
|
|
Settings<L> settings = getGlobalSettings();
|
|
return displayOrChangeNPCSetting(trait, setting, settings, newValue, sender);
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Changes the given NPC setting, or displays the current value if a new value isn't specified
|
|
*
|
|
* @param trait <p>The trait belonging to the selected NPC</p>
|
|
* @param setting <p>The NPC setting to change</p>
|
|
* @param globalSettings <p>The global settings to get default values from</p>
|
|
* @param newValue <p>The value to change the setting to</p>
|
|
* @param sender <p>The command sender to notify about results</p>
|
|
* @return <p>True if everything went successfully</p>
|
|
*/
|
|
private boolean displayOrChangeNPCSetting(@NotNull CustomTrait<L> trait,
|
|
@NotNull L setting,
|
|
@NotNull Settings<L> globalSettings,
|
|
@Nullable String newValue,
|
|
@NotNull CommandSender sender) {
|
|
if (newValue == null) {
|
|
//Display the current value of the setting
|
|
displayNPCSetting(trait, setting, globalSettings, sender);
|
|
} else {
|
|
//If an empty value or null, clear the value instead of changing it
|
|
if (InputParsingHelper.isEmpty(newValue)) {
|
|
newValue = null;
|
|
} else {
|
|
//Abort if an invalid value is given
|
|
boolean isValidType = TypeValidationHelper.isValid(setting.getValueType(), newValue, sender);
|
|
if (!isValidType) {
|
|
return false;
|
|
}
|
|
newValue = ChatColor.translateAlternateColorCodes('&', newValue);
|
|
}
|
|
|
|
//Change the setting
|
|
Settings<L> settings = trait.getTraitSettings();
|
|
if (settings == null) {
|
|
BlacksmithPlugin.getInstance().getLogger().log(Level.SEVERE, "Settings for a CustomTrait has not " +
|
|
"been initialized! Please inform the developer!");
|
|
return false;
|
|
}
|
|
settings.changeValue(setting, newValue);
|
|
BlacksmithPlugin.getStringFormatter().displaySuccessMessage(sender,
|
|
getValueChangedMessage(setting.getCommandName(), String.valueOf(newValue)));
|
|
//Save the changes immediately to prevent data loss on server crash
|
|
CitizensAPI.getNPCRegistry().saveToStore();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Displays the current value of the given NPC setting
|
|
*
|
|
* @param trait <p>The trait of the NPC to get the value from</p>
|
|
* @param setting <p>The NPC setting to see the value of</p>
|
|
* @param globalSettings <p>The global settings to get default values from</p>
|
|
* @param sender <p>The command sender to display the value to</p>
|
|
*/
|
|
private void displayNPCSetting(@NotNull CustomTrait<L> trait,
|
|
@NotNull L setting,
|
|
@NotNull Settings<L> globalSettings,
|
|
@NotNull CommandSender sender) {
|
|
Settings<L> settings = trait.getTraitSettings();
|
|
if (settings == null) {
|
|
BlacksmithPlugin.getInstance().getLogger().log(Level.SEVERE, "Settings for a CustomTrait has not " +
|
|
"been initialized! Please inform the developer!");
|
|
return;
|
|
}
|
|
|
|
StringFormatter formatter = BlacksmithPlugin.getStringFormatter();
|
|
|
|
//Find the value of the specified setting
|
|
String commandName = setting.getCommandName();
|
|
String currentValue = String.valueOf(settings.getRawValue(setting));
|
|
String defaultValue = String.valueOf(setting.getDefaultValue());
|
|
String marker = formatter.getUnFormattedMessage(BlacksmithTranslatableMessage.SETTING_OVERRIDDEN_MARKER);
|
|
boolean isMessage = setting.isMessage();
|
|
boolean isSet = !InputParsingHelper.isEmpty(currentValue);
|
|
|
|
// Display the description for how this setting is used
|
|
formatter.displaySuccessMessage(sender, setting.getDescription());
|
|
|
|
// Display the default value
|
|
formatter.displayNeutralMessage(sender, getDefaultValueMessage(commandName, defaultValue));
|
|
if (isMessage) {
|
|
ConfigCommandHelper.displayRaw(sender, defaultValue);
|
|
}
|
|
|
|
if (!isSet) {
|
|
//Display the global value, if no custom value has been specified
|
|
currentValue = String.valueOf(globalSettings.getRawValue(setting));
|
|
}
|
|
|
|
// Display the value with a marker if it's customized
|
|
formatter.displayNeutralMessage(sender, getCurrentValueMessage(commandName, currentValue) + (isSet ? marker : ""));
|
|
|
|
if (isMessage) {
|
|
ConfigCommandHelper.displayRaw(sender, currentValue);
|
|
}
|
|
}
|
|
|
|
}
|