Separated commands and handlers

WIP
This commit is contained in:
Norbi Peti 2019-02-02 02:45:32 +01:00
parent ab603276d3
commit ab24480f89
No known key found for this signature in database
GPG key ID: DBA4C4549A927E56
8 changed files with 98 additions and 69 deletions

View file

@ -12,7 +12,6 @@
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="ButtonCore (1) (com.github.TBMCPlugins.ButtonCore)" />
<orderEntry type="module" module-name="ButtonCore (1) (com.github.TBMCPlugins.ButtonCore)" />
<orderEntry type="library" name="Maven: org.reflections:reflections:0.9.10" level="project" />
<orderEntry type="library" name="Maven: com.google.code.findbugs:annotations:2.0.1" level="project" />
<orderEntry type="library" name="Maven: org.javassist:javassist:3.20.0-GA" level="project" />

View file

@ -2,8 +2,9 @@ package buttondevteam.core;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.architecture.Component;
import buttondevteam.lib.chat.Command2MC;
import buttondevteam.lib.chat.Command2.Subcommand;
import buttondevteam.lib.chat.CommandClass;
import buttondevteam.lib.chat.ICommand2MC;
import lombok.val;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
@ -15,10 +16,9 @@ import java.util.Optional;
"§6---- Component command ----",
"Can be used to enable/disable/list components"
})
public class ComponentCommand extends Command2MC {
public class ComponentCommand extends ICommand2MC {
public ComponentCommand() {
addParamConverter(Plugin.class, arg -> Bukkit.getPluginManager().getPlugin(arg));
getManager().addParamConverter(Plugin.class, arg -> Bukkit.getPluginManager().getPlugin(arg));
}
@Subcommand

View file

@ -2,6 +2,7 @@ package buttondevteam.lib.architecture;
import buttondevteam.core.ComponentManager;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.chat.Command2MC;
import buttondevteam.lib.chat.TBMCChatAPI;
import lombok.AccessLevel;
import lombok.Getter;
@ -11,6 +12,8 @@ import org.bukkit.plugin.java.JavaPlugin;
import java.util.Stack;
public abstract class ButtonPlugin extends JavaPlugin {
@Getter
private static Command2MC command2MC = new Command2MC();
@Getter(AccessLevel.PROTECTED)
private IHaveConfig iConfig;
/**

View file

@ -3,7 +3,7 @@ package buttondevteam.lib.architecture;
import buttondevteam.core.ComponentManager;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.architecture.exceptions.UnregisteredComponentException;
import buttondevteam.lib.chat.Command2MC;
import buttondevteam.lib.chat.ICommand2;
import buttondevteam.lib.chat.TBMCChatAPI;
import buttondevteam.lib.chat.TBMCCommandBase;
import lombok.Getter;
@ -197,8 +197,8 @@ public abstract class Component {
*
* @param commandBase Custom coded command class
*/
protected final void registerCommand(Command2MC commandBase) {
Command2MC.registerCommand(commandBase);
protected final void registerCommand(ICommand2 commandBase) {
ButtonPlugin.getCommand2MC().registerCommand(commandBase);
}
/**

View file

@ -25,29 +25,6 @@ import java.util.stream.Collectors;
* The args may be null if the conversion failed.
*/
public abstract class Command2 {
/**
* Default handler for commands, can be used to copy the args too.
*
* @param sender The sender which ran the command
* @param args All of the arguments passed as is
* @return The success of the command
*/
public boolean def(CommandSender sender, @TextArg String args) {
return false;
}
/**
* Convenience method. Return with this.
*
* @param sender The sender of the command
* @param message The message to send to the sender
* @return Always true so that the usage isn't shown
*/
protected boolean respond(CommandSender sender, String message) {
sender.sendMessage(message);
return true;
}
/**
* TODO: @CommandClass(helpText=...)
* Parameters annotated with this receive all of the remaining arguments
@ -70,16 +47,11 @@ public abstract class Command2 {
}
@RequiredArgsConstructor
protected static class SubcommandData<T extends Command2> {
protected static class SubcommandData<T extends ICommand2> {
public final Method method;
public final T command;
public final String[] helpText;
}
public Command2() {
path = getcmdpath();
}
/**
* Adds a param converter that obtains a specific object from a string parameter.
* The converter may return null.
@ -88,11 +60,15 @@ public abstract class Command2 {
* @param converter The converter to use
* @param <T> The type of the result
*/
protected static <T> void addParamConverter(Class<T> cl, Function<String, T> converter, HashMap<Class<?>, Function<String, ?>> map) {
public abstract <T> void addParamConverter(Class<T> cl, Function<String, T> converter);
protected <T> void addParamConverter(Class<T> cl, Function<String, T> converter, HashMap<Class<?>, Function<String, ?>> map) {
map.put(cl, converter);
}
protected static <T extends Command2> boolean handleCommand(CommandSender sender, String commandline,
public abstract boolean handleCommand(CommandSender sender, String commandLine) throws Exception;
protected <T extends ICommand2> boolean handleCommand(CommandSender sender, String commandline,
HashMap<String, SubcommandData<T>> subcommands, HashMap<Class<?>, Function<String, ?>> paramConverters) throws Exception {
for (int i = commandline.length(); i != -1; i = commandline.lastIndexOf(' ', i - 1)) {
String subcommand = commandline.substring(0, i).toLowerCase();
@ -147,7 +123,9 @@ public abstract class Command2 {
return false; //Didn't handle
} //TODO: Add to the help
protected static <T extends Command2> void registerCommand(T command, HashMap<String, SubcommandData<T>> subcommands, char commandChar) {
public abstract void registerCommand(ICommand2 command);
protected <T extends ICommand2> void registerCommand(T command, HashMap<String, SubcommandData<T>> subcommands, char commandChar) {
val path = command.getCommandPath();
try { //Register the default handler first so it can be reliably overwritten
val method = command.getClass().getMethod("def", CommandSender.class, String.class);
@ -200,28 +178,5 @@ public abstract class Command2 {
return ht;
}
private final String path;
/**
* The command's path, or name if top-level command.<br>
* For example:<br>
* "u admin updateplugin" or "u" for the top level one<br>
* <u>The path must be lowercase!</u><br>
*
* @return The command path, <i>which is the command class name by default</i> (removing any "command" from it) - Change via the {@link CommandClass} annotation
*/
public final String getCommandPath() {
return path;
}
private String getcmdpath() {
if (!getClass().isAnnotationPresent(CommandClass.class))
throw new RuntimeException(
"No @CommandClass annotation on command class " + getClass().getSimpleName() + "!");
Function<Class<?>, String> getFromClass = cl -> cl.getSimpleName().toLowerCase().replace("commandbase", "") // <-- ...
.replace("command", "");
String path = getClass().getAnnotation(CommandClass.class).path();
path = path.length() == 0 ? getFromClass.apply(getClass()) : path;
return path;
}
public abstract boolean hasPermission(CommandSender sender, ICommand2 command);
} //TODO: Test support of Player instead of CommandSender

View file

@ -7,18 +7,18 @@ import java.util.function.Function;
public class Command2MC extends Command2 {
private static HashMap<String, SubcommandData<Command2MC>> subcommands = new HashMap<>();
private static HashMap<Class<?>, Function<String, ?>> paramConverters = new HashMap<>();
private HashMap<String, SubcommandData<ICommand2>> subcommands = new HashMap<>();
private HashMap<Class<?>, Function<String, ?>> paramConverters = new HashMap<>();
public static boolean handleCommand(CommandSender sender, String commandLine) throws Exception {
public boolean handleCommand(CommandSender sender, String commandLine) throws Exception {
return handleCommand(sender, commandLine, subcommands, paramConverters);
}
public static void registerCommand(Command2MC command) {
public void registerCommand(ICommand2 command) {
registerCommand(command, subcommands, '/');
}
public static <T> void addParamConverter(Class<T> cl, Function<String, T> converter) {
public <T> void addParamConverter(Class<T> cl, Function<String, T> converter) {
addParamConverter(cl, converter, paramConverters);
}
}

View file

@ -0,0 +1,63 @@
package buttondevteam.lib.chat;
import lombok.Getter;
import org.bukkit.command.CommandSender;
import java.util.function.Function;
public abstract class ICommand2 {
/**
* Default handler for commands, can be used to copy the args too.
*
* @param sender The sender which ran the command
* @param args All of the arguments passed as is
* @return The success of the command
*/
public boolean def(CommandSender sender, @Command2.TextArg String args) {
return false;
}
/**
* Convenience method. Return with this.
*
* @param sender The sender of the command
* @param message The message to send to the sender
* @return Always true so that the usage isn't shown
*/
protected boolean respond(CommandSender sender, String message) {
sender.sendMessage(message);
return true;
}
private final String path;
@Getter
private final Command2 manager;
public ICommand2(Command2 manager) {
path = getcmdpath();
this.manager = manager;
}
/**
* The command's path, or name if top-level command.<br>
* For example:<br>
* "u admin updateplugin" or "u" for the top level one<br>
* <u>The path must be lowercase!</u><br>
*
* @return The command path, <i>which is the command class name by default</i> (removing any "command" from it) - Change via the {@link CommandClass} annotation
*/
public final String getCommandPath() {
return path;
}
private String getcmdpath() {
if (!getClass().isAnnotationPresent(CommandClass.class))
throw new RuntimeException(
"No @CommandClass annotation on command class " + getClass().getSimpleName() + "!");
Function<Class<?>, String> getFromClass = cl -> cl.getSimpleName().toLowerCase().replace("commandbase", "") // <-- ...
.replace("command", "");
String path = getClass().getAnnotation(CommandClass.class).path();
path = path.length() == 0 ? getFromClass.apply(getClass()) : path;
return path;
}
}

View file

@ -0,0 +1,9 @@
package buttondevteam.lib.chat;
import buttondevteam.lib.architecture.ButtonPlugin;
public class ICommand2MC extends ICommand2 {
public ICommand2MC() {
super(ButtonPlugin.getCommand2MC());
}
}