完善 @TCommand 注解
新增 TCommandHandler 类用于动态命令注册
This commit is contained in:
@@ -25,14 +25,21 @@ import java.util.stream.Collectors;
|
||||
* @Author sky
|
||||
* @Since 2018-05-07 21:38
|
||||
*/
|
||||
public abstract class BaseMainCommand implements IMainCommand, CommandExecutor, TabExecutor {
|
||||
public abstract class BaseMainCommand implements CommandExecutor, TabExecutor {
|
||||
|
||||
private PluginCommand registerCommand;
|
||||
private List<Class<?>> linkClasses = new CopyOnWriteArrayList<>();
|
||||
private List<BaseSubCommand> subCommands = new CopyOnWriteArrayList<>();
|
||||
|
||||
/**
|
||||
* 指令标题
|
||||
*
|
||||
* @return 文本
|
||||
*/
|
||||
abstract public String getCommandTitle();
|
||||
|
||||
public static BaseMainCommand createCommandExecutor(String command, BaseMainCommand baseMainCommand) {
|
||||
Preconditions.checkArgument(Bukkit.getPluginCommand(command) != null, "PluginCommand \"" + command + "\"not found");
|
||||
Preconditions.checkArgument(Bukkit.getPluginCommand(command) != null, "PluginCommand \"" + command + "\" not found");
|
||||
Preconditions.checkArgument(baseMainCommand != null, "Executor cannot be null");
|
||||
Preconditions.checkArgument(baseMainCommand.getClass() != BaseMainCommand.class, "Executor can not be \"BaseMainCommand.class\"");
|
||||
baseMainCommand.setRegisterCommand(Bukkit.getPluginCommand(command));
|
||||
@@ -99,6 +106,11 @@ public abstract class BaseMainCommand implements IMainCommand, CommandExecutor,
|
||||
subCommands.add(subCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(CommandSender commandSender, Command command, String s, String[] args) {
|
||||
return args.length == 1 ? subCommands.stream().filter(subCommand -> subCommand != null && hasPermission(commandSender, subCommand) && (args[0].isEmpty() || subCommand.getLabel().toLowerCase().startsWith(args[0].toLowerCase()))).map(BaseSubCommand::getLabel).collect(Collectors.toList()) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
|
||||
if (args.length == 0) {
|
||||
@@ -134,11 +146,6 @@ public abstract class BaseMainCommand implements IMainCommand, CommandExecutor,
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(CommandSender commandSender, Command command, String s, String[] args) {
|
||||
return args.length == 1 ? subCommands.stream().filter(subCommand -> subCommand != null && hasPermission(commandSender, subCommand) && (args[0].isEmpty() || subCommand.getLabel().toLowerCase().startsWith(args[0].toLowerCase()))).map(ISubCommand::getLabel).collect(Collectors.toList()) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "registerCommand=" + "BaseMainCommand{" + registerCommand + ", linkClasses=" + linkClasses + ", subCommands=" + subCommands + '}';
|
||||
@@ -161,6 +168,12 @@ public abstract class BaseMainCommand implements IMainCommand, CommandExecutor,
|
||||
return Objects.hash(getRegisterCommand(), getLinkClasses(), getSubCommands());
|
||||
}
|
||||
|
||||
// *********************************
|
||||
//
|
||||
// Private Methods
|
||||
//
|
||||
// *********************************
|
||||
|
||||
private String getEmptyLine() {
|
||||
return TabooLib.getVerint() < 10800 ? "~" : "";
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package me.skymc.taboolib.commands.internal;
|
||||
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.commands.internal.type.CommandArgument;
|
||||
import me.skymc.taboolib.commands.internal.type.CommandType;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -11,28 +14,91 @@ import java.util.stream.IntStream;
|
||||
* @author Bkm016
|
||||
* @since 2018-04-17
|
||||
*/
|
||||
public abstract class BaseSubCommand implements ISubCommand {
|
||||
public abstract class BaseSubCommand {
|
||||
|
||||
/**
|
||||
* 指令名
|
||||
*
|
||||
* @return 文本
|
||||
*/
|
||||
abstract public String getLabel();
|
||||
|
||||
/**
|
||||
* 指令描述
|
||||
*
|
||||
* @return 文本
|
||||
*/
|
||||
abstract public String getDescription();
|
||||
|
||||
/**
|
||||
* 指令参数
|
||||
*
|
||||
* @return {@link CommandArgument}
|
||||
*/
|
||||
abstract public CommandArgument[] getArguments();
|
||||
|
||||
/**
|
||||
* 指令执行方法
|
||||
*
|
||||
* @param sender 指令使用者
|
||||
* @param command 指令对象
|
||||
* @param label 主命令
|
||||
* @param args 参数(不含主命令及子命令)
|
||||
*/
|
||||
abstract public void onCommand(CommandSender sender, Command command, String label, String[] args);
|
||||
|
||||
/**
|
||||
* 指令执行者
|
||||
*
|
||||
* @return {@link CommandType}
|
||||
*/
|
||||
public CommandType getType() {
|
||||
return CommandType.ALL;
|
||||
}
|
||||
|
||||
/**
|
||||
* 参数是否屏蔽子命令名
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean ignoredLabel() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否需要玩家在线
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean requiredPlayer() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 需要权限
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public String getPermission() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 参数是否符合
|
||||
*
|
||||
* @param args 参数
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean isParameterConform(String[] args) {
|
||||
return IntStream.range(0, getArguments().length).noneMatch(i -> getArguments()[i].isRequired() && (args == null || args.length <= i));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取帮助文本
|
||||
*
|
||||
* @param label 子命令标题
|
||||
* @return String
|
||||
*/
|
||||
public String getCommandString(String label) {
|
||||
String stringBuilder = Arrays.stream(getArguments()).map(parameter -> parameter.toString() + " ").collect(Collectors.joining());
|
||||
return TLocale.asString("COMMANDS.INTERNAL.COMMAND-HELP", label, getLabel(), stringBuilder.trim(), getDescription());
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
package me.skymc.taboolib.commands.internal;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-05-07 21:36
|
||||
*/
|
||||
public interface IMainCommand {
|
||||
|
||||
/**
|
||||
* 指令标题
|
||||
*
|
||||
* @return 文本
|
||||
*/
|
||||
String getCommandTitle();
|
||||
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
package me.skymc.taboolib.commands.internal;
|
||||
|
||||
import me.skymc.taboolib.commands.internal.type.CommandArgument;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
/**
|
||||
* @author Bkm016
|
||||
* @since 2018-04-17
|
||||
*/
|
||||
public interface ISubCommand {
|
||||
|
||||
/**
|
||||
* 指令名
|
||||
*
|
||||
* @return 文本
|
||||
*/
|
||||
String getLabel();
|
||||
|
||||
/**
|
||||
* 指令描述
|
||||
*
|
||||
* @return 文本
|
||||
*/
|
||||
String getDescription();
|
||||
|
||||
/**
|
||||
* 指令参数
|
||||
*
|
||||
* @return {@link CommandArgument}
|
||||
*/
|
||||
CommandArgument[] getArguments();
|
||||
|
||||
/**
|
||||
* 指令执行方法
|
||||
*
|
||||
* @param sender 指令使用者
|
||||
* @param command 指令对象
|
||||
* @param label 主命令
|
||||
* @param args 参数(不含主命令及子命令)
|
||||
*/
|
||||
void onCommand(CommandSender sender, Command command, String label, String[] args);
|
||||
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
package me.skymc.taboolib.commands.internal;
|
||||
|
||||
import me.skymc.taboolib.fileutils.FileUtils;
|
||||
import me.skymc.taboolib.listener.TListener;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.server.PluginEnableEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-05-23 2:43
|
||||
*/
|
||||
@TListener(register = "onLoad")
|
||||
public class TBaseCommand implements Listener {
|
||||
|
||||
void onLoad() {
|
||||
registerCommands();
|
||||
}
|
||||
|
||||
/**
|
||||
* 向服务端注册 BaseMainCommand 类
|
||||
*
|
||||
* @param command 命令全称(需在 plugin.yml 内注册)
|
||||
* @param baseMainCommand 命令对象
|
||||
* @return {@link BaseMainCommand}
|
||||
*/
|
||||
public static BaseMainCommand registerCommand(String command, BaseMainCommand baseMainCommand) {
|
||||
return BaseMainCommand.createCommandExecutor(command, baseMainCommand);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册所有插件的所有 TCommand 命令
|
||||
*/
|
||||
public static void registerCommands() {
|
||||
for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
|
||||
try {
|
||||
registerCommand(plugin);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册插件的所有 TCommand 命令
|
||||
*
|
||||
* @param plugin 插件
|
||||
*/
|
||||
public static void registerCommand(Plugin plugin) {
|
||||
for (Class pluginClass : FileUtils.getClasses(plugin)) {
|
||||
if (BaseMainCommand.class.isAssignableFrom(pluginClass) && pluginClass.isAnnotationPresent(TCommand.class)) {
|
||||
TCommand tCommand = (TCommand) pluginClass.getAnnotation(TCommand.class);
|
||||
try {
|
||||
registerCommand(tCommand.name(), (BaseMainCommand) pluginClass.newInstance());
|
||||
} catch (InstantiationException | IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onEnable(PluginEnableEvent e) {
|
||||
try {
|
||||
registerCommand(e.getPlugin());
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
@@ -15,4 +16,13 @@ public @interface TCommand {
|
||||
|
||||
String name();
|
||||
|
||||
String permission() default "";
|
||||
|
||||
String permissionMessage() default "";
|
||||
|
||||
String description() default "";
|
||||
|
||||
String usage() default "";
|
||||
|
||||
String[] aliases() default "";
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
package me.skymc.taboolib.commands.internal;
|
||||
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import me.skymc.taboolib.fileutils.FileUtils;
|
||||
import me.skymc.taboolib.listener.TListener;
|
||||
import me.skymc.taboolib.methods.ReflectionUtils;
|
||||
import me.skymc.taboolib.string.ArrayUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.*;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.server.PluginEnableEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-05-23 2:43
|
||||
*/
|
||||
@TListener
|
||||
public class TCommandHandler implements Listener {
|
||||
|
||||
private static SimpleCommandMap commandMap;
|
||||
|
||||
public TCommandHandler() {
|
||||
try {
|
||||
Field commandMap = Bukkit.getPluginManager().getClass().getDeclaredField("commandMap");
|
||||
commandMap.setAccessible(true);
|
||||
TCommandHandler.commandMap = (SimpleCommandMap) commandMap.get(Bukkit.getPluginManager());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
registerCommands();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onEnable(PluginEnableEvent e) {
|
||||
try {
|
||||
registerCommand(e.getPlugin());
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean registerPluginCommand(Plugin plugin, String command, CommandExecutor commandExecutor) {
|
||||
return registerPluginCommand(plugin, command, "", "/" + command, new ArrayList<>(), null, null, commandExecutor, null);
|
||||
}
|
||||
|
||||
public static boolean registerPluginCommand(Plugin plugin, String command, CommandExecutor commandExecutor, TabExecutor tabExecutor) {
|
||||
return registerPluginCommand(plugin, command, "", "/" + command, new ArrayList<>(), null, null, commandExecutor, tabExecutor);
|
||||
}
|
||||
|
||||
public static boolean registerPluginCommand(Plugin plugin, String command, String description, CommandExecutor commandExecutor, TabExecutor tabExecutor) {
|
||||
return registerPluginCommand(plugin, command, description, "/" + command, new ArrayList<>(), null, null, commandExecutor, tabExecutor);
|
||||
}
|
||||
|
||||
public static boolean registerPluginCommand(Plugin plugin, String command, String description, String usage, CommandExecutor commandExecutor, TabExecutor tabExecutor) {
|
||||
return registerPluginCommand(plugin, command, description, usage, new ArrayList<>(), null, null, commandExecutor, tabExecutor);
|
||||
}
|
||||
|
||||
public static boolean registerPluginCommand(Plugin plugin, String command, String description, String usage, List<String> aliases, CommandExecutor commandExecutor, TabExecutor tabExecutor) {
|
||||
return registerPluginCommand(plugin, command, description, usage, aliases, null, null, commandExecutor, tabExecutor);
|
||||
}
|
||||
|
||||
/**
|
||||
* 向服务端动态注册命令
|
||||
*
|
||||
* @param plugin 所属插件
|
||||
* @param command 命令名称
|
||||
* @param description 命令描述
|
||||
* @param usage 命令用法
|
||||
* @param aliases 别名
|
||||
* @param permission 权限
|
||||
* @param permissionMessage 权限提示
|
||||
* @param commandExecutor 命令执行器
|
||||
* @param tabExecutor 补全执行器
|
||||
* @return 注册结果(boolean)
|
||||
*/
|
||||
public static boolean registerPluginCommand(Plugin plugin, String command, String description, String usage, List<String> aliases, String permission, String permissionMessage, CommandExecutor commandExecutor, TabExecutor tabExecutor) {
|
||||
try {
|
||||
Constructor<PluginCommand> constructor = PluginCommand.class.getDeclaredConstructor(String.class, Plugin.class);
|
||||
constructor.setAccessible(true);
|
||||
PluginCommand pluginCommand = constructor.newInstance(command, plugin);
|
||||
pluginCommand.setExecutor(commandExecutor);
|
||||
pluginCommand.setTabCompleter(tabExecutor);
|
||||
ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "description", description);
|
||||
ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "usageMessage", usage);
|
||||
ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "aliases", aliases);
|
||||
ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "activeAliases", aliases);
|
||||
ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "permission", permission);
|
||||
ReflectionUtils.setValue(pluginCommand, pluginCommand.getClass().getSuperclass(), true, "permissionMessage", permissionMessage);
|
||||
commandMap.register(command, pluginCommand);
|
||||
TLocale.Logger.info("COMMANDS.INTERNAL.COMMAND-CREATE", plugin.getName(), command);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
TLocale.Logger.info("COMMANDS.INTERNAL.COMMAND-CREATE-FAILED", plugin.getName(), command, e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 向服务端注册 BaseMainCommand 类
|
||||
*
|
||||
* @param command 命令全称(需在 plugin.yml 内注册)
|
||||
* @param baseMainCommand 命令对象
|
||||
* @return {@link BaseMainCommand}
|
||||
*/
|
||||
public static BaseMainCommand registerCommand(TCommand tCommand, String command, BaseMainCommand baseMainCommand, Plugin plugin) {
|
||||
if (Bukkit.getPluginCommand(command) == null) {
|
||||
registerPluginCommand(
|
||||
plugin,
|
||||
command,
|
||||
ArrayUtils.skipEmpty(tCommand.description(), "Registered by TabooLib."),
|
||||
ArrayUtils.skipEmpty(tCommand.usage(), "/" + command),
|
||||
ArrayUtils.skipEmpty(ArrayUtils.asList(tCommand.aliases()), new ArrayList<>()),
|
||||
ArrayUtils.skipEmpty(tCommand.permission()),
|
||||
ArrayUtils.skipEmpty(tCommand.permissionMessage()),
|
||||
baseMainCommand,
|
||||
baseMainCommand);
|
||||
}
|
||||
return BaseMainCommand.createCommandExecutor(command, baseMainCommand);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册所有插件的所有 TCommand 命令
|
||||
*/
|
||||
public static void registerCommands() {
|
||||
for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
|
||||
try {
|
||||
registerCommand(plugin);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册插件的所有 TCommand 命令
|
||||
*
|
||||
* @param plugin 插件
|
||||
*/
|
||||
public static void registerCommand(Plugin plugin) {
|
||||
for (Class pluginClass : FileUtils.getClasses(plugin)) {
|
||||
if (BaseMainCommand.class.isAssignableFrom(pluginClass) && pluginClass.isAnnotationPresent(TCommand.class)) {
|
||||
TCommand tCommand = (TCommand) pluginClass.getAnnotation(TCommand.class);
|
||||
try {
|
||||
registerCommand(tCommand, tCommand.name(), (BaseMainCommand) pluginClass.newInstance(), plugin);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取插件注册的命令
|
||||
*
|
||||
* @param command 命令名称
|
||||
* @return {@link Command}
|
||||
*/
|
||||
public static Command getPluginCommand(String command) {
|
||||
return commandMap.getCommand(command);
|
||||
}
|
||||
|
||||
// *********************************
|
||||
//
|
||||
// Getter and Setter
|
||||
//
|
||||
// *********************************
|
||||
|
||||
public static SimpleCommandMap getCommandMap() {
|
||||
return commandMap;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user