mirror of
https://e.coding.net/circlecloud/YumCore.git
synced 2024-11-24 02:08:48 +00:00
feat: 修复命令注册错误
Signed-off-by: 502647092 <admin@yumc.pw>
This commit is contained in:
parent
1a7e967826
commit
ad4126a810
@ -1,130 +1,129 @@
|
||||
package pw.yumc.YumCore.commands;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import pw.yumc.YumCore.bukkit.P;
|
||||
import pw.yumc.YumCore.commands.annotation.Async;
|
||||
import pw.yumc.YumCore.commands.annotation.Cmd;
|
||||
import pw.yumc.YumCore.commands.annotation.Help;
|
||||
import pw.yumc.YumCore.commands.annotation.Sort;
|
||||
import pw.yumc.YumCore.commands.exception.CommandException;
|
||||
|
||||
/**
|
||||
* 命令信息存储类
|
||||
*
|
||||
* @since 2016年7月23日 上午9:56:42
|
||||
* @author 喵♂呜
|
||||
*/
|
||||
public class CommandInfo {
|
||||
public static CommandInfo Unknow = new CommandInfo();
|
||||
private final Object origin;
|
||||
private final Method method;
|
||||
private final String name;
|
||||
private final List<String> aliases;
|
||||
private final boolean async;
|
||||
private final Cmd command;
|
||||
private final Help help;
|
||||
private final int sort;
|
||||
|
||||
public CommandInfo(final Method method, final Object origin, final Cmd command, final Help help, final boolean async, final int sort) {
|
||||
this.method = method;
|
||||
this.origin = origin;
|
||||
this.name = "".equals(command.name()) ? method.getName().toLowerCase() : command.name();
|
||||
this.aliases = Arrays.asList(command.aliases());
|
||||
this.command = command;
|
||||
this.help = help;
|
||||
this.async = async;
|
||||
this.sort = sort;
|
||||
}
|
||||
|
||||
private CommandInfo() {
|
||||
this.method = null;
|
||||
this.origin = null;
|
||||
this.name = "unknow";
|
||||
this.aliases = null;
|
||||
this.command = null;
|
||||
this.help = null;
|
||||
this.async = false;
|
||||
this.sort = 0;
|
||||
}
|
||||
|
||||
public static CommandInfo parse(final Method method, final Object origin) {
|
||||
final Class<?> clazz = method.getClass();
|
||||
final Cmd command = clazz.getAnnotation(Cmd.class);
|
||||
if (command != null) {
|
||||
final Help help = clazz.getAnnotation(Help.class);
|
||||
final Async async = clazz.getAnnotation(Async.class);
|
||||
final Sort sort = clazz.getAnnotation(Sort.class);
|
||||
return new CommandInfo(method, origin, command, help != null ? help : Help.DEFAULT, async != null, sort != null ? sort.sort() : 50);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (obj instanceof CommandInfo) {
|
||||
return name.equalsIgnoreCase(((CommandInfo) obj).getName());
|
||||
}
|
||||
return super.equals(obj);
|
||||
}
|
||||
|
||||
public boolean execute(final CommandSender sender, final Command command, final String label, final String[] args) {
|
||||
if (method == null) {
|
||||
return false;
|
||||
}
|
||||
final CommandArgument cmdArgs = new CommandArgument(sender, command, label, args);
|
||||
final Runnable runnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
try {
|
||||
cmdArgs.check(CommandInfo.this);
|
||||
} catch (final CommandException e) {
|
||||
sender.sendMessage(e.getMessage());
|
||||
return;
|
||||
}
|
||||
method.invoke(origin, cmdArgs);
|
||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
|
||||
throw new CommandException(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
if (async) {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(P.instance, runnable);
|
||||
} else {
|
||||
runnable.run();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public Cmd getCommand() {
|
||||
return command;
|
||||
}
|
||||
|
||||
public Help getHelp() {
|
||||
return help;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getSort() {
|
||||
return sort;
|
||||
}
|
||||
|
||||
public boolean isAsync() {
|
||||
return async;
|
||||
}
|
||||
|
||||
public boolean isValid(final String cmd) {
|
||||
return name.equalsIgnoreCase(cmd) || aliases.contains(cmd);
|
||||
}
|
||||
}
|
||||
package pw.yumc.YumCore.commands;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import pw.yumc.YumCore.bukkit.P;
|
||||
import pw.yumc.YumCore.commands.annotation.Async;
|
||||
import pw.yumc.YumCore.commands.annotation.Cmd;
|
||||
import pw.yumc.YumCore.commands.annotation.Help;
|
||||
import pw.yumc.YumCore.commands.annotation.Sort;
|
||||
import pw.yumc.YumCore.commands.exception.CommandException;
|
||||
|
||||
/**
|
||||
* 命令信息存储类
|
||||
*
|
||||
* @since 2016年7月23日 上午9:56:42
|
||||
* @author 喵♂呜
|
||||
*/
|
||||
public class CommandInfo {
|
||||
public static CommandInfo Unknow = new CommandInfo();
|
||||
private final Object origin;
|
||||
private final Method method;
|
||||
private final String name;
|
||||
private final List<String> aliases;
|
||||
private final boolean async;
|
||||
private final Cmd command;
|
||||
private final Help help;
|
||||
private final int sort;
|
||||
|
||||
public CommandInfo(final Method method, final Object origin, final Cmd command, final Help help, final boolean async, final int sort) {
|
||||
this.method = method;
|
||||
this.origin = origin;
|
||||
this.name = "".equals(command.name()) ? method.getName().toLowerCase() : command.name();
|
||||
this.aliases = Arrays.asList(command.aliases());
|
||||
this.command = command;
|
||||
this.help = help;
|
||||
this.async = async;
|
||||
this.sort = sort;
|
||||
}
|
||||
|
||||
private CommandInfo() {
|
||||
this.method = null;
|
||||
this.origin = null;
|
||||
this.name = "unknow";
|
||||
this.aliases = null;
|
||||
this.command = null;
|
||||
this.help = null;
|
||||
this.async = false;
|
||||
this.sort = 0;
|
||||
}
|
||||
|
||||
public static CommandInfo parse(final Method method, final Object origin) {
|
||||
final Cmd command = method.getAnnotation(Cmd.class);
|
||||
if (command != null) {
|
||||
final Help help = method.getAnnotation(Help.class);
|
||||
final Async async = method.getAnnotation(Async.class);
|
||||
final Sort sort = method.getAnnotation(Sort.class);
|
||||
return new CommandInfo(method, origin, command, help != null ? help : Help.DEFAULT, async != null, sort != null ? sort.sort() : 50);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (obj instanceof CommandInfo) {
|
||||
return name.equalsIgnoreCase(((CommandInfo) obj).getName());
|
||||
}
|
||||
return super.equals(obj);
|
||||
}
|
||||
|
||||
public boolean execute(final CommandSender sender, final Command command, final String label, final String[] args) {
|
||||
if (method == null) {
|
||||
return false;
|
||||
}
|
||||
final CommandArgument cmdArgs = new CommandArgument(sender, command, label, args);
|
||||
final Runnable runnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
try {
|
||||
cmdArgs.check(CommandInfo.this);
|
||||
} catch (final CommandException e) {
|
||||
sender.sendMessage(e.getMessage());
|
||||
return;
|
||||
}
|
||||
method.invoke(origin, cmdArgs);
|
||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
|
||||
throw new CommandException(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
if (async) {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(P.instance, runnable);
|
||||
} else {
|
||||
runnable.run();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public Cmd getCommand() {
|
||||
return command;
|
||||
}
|
||||
|
||||
public Help getHelp() {
|
||||
return help;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getSort() {
|
||||
return sort;
|
||||
}
|
||||
|
||||
public boolean isAsync() {
|
||||
return async;
|
||||
}
|
||||
|
||||
public boolean isValid(final String cmd) {
|
||||
return name.equalsIgnoreCase(cmd) || aliases.contains(cmd);
|
||||
}
|
||||
}
|
||||
|
@ -1,198 +1,232 @@
|
||||
package pw.yumc.YumCore.commands;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.command.TabExecutor;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.util.StringUtil;
|
||||
|
||||
import pw.yumc.YumCore.bukkit.Log;
|
||||
import pw.yumc.YumCore.bukkit.P;
|
||||
import pw.yumc.YumCore.bukkit.compatible.C;
|
||||
import pw.yumc.YumCore.commands.api.CommandExecutor;
|
||||
|
||||
/**
|
||||
* 命令管理类
|
||||
*
|
||||
* @since 2016年7月23日 上午9:06:03
|
||||
* @author 喵♂呜
|
||||
*/
|
||||
public class CommandManager implements TabExecutor {
|
||||
private final String argumentTypeError = "注解命令方法 %s 位于 %s 的参数错误 应只有 CommandArgument 参数!";
|
||||
private final String returnTypeError = "注解命令补全 %s 位于 %s 的返回值错误 应实现 List 接口!";
|
||||
/**
|
||||
* 插件实例类
|
||||
*/
|
||||
JavaPlugin plugin = P.instance;
|
||||
/**
|
||||
* 命令列表
|
||||
*/
|
||||
Set<CommandInfo> cmdlist = new HashSet<>();
|
||||
/**
|
||||
* Tab列表
|
||||
*/
|
||||
Set<TabInfo> tablist = new HashSet<>();
|
||||
/**
|
||||
* 命令缓存列表
|
||||
*/
|
||||
Map<String, CommandInfo> cmdcache = new HashMap<>();
|
||||
/**
|
||||
* 命令帮助
|
||||
*/
|
||||
CommandHelp help = new CommandHelp(cmdlist);
|
||||
|
||||
/**
|
||||
* 命令管理器
|
||||
*
|
||||
* @param name
|
||||
* 注册的命令
|
||||
*/
|
||||
public CommandManager(final String name) {
|
||||
final PluginCommand cmd = plugin.getCommand(name);
|
||||
if (cmd == null) {
|
||||
throw new IllegalStateException("未找到命令 必须在plugin.yml先注册 " + name + " 命令!");
|
||||
}
|
||||
cmd.setExecutor(this);
|
||||
cmd.setTabCompleter(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 命令管理器
|
||||
*
|
||||
* @param name
|
||||
* 注册的命令
|
||||
* @param executor
|
||||
* 命令执行类
|
||||
*/
|
||||
public CommandManager(final String name, final CommandExecutor executor) {
|
||||
this(name);
|
||||
registerCommands(executor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(final CommandSender sender, final Command command, final String label, final String[] args) {
|
||||
if (args.length == 0) {
|
||||
help.send(sender, command, label, args);
|
||||
return true;
|
||||
}
|
||||
final String subcmd = args[0].toLowerCase();
|
||||
if (subcmd.equalsIgnoreCase("help")) {
|
||||
help.send(sender, command, label, args);
|
||||
return true;
|
||||
}
|
||||
final String[] subargs = moveStrings(args, 1);
|
||||
if (!cmdcache.containsKey(label)) {
|
||||
for (final CommandInfo cmdinfo : cmdlist) {
|
||||
if (cmdinfo.isValid(label)) {
|
||||
cmdcache.put(label, cmdinfo);
|
||||
break;
|
||||
}
|
||||
}
|
||||
cmdcache.put(label, CommandInfo.Unknow);
|
||||
}
|
||||
return cmdcache.get(label).execute(sender, command, label, subargs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(final CommandSender sender, final Command command, final String alias, final String[] args) {
|
||||
final List<String> completions = new ArrayList<>();
|
||||
final String token = args[args.length - 1];
|
||||
if (args.length == 1) {
|
||||
final Set<String> commands = this.cmdcache.keySet();
|
||||
StringUtil.copyPartialMatches(args[0], commands, completions);
|
||||
} else if (args.length >= 2) {
|
||||
for (final TabInfo tab : tablist) {
|
||||
StringUtil.copyPartialMatches(token, tab.execute(sender, command, token, args), completions);
|
||||
}
|
||||
StringUtil.copyPartialMatches(token, getPlayerTabComplete(sender, command, alias, args), completions);
|
||||
}
|
||||
Collections.sort(completions, String.CASE_INSENSITIVE_ORDER);
|
||||
return completions;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过注解读取命令并注册
|
||||
*
|
||||
* @param clazz
|
||||
* 子命令处理类
|
||||
*/
|
||||
public void registerCommands(final CommandExecutor clazz) {
|
||||
final Method[] methods = clazz.getClass().getDeclaredMethods();
|
||||
for (final Method method : methods) {
|
||||
final CommandInfo ci = CommandInfo.parse(method, clazz);
|
||||
if (ci != null) {
|
||||
final Class<?>[] params = method.getParameterTypes();
|
||||
if (params.length == 1 && params[0].equals(CommandArgument.class)) {
|
||||
if (cmdlist.add(ci)) {
|
||||
cmdcache.put(ci.getName(), ci);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
Log.warning(String.format(argumentTypeError, method.getName(), clazz.getClass().getName()));
|
||||
}
|
||||
}
|
||||
final TabInfo ti = TabInfo.parse(method, clazz);
|
||||
if (ti != null) {
|
||||
if (!method.getReturnType().equals(List.class)) {
|
||||
Log.warning(String.format(returnTypeError, method.getName(), clazz.getClass().getName()));
|
||||
continue;
|
||||
}
|
||||
tablist.add(ti);
|
||||
}
|
||||
}
|
||||
help = new CommandHelp(cmdlist);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取玩家命令补全
|
||||
*
|
||||
* @param sender
|
||||
* 命令发送者
|
||||
* @param command
|
||||
* 命令
|
||||
* @param alias
|
||||
* 别名
|
||||
* @param args
|
||||
* 数组
|
||||
* @return 在线玩家数组
|
||||
*/
|
||||
private List<String> getPlayerTabComplete(final CommandSender sender, final Command command, final String alias, final String[] args) {
|
||||
final String lastWord = args[args.length - 1];
|
||||
final Player senderPlayer = sender instanceof Player ? (Player) sender : null;
|
||||
final ArrayList<String> matchedPlayers = new ArrayList<>();
|
||||
for (final Player player : C.Player.getOnlinePlayers()) {
|
||||
final String name = player.getName();
|
||||
if ((senderPlayer == null || senderPlayer.canSee(player)) && StringUtil.startsWithIgnoreCase(name, lastWord)) {
|
||||
matchedPlayers.add(name);
|
||||
}
|
||||
}
|
||||
return matchedPlayers;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转移数组
|
||||
*
|
||||
* @param args
|
||||
* 原数组
|
||||
* @param start
|
||||
* 数组开始位置
|
||||
* @return 转移后的数组字符串
|
||||
*/
|
||||
private String[] moveStrings(final String[] args, final int start) {
|
||||
final String[] ret = new String[args.length - start];
|
||||
System.arraycopy(args, start, ret, 0, ret.length);
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
package pw.yumc.YumCore.commands;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.command.TabExecutor;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.util.StringUtil;
|
||||
|
||||
import pw.yumc.YumCore.bukkit.Log;
|
||||
import pw.yumc.YumCore.bukkit.P;
|
||||
import pw.yumc.YumCore.bukkit.compatible.C;
|
||||
import pw.yumc.YumCore.commands.api.CommandExecutor;
|
||||
|
||||
/**
|
||||
* 命令管理类
|
||||
*
|
||||
* @since 2016年7月23日 上午9:06:03
|
||||
* @author 喵♂呜
|
||||
*/
|
||||
public class CommandManager implements TabExecutor {
|
||||
private final String argumentTypeError = "注解命令方法 %s 位于 %s 的参数错误 应只有 CommandArgument 参数!";
|
||||
private final String returnTypeError = "注解命令补全 %s 位于 %s 的返回值错误 应实现 List 接口!";
|
||||
/**
|
||||
* 插件实例类
|
||||
*/
|
||||
JavaPlugin plugin = P.instance;
|
||||
/**
|
||||
* 命令列表
|
||||
*/
|
||||
Set<CommandInfo> cmdlist = new HashSet<>();
|
||||
/**
|
||||
* Tab列表
|
||||
*/
|
||||
Set<TabInfo> tablist = new HashSet<>();
|
||||
/**
|
||||
* 命令缓存列表
|
||||
*/
|
||||
Map<String, CommandInfo> cmdcache = new HashMap<>();
|
||||
/**
|
||||
* 命令帮助
|
||||
*/
|
||||
CommandHelp help = new CommandHelp(cmdlist);
|
||||
|
||||
/**
|
||||
* 插件命令
|
||||
*/
|
||||
PluginCommand cmd;
|
||||
|
||||
/**
|
||||
* 命令管理器
|
||||
*
|
||||
* @param name
|
||||
* 注册的命令
|
||||
*/
|
||||
public CommandManager(final String name) {
|
||||
cmd = plugin.getCommand(name);
|
||||
if (cmd == null) {
|
||||
throw new IllegalStateException("未找到命令 必须在plugin.yml先注册 " + name + " 命令!");
|
||||
}
|
||||
cmd.setExecutor(this);
|
||||
cmd.setTabCompleter(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 命令管理器
|
||||
*
|
||||
* @param name
|
||||
* 注册的命令
|
||||
* @param executor
|
||||
* 命令执行类
|
||||
*/
|
||||
public CommandManager(final String name, final CommandExecutor executor) {
|
||||
this(name);
|
||||
register(executor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(final CommandSender sender, final Command command, final String label, final String[] args) {
|
||||
if (args.length == 0) {
|
||||
help.send(sender, command, label, args);
|
||||
return true;
|
||||
}
|
||||
final String subcmd = args[0].toLowerCase();
|
||||
if (subcmd.equalsIgnoreCase("help")) {
|
||||
help.send(sender, command, label, args);
|
||||
return true;
|
||||
}
|
||||
final String[] subargs = moveStrings(args, 1);
|
||||
if (!cmdcache.containsKey(label)) {
|
||||
for (final CommandInfo cmdinfo : cmdlist) {
|
||||
if (cmdinfo.isValid(subcmd)) {
|
||||
cmdcache.put(subcmd, cmdinfo);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!cmdcache.containsKey(subcmd)) {
|
||||
cmdcache.put(subcmd, CommandInfo.Unknow);
|
||||
}
|
||||
}
|
||||
return cmdcache.get(subcmd).execute(sender, command, label, subargs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> onTabComplete(final CommandSender sender, final Command command, final String alias, final String[] args) {
|
||||
final List<String> completions = new ArrayList<>();
|
||||
final String token = args[args.length - 1];
|
||||
if (args.length == 1) {
|
||||
final Set<String> commands = this.cmdcache.keySet();
|
||||
StringUtil.copyPartialMatches(args[0], commands, completions);
|
||||
} else if (args.length >= 2) {
|
||||
for (final TabInfo tab : tablist) {
|
||||
StringUtil.copyPartialMatches(token, tab.execute(sender, command, token, args), completions);
|
||||
}
|
||||
StringUtil.copyPartialMatches(token, getPlayerTabComplete(sender, command, alias, args), completions);
|
||||
}
|
||||
Collections.sort(completions, String.CASE_INSENSITIVE_ORDER);
|
||||
return completions;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过注解读取命令并注册
|
||||
*
|
||||
* @param clazz
|
||||
* 子命令处理类
|
||||
*/
|
||||
public void register(final CommandExecutor clazz) {
|
||||
final Method[] methods = clazz.getClass().getDeclaredMethods();
|
||||
for (final Method method : methods) {
|
||||
if (registerCommand(method, clazz)) {
|
||||
continue;
|
||||
}
|
||||
registerTab(method, clazz);
|
||||
}
|
||||
help = new CommandHelp(cmdlist);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取玩家命令补全
|
||||
*
|
||||
* @param sender
|
||||
* 命令发送者
|
||||
* @param command
|
||||
* 命令
|
||||
* @param alias
|
||||
* 别名
|
||||
* @param args
|
||||
* 数组
|
||||
* @return 在线玩家数组
|
||||
*/
|
||||
private List<String> getPlayerTabComplete(final CommandSender sender, final Command command, final String alias, final String[] args) {
|
||||
final String lastWord = args[args.length - 1];
|
||||
final Player senderPlayer = sender instanceof Player ? (Player) sender : null;
|
||||
final ArrayList<String> matchedPlayers = new ArrayList<>();
|
||||
for (final Player player : C.Player.getOnlinePlayers()) {
|
||||
final String name = player.getName();
|
||||
if ((senderPlayer == null || senderPlayer.canSee(player)) && StringUtil.startsWithIgnoreCase(name, lastWord)) {
|
||||
matchedPlayers.add(name);
|
||||
}
|
||||
}
|
||||
return matchedPlayers;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转移数组
|
||||
*
|
||||
* @param args
|
||||
* 原数组
|
||||
* @param start
|
||||
* 数组开始位置
|
||||
* @return 转移后的数组字符串
|
||||
*/
|
||||
private String[] moveStrings(final String[] args, final int start) {
|
||||
final String[] ret = new String[args.length - start];
|
||||
System.arraycopy(args, start, ret, 0, ret.length);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册命令
|
||||
*
|
||||
* @param method
|
||||
* 方法
|
||||
* @param clazz
|
||||
* 调用对象
|
||||
* @return 是否成功
|
||||
*/
|
||||
private boolean registerCommand(final Method method, final CommandExecutor clazz) {
|
||||
final CommandInfo ci = CommandInfo.parse(method, clazz);
|
||||
if (ci != null) {
|
||||
final Class<?>[] params = method.getParameterTypes();
|
||||
if (params.length == 1 && params[0].equals(CommandArgument.class)) {
|
||||
cmdlist.add(ci);
|
||||
cmdcache.put(ci.getName(), ci);
|
||||
return true;
|
||||
}
|
||||
Log.warning(String.format(argumentTypeError, method.getName(), clazz.getClass().getName()));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册Tab补全
|
||||
*
|
||||
* @param method
|
||||
* 方法
|
||||
* @param clazz
|
||||
* 调用对象
|
||||
* @return 是否成功
|
||||
*/
|
||||
private boolean registerTab(final Method method, final CommandExecutor clazz) {
|
||||
final TabInfo ti = TabInfo.parse(method, clazz);
|
||||
if (ti != null) {
|
||||
if (method.getReturnType().equals(List.class)) {
|
||||
tablist.add(ti);
|
||||
return true;
|
||||
}
|
||||
Log.warning(String.format(returnTypeError, method.getName(), clazz.getClass().getName()));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1,80 +1,79 @@
|
||||
package pw.yumc.YumCore.commands;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import pw.yumc.YumCore.bukkit.P;
|
||||
import pw.yumc.YumCore.commands.annotation.Tab;
|
||||
|
||||
/**
|
||||
* Tab补全
|
||||
*
|
||||
* @since 2016年7月23日 上午9:56:42
|
||||
* @author 喵♂呜
|
||||
*/
|
||||
public class TabInfo {
|
||||
private final Object origin;
|
||||
private final Method method;
|
||||
|
||||
public TabInfo(final Method method, final Object origin) {
|
||||
this.method = method;
|
||||
this.origin = origin;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析TabInfo
|
||||
*
|
||||
* @param method
|
||||
* 方法
|
||||
* @param origin
|
||||
* 对象
|
||||
* @return {@link TabInfo}
|
||||
*/
|
||||
public static TabInfo parse(final Method method, final Object origin) {
|
||||
final Class<?> clazz = method.getClass();
|
||||
final Tab tab = clazz.getAnnotation(Tab.class);
|
||||
if (tab != null) {
|
||||
return new TabInfo(method, origin);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (obj instanceof TabInfo) {
|
||||
return method.equals(((TabInfo) obj).getMethod());
|
||||
}
|
||||
return super.equals(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得补全List
|
||||
*
|
||||
* @param sender
|
||||
* 发送者
|
||||
* @param command
|
||||
* 命令
|
||||
* @param label
|
||||
* 命令
|
||||
* @param args
|
||||
* 参数
|
||||
* @return Tab补全信息
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<String> execute(final CommandSender sender, final org.bukkit.command.Command command, final String label, final String[] args) {
|
||||
final CommandArgument cmdArgs = new CommandArgument(sender, command, label, args);
|
||||
try {
|
||||
return (List<String>) method.invoke(origin, cmdArgs);
|
||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
|
||||
throw new RuntimeException("调用Tab自动补全发生错误 请反馈给开发者 " + Arrays.toString(P.instance.getDescription().getAuthors().toArray()) + " !", e);
|
||||
}
|
||||
}
|
||||
|
||||
public Method getMethod() {
|
||||
return method;
|
||||
}
|
||||
}
|
||||
package pw.yumc.YumCore.commands;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import pw.yumc.YumCore.bukkit.P;
|
||||
import pw.yumc.YumCore.commands.annotation.Tab;
|
||||
|
||||
/**
|
||||
* Tab补全
|
||||
*
|
||||
* @since 2016年7月23日 上午9:56:42
|
||||
* @author 喵♂呜
|
||||
*/
|
||||
public class TabInfo {
|
||||
private final Object origin;
|
||||
private final Method method;
|
||||
|
||||
public TabInfo(final Method method, final Object origin) {
|
||||
this.method = method;
|
||||
this.origin = origin;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析TabInfo
|
||||
*
|
||||
* @param method
|
||||
* 方法
|
||||
* @param origin
|
||||
* 对象
|
||||
* @return {@link TabInfo}
|
||||
*/
|
||||
public static TabInfo parse(final Method method, final Object origin) {
|
||||
final Tab tab = method.getAnnotation(Tab.class);
|
||||
if (tab != null) {
|
||||
return new TabInfo(method, origin);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (obj instanceof TabInfo) {
|
||||
return method.equals(((TabInfo) obj).getMethod());
|
||||
}
|
||||
return super.equals(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得补全List
|
||||
*
|
||||
* @param sender
|
||||
* 发送者
|
||||
* @param command
|
||||
* 命令
|
||||
* @param label
|
||||
* 命令
|
||||
* @param args
|
||||
* 参数
|
||||
* @return Tab补全信息
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<String> execute(final CommandSender sender, final org.bukkit.command.Command command, final String label, final String[] args) {
|
||||
final CommandArgument cmdArgs = new CommandArgument(sender, command, label, args);
|
||||
try {
|
||||
return (List<String>) method.invoke(origin, cmdArgs);
|
||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
|
||||
throw new RuntimeException("调用Tab自动补全发生错误 请反馈给开发者 " + Arrays.toString(P.instance.getDescription().getAuthors().toArray()) + " !", e);
|
||||
}
|
||||
}
|
||||
|
||||
public Method getMethod() {
|
||||
return method;
|
||||
}
|
||||
}
|
||||
|
@ -1,44 +1,44 @@
|
||||
package pw.yumc.YumCore.commands.annotation;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 命令帮助注解
|
||||
*
|
||||
* @since 2016年7月23日 上午9:00:07
|
||||
* @author 喵♂呜
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Help {
|
||||
public static Help DEFAULT = new Help() {
|
||||
@Override
|
||||
public Class<? extends Annotation> annotationType() {
|
||||
return getClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "这家伙很懒";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String possibleArguments() {
|
||||
return "没有帮助信息";
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @return 命令描述
|
||||
*/
|
||||
String description() default "无";
|
||||
|
||||
/**
|
||||
* @return 当前命令可能需要的参数
|
||||
*/
|
||||
String possibleArguments() default "";
|
||||
}
|
||||
package pw.yumc.YumCore.commands.annotation;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 命令帮助注解
|
||||
*
|
||||
* @since 2016年7月23日 上午9:00:07
|
||||
* @author 喵♂呜
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Help {
|
||||
public static Help DEFAULT = new Help() {
|
||||
@Override
|
||||
public Class<? extends Annotation> annotationType() {
|
||||
return getClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return "没写帮助信息";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String possibleArguments() {
|
||||
return "这家伙很懒";
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @return 命令描述
|
||||
*/
|
||||
String description() default "无";
|
||||
|
||||
/**
|
||||
* @return 当前命令可能需要的参数
|
||||
*/
|
||||
String possibleArguments() default "";
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user