mirror of
https://github.com/aikar/commands.git
synced 2026-06-11 18:40:37 +00:00
supper inner classes and parent up subcommand bases - Resolves #20
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
package co.aikar.acfexample;
|
||||
|
||||
import co.aikar.commands.BaseCommand;
|
||||
import co.aikar.commands.BaseSubCommand;
|
||||
import co.aikar.commands.annotation.CommandAlias;
|
||||
import co.aikar.commands.annotation.CommandCompletion;
|
||||
import co.aikar.commands.annotation.CommandPermission;
|
||||
@@ -38,7 +39,7 @@ import org.bukkit.entity.Player;
|
||||
@CommandAlias("acf|somecommand|sc|somcom")
|
||||
public class SomeCommand extends BaseCommand {
|
||||
|
||||
@Subcommand("test")
|
||||
@Subcommand("test4")
|
||||
@CommandAlias("acftest|acft")
|
||||
public void onCommand(CommandSender sender, SomeObject someObject) {
|
||||
sender.sendMessage("You got an object of type: " + someObject.getClass().getName() + " with a value of: " + someObject.getValue());
|
||||
@@ -79,4 +80,35 @@ public class SomeCommand extends BaseCommand {
|
||||
public void onTestSub1(CommandSender sender, String hi) {
|
||||
sender.sendMessage(hi);
|
||||
}
|
||||
|
||||
@Subcommand("test|txt|tfoo")
|
||||
public class Test extends BaseSubCommand {
|
||||
|
||||
@Subcommand("test1|td1")
|
||||
@CommandCompletion("FOO")
|
||||
public void onTest1(Player player, String testX) {
|
||||
player.sendMessage("You got test inner test1: " + testX);
|
||||
}
|
||||
@Subcommand("test2|td2")
|
||||
@CommandCompletion("BAR")
|
||||
public void onTest2(Player player, String testY) {
|
||||
player.sendMessage("You got test inner test2: " + testY);
|
||||
}
|
||||
|
||||
@Subcommand("next")
|
||||
public class TestInner extends BaseSubCommand {
|
||||
|
||||
@Subcommand("test3|td4")
|
||||
@CommandCompletion("FOO")
|
||||
public void onTest1(Player player, String testX) {
|
||||
player.sendMessage("You got test inner inner test3: " + testX);
|
||||
}
|
||||
@CommandAlias("deepinner")
|
||||
@Subcommand("test4|td4")
|
||||
@CommandCompletion("BAR")
|
||||
public void onTest2(Player player, String testY) {
|
||||
player.sendMessage("You got test inner inner test4: " + testY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,8 +40,11 @@ import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.util.StringUtil;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
@@ -52,9 +55,10 @@ import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public abstract class BaseCommand extends Command {
|
||||
public class BaseCommand extends Command {
|
||||
|
||||
public static final String UNKNOWN = "__unknown";
|
||||
public static final String DEFAULT = "__default";
|
||||
@@ -102,10 +106,12 @@ public abstract class BaseCommand extends Command {
|
||||
}
|
||||
|
||||
void onRegister(CommandManager manager) {
|
||||
onRegister(manager, getName());
|
||||
}
|
||||
void onRegister(CommandManager manager, String cmd) {
|
||||
this.manager = manager;
|
||||
final Class<? extends BaseCommand> self = this.getClass();
|
||||
CommandAlias rootCmdAlias = self.getAnnotation(CommandAlias.class);
|
||||
String cmd = this.getName();
|
||||
if (cmd == null) {
|
||||
if (rootCmdAlias == null) {
|
||||
cmd = "__" + self.getSimpleName();
|
||||
@@ -141,7 +147,7 @@ public abstract class BaseCommand extends Command {
|
||||
for (Method method : self.getDeclaredMethods()) {
|
||||
method.setAccessible(true);
|
||||
String sublist = null;
|
||||
final Subcommand sub = method.getAnnotation(Subcommand.class);
|
||||
String sub = getSubcommandValue(method);
|
||||
final Default def = method.getAnnotation(Default.class);
|
||||
|
||||
final CommandAlias commandAliases = method.getAnnotation(CommandAlias.class);
|
||||
@@ -155,7 +161,7 @@ public abstract class BaseCommand extends Command {
|
||||
}
|
||||
}
|
||||
if (sub != null) {
|
||||
sublist = sub.value();
|
||||
sublist = sub;
|
||||
} else if (commandAliases != null) {
|
||||
sublist = commandAliases.value();
|
||||
}
|
||||
@@ -185,7 +191,55 @@ public abstract class BaseCommand extends Command {
|
||||
}
|
||||
}
|
||||
|
||||
register(getName(), this);
|
||||
register(cmd, this);
|
||||
for (Class<?> clazz : this.getClass().getDeclaredClasses()) {
|
||||
if (BaseSubCommand.class.isAssignableFrom(clazz)) {
|
||||
try {
|
||||
BaseSubCommand subCommand = null;
|
||||
Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();
|
||||
for (Constructor<?> declaredConstructor : declaredConstructors) {
|
||||
|
||||
declaredConstructor.setAccessible(true);
|
||||
Parameter[] parameters = declaredConstructor.getParameters();
|
||||
if (parameters.length == 1) {
|
||||
subCommand = (BaseSubCommand) declaredConstructor.newInstance(this);
|
||||
} else {
|
||||
ACFLog.info("Found unusable constructor: " + declaredConstructor.getName() + "(" + Stream.of(parameters).map(p -> p.getType().getSimpleName() + " " + p.getName()).collect(Collectors.joining(", ")) + ")");
|
||||
}
|
||||
}
|
||||
if (subCommand != null) {
|
||||
subCommand.setParentCommand(this);
|
||||
subCommand.onRegister(manager, cmd);
|
||||
this.subCommands.putAll(subCommand.subCommands);
|
||||
this.registeredCommands.putAll(subCommand.registeredCommands);
|
||||
} else {
|
||||
ACFLog.severe("Could not find a subcommand ctor for " + clazz.getName());
|
||||
}
|
||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String getSubcommandValue(Method method) {
|
||||
final Subcommand sub = method.getAnnotation(Subcommand.class);
|
||||
if (sub == null) {
|
||||
return null;
|
||||
}
|
||||
List<String> subList = new ArrayList<>();
|
||||
subList.add(sub.value());
|
||||
Class<?> clazz = method.getDeclaringClass();
|
||||
while (clazz != null) {
|
||||
Subcommand classSub = clazz.getAnnotation(Subcommand.class);
|
||||
if (classSub != null) {
|
||||
subList.add(classSub.value());
|
||||
}
|
||||
clazz = clazz.getEnclosingClass();
|
||||
}
|
||||
Collections.reverse(subList);
|
||||
return ACFUtil.join(subList, " ");
|
||||
}
|
||||
|
||||
private void register(String name, BaseCommand cmd) {
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017 Daniel Ennis (Aikar) - MIT License
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package co.aikar.commands;
|
||||
|
||||
public class BaseSubCommand extends BaseCommand {
|
||||
private BaseCommand parentCommand;
|
||||
public BaseSubCommand() {}
|
||||
|
||||
void setParentCommand(BaseCommand command) {
|
||||
this.parentCommand = command;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return parentCommand.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return parentCommand.getLabel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return parentCommand.getDescription();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUsage() {
|
||||
return parentCommand.getUsage();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user