Component unregistering, command impr.
Automatically unregistering components in order (#57) Made the command system applicable for Discord as well
This commit is contained in:
parent
7331568886
commit
a4e96b0ed7
9 changed files with 78 additions and 47 deletions
|
@ -2,7 +2,7 @@ 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.Command2;
|
import buttondevteam.lib.chat.Command2MC;
|
||||||
import buttondevteam.lib.chat.CommandClass;
|
import buttondevteam.lib.chat.CommandClass;
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
@ -15,7 +15,7 @@ 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 Command2 {
|
public class ComponentCommand extends Command2MC {
|
||||||
public ComponentCommand() {
|
public ComponentCommand() {
|
||||||
addParamConverter(Plugin.class, arg -> Bukkit.getPluginManager().getPlugin(arg));
|
addParamConverter(Plugin.class, arg -> Bukkit.getPluginManager().getPlugin(arg));
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package buttondevteam.core;
|
package buttondevteam.core;
|
||||||
|
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
|
import buttondevteam.lib.architecture.ButtonPlugin;
|
||||||
import buttondevteam.lib.architecture.Component;
|
import buttondevteam.lib.architecture.Component;
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
|
|
||||||
|
@ -31,16 +32,11 @@ public final class ComponentManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disables all components that are enabled
|
* Unregister all components of a plugin that are enabled - called on {@link ButtonPlugin} disable
|
||||||
*/
|
*/
|
||||||
public static void disableComponents() {
|
public static void unregComponents(ButtonPlugin plugin) {
|
||||||
Component.getComponents().values().stream().filter(Component::isEnabled).forEach(c -> {
|
while (!plugin.getComponentStack().empty()) //Unregister in reverse order
|
||||||
try {
|
Component.unregisterComponent(plugin, plugin.getComponentStack().pop()); //Components are pushed on register
|
||||||
Component.setComponentEnabled(c, false);
|
|
||||||
} catch (Exception e) {
|
|
||||||
TBMCCoreAPI.SendException("Failed to disable one of the components: " + c.getClass().getSimpleName(), e);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
componentsEnabled = false;
|
componentsEnabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +52,7 @@ public final class ComponentManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Will also return false if the component is not registered.
|
* Will also return null if the component is not registered.
|
||||||
*
|
*
|
||||||
* @param cl The component class
|
* @param cl The component class
|
||||||
* @return The component if it's registered and enabled
|
* @return The component if it's registered and enabled
|
||||||
|
|
|
@ -14,7 +14,7 @@ import buttondevteam.lib.architecture.ButtonPlugin;
|
||||||
import buttondevteam.lib.architecture.Component;
|
import buttondevteam.lib.architecture.Component;
|
||||||
import buttondevteam.lib.architecture.ConfigData;
|
import buttondevteam.lib.architecture.ConfigData;
|
||||||
import buttondevteam.lib.chat.Color;
|
import buttondevteam.lib.chat.Color;
|
||||||
import buttondevteam.lib.chat.Command2;
|
import buttondevteam.lib.chat.Command2MC;
|
||||||
import buttondevteam.lib.chat.TBMCChatAPI;
|
import buttondevteam.lib.chat.TBMCChatAPI;
|
||||||
import buttondevteam.lib.player.ChromaGamerBase;
|
import buttondevteam.lib.player.ChromaGamerBase;
|
||||||
import buttondevteam.lib.player.TBMCPlayer;
|
import buttondevteam.lib.player.TBMCPlayer;
|
||||||
|
@ -69,7 +69,7 @@ public class MainPlugin extends ButtonPlugin {
|
||||||
Component.registerComponent(this, new MemberComponent());
|
Component.registerComponent(this, new MemberComponent());
|
||||||
Component.registerComponent(this, new TownyComponent());
|
Component.registerComponent(this, new TownyComponent());
|
||||||
ComponentManager.enableComponents();
|
ComponentManager.enableComponents();
|
||||||
Command2.registerCommand(new ComponentCommand());
|
Command2MC.registerCommand(new ComponentCommand());
|
||||||
TBMCCoreAPI.RegisterEventsForExceptions(new PlayerListener(), this);
|
TBMCCoreAPI.RegisterEventsForExceptions(new PlayerListener(), this);
|
||||||
ChromaGamerBase.addConverter(commandSender -> Optional.ofNullable(commandSender instanceof ConsoleCommandSender || commandSender instanceof BlockCommandSender
|
ChromaGamerBase.addConverter(commandSender -> Optional.ofNullable(commandSender instanceof ConsoleCommandSender || commandSender instanceof BlockCommandSender
|
||||||
? TBMCPlayer.getPlayer(new UUID(0, 0), TBMCPlayer.class) : null)); //Console & cmdblocks
|
? TBMCPlayer.getPlayer(new UUID(0, 0), TBMCPlayer.class) : null)); //Console & cmdblocks
|
||||||
|
@ -101,7 +101,6 @@ public class MainPlugin extends ButtonPlugin {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void pluginDisable() {
|
public void pluginDisable() {
|
||||||
ComponentManager.disableComponents();
|
|
||||||
logger.info("Saving player data...");
|
logger.info("Saving player data...");
|
||||||
TBMCPlayerBase.savePlayers();
|
TBMCPlayerBase.savePlayers();
|
||||||
logger.info("Player data saved.");
|
logger.info("Player data saved.");
|
||||||
|
|
|
@ -3,7 +3,7 @@ package buttondevteam.core;
|
||||||
import buttondevteam.lib.TBMCCommandPreprocessEvent;
|
import buttondevteam.lib.TBMCCommandPreprocessEvent;
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
import buttondevteam.lib.TBMCSystemChatEvent;
|
import buttondevteam.lib.TBMCSystemChatEvent;
|
||||||
import buttondevteam.lib.chat.Command2;
|
import buttondevteam.lib.chat.Command2MC;
|
||||||
import buttondevteam.lib.player.TBMCPlayerBase;
|
import buttondevteam.lib.player.TBMCPlayerBase;
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
@ -64,7 +64,7 @@ public class PlayerListener implements Listener {
|
||||||
public void onTBMCPreprocess(TBMCCommandPreprocessEvent event) {
|
public void onTBMCPreprocess(TBMCCommandPreprocessEvent event) {
|
||||||
if (event.isCancelled()) return;
|
if (event.isCancelled()) return;
|
||||||
try {
|
try {
|
||||||
event.setCancelled(Command2.handleCommand(event.getSender(), event.getMessage()));
|
event.setCancelled(Command2MC.handleCommand(event.getSender(), event.getMessage()));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
TBMCCoreAPI.SendException("Command processing failed for sender '" + event.getSender() + "' and message '" + event.getMessage() + "'", e);
|
TBMCCoreAPI.SendException("Command processing failed for sender '" + event.getSender() + "' and message '" + event.getMessage() + "'", e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import buttondevteam.lib.chat.TBMCChatAPI;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Server;
|
import org.bukkit.Server;
|
||||||
import org.bukkit.plugin.PluginManager;
|
import org.bukkit.plugin.PluginManager;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
import org.bukkit.scheduler.BukkitScheduler;
|
import org.bukkit.scheduler.BukkitScheduler;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.mockito.invocation.InvocationOnMock;
|
import org.mockito.invocation.InvocationOnMock;
|
||||||
|
@ -40,7 +41,7 @@ public class TestPrepare {
|
||||||
return cl.isAssignableFrom(invocation.getMethod().getReturnType());
|
return cl.isAssignableFrom(invocation.getMethod().getReturnType());
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
Component.registerComponent(Mockito.mock(MainPlugin.class), new ChannelComponent());
|
Component.registerComponent(Mockito.mock(JavaPlugin.class), new ChannelComponent());
|
||||||
TBMCChatAPI.RegisterChatChannel(Channel.GlobalChat = new Channel("§fg§f", Color.White, "g", null));
|
TBMCChatAPI.RegisterChatChannel(Channel.GlobalChat = new Channel("§fg§f", Color.White, "g", null));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package buttondevteam.lib.architecture;
|
package buttondevteam.lib.architecture;
|
||||||
|
|
||||||
|
import buttondevteam.core.ComponentManager;
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
import buttondevteam.lib.chat.TBMCChatAPI;
|
import buttondevteam.lib.chat.TBMCChatAPI;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
|
@ -7,9 +8,16 @@ import lombok.Getter;
|
||||||
import lombok.experimental.var;
|
import lombok.experimental.var;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
|
import java.util.Stack;
|
||||||
|
|
||||||
public abstract class ButtonPlugin extends JavaPlugin {
|
public abstract class ButtonPlugin extends JavaPlugin {
|
||||||
@Getter(AccessLevel.PROTECTED)
|
@Getter(AccessLevel.PROTECTED)
|
||||||
private IHaveConfig iConfig;
|
private IHaveConfig iConfig;
|
||||||
|
/**
|
||||||
|
* Used to unregister components in the right order
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
private Stack<Component> componentStack = new Stack<>();
|
||||||
|
|
||||||
protected abstract void pluginEnable();
|
protected abstract void pluginEnable();
|
||||||
|
|
||||||
|
@ -30,6 +38,7 @@ public abstract class ButtonPlugin extends JavaPlugin {
|
||||||
@Override
|
@Override
|
||||||
public final void onDisable() {
|
public final void onDisable() {
|
||||||
try {
|
try {
|
||||||
|
ComponentManager.unregComponents(this);
|
||||||
pluginDisable();
|
pluginDisable();
|
||||||
saveConfig();
|
saveConfig();
|
||||||
iConfig = null; //Clearing the hashmap is not enough, we need to update the section as well
|
iConfig = null; //Clearing the hashmap is not enough, we need to update the section as well
|
||||||
|
|
|
@ -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.Command2;
|
import buttondevteam.lib.chat.Command2MC;
|
||||||
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;
|
||||||
|
@ -39,7 +39,8 @@ public abstract class Component {
|
||||||
/**
|
/**
|
||||||
* Registers a component checking it's dependencies and calling {@link #register(JavaPlugin)}.<br>
|
* Registers a component checking it's dependencies and calling {@link #register(JavaPlugin)}.<br>
|
||||||
* Make sure to register the dependencies first.<br>
|
* Make sure to register the dependencies first.<br>
|
||||||
* The component will be enabled automatically, regardless of when it was registered.
|
* The component will be enabled automatically, regardless of when it was registered.<br>
|
||||||
|
* <b>If not using {@link ButtonPlugin}, call {@link ComponentManager#unregComponents(ButtonPlugin)} on plugin disable.</b>
|
||||||
*
|
*
|
||||||
* @param component The component to register
|
* @param component The component to register
|
||||||
* @return Whether the component is registered successfully (it may have failed to enable)
|
* @return Whether the component is registered successfully (it may have failed to enable)
|
||||||
|
@ -50,15 +51,13 @@ public abstract class Component {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unregisters a component by calling {@link #unregister(JavaPlugin)}.<br>
|
* Unregisters a component by calling {@link #unregister(JavaPlugin)}.<br>
|
||||||
* Make sure to unregister the dependencies last.
|
* Make sure to unregister the dependencies last.<br>
|
||||||
|
* <b>Components will be unregistered in opposite order of registering by default by {@link ButtonPlugin} or {@link ComponentManager#unregComponents(ButtonPlugin)}.</b>
|
||||||
*
|
*
|
||||||
* @param componentClass The component class to unregister
|
* @param component The component to unregister
|
||||||
* @return Whether the component is unregistered successfully (it also got disabled)
|
* @return Whether the component is unregistered successfully (it also got disabled)
|
||||||
*/
|
*/
|
||||||
public static boolean unregisterComponent(JavaPlugin plugin, Class<? extends Component> componentClass) {
|
public static boolean unregisterComponent(JavaPlugin plugin, Component component) {
|
||||||
val component = components.get(componentClass);
|
|
||||||
if (component == null)
|
|
||||||
return false; //Failed to load
|
|
||||||
return registerUnregisterComponent(plugin, component, false);
|
return registerUnregisterComponent(plugin, component, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,10 +74,16 @@ public abstract class Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (register) {
|
if (register) {
|
||||||
|
if (components.containsKey(component.getClass())) {
|
||||||
|
TBMCCoreAPI.SendException("Failed to register component " + component.getClassName(), new IllegalArgumentException("The component is already registered!"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
component.plugin = plugin;
|
component.plugin = plugin;
|
||||||
updateConfig(plugin, component);
|
updateConfig(plugin, component);
|
||||||
component.register(plugin);
|
component.register(plugin);
|
||||||
components.put(component.getClass(), component);
|
components.put(component.getClass(), component);
|
||||||
|
if (plugin instanceof ButtonPlugin)
|
||||||
|
((ButtonPlugin) plugin).getComponentStack().push(component);
|
||||||
if (ComponentManager.areComponentsEnabled() && component.shouldBeEnabled().get()) {
|
if (ComponentManager.areComponentsEnabled() && component.shouldBeEnabled().get()) {
|
||||||
try { //Enable components registered after the previous ones getting enabled
|
try { //Enable components registered after the previous ones getting enabled
|
||||||
setComponentEnabled(component, true);
|
setComponentEnabled(component, true);
|
||||||
|
@ -90,6 +95,8 @@ public abstract class Component {
|
||||||
}
|
}
|
||||||
return true; //Component shouldn't be enabled
|
return true; //Component shouldn't be enabled
|
||||||
} else {
|
} else {
|
||||||
|
if (!components.containsKey(component.getClass()))
|
||||||
|
return true; //Already unregistered
|
||||||
if (component.enabled) {
|
if (component.enabled) {
|
||||||
try {
|
try {
|
||||||
setComponentEnabled(component, false);
|
setComponentEnabled(component, false);
|
||||||
|
@ -190,8 +197,8 @@ public abstract class Component {
|
||||||
*
|
*
|
||||||
* @param commandBase Custom coded command class
|
* @param commandBase Custom coded command class
|
||||||
*/
|
*/
|
||||||
protected final void registerCommand(Command2 commandBase) {
|
protected final void registerCommand(Command2MC commandBase) {
|
||||||
Command2.registerCommand(commandBase);
|
Command2MC.registerCommand(commandBase);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -70,15 +70,12 @@ public abstract class Command2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
private static class SubcommandData {
|
protected static class SubcommandData<T extends Command2> {
|
||||||
public final Method method;
|
public final Method method;
|
||||||
public final Command2 command;
|
public final T command;
|
||||||
public final String[] helpText;
|
public final String[] helpText;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static HashMap<String, SubcommandData> subcommands = new HashMap<>();
|
|
||||||
private static HashMap<Class<?>, Function<String, ?>> paramConverters = new HashMap<>();
|
|
||||||
|
|
||||||
public Command2() {
|
public Command2() {
|
||||||
path = getcmdpath();
|
path = getcmdpath();
|
||||||
}
|
}
|
||||||
|
@ -91,18 +88,16 @@ 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
|
||||||
*/
|
*/
|
||||||
public static <T> void addParamConverter(Class<T> cl, Function<String, T> converter) {
|
protected static <T> void addParamConverter(Class<T> cl, Function<String, T> converter, HashMap<Class<?>, Function<String, ?>> map) {
|
||||||
paramConverters.put(cl, converter);
|
map.put(cl, converter);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean handleCommand(CommandSender sender, String commandline) throws Exception {
|
protected static <T extends Command2> 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)) {
|
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();
|
||||||
//System.out.println("Subcommand: "+subcommand);
|
|
||||||
//System.out.println("Subcmds: "+subcommands.toString());
|
|
||||||
SubcommandData sd = subcommands.get(subcommand); //O(1)
|
SubcommandData sd = subcommands.get(subcommand); //O(1)
|
||||||
if (sd == null) continue; //TODO: This will run each time someone runs any command
|
if (sd == null) continue; //TODO: This will run each time someone runs any command
|
||||||
//System.out.println("sd.method: "+sd.method); //TODO: Rename in Maven
|
|
||||||
val params = new ArrayList<Object>(sd.method.getParameterCount());
|
val params = new ArrayList<Object>(sd.method.getParameterCount());
|
||||||
int j = subcommand.length(), pj;
|
int j = subcommand.length(), pj;
|
||||||
Class<?>[] parameterTypes = sd.method.getParameterTypes();
|
Class<?>[] parameterTypes = sd.method.getParameterTypes();
|
||||||
|
@ -152,27 +147,28 @@ public abstract class Command2 {
|
||||||
return false; //Didn't handle
|
return false; //Didn't handle
|
||||||
} //TODO: Add to the help
|
} //TODO: Add to the help
|
||||||
|
|
||||||
public static void registerCommand(Command2 command) {
|
protected static <T extends Command2> 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
|
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);
|
||||||
val cc = command.getClass().getAnnotation(CommandClass.class);
|
val cc = command.getClass().getAnnotation(CommandClass.class);
|
||||||
var ht = cc == null ? new String[0] : cc.helpText();
|
var ht = cc == null ? new String[0] : cc.helpText();
|
||||||
String[] both = Arrays.copyOf(ht, ht.length + 1);
|
String[] both = Arrays.copyOf(ht, ht.length + 1);
|
||||||
both[ht.length] = "Usage: /" + command.path; //TODO: Print subcommands
|
both[ht.length] = "Usage: " + commandChar + path; //TODO: Print subcommands
|
||||||
ht = both;
|
ht = both;
|
||||||
subcommands.put("/" + command.path, new SubcommandData(method, command, ht)); //TODO: Disable components when the plugin is disabled
|
subcommands.put(commandChar + path, new SubcommandData<>(method, command, ht)); //TODO: Disable components when the plugin is disabled
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
TBMCCoreAPI.SendException("Could not register default handler for command /" + command.path, e);
|
TBMCCoreAPI.SendException("Could not register default handler for command /" + path, e);
|
||||||
} //Continue on
|
} //Continue on
|
||||||
for (val method : command.getClass().getMethods()) {
|
for (val method : command.getClass().getMethods()) {
|
||||||
val ann = method.getAnnotation(Subcommand.class);
|
val ann = method.getAnnotation(Subcommand.class);
|
||||||
if (ann != null) {
|
if (ann != null) {
|
||||||
val cc = command.getClass().getAnnotation(CommandClass.class);
|
val cc = command.getClass().getAnnotation(CommandClass.class);
|
||||||
var ht = ann.helpText().length != 0 || cc == null ? ann.helpText() : cc.helpText(); //If cc is null then it's empty array
|
var ht = ann.helpText().length != 0 || cc == null ? ann.helpText() : cc.helpText(); //If cc is null then it's empty array
|
||||||
val subcommand = "/" + command.path + //Add command path (class name by default)
|
val subcommand = commandChar + path + //Add command path (class name by default)
|
||||||
(method.getName().equals("def") ? "" : " " + method.getName().replace('_', ' ').toLowerCase()); //Add method name, unless it's 'def'
|
(method.getName().equals("def") ? "" : " " + method.getName().replace('_', ' ').toLowerCase()); //Add method name, unless it's 'def'
|
||||||
ht = getHelpText(method, ht, subcommand);
|
ht = getHelpText(method, ht, subcommand);
|
||||||
subcommands.put(subcommand, new SubcommandData(method, command, ht)); //Result of the above (def) is that it will show the help text
|
subcommands.put(subcommand, new SubcommandData<>(method, command, ht)); //Result of the above (def) is that it will show the help text
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -211,11 +207,10 @@ public abstract class Command2 {
|
||||||
* For example:<br>
|
* For example:<br>
|
||||||
* "u admin updateplugin" or "u" for the top level one<br>
|
* "u admin updateplugin" or "u" for the top level one<br>
|
||||||
* <u>The path must be lowercase!</u><br>
|
* <u>The path must be lowercase!</u><br>
|
||||||
* <b>Abstract classes with no {@link CommandClass} annotations will be ignored.</b>
|
|
||||||
*
|
*
|
||||||
* @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
|
* @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() {
|
public final String getCommandPath() {
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
package buttondevteam.lib.chat;
|
||||||
|
|
||||||
|
import org.bukkit.command.CommandSender;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
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<>();
|
||||||
|
|
||||||
|
public static boolean handleCommand(CommandSender sender, String commandLine) throws Exception {
|
||||||
|
return handleCommand(sender, commandLine, subcommands, paramConverters);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void registerCommand(Command2MC command) {
|
||||||
|
registerCommand(command, subcommands, '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> void addParamConverter(Class<T> cl, Function<String, T> converter) {
|
||||||
|
addParamConverter(cl, converter, paramConverters);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue