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
2263ac395d
commit
467abec4af
@ -125,10 +125,10 @@ public class CommandHelp {
|
||||
* @param args
|
||||
* 参数
|
||||
*/
|
||||
public void send(final CommandSender sender, final Command command, final String label, final String[] args) {
|
||||
public boolean send(final CommandSender sender, final Command command, final String label, final String[] args) {
|
||||
if (this.HELPPAGECOUNT == 0) {
|
||||
sender.sendMessage(commandNotFound);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
int page = 1;
|
||||
try {
|
||||
@ -163,6 +163,7 @@ public class CommandHelp {
|
||||
cacheHelp.put(helpkey, helpList.toArray(new String[0]));
|
||||
}
|
||||
sender.sendMessage(cacheHelp.get(helpkey));
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -141,16 +141,13 @@ public class CommandManager implements TabExecutor {
|
||||
if (defCmd != null) {
|
||||
return defCmd.execute(new CommandArgument(sender, command, label, args));
|
||||
}
|
||||
help.send(sender, command, label, args);
|
||||
return true;
|
||||
return help.send(sender, command, label, args);
|
||||
}
|
||||
final String subcmd = args[0].toLowerCase();
|
||||
if (subcmd.equalsIgnoreCase("help")) {
|
||||
help.send(sender, command, label, args);
|
||||
return true;
|
||||
return help.send(sender, command, label, args);
|
||||
}
|
||||
final CommandInfo ci = checkCache(subcmd);
|
||||
return ci.execute(new CommandArgument(sender, command, label, moveStrings(args, 1)));
|
||||
return getByCache(subcmd).execute(new CommandArgument(sender, command, label, moveStrings(args, 1)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -218,7 +215,7 @@ public class CommandManager implements TabExecutor {
|
||||
* 子命令
|
||||
* @return 命令信息
|
||||
*/
|
||||
private CommandInfo checkCache(final String subcmd) {
|
||||
private CommandInfo getByCache(final String subcmd) {
|
||||
if (!cmdCache.containsKey(subcmd)) {
|
||||
for (final CommandInfo cmdinfo : cmds) {
|
||||
if (cmdinfo.isValid(subcmd)) {
|
||||
|
@ -2,15 +2,18 @@ package pw.yumc.YumCore.commands;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
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;
|
||||
@ -32,26 +35,31 @@ public class CommandParse {
|
||||
new PlayerParse();
|
||||
new StringParse();
|
||||
}
|
||||
public List<Parse> parse = new LinkedList<>();
|
||||
public List<Object> parsed = new LinkedList<>();
|
||||
private final List<Parse> parse = new LinkedList<>();
|
||||
|
||||
public CommandParse(final Class[] classes, final Annotation[][] annons) {
|
||||
private final boolean isMain;
|
||||
|
||||
public CommandParse(final Class[] classes, final Annotation[][] annons, final boolean isMain) {
|
||||
this.isMain = isMain;
|
||||
for (int i = 0; i < classes.length; i++) {
|
||||
final Class clazz = classes[i];
|
||||
final Annotation[] annotations = annons[i];
|
||||
if (clazz.isAssignableFrom(CommandSender.class)) {
|
||||
continue;
|
||||
}
|
||||
if (!allparses.containsKey(clazz)) {
|
||||
throw new CommandParseException(String.format("无法解析的参数类型 %s !", clazz.getName()));
|
||||
Parse parse = allparses.get(clazz);
|
||||
if (parse == null) {
|
||||
if (!clazz.isEnum()) {
|
||||
throw new CommandParseException(String.format("存在无法解析的参数类型 %s", clazz.getName()));
|
||||
}
|
||||
parse = new EnumParse(clazz);
|
||||
}
|
||||
final Parse parse = allparses.get(clazz).clone();
|
||||
this.parse.add(parse.parseAnnotation(annotations));
|
||||
this.parse.add(parse.clone().parseAnnotation(annotations));
|
||||
}
|
||||
}
|
||||
|
||||
public static CommandParse get(final Method method) {
|
||||
return new CommandParse(method.getParameterTypes(), method.getParameterAnnotations());
|
||||
return new CommandParse(method.getParameterTypes(), method.getParameterAnnotations(), method.getReturnType().equals(boolean.class));
|
||||
}
|
||||
|
||||
public static void registerParse(final Class clazz, final Parse parse) {
|
||||
@ -60,18 +68,16 @@ public class CommandParse {
|
||||
|
||||
public Object[] parse(final CommandArgument cmdArgs) {
|
||||
final String args[] = cmdArgs.getArgs();
|
||||
if (args.length == 0) {
|
||||
return null;
|
||||
}
|
||||
final List<Object> pobjs = new LinkedList<>();
|
||||
pobjs.add(cmdArgs.getSender());
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
for (int i = 0; i < parse.size(); i++) {
|
||||
try {
|
||||
if (i < parse.size()) {
|
||||
pobjs.add(parse.get(i).parse(args[i]));
|
||||
}
|
||||
final Parse p = parse.get(i);
|
||||
final String param = i < args.length ? args[i] : p.def;
|
||||
pobjs.add(param == null ? param : p.parse(param));
|
||||
} catch (final Exception e) {
|
||||
throw new CommandException(String.format("第 %s 个参数 ", i + 1) + e.getMessage());
|
||||
Log.debug(e);
|
||||
throw new CommandParseException(String.format("第 %s 个参数 ", isMain ? 1 : 2 + i) + e.getMessage());
|
||||
}
|
||||
}
|
||||
return pobjs.toArray();
|
||||
@ -88,7 +94,26 @@ public class CommandParse {
|
||||
try {
|
||||
return Boolean.parseBoolean(arg);
|
||||
} catch (final Exception e) {
|
||||
throw new CommandParseException("必须为True或者False!");
|
||||
throw new CommandParseException("必须为True或者False!", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class EnumParse extends Parse<Enum> {
|
||||
Class<Enum> etype;
|
||||
Enum[] elist;
|
||||
|
||||
public EnumParse(final Class<Enum> etype) {
|
||||
this.etype = etype;
|
||||
this.elist = etype.getEnumConstants();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Enum parse(final String arg) {
|
||||
try {
|
||||
return Enum.valueOf(etype, arg);
|
||||
} catch (final IllegalArgumentException ex) {
|
||||
throw new CommandParseException(String.format("不是 %s 有效值为 %s", etype.getSimpleName(), Arrays.toString(elist)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -107,8 +132,8 @@ public class CommandParse {
|
||||
throwRange();
|
||||
}
|
||||
return result;
|
||||
} catch (final Exception e) {
|
||||
throw new CommandParseException("必须为数字!");
|
||||
} catch (final NumberFormatException e) {
|
||||
throw new CommandParseException("必须为数字!", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -127,17 +152,32 @@ public class CommandParse {
|
||||
throwRange();
|
||||
}
|
||||
return result;
|
||||
} catch (final NumberFormatException e) {
|
||||
throw new CommandParseException("必须为数字!", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class MaterialParse extends Parse<Material> {
|
||||
public MaterialParse() {
|
||||
allparses.put(String.class, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Material parse(final String arg) {
|
||||
try {
|
||||
return Material.valueOf(arg);
|
||||
} catch (final Exception e) {
|
||||
throw new CommandParseException("必须为数字!");
|
||||
throw new CommandParseException("玩家 " + arg + "不存在或不在线!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static abstract class Parse<RT> implements Cloneable {
|
||||
protected Object def;
|
||||
protected Map<String, Object> attrs = new HashMap<>();
|
||||
protected int min;
|
||||
protected int max;
|
||||
protected String def;
|
||||
protected Map<String, String> attrs = new HashMap<>();
|
||||
protected int min = 0;
|
||||
protected int max = Integer.MAX_VALUE;
|
||||
|
||||
@Override
|
||||
public Parse<RT> clone() {
|
||||
@ -148,43 +188,33 @@ public class CommandParse {
|
||||
}
|
||||
}
|
||||
|
||||
public Object getDefault() {
|
||||
public String getDefault() {
|
||||
return def;
|
||||
}
|
||||
|
||||
public void load() {
|
||||
def = attrs.get("default");
|
||||
min = (int) attrs.get("min");
|
||||
max = (int) attrs.get("max");
|
||||
}
|
||||
|
||||
public abstract RT parse(String arg) throws CommandParseException;
|
||||
|
||||
public Parse<RT> parseAnnotation(final Annotation[] annotations) {
|
||||
for (final Annotation annotation : annotations) {
|
||||
if (annotation.annotationType() == Default.class) {
|
||||
setAttr("default", ((Default) annotation).value());
|
||||
def = ((Default) annotation).value();
|
||||
} else if (annotation.annotationType() == Limit.class) {
|
||||
setAttr("min", ((Limit) annotation).min());
|
||||
setAttr("max", ((Limit) annotation).max());
|
||||
min = ((Limit) annotation).min();
|
||||
max = ((Limit) annotation).max();
|
||||
} else if (annotation.annotationType() == KeyValue.class) {
|
||||
final KeyValue kv = (KeyValue) annotation;
|
||||
setAttr(kv.key(), kv.value());
|
||||
attrs.put(kv.key(), kv.value());
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setAttr(final String name, final Object value) {
|
||||
attrs.put(name, value);
|
||||
}
|
||||
|
||||
public void throwRange() {
|
||||
throwRange(null);
|
||||
}
|
||||
|
||||
public void throwRange(final String str) {
|
||||
throw new CommandException(String.format(str == null ? "必须在 %s 到 %s之间!" : str, min, max));
|
||||
throw new CommandException(String.format(str == null ? "必须在 %s 到 %s 之间!" : str, min, max));
|
||||
}
|
||||
}
|
||||
|
||||
@ -204,8 +234,13 @@ public class CommandParse {
|
||||
}
|
||||
|
||||
public static class StringParse extends Parse<String> {
|
||||
List<String> options;
|
||||
|
||||
public StringParse() {
|
||||
allparses.put(String.class, this);
|
||||
if (attrs.containsKey("option")) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -11,7 +11,7 @@ import java.lang.annotation.Target;
|
||||
* @since 2016年7月23日 上午9:00:27
|
||||
* @author 喵♂呜
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Target(ElementType.PARAMETER)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Limit {
|
||||
/**
|
||||
|
@ -0,0 +1,22 @@
|
||||
package pw.yumc.YumCore.commands.exception;
|
||||
|
||||
/**
|
||||
* 命令参数解析异常
|
||||
*
|
||||
* @author 喵♂呜
|
||||
* @since 2016年10月5日 下午5:15:43
|
||||
*/
|
||||
public class CommandArgumentException extends CommandException {
|
||||
|
||||
public CommandArgumentException(final Exception e) {
|
||||
super(e);
|
||||
}
|
||||
|
||||
public CommandArgumentException(final String string) {
|
||||
super(string);
|
||||
}
|
||||
|
||||
public CommandArgumentException(final String string, final Exception e) {
|
||||
super(string, e);
|
||||
}
|
||||
}
|
@ -17,7 +17,9 @@ 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;
|
||||
|
||||
/**
|
||||
* 命令信息存储类
|
||||
@ -29,6 +31,7 @@ public class CommandInfo {
|
||||
public static final CommandInfo Unknow = new CommandInfo();
|
||||
private static final String onlyExecutor = "§c当前命令仅允许 §b%s §c执行!";
|
||||
private static final String losePerm = "§c你需要有 %s 的权限才能执行此命令!";
|
||||
private static final String argErr = "§c参数错误: §4%s";
|
||||
private static final String cmdErr = "§6错误原因: §4命令参数不正确!";
|
||||
private static final String cmdUse = "§6使用方法: §e/%s %s %s";
|
||||
private static final String cmdDes = "§6命令描述: §3%s";
|
||||
@ -121,6 +124,8 @@ public class CommandInfo {
|
||||
public void run() {
|
||||
try {
|
||||
method.invoke(origin, parse.parse(cmdArgs));
|
||||
} catch (final CommandParseException | CommandArgumentException e) {
|
||||
Log.toSender(cmdArgs.getSender(), argErr, e.getMessage());
|
||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
|
||||
throw new CommandException(e);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user