Separated commands and handlers
WIP
This commit is contained in:
parent
ab603276d3
commit
ab24480f89
8 changed files with 98 additions and 69 deletions
|
@ -12,7 +12,6 @@
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<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="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: 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: com.google.code.findbugs:annotations:2.0.1" level="project" />
|
||||||
<orderEntry type="library" name="Maven: org.javassist:javassist:3.20.0-GA" level="project" />
|
<orderEntry type="library" name="Maven: org.javassist:javassist:3.20.0-GA" level="project" />
|
||||||
|
|
|
@ -2,8 +2,9 @@ package buttondevteam.core;
|
||||||
|
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
import buttondevteam.lib.architecture.Component;
|
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.CommandClass;
|
||||||
|
import buttondevteam.lib.chat.ICommand2MC;
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
|
@ -15,10 +16,9 @@ import java.util.Optional;
|
||||||
"§6---- Component command ----",
|
"§6---- Component command ----",
|
||||||
"Can be used to enable/disable/list components"
|
"Can be used to enable/disable/list components"
|
||||||
})
|
})
|
||||||
public class ComponentCommand extends Command2MC {
|
public class ComponentCommand extends ICommand2MC {
|
||||||
public ComponentCommand() {
|
public ComponentCommand() {
|
||||||
addParamConverter(Plugin.class, arg -> Bukkit.getPluginManager().getPlugin(arg));
|
getManager().addParamConverter(Plugin.class, arg -> Bukkit.getPluginManager().getPlugin(arg));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subcommand
|
@Subcommand
|
||||||
|
|
|
@ -2,6 +2,7 @@ package buttondevteam.lib.architecture;
|
||||||
|
|
||||||
import buttondevteam.core.ComponentManager;
|
import buttondevteam.core.ComponentManager;
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
|
import buttondevteam.lib.chat.Command2MC;
|
||||||
import buttondevteam.lib.chat.TBMCChatAPI;
|
import buttondevteam.lib.chat.TBMCChatAPI;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
@ -11,6 +12,8 @@ import org.bukkit.plugin.java.JavaPlugin;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
|
|
||||||
public abstract class ButtonPlugin extends JavaPlugin {
|
public abstract class ButtonPlugin extends JavaPlugin {
|
||||||
|
@Getter
|
||||||
|
private static Command2MC command2MC = new Command2MC();
|
||||||
@Getter(AccessLevel.PROTECTED)
|
@Getter(AccessLevel.PROTECTED)
|
||||||
private IHaveConfig iConfig;
|
private IHaveConfig iConfig;
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -3,7 +3,7 @@ package buttondevteam.lib.architecture;
|
||||||
import buttondevteam.core.ComponentManager;
|
import buttondevteam.core.ComponentManager;
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
import buttondevteam.lib.architecture.exceptions.UnregisteredComponentException;
|
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.TBMCChatAPI;
|
||||||
import buttondevteam.lib.chat.TBMCCommandBase;
|
import buttondevteam.lib.chat.TBMCCommandBase;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
@ -197,8 +197,8 @@ public abstract class Component {
|
||||||
*
|
*
|
||||||
* @param commandBase Custom coded command class
|
* @param commandBase Custom coded command class
|
||||||
*/
|
*/
|
||||||
protected final void registerCommand(Command2MC commandBase) {
|
protected final void registerCommand(ICommand2 commandBase) {
|
||||||
Command2MC.registerCommand(commandBase);
|
ButtonPlugin.getCommand2MC().registerCommand(commandBase);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -25,29 +25,6 @@ import java.util.stream.Collectors;
|
||||||
* The args may be null if the conversion failed.
|
* The args may be null if the conversion failed.
|
||||||
*/
|
*/
|
||||||
public abstract class Command2 {
|
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=...)
|
* TODO: @CommandClass(helpText=...)
|
||||||
* Parameters annotated with this receive all of the remaining arguments
|
* Parameters annotated with this receive all of the remaining arguments
|
||||||
|
@ -70,16 +47,11 @@ public abstract class Command2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
protected static class SubcommandData<T extends Command2> {
|
protected static class SubcommandData<T extends ICommand2> {
|
||||||
public final Method method;
|
public final Method method;
|
||||||
public final T command;
|
public final T command;
|
||||||
public final String[] helpText;
|
public final String[] helpText;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Command2() {
|
|
||||||
path = getcmdpath();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a param converter that obtains a specific object from a string parameter.
|
* Adds a param converter that obtains a specific object from a string parameter.
|
||||||
* The converter may return null.
|
* The converter may return null.
|
||||||
|
@ -88,11 +60,15 @@ public abstract class Command2 {
|
||||||
* @param converter The converter to use
|
* @param converter The converter to use
|
||||||
* @param <T> The type of the result
|
* @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);
|
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 {
|
HashMap<String, SubcommandData<T>> subcommands, HashMap<Class<?>, Function<String, ?>> paramConverters) throws Exception {
|
||||||
for (int i = commandline.length(); i != -1; i = commandline.lastIndexOf(' ', i - 1)) {
|
for (int i = commandline.length(); i != -1; i = commandline.lastIndexOf(' ', i - 1)) {
|
||||||
String subcommand = commandline.substring(0, i).toLowerCase();
|
String subcommand = commandline.substring(0, i).toLowerCase();
|
||||||
|
@ -147,7 +123,9 @@ public abstract class Command2 {
|
||||||
return false; //Didn't handle
|
return false; //Didn't handle
|
||||||
} //TODO: Add to the help
|
} //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();
|
val path = command.getCommandPath();
|
||||||
try { //Register the default handler first so it can be reliably overwritten
|
try { //Register the default handler first so it can be reliably overwritten
|
||||||
val method = command.getClass().getMethod("def", CommandSender.class, String.class);
|
val method = command.getClass().getMethod("def", CommandSender.class, String.class);
|
||||||
|
@ -200,28 +178,5 @@ public abstract class Command2 {
|
||||||
return ht;
|
return ht;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final String path;
|
public abstract boolean hasPermission(CommandSender sender, ICommand2 command);
|
||||||
|
|
||||||
/**
|
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
} //TODO: Test support of Player instead of CommandSender
|
} //TODO: Test support of Player instead of CommandSender
|
||||||
|
|
|
@ -7,18 +7,18 @@ import java.util.function.Function;
|
||||||
|
|
||||||
public class Command2MC extends Command2 {
|
public class Command2MC extends Command2 {
|
||||||
|
|
||||||
private static HashMap<String, SubcommandData<Command2MC>> subcommands = new HashMap<>();
|
private HashMap<String, SubcommandData<ICommand2>> subcommands = new HashMap<>();
|
||||||
private static HashMap<Class<?>, Function<String, ?>> paramConverters = 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);
|
return handleCommand(sender, commandLine, subcommands, paramConverters);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void registerCommand(Command2MC command) {
|
public void registerCommand(ICommand2 command) {
|
||||||
registerCommand(command, subcommands, '/');
|
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);
|
addParamConverter(cl, converter, paramConverters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package buttondevteam.lib.chat;
|
||||||
|
|
||||||
|
import buttondevteam.lib.architecture.ButtonPlugin;
|
||||||
|
|
||||||
|
public class ICommand2MC extends ICommand2 {
|
||||||
|
public ICommand2MC() {
|
||||||
|
super(ButtonPlugin.getCommand2MC());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue