Command and Command bank.
parent
cb9767f8bd
commit
2b0238dff1
@ -0,0 +1,191 @@
|
||||
package net.pingex.dcf.commands;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents a single command.
|
||||
*/
|
||||
public abstract class Command implements ICommandExecutor
|
||||
{
|
||||
/**
|
||||
* Main name of the command
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* Command can also be called using the following list of aliases
|
||||
*/
|
||||
private List<String> aliases;
|
||||
|
||||
/**
|
||||
* Description of the command.
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* Is the command enabled ? Can it be invoked ?
|
||||
*/
|
||||
private boolean isEnabled;
|
||||
|
||||
/**
|
||||
* Command usage help
|
||||
*/
|
||||
private String usage;
|
||||
|
||||
/**
|
||||
* Basic constructor.
|
||||
* @param name Name of the command
|
||||
* @param aliases Aliases, if any
|
||||
* @param description Description of the command
|
||||
* @param isEnabled Is the command enabled ?
|
||||
* @param usage Command usage help
|
||||
*/
|
||||
public Command(String name, List<String> aliases, String description, boolean isEnabled, String usage)
|
||||
{
|
||||
this.name = name;
|
||||
this.aliases = aliases;
|
||||
this.description = description;
|
||||
this.isEnabled = isEnabled;
|
||||
this.usage = usage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Contains Command default values
|
||||
*/
|
||||
public static class Defaults
|
||||
{
|
||||
public static final List<String> ALIASES = Collections.emptyList();
|
||||
public static final String DESCRIPTION = "No command description provided.";
|
||||
public static final boolean IS_ENABLED = true;
|
||||
public static final String USAGE = "No command usage provided.";
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for a command
|
||||
*/
|
||||
public static class Builder
|
||||
{
|
||||
/**
|
||||
* Main name of the command
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* Command can also be called using the following list of aliases
|
||||
*/
|
||||
private List<String> aliases = Defaults.ALIASES;
|
||||
|
||||
/**
|
||||
* Description of the command.
|
||||
*/
|
||||
private String description = Defaults.DESCRIPTION;
|
||||
|
||||
/**
|
||||
* Is the command enabled ? Can it be invoked ?
|
||||
*/
|
||||
private boolean isEnabled = Defaults.IS_ENABLED;
|
||||
|
||||
/**
|
||||
* Command usage help
|
||||
*/
|
||||
private String usage = Defaults.USAGE;
|
||||
|
||||
public Builder(String name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Builder aliases(List<String> aliases)
|
||||
{
|
||||
this.aliases = aliases;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set aliases using varargs
|
||||
* @param aliases Aliases varargs
|
||||
*/
|
||||
public Builder aliases(String... aliases)
|
||||
{
|
||||
this.aliases = Arrays.asList(aliases);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder description(String description)
|
||||
{
|
||||
this.description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder enabled(boolean enabled)
|
||||
{
|
||||
isEnabled = enabled;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder usage(String usage)
|
||||
{
|
||||
this.usage = usage;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a new Command using a supplied executor.
|
||||
* @param toExecute The body of the command.
|
||||
* @return Built command.
|
||||
*/
|
||||
public Command build(ICommandExecutor toExecute)
|
||||
{
|
||||
return new Command(name, aliases, description, isEnabled, usage)
|
||||
{
|
||||
@Override
|
||||
public void execute(List<String> arguments)
|
||||
{
|
||||
toExecute.execute(arguments);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a builder for a new command.
|
||||
* @param name The name of the future command
|
||||
* @return A new manipulable builder to build the command.
|
||||
*/
|
||||
public static Builder builder(String name)
|
||||
{
|
||||
return new Builder(name);
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public List<String> getAliases()
|
||||
{
|
||||
return aliases;
|
||||
}
|
||||
|
||||
public String getDescription()
|
||||
{
|
||||
return description;
|
||||
}
|
||||
|
||||
public boolean isEnabled()
|
||||
{
|
||||
return isEnabled;
|
||||
}
|
||||
|
||||
public String getUsage()
|
||||
{
|
||||
return usage;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled)
|
||||
{
|
||||
isEnabled = enabled;
|
||||
}
|
||||
}
|
@ -0,0 +1,140 @@
|
||||
package net.pingex.dcf.commands;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Command bank
|
||||
*/
|
||||
public class CommandRegistry
|
||||
{
|
||||
/**
|
||||
* Command main store
|
||||
*/
|
||||
private static Set<Command> commandSet = new HashSet<>();
|
||||
|
||||
/**
|
||||
* Logger
|
||||
*/
|
||||
private static final Logger LOGGER = LogManager.getLogger(CommandRegistry.class);
|
||||
|
||||
/**
|
||||
* Register a command and its aliases to the bank
|
||||
* @param toRegister Command to register
|
||||
*/
|
||||
public static void registerCommand(Command toRegister)
|
||||
{
|
||||
LOGGER.debug("Attempting to register command {}.", toRegister.getName());
|
||||
|
||||
if(commandExists(toRegister.getName()))
|
||||
{
|
||||
LOGGER.warn("Fail to add command: {} is already registered as a command.", toRegister.getName());
|
||||
return;
|
||||
}
|
||||
if(aliasExists(toRegister.getName())) LOGGER.info("Overriding registered alias {} for a new command with the same name.", toRegister.getName());
|
||||
|
||||
LOGGER.info("Registering command {}.", toRegister.getName());
|
||||
commandSet.add(toRegister);
|
||||
|
||||
// Check for conflicting aliases
|
||||
toRegister.getAliases().stream().filter(CommandRegistry::aliasExists).forEach(i ->
|
||||
{
|
||||
LOGGER.warn("Conflicting alias {} for command {}, removing. (original command: {})", i, toRegister.getName(), getAliasByName(i).get().getName());
|
||||
toRegister.getAliases().remove(i);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a command from the bank.
|
||||
* A command cannot be removed using one of its alias.
|
||||
* @param commandName Target command
|
||||
*/
|
||||
public static void unregisterCommandByName(String commandName)
|
||||
{
|
||||
LOGGER.debug("Resolving command {}.", commandName);
|
||||
Optional<Command> target = getCommandByName(commandName);
|
||||
|
||||
if(target.isPresent()) unregisterCommand(target.get());
|
||||
else LOGGER.warn("Attempting to remove a command which is unknown to DCF.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a command from the bank.
|
||||
* @param toUnregister Target command
|
||||
*/
|
||||
public static void unregisterCommand(Command toUnregister)
|
||||
{
|
||||
LOGGER.debug("Attempting to remove command {} from the bank.", toUnregister.getName());
|
||||
if(!commandSet.contains(toUnregister))
|
||||
{
|
||||
LOGGER.warn("Attempting to remove a command which is unknown to DCF.");
|
||||
return;
|
||||
}
|
||||
|
||||
commandSet.remove(toUnregister);
|
||||
LOGGER.info("Removed command {}.", toUnregister.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells if the command is registered (excluding aliases).
|
||||
* @param commandName Target command
|
||||
* @return `true` if the command is registered, `false` otherwise
|
||||
*/
|
||||
public static boolean commandExists(String commandName)
|
||||
{
|
||||
return commandSet.stream().anyMatch(e -> e.getName().equals(commandName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells if the alias is registered.
|
||||
* @param aliasName Target alias
|
||||
* @return `true` if the alias is registered, `false` otherwise
|
||||
*/
|
||||
public static boolean aliasExists(String aliasName)
|
||||
{
|
||||
return commandSet.stream().anyMatch(e -> e.getAliases().contains(aliasName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells if the command exists (including aliases).
|
||||
* Command have precedence over aliases.
|
||||
* @param commandName Target command
|
||||
* @return `true` if the command exists, `false` otherwise
|
||||
*/
|
||||
public static boolean exists(String commandName)
|
||||
{
|
||||
return commandExists(commandName) || aliasExists(commandName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a command or an alias designed by its name. Commands have precedence over aliases.
|
||||
* @param commandName Target command
|
||||
* @return {@code Optional.empty()} if no command was found, {@code Optional.of(Command)} otherwise
|
||||
*/
|
||||
public static Optional<Command> getCommandOrAliasByName(String commandName)
|
||||
{
|
||||
return commandExists(commandName) ? getCommandByName(commandName) : getAliasByName(commandName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a command by one of its aliases.
|
||||
* @param aliasName Target command with this alias.
|
||||
* @return {@code Optional.empty()} if no command was found, {@code Optional.of(Command)} otherwise
|
||||
*/
|
||||
public static Optional<Command> getAliasByName(String aliasName)
|
||||
{
|
||||
return commandSet.stream().filter(e -> e.getAliases().contains(aliasName)).findFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a command designed by its name, excluding aliases.
|
||||
* @param commandName Target command
|
||||
* @return {@code Optional.empty()} if no command was found, {@code Optional.of(Command)} otherwise
|
||||
*/
|
||||
public static Optional<Command> getCommandByName(String commandName)
|
||||
{
|
||||
return commandSet.stream().filter(e -> e.getName().equals(commandName)).findFirst();
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package net.pingex.dcf.commands;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The body of a command.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ICommandExecutor
|
||||
{
|
||||
void execute(List<String> arguments);
|
||||
}
|
Reference in New Issue