mirror of
https://e.coding.net/circlecloud/YumCore.git
synced 2024-12-25 07:08:52 +00:00
refactor: 重构命令类库 支持自定义生成帮助页面
Signed-off-by: 502647092 <admin@yumc.pw>
This commit is contained in:
parent
877ef5e0b5
commit
24846733e8
@ -2,10 +2,11 @@ package pw.yumc.YumCore.commands;
|
||||
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import pw.yumc.YumCore.bukkit.P;
|
||||
import pw.yumc.YumCore.bukkit.Log;
|
||||
import pw.yumc.YumCore.commands.annotation.Help;
|
||||
import pw.yumc.YumCore.commands.info.CommandInfo;
|
||||
import pw.yumc.YumCore.commands.interfaces.CommandHelpParse;
|
||||
import pw.yumc.YumCore.commands.interfaces.HelpGenerator;
|
||||
import pw.yumc.YumCore.commands.interfaces.HelpParse;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@ -16,19 +17,7 @@ import java.util.*;
|
||||
* @author 喵♂呜
|
||||
*/
|
||||
public class CommandHelp {
|
||||
/**
|
||||
* 消息配置
|
||||
*/
|
||||
private static String prefix = String.format("§6[§b%s§6] ", P.instance.getName());
|
||||
private static String commandNotFound = prefix + "§c当前插件未注册默认命令以及子命令!";
|
||||
private static String pageNotFound = prefix + "§c不存在的帮助页面 §b请输入 /%s help §e1-%s";
|
||||
private static String helpTitle = String.format("§6========= %s §6帮助 §aBy §b喵♂呜 §6=========", prefix);
|
||||
private static String helpBody = "§6/%1$s §a%2$s §e%3$s §6- §b%4$s";
|
||||
private static String helpFooter = "§6查看更多的帮助页面 §b请输入 /%s help §e1-%s";
|
||||
/**
|
||||
* 帮助页面每页行数
|
||||
*/
|
||||
private static int LINES_PER_PAGE = 7;
|
||||
private static String commandNotFound = "§c当前插件未注册默认命令以及子命令!";
|
||||
/**
|
||||
* 默认命令
|
||||
*/
|
||||
@ -38,17 +27,21 @@ public class CommandHelp {
|
||||
*/
|
||||
private List<CommandInfo> cmdlist;
|
||||
/**
|
||||
* 命令解析
|
||||
* 帮助页生成
|
||||
*/
|
||||
private CommandHelpParse helpParse;
|
||||
/**
|
||||
* 帮助页面数量
|
||||
*/
|
||||
private int HELPPAGECOUNT;
|
||||
private HelpGenerator helpGenerator = new DefaultHelpGenerator();
|
||||
/**
|
||||
* 帮助列表缓存
|
||||
*/
|
||||
private Map<String, String[]> cacheHelp = new HashMap<>();
|
||||
/**
|
||||
* 帮助页面每页行数
|
||||
*/
|
||||
private static int LINES_PER_PAGE = 7;
|
||||
/**
|
||||
* 帮助页面数量
|
||||
*/
|
||||
private int HELPPAGECOUNT;
|
||||
|
||||
/**
|
||||
* 命令帮助
|
||||
@ -70,40 +63,12 @@ public class CommandHelp {
|
||||
*/
|
||||
public CommandHelp(CommandInfo defCmd, Collection<? extends CommandInfo> list) {
|
||||
this.defCmd = defCmd;
|
||||
cmdlist = new LinkedList<CommandInfo>(list);
|
||||
cmdlist = new LinkedList<>(list);
|
||||
Collections.sort(cmdlist, new CommandNameComparator());
|
||||
Collections.sort(cmdlist, new CommandComparator());
|
||||
HELPPAGECOUNT = (int) Math.ceil((double) cmdlist.size() / LINES_PER_PAGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化命令信息
|
||||
*
|
||||
* @param ci
|
||||
* 命令信息
|
||||
* @param label
|
||||
* 命令
|
||||
* @return 格式化后的字串
|
||||
*/
|
||||
public String formatCommand(CommandInfo ci, String label) {
|
||||
String aliases = Arrays.toString(ci.getCommand().aliases());
|
||||
String cmd = ci.getName() + (aliases.length() == 2 ? "" : "§7" + aliases);
|
||||
Help help = ci.getHelp();
|
||||
return String.format(helpBody, label, cmd, help.possibleArguments(), formatHelp(help.value()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析帮助
|
||||
*
|
||||
* @param value
|
||||
* 参数
|
||||
* @return 解析后的帮助
|
||||
*/
|
||||
public String formatHelp(String value) {
|
||||
if (helpParse != null) { return helpParse.parse(value); }
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送帮助
|
||||
*
|
||||
@ -115,56 +80,63 @@ public class CommandHelp {
|
||||
* 标签
|
||||
* @param args
|
||||
* 参数
|
||||
* @return 是否发送成功
|
||||
*/
|
||||
public boolean send(CommandSender sender, Command command, String label, String[] args) {
|
||||
if (this.HELPPAGECOUNT == 0) {
|
||||
sender.sendMessage(commandNotFound);
|
||||
Log.toSender(sender, commandNotFound);
|
||||
return true;
|
||||
}
|
||||
int page = 1;
|
||||
try {
|
||||
page = Integer.parseInt(args[1]);
|
||||
page = page == 0 ? 1 : page;
|
||||
} catch (Exception e) {
|
||||
// Ignore
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
String helpkey = label + page;
|
||||
if (!cacheHelp.containsKey(helpkey)) {
|
||||
List<String> helpList = new LinkedList<>();
|
||||
if (page > this.HELPPAGECOUNT || page < 1) {
|
||||
// 帮助页面不存在
|
||||
helpList.add(String.format(pageNotFound, label, HELPPAGECOUNT));
|
||||
if (page > HELPPAGECOUNT || page < 1) {
|
||||
// 帮助页面不存在
|
||||
cacheHelp.put(helpkey, new String[] { helpGenerator.notFound(label, HELPPAGECOUNT) });
|
||||
} else {
|
||||
List<String> helpList = new LinkedList<>();
|
||||
// 帮助标题
|
||||
helpList.add(helpTitle);
|
||||
helpList.add(helpGenerator.title());
|
||||
if (page == 1 && defCmd != null) {
|
||||
helpList.add(formatCommand(defCmd, label));
|
||||
helpList.add(helpGenerator.body(label, defCmd));
|
||||
}
|
||||
int start = LINES_PER_PAGE * (page - 1);
|
||||
int end = start + LINES_PER_PAGE;
|
||||
for (int i = start; i < end; i++) {
|
||||
if (this.cmdlist.size() > i) {
|
||||
if (cmdlist.size() > i) {
|
||||
// 帮助列表
|
||||
helpList.add(formatCommand(cmdlist.get(i), label));
|
||||
helpList.add(helpGenerator.body(label, cmdlist.get(i)));
|
||||
}
|
||||
}
|
||||
// 帮助结尾
|
||||
helpList.add(String.format(helpFooter, label, HELPPAGECOUNT));
|
||||
helpList.add(helpGenerator.foot(label, HELPPAGECOUNT));
|
||||
cacheHelp.put(helpkey, helpList.toArray(new String[] {}));
|
||||
}
|
||||
cacheHelp.put(helpkey, helpList.toArray(new String[0]));
|
||||
}
|
||||
sender.sendMessage(cacheHelp.get(helpkey));
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置解析器
|
||||
*
|
||||
* @param helpParse
|
||||
* 帮助解析器
|
||||
* 设置帮助生成器
|
||||
*
|
||||
* @param helpGenerator
|
||||
* 帮助生成器
|
||||
*/
|
||||
public void setHelpParse(CommandHelpParse helpParse) {
|
||||
this.helpParse = helpParse;
|
||||
public void setHelpGenerator(HelpGenerator helpGenerator) {
|
||||
this.helpGenerator = helpGenerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 命令帮助生成器
|
||||
*/
|
||||
public HelpGenerator getHelpGenerator() {
|
||||
return helpGenerator;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -198,4 +170,63 @@ public class CommandHelp {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class DefaultHelpGenerator implements HelpGenerator {
|
||||
/**
|
||||
* 消息配置
|
||||
*/
|
||||
private static String helpTitle = String.format("§6========= %s §6帮助 §aBy §b喵♂呜 §6=========", Log.getPrefix());
|
||||
private static String helpBody = "§6/%1$s §a%2$s §e%3$s §6- §b%4$s";
|
||||
private static String helpFooter = "§6查看更多的帮助页面 §b请输入 /%s help §e1-%s";
|
||||
private static String pageNotFound = "§c不存在的帮助页面 §b请输入 /%s help §e1-%s";
|
||||
/**
|
||||
* 帮助解析
|
||||
*/
|
||||
private HelpParse helpParse;
|
||||
|
||||
@Override
|
||||
public String title() {
|
||||
return helpTitle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String body(String label, CommandInfo ci) {
|
||||
String aliases = Arrays.toString(ci.getCommand().aliases());
|
||||
String cmd = ci.getName() + (aliases.length() == 2 ? "" : "§7" + aliases);
|
||||
Help help = ci.getHelp();
|
||||
return String.format(helpBody, label, cmd, help.possibleArguments(), parse(help.value()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String foot(String label, int HELPPAGECOUNT) {
|
||||
return String.format(helpFooter, label, HELPPAGECOUNT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String notFound(String label, int HELPPAGECOUNT) {
|
||||
return String.format(pageNotFound, label, HELPPAGECOUNT);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析帮助
|
||||
*
|
||||
* @param value
|
||||
* 参数
|
||||
* @return 解析后的帮助
|
||||
*/
|
||||
public String parse(String value) {
|
||||
if (helpParse != null) { return helpParse.parse(value); }
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置解析器
|
||||
*
|
||||
* @param helpParse
|
||||
* 帮助解析器
|
||||
*/
|
||||
public void setHelpParse(HelpParse helpParse) {
|
||||
this.helpParse = helpParse;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,10 +10,16 @@ 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.exception.ArgumentException;
|
||||
import pw.yumc.YumCore.commands.exception.CommandException;
|
||||
import pw.yumc.YumCore.commands.exception.PermissionException;
|
||||
import pw.yumc.YumCore.commands.exception.SenderException;
|
||||
import pw.yumc.YumCore.commands.info.CommandInfo;
|
||||
import pw.yumc.YumCore.commands.info.CommandTabInfo;
|
||||
import pw.yumc.YumCore.commands.interfaces.CommandExecutor;
|
||||
import pw.yumc.YumCore.commands.interfaces.CommandHelpParse;
|
||||
import pw.yumc.YumCore.commands.interfaces.ErrorHanlder;
|
||||
import pw.yumc.YumCore.commands.interfaces.Executor;
|
||||
import pw.yumc.YumCore.commands.interfaces.HelpGenerator;
|
||||
import pw.yumc.YumCore.commands.interfaces.HelpParse;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
@ -30,6 +36,11 @@ import java.util.*;
|
||||
public class CommandManager implements TabExecutor {
|
||||
private static String argumentTypeError = "注解命令方法 %s 位于 %s 的参数错误 第一个参数应实现 CommandSender 接口!";
|
||||
private static String returnTypeError = "注解命令补全 %s 位于 %s 的返回值错误 应实现 List 接口!";
|
||||
private static String onlyExecutor = "§c当前命令仅允许 §b%s §c执行!";
|
||||
private static String losePerm = "§c你需要有 %s 的权限才能执行此命令!";
|
||||
private static String cmdErr = "§6错误原因: §4命令参数不正确!";
|
||||
private static String cmdUse = "§6使用方法: §e/%s %s%s";
|
||||
private static String cmdDes = "§6命令描述: §3%s";
|
||||
private static Constructor<PluginCommand> PluginCommandConstructor;
|
||||
private static Map<String, Command> knownCommands;
|
||||
private static Map<String, Plugin> lookupNames;
|
||||
@ -57,6 +68,31 @@ public class CommandManager implements TabExecutor {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 命令帮助
|
||||
*/
|
||||
private CommandHelp help;
|
||||
/**
|
||||
* 插件命令
|
||||
*/
|
||||
private PluginCommand cmd;
|
||||
/**
|
||||
* 命令错误处理
|
||||
*/
|
||||
private ErrorHanlder commandErrorHanlder = new ErrorHanlder() {
|
||||
@Override
|
||||
public void error(CommandException e, CommandSender sender, CommandInfo info, CommandArgument args) {
|
||||
if (e instanceof SenderException) {
|
||||
Log.toSender(sender, onlyExecutor, info.getExecutorStr());
|
||||
} else if (e instanceof PermissionException) {
|
||||
Log.toSender(sender, losePerm, info.getCommand().permission());
|
||||
} else if (e instanceof ArgumentException) {
|
||||
Log.toSender(sender, cmdErr);
|
||||
Log.toSender(sender, cmdUse, args.getAlias(), info.isDefault() ? "" : info.getName() + " ", info.getHelp().possibleArguments());
|
||||
Log.toSender(sender, cmdDes, info.getHelp().value());
|
||||
}
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 插件实例类
|
||||
*/
|
||||
@ -81,14 +117,6 @@ public class CommandManager implements TabExecutor {
|
||||
* 命令名称缓存
|
||||
*/
|
||||
private List<String> cmdNameCache = new ArrayList<>();
|
||||
/**
|
||||
* 命令帮助
|
||||
*/
|
||||
private CommandHelp help;
|
||||
/**
|
||||
* 插件命令
|
||||
*/
|
||||
private PluginCommand cmd;
|
||||
|
||||
/**
|
||||
* 命令管理器
|
||||
@ -118,7 +146,7 @@ public class CommandManager implements TabExecutor {
|
||||
* @param executor
|
||||
* 命令执行类
|
||||
*/
|
||||
public CommandManager(String name, CommandExecutor... executor) {
|
||||
public CommandManager(String name, Executor... executor) {
|
||||
this(name);
|
||||
register(executor);
|
||||
}
|
||||
@ -207,11 +235,19 @@ public class CommandManager implements TabExecutor {
|
||||
String subcmd = args[0].toLowerCase();
|
||||
if (subcmd.equalsIgnoreCase("help")) { return help.send(sender, command, label, args); }
|
||||
CommandInfo cmd = getByCache(subcmd);
|
||||
CommandArgument arg;
|
||||
if (cmd.equals(CommandInfo.Unknow) && defCmd != null) {
|
||||
return defCmd.execute(new CommandArgument(sender, command, label, args));
|
||||
cmd = defCmd;
|
||||
arg = new CommandArgument(sender, command, label, args);
|
||||
} else {
|
||||
return cmd.execute(new CommandArgument(sender, command, label, moveStrings(args, 1)));
|
||||
arg = new CommandArgument(sender, command, label, moveStrings(args, 1));
|
||||
}
|
||||
try {
|
||||
return cmd.execute(arg);
|
||||
} catch (CommandException e) {
|
||||
commandErrorHanlder.error(e, sender, cmd, arg);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -235,8 +271,8 @@ public class CommandManager implements TabExecutor {
|
||||
* @param clazzs
|
||||
* 子命令处理类
|
||||
*/
|
||||
public void register(CommandExecutor... clazzs) {
|
||||
for (CommandExecutor clazz : clazzs) {
|
||||
public CommandManager register(Executor... clazzs) {
|
||||
for (Executor clazz : clazzs) {
|
||||
Method[] methods = clazz.getClass().getDeclaredMethods();
|
||||
for (Method method : methods) {
|
||||
if (registerCommand(method, clazz)) {
|
||||
@ -247,6 +283,7 @@ public class CommandManager implements TabExecutor {
|
||||
}
|
||||
help = new CommandHelp(defCmd, cmds);
|
||||
buildCmdNameCache();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -258,7 +295,7 @@ public class CommandManager implements TabExecutor {
|
||||
* 调用对象
|
||||
* @return 是否成功
|
||||
*/
|
||||
private boolean registerCommand(Method method, CommandExecutor clazz) {
|
||||
private boolean registerCommand(Method method, Executor clazz) {
|
||||
CommandInfo ci = CommandInfo.parse(method, clazz);
|
||||
if (ci != null) {
|
||||
Class[] params = method.getParameterTypes();
|
||||
@ -289,7 +326,7 @@ public class CommandManager implements TabExecutor {
|
||||
* 调用对象
|
||||
* @return 是否成功
|
||||
*/
|
||||
private boolean registerTab(Method method, CommandExecutor clazz) {
|
||||
private boolean registerTab(Method method, Executor clazz) {
|
||||
CommandTabInfo ti = CommandTabInfo.parse(method, clazz);
|
||||
if (ti != null) {
|
||||
if (method.getReturnType().equals(List.class)) {
|
||||
@ -301,13 +338,40 @@ public class CommandManager implements TabExecutor {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置命令错误处理器
|
||||
*
|
||||
* @param commandErrorHanlder
|
||||
* 命令错误处理器
|
||||
*/
|
||||
public CommandManager setCommandErrorHanlder(ErrorHanlder commandErrorHanlder) {
|
||||
this.commandErrorHanlder = commandErrorHanlder;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置帮助生成器
|
||||
*
|
||||
* @param helpGenerator
|
||||
* 帮助生成器
|
||||
*/
|
||||
public CommandManager setHelpGenerator(HelpGenerator helpGenerator) {
|
||||
help.setHelpGenerator(helpGenerator);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置帮助解析器
|
||||
*
|
||||
* @param helpParse
|
||||
* 帮助解析器
|
||||
*/
|
||||
public void setHelpParse(CommandHelpParse helpParse) {
|
||||
help.setHelpParse(helpParse);
|
||||
public CommandManager setHelpParse(HelpParse helpParse) {
|
||||
if (help.getHelpGenerator() instanceof CommandHelp.DefaultHelpGenerator) {
|
||||
((CommandHelp.DefaultHelpGenerator) help.getHelpGenerator()).setHelpParse(helpParse);
|
||||
} else {
|
||||
Log.w("已设置自定义帮助生成器 解析器设置将不会生效!");
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +1,19 @@
|
||||
package pw.yumc.YumCore.commands;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import pw.yumc.YumCore.bukkit.Log;
|
||||
import pw.yumc.YumCore.commands.annotation.Default;
|
||||
import pw.yumc.YumCore.commands.annotation.KeyValue;
|
||||
import pw.yumc.YumCore.commands.annotation.Limit;
|
||||
import pw.yumc.YumCore.commands.exception.CommandParseException;
|
||||
import pw.yumc.YumCore.commands.exception.ParseException;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 命令参数解析
|
||||
@ -47,7 +46,7 @@ public class CommandParse {
|
||||
if (clazz.isEnum()) {
|
||||
parse = new EnumParse(clazz);
|
||||
}
|
||||
if (parse == null) { throw new CommandParseException(String.format("存在无法解析的参数类型 %s", clazz.getName())); }
|
||||
if (parse == null) { throw new ParseException(String.format("存在无法解析的参数类型 %s", clazz.getName())); }
|
||||
this.parse.add(parse.clone().parseAnnotation(annotations));
|
||||
}
|
||||
}
|
||||
@ -92,7 +91,7 @@ public class CommandParse {
|
||||
}
|
||||
pobjs.add(param == null ? null : p.parse(cmdArgs.getSender(), param));
|
||||
} catch (Exception e) {
|
||||
throw new CommandParseException(String.format("第 %s 个参数 ", isMain ? 1 : 2 + i) + e.getMessage());
|
||||
throw new ParseException(String.format("第 %s 个参数 ", isMain ? 1 : 2 + i) + e.getMessage());
|
||||
}
|
||||
}
|
||||
Log.d("解析参数: %s => %s", Arrays.toString(args), pobjs);
|
||||
@ -110,7 +109,7 @@ public class CommandParse {
|
||||
try {
|
||||
return Boolean.parseBoolean(arg);
|
||||
} catch (Exception e) {
|
||||
throw new CommandParseException("必须为True或者False!", e);
|
||||
throw new ParseException("必须为True或者False!", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -129,7 +128,7 @@ public class CommandParse {
|
||||
try {
|
||||
return Enum.valueOf(etype, arg);
|
||||
} catch (IllegalArgumentException ex) {
|
||||
throw new CommandParseException(String.format("不是 %s 有效值为 %s", etype.getSimpleName(), Arrays.toString(elist)));
|
||||
throw new ParseException(String.format("不是 %s 有效值为 %s", etype.getSimpleName(), Arrays.toString(elist)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -140,9 +139,9 @@ public class CommandParse {
|
||||
}
|
||||
|
||||
@Override
|
||||
public File parse(CommandSender sender, String arg) throws CommandParseException {
|
||||
public File parse(CommandSender sender, String arg) throws ParseException {
|
||||
File file = new File(arg);
|
||||
if (attrs.containsKey("check") && !file.exists()) { throw new CommandParseException("文件 " + arg + " 不存在!"); }
|
||||
if (attrs.containsKey("check") && !file.exists()) { throw new ParseException("文件 " + arg + " 不存在!"); }
|
||||
return file;
|
||||
}
|
||||
}
|
||||
@ -162,7 +161,7 @@ public class CommandParse {
|
||||
}
|
||||
return result;
|
||||
} catch (NumberFormatException e) {
|
||||
throw new CommandParseException("必须为数字!", e);
|
||||
throw new ParseException("必须为数字!", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -182,7 +181,7 @@ public class CommandParse {
|
||||
}
|
||||
return result;
|
||||
} catch (NumberFormatException e) {
|
||||
throw new CommandParseException("必须为数字!", e);
|
||||
throw new ParseException("必须为数字!", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -202,7 +201,7 @@ public class CommandParse {
|
||||
}
|
||||
return result;
|
||||
} catch (NumberFormatException e) {
|
||||
throw new CommandParseException("必须为数字!", e);
|
||||
throw new ParseException("必须为数字!", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -217,7 +216,7 @@ public class CommandParse {
|
||||
try {
|
||||
return Material.valueOf(arg);
|
||||
} catch (Exception e) {
|
||||
throw new CommandParseException(String.format("%s 不是一个有效的Material枚举", arg), e);
|
||||
throw new ParseException(String.format("%s 不是一个有效的Material枚举", arg), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -241,7 +240,7 @@ public class CommandParse {
|
||||
return def;
|
||||
}
|
||||
|
||||
public abstract RT parse(CommandSender sender, String arg) throws CommandParseException;
|
||||
public abstract RT parse(CommandSender sender, String arg) throws ParseException;
|
||||
|
||||
public Parse<RT> parseAnnotation(Annotation[] annotations) {
|
||||
for (Annotation annotation : annotations) {
|
||||
@ -259,7 +258,7 @@ public class CommandParse {
|
||||
}
|
||||
|
||||
public void throwException(String str, Object... objects) {
|
||||
throw new CommandParseException(String.format(str, objects));
|
||||
throw new ParseException(String.format(str, objects));
|
||||
}
|
||||
|
||||
public void throwRange() {
|
||||
@ -267,7 +266,7 @@ public class CommandParse {
|
||||
}
|
||||
|
||||
public void throwRange(String str) {
|
||||
throw new CommandParseException(String.format(str == null ? "范围必须在 %s 到 %s 之间!" : str, min, max));
|
||||
throw new ParseException(String.format(str == null ? "范围必须在 %s 到 %s 之间!" : str, min, max));
|
||||
}
|
||||
}
|
||||
|
||||
@ -281,7 +280,7 @@ public class CommandParse {
|
||||
@Override
|
||||
public Player parse(CommandSender sender, String arg) {
|
||||
Player p = Bukkit.getPlayerExact(arg);
|
||||
if (check && p == null) { throw new CommandParseException("玩家 " + arg + " 不存在或不在线!"); }
|
||||
if (check && p == null) { throw new ParseException("玩家 " + arg + " 不存在或不在线!"); }
|
||||
return p;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,22 @@
|
||||
package pw.yumc.YumCore.commands.exception;
|
||||
|
||||
/**
|
||||
* 命令参数解析异常
|
||||
*
|
||||
* @author 喵♂呜
|
||||
* @since 2016年10月5日 下午5:15:43
|
||||
*/
|
||||
public class ArgumentException extends CommandException {
|
||||
|
||||
public ArgumentException(Exception e) {
|
||||
super(e);
|
||||
}
|
||||
|
||||
public ArgumentException(String string) {
|
||||
super(string);
|
||||
}
|
||||
|
||||
public ArgumentException(String string, Exception e) {
|
||||
super(string, e);
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
package pw.yumc.YumCore.commands.exception;
|
||||
|
||||
/**
|
||||
* 命令参数解析异常
|
||||
*
|
||||
* @author 喵♂呜
|
||||
* @since 2016年10月5日 下午5:15:43
|
||||
*/
|
||||
public class CommandArgumentException extends CommandException {
|
||||
|
||||
public CommandArgumentException(Exception e) {
|
||||
super(e);
|
||||
}
|
||||
|
||||
public CommandArgumentException(String string) {
|
||||
super(string);
|
||||
}
|
||||
|
||||
public CommandArgumentException(String string, Exception e) {
|
||||
super(string, e);
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
package pw.yumc.YumCore.commands.exception;
|
||||
|
||||
/**
|
||||
* 命令参数解析异常
|
||||
*
|
||||
* @author 喵♂呜
|
||||
* @since 2016年10月5日 下午5:15:43
|
||||
*/
|
||||
public class CommandParseException extends CommandException {
|
||||
|
||||
public CommandParseException(Exception e) {
|
||||
super(e);
|
||||
}
|
||||
|
||||
public CommandParseException(String string) {
|
||||
super(string);
|
||||
}
|
||||
|
||||
public CommandParseException(String string, Exception e) {
|
||||
super(string, e);
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package pw.yumc.YumCore.commands.exception;
|
||||
|
||||
/**
|
||||
* 命令参数解析异常
|
||||
*
|
||||
* @author 喵♂呜
|
||||
* @since 2016年10月5日 下午5:15:43
|
||||
*/
|
||||
public class ParseException extends CommandException {
|
||||
|
||||
public ParseException(Exception e) {
|
||||
super(e);
|
||||
}
|
||||
|
||||
public ParseException(String string) {
|
||||
super(string);
|
||||
}
|
||||
|
||||
public ParseException(String string, Exception e) {
|
||||
super(string, e);
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package pw.yumc.YumCore.commands.exception;
|
||||
|
||||
/**
|
||||
* 命令参数解析异常
|
||||
*
|
||||
* @author 喵♂呜
|
||||
* @since 2016年10月5日 下午5:15:43
|
||||
*/
|
||||
public class PermissionException extends CommandException {
|
||||
|
||||
public PermissionException(Exception e) {
|
||||
super(e);
|
||||
}
|
||||
|
||||
public PermissionException(String string) {
|
||||
super(string);
|
||||
}
|
||||
|
||||
public PermissionException(String string, Exception e) {
|
||||
super(string, e);
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package pw.yumc.YumCore.commands.exception;
|
||||
|
||||
/**
|
||||
* 命令参数解析异常
|
||||
*
|
||||
* @author 喵♂呜
|
||||
* @since 2016年10月5日 下午5:15:43
|
||||
*/
|
||||
public class SenderException extends CommandException {
|
||||
|
||||
public SenderException(Exception e) {
|
||||
super(e);
|
||||
}
|
||||
|
||||
public SenderException(String string) {
|
||||
super(string);
|
||||
}
|
||||
|
||||
public SenderException(String string, Exception e) {
|
||||
super(string, e);
|
||||
}
|
||||
}
|
@ -11,9 +11,7 @@ import pw.yumc.YumCore.commands.annotation.Cmd;
|
||||
import pw.yumc.YumCore.commands.annotation.Cmd.Executor;
|
||||
import pw.yumc.YumCore.commands.annotation.Help;
|
||||
import pw.yumc.YumCore.commands.annotation.Sort;
|
||||
import pw.yumc.YumCore.commands.exception.CommandArgumentException;
|
||||
import pw.yumc.YumCore.commands.exception.CommandException;
|
||||
import pw.yumc.YumCore.commands.exception.CommandParseException;
|
||||
import pw.yumc.YumCore.commands.exception.*;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
@ -30,12 +28,7 @@ import java.util.Objects;
|
||||
*/
|
||||
public class CommandInfo {
|
||||
public static CommandInfo Unknow = new CommandInfo();
|
||||
private static String onlyExecutor = "§c当前命令仅允许 §b%s §c执行!";
|
||||
private static String losePerm = "§c你需要有 %s 的权限才能执行此命令!";
|
||||
private static String argErr = "§c参数错误: §4%s";
|
||||
private static String cmdErr = "§6错误原因: §4命令参数不正确!";
|
||||
private static String cmdUse = "§6使用方法: §e/%s %s %s";
|
||||
private static String cmdDes = "§6命令描述: §3%s";
|
||||
private static Help defHelp = new Help() {
|
||||
@Override
|
||||
public Class<? extends Annotation> annotationType() {
|
||||
@ -59,6 +52,7 @@ public class CommandInfo {
|
||||
private List<Executor> executors;
|
||||
private String executorStr;
|
||||
private boolean async;
|
||||
private boolean def;
|
||||
private Cmd command;
|
||||
private Help help;
|
||||
private int sort;
|
||||
@ -74,6 +68,7 @@ public class CommandInfo {
|
||||
this.command = command;
|
||||
this.help = help != null ? help : defHelp;
|
||||
this.async = async;
|
||||
this.def = method.getReturnType().equals(boolean.class);
|
||||
this.sort = sort;
|
||||
this.parse = parse;
|
||||
}
|
||||
@ -88,6 +83,7 @@ public class CommandInfo {
|
||||
this.command = null;
|
||||
this.help = null;
|
||||
this.async = false;
|
||||
this.def = false;
|
||||
this.sort = 0;
|
||||
this.parse = null;
|
||||
}
|
||||
@ -122,24 +118,23 @@ public class CommandInfo {
|
||||
*/
|
||||
public boolean execute(final CommandArgument cmdArgs) {
|
||||
if (method == null) { return false; }
|
||||
if (check(cmdArgs)) {
|
||||
Runnable runnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
method.invoke(origin, parse.parse(cmdArgs));
|
||||
} catch (CommandParseException | CommandArgumentException e) {
|
||||
Log.toSender(cmdArgs.getSender(), argErr, e.getMessage());
|
||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
|
||||
throw new CommandException(e);
|
||||
}
|
||||
check(cmdArgs);
|
||||
Runnable runnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
method.invoke(origin, parse.parse(cmdArgs));
|
||||
} catch (ParseException | ArgumentException e) {
|
||||
Log.toSender(cmdArgs.getSender(), argErr, e.getMessage());
|
||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
|
||||
throw new CommandException(e);
|
||||
}
|
||||
};
|
||||
if (async) {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(P.instance, runnable);
|
||||
} else {
|
||||
runnable.run();
|
||||
}
|
||||
};
|
||||
if (async) {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(P.instance, runnable);
|
||||
} else {
|
||||
runnable.run();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -179,6 +174,20 @@ public class CommandInfo {
|
||||
return async;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 是否为默认命令
|
||||
*/
|
||||
public boolean isDefault() {
|
||||
return def;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 允许的命令发送者
|
||||
*/
|
||||
public String getExecutorStr() {
|
||||
return executorStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证命令是否匹配
|
||||
*
|
||||
@ -203,36 +212,11 @@ public class CommandInfo {
|
||||
return Objects.hash(origin, method, name);
|
||||
}
|
||||
|
||||
private boolean check(CommandArgument cmdArgs) {
|
||||
private void check(CommandArgument cmdArgs) {
|
||||
CommandSender sender = cmdArgs.getSender();
|
||||
return checkSender(sender) && checkArgs(sender, cmdArgs) && checkPerm(sender);
|
||||
}
|
||||
|
||||
private boolean checkArgs(CommandSender sender, CommandArgument cmdArgs) {
|
||||
if (cmdArgs.getArgs().length < command.minimumArguments()) {
|
||||
Log.toSender(sender, cmdErr);
|
||||
Log.toSender(sender, cmdUse, cmdArgs.getAlias(), getName(), help.possibleArguments());
|
||||
Log.toSender(sender, cmdDes, help.value());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean checkPerm(CommandSender sender) {
|
||||
String perm = command.permission();
|
||||
if (!"".equals(perm) && !sender.hasPermission(perm)) {
|
||||
Log.toSender(sender, losePerm, perm);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean checkSender(CommandSender sender) {
|
||||
if (!executors.contains(Executor.ALL) && !executors.contains(Executor.valueOf(sender))) {
|
||||
Log.toSender(sender, onlyExecutor, executorStr);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
if (!executors.contains(Executor.ALL) && !executors.contains(Executor.valueOf(sender))) { throw new SenderException(executorStr); }
|
||||
if (!"".equals(command.permission()) && !sender.hasPermission(command.permission())) { throw new PermissionException(command.permission()); }
|
||||
if (cmdArgs.getArgs().length < command.minimumArguments()) { throw new ArgumentException(String.valueOf(command.minimumArguments())); }
|
||||
}
|
||||
|
||||
private String eS(List<Executor> executors) {
|
||||
|
@ -0,0 +1,16 @@
|
||||
package pw.yumc.YumCore.commands.interfaces;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
import pw.yumc.YumCore.commands.CommandArgument;
|
||||
import pw.yumc.YumCore.commands.exception.CommandException;
|
||||
import pw.yumc.YumCore.commands.info.CommandInfo;
|
||||
|
||||
/**
|
||||
* 命令错误处理
|
||||
*
|
||||
* @since 2016年7月23日 上午9:55:51
|
||||
* @author 喵♂呜
|
||||
*/
|
||||
public interface ErrorHanlder {
|
||||
void error(CommandException e, CommandSender sender, CommandInfo info, CommandArgument args);
|
||||
}
|
@ -1,11 +1,11 @@
|
||||
package pw.yumc.YumCore.commands.interfaces;
|
||||
|
||||
/**
|
||||
* 命令执行类
|
||||
*
|
||||
* @since 2016年7月23日 上午9:55:51
|
||||
* @author 喵♂呜
|
||||
*/
|
||||
public interface CommandExecutor {
|
||||
|
||||
}
|
||||
package pw.yumc.YumCore.commands.interfaces;
|
||||
|
||||
/**
|
||||
* 命令执行类
|
||||
*
|
||||
* @since 2016年7月23日 上午9:55:51
|
||||
* @author 喵♂呜
|
||||
*/
|
||||
public interface Executor {
|
||||
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package pw.yumc.YumCore.commands.interfaces;
|
||||
|
||||
import pw.yumc.YumCore.commands.info.CommandInfo;
|
||||
|
||||
/**
|
||||
* 帮助页生成器
|
||||
*
|
||||
* @author 喵♂呜
|
||||
* @since 2016年11月16日 上午12:39:26
|
||||
*/
|
||||
public interface HelpGenerator {
|
||||
/**
|
||||
* @return 帮助标题
|
||||
*/
|
||||
String title();
|
||||
|
||||
/**
|
||||
* 格式化命令信息
|
||||
*
|
||||
* @param label 命令
|
||||
* @param ci 命令信息
|
||||
* @return 格式化后的字串
|
||||
*/
|
||||
String body(String label, CommandInfo ci);
|
||||
|
||||
/**
|
||||
* 格式化帮助尾部
|
||||
*
|
||||
* @param label 命令标签
|
||||
* @param HELPPAGECOUNT 帮助页数
|
||||
* @return 帮助尾部
|
||||
*/
|
||||
String foot(String label, int HELPPAGECOUNT);
|
||||
|
||||
/**
|
||||
* 格式化未找到
|
||||
*
|
||||
* @param label 命令标签
|
||||
* @param HELPPAGECOUNT 帮助页数
|
||||
* @return 未找到提示
|
||||
*/
|
||||
String notFound(String label, int HELPPAGECOUNT);
|
||||
}
|
@ -1,18 +1,18 @@
|
||||
package pw.yumc.YumCore.commands.interfaces;
|
||||
|
||||
/**
|
||||
* 命令解析接口
|
||||
*
|
||||
* @author 喵♂呜
|
||||
* @since 2016年9月14日 上午12:39:26
|
||||
*/
|
||||
public interface CommandHelpParse {
|
||||
/**
|
||||
* 解析命令帮助
|
||||
*
|
||||
* @param str
|
||||
* 参数
|
||||
* @return 命令帮助
|
||||
*/
|
||||
String parse(String str);
|
||||
}
|
||||
package pw.yumc.YumCore.commands.interfaces;
|
||||
|
||||
/**
|
||||
* 命令解析接口
|
||||
*
|
||||
* @author 喵♂呜
|
||||
* @since 2016年9月14日 上午12:39:26
|
||||
*/
|
||||
public interface HelpParse {
|
||||
/**
|
||||
* 解析命令帮助
|
||||
*
|
||||
* @param str
|
||||
* 参数
|
||||
* @return 命令帮助
|
||||
*/
|
||||
String parse(String str);
|
||||
}
|
Loading…
Reference in New Issue
Block a user