1
0
mirror of https://e.coding.net/circlecloud/YumCore.git synced 2024-11-22 01:48:50 +00:00

feat: 添加枚举解析 优化处理流程

Signed-off-by: 502647092 <admin@yumc.pw>
This commit is contained in:
502647092 2016-10-11 19:26:07 +08:00
parent 2263ac395d
commit 467abec4af
6 changed files with 134 additions and 74 deletions

View File

@ -125,10 +125,10 @@ public class CommandHelp {
* @param args * @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) { if (this.HELPPAGECOUNT == 0) {
sender.sendMessage(commandNotFound); sender.sendMessage(commandNotFound);
return; return true;
} }
int page = 1; int page = 1;
try { try {
@ -163,6 +163,7 @@ public class CommandHelp {
cacheHelp.put(helpkey, helpList.toArray(new String[0])); cacheHelp.put(helpkey, helpList.toArray(new String[0]));
} }
sender.sendMessage(cacheHelp.get(helpkey)); sender.sendMessage(cacheHelp.get(helpkey));
return true;
} }
/** /**

View File

@ -141,16 +141,13 @@ public class CommandManager implements TabExecutor {
if (defCmd != null) { if (defCmd != null) {
return defCmd.execute(new CommandArgument(sender, command, label, args)); return defCmd.execute(new CommandArgument(sender, command, label, args));
} }
help.send(sender, command, label, args); return help.send(sender, command, label, args);
return true;
} }
final String subcmd = args[0].toLowerCase(); final String subcmd = args[0].toLowerCase();
if (subcmd.equalsIgnoreCase("help")) { if (subcmd.equalsIgnoreCase("help")) {
help.send(sender, command, label, args); return help.send(sender, command, label, args);
return true;
} }
final CommandInfo ci = checkCache(subcmd); return getByCache(subcmd).execute(new CommandArgument(sender, command, label, moveStrings(args, 1)));
return ci.execute(new CommandArgument(sender, command, label, moveStrings(args, 1)));
} }
@Override @Override
@ -218,7 +215,7 @@ public class CommandManager implements TabExecutor {
* 子命令 * 子命令
* @return 命令信息 * @return 命令信息
*/ */
private CommandInfo checkCache(final String subcmd) { private CommandInfo getByCache(final String subcmd) {
if (!cmdCache.containsKey(subcmd)) { if (!cmdCache.containsKey(subcmd)) {
for (final CommandInfo cmdinfo : cmds) { for (final CommandInfo cmdinfo : cmds) {
if (cmdinfo.isValid(subcmd)) { if (cmdinfo.isValid(subcmd)) {

View File

@ -2,15 +2,18 @@ package pw.yumc.YumCore.commands;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import pw.yumc.YumCore.bukkit.Log;
import pw.yumc.YumCore.commands.annotation.Default; import pw.yumc.YumCore.commands.annotation.Default;
import pw.yumc.YumCore.commands.annotation.KeyValue; import pw.yumc.YumCore.commands.annotation.KeyValue;
import pw.yumc.YumCore.commands.annotation.Limit; import pw.yumc.YumCore.commands.annotation.Limit;
@ -32,26 +35,31 @@ public class CommandParse {
new PlayerParse(); new PlayerParse();
new StringParse(); new StringParse();
} }
public List<Parse> parse = new LinkedList<>(); private final List<Parse> parse = new LinkedList<>();
public List<Object> parsed = 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++) { for (int i = 0; i < classes.length; i++) {
final Class clazz = classes[i]; final Class clazz = classes[i];
final Annotation[] annotations = annons[i]; final Annotation[] annotations = annons[i];
if (clazz.isAssignableFrom(CommandSender.class)) { if (clazz.isAssignableFrom(CommandSender.class)) {
continue; continue;
} }
if (!allparses.containsKey(clazz)) { Parse parse = allparses.get(clazz);
throw new CommandParseException(String.format("无法解析的参数类型 %s !", clazz.getName())); 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.clone().parseAnnotation(annotations));
this.parse.add(parse.parseAnnotation(annotations));
} }
} }
public static CommandParse get(final Method method) { 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) { public static void registerParse(final Class clazz, final Parse parse) {
@ -60,18 +68,16 @@ public class CommandParse {
public Object[] parse(final CommandArgument cmdArgs) { public Object[] parse(final CommandArgument cmdArgs) {
final String args[] = cmdArgs.getArgs(); final String args[] = cmdArgs.getArgs();
if (args.length == 0) {
return null;
}
final List<Object> pobjs = new LinkedList<>(); final List<Object> pobjs = new LinkedList<>();
pobjs.add(cmdArgs.getSender()); pobjs.add(cmdArgs.getSender());
for (int i = 0; i < args.length; i++) { for (int i = 0; i < parse.size(); i++) {
try { try {
if (i < parse.size()) { final Parse p = parse.get(i);
pobjs.add(parse.get(i).parse(args[i])); final String param = i < args.length ? args[i] : p.def;
} pobjs.add(param == null ? param : p.parse(param));
} catch (final Exception e) { } 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(); return pobjs.toArray();
@ -88,7 +94,26 @@ public class CommandParse {
try { try {
return Boolean.parseBoolean(arg); return Boolean.parseBoolean(arg);
} catch (final Exception e) { } 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(); throwRange();
} }
return result; return result;
} catch (final Exception e) { } catch (final NumberFormatException e) {
throw new CommandParseException("必须为数字!"); throw new CommandParseException("必须为数字!", e);
} }
} }
} }
@ -127,17 +152,32 @@ public class CommandParse {
throwRange(); throwRange();
} }
return result; 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) { } catch (final Exception e) {
throw new CommandParseException("必须为数字!"); throw new CommandParseException("玩家 " + arg + "不存在或不在线!");
} }
} }
} }
public static abstract class Parse<RT> implements Cloneable { public static abstract class Parse<RT> implements Cloneable {
protected Object def; protected String def;
protected Map<String, Object> attrs = new HashMap<>(); protected Map<String, String> attrs = new HashMap<>();
protected int min; protected int min = 0;
protected int max; protected int max = Integer.MAX_VALUE;
@Override @Override
public Parse<RT> clone() { public Parse<RT> clone() {
@ -148,43 +188,33 @@ public class CommandParse {
} }
} }
public Object getDefault() { public String getDefault() {
return def; 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 abstract RT parse(String arg) throws CommandParseException;
public Parse<RT> parseAnnotation(final Annotation[] annotations) { public Parse<RT> parseAnnotation(final Annotation[] annotations) {
for (final Annotation annotation : annotations) { for (final Annotation annotation : annotations) {
if (annotation.annotationType() == Default.class) { if (annotation.annotationType() == Default.class) {
setAttr("default", ((Default) annotation).value()); def = ((Default) annotation).value();
} else if (annotation.annotationType() == Limit.class) { } else if (annotation.annotationType() == Limit.class) {
setAttr("min", ((Limit) annotation).min()); min = ((Limit) annotation).min();
setAttr("max", ((Limit) annotation).max()); max = ((Limit) annotation).max();
} else if (annotation.annotationType() == KeyValue.class) { } else if (annotation.annotationType() == KeyValue.class) {
final KeyValue kv = (KeyValue) annotation; final KeyValue kv = (KeyValue) annotation;
setAttr(kv.key(), kv.value()); attrs.put(kv.key(), kv.value());
} }
} }
return this; return this;
} }
public void setAttr(final String name, final Object value) {
attrs.put(name, value);
}
public void throwRange() { public void throwRange() {
throwRange(null); throwRange(null);
} }
public void throwRange(final String str) { 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> { public static class StringParse extends Parse<String> {
List<String> options;
public StringParse() { public StringParse() {
allparses.put(String.class, this); allparses.put(String.class, this);
if (attrs.containsKey("option")) {
}
} }
@Override @Override

View File

@ -1,26 +1,26 @@
package pw.yumc.YumCore.commands.annotation; package pw.yumc.YumCore.commands.annotation;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
/** /**
* 参数限制 * 参数限制
* *
* @since 2016年7月23日 上午9:00:27 * @since 2016年7月23日 上午9:00:27
* @author * @author
*/ */
@Target(ElementType.METHOD) @Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface Limit { public @interface Limit {
/** /**
* @return 最大长度(最大值) * @return 最大长度(最大值)
*/ */
int max() default 255; int max() default 255;
/** /**
* @return 最小长度(或最小值) * @return 最小长度(或最小值)
*/ */
int min(); int min();
} }

View File

@ -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);
}
}

View File

@ -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.Cmd.Executor;
import pw.yumc.YumCore.commands.annotation.Help; import pw.yumc.YumCore.commands.annotation.Help;
import pw.yumc.YumCore.commands.annotation.Sort; 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.CommandException;
import pw.yumc.YumCore.commands.exception.CommandParseException;
/** /**
* 命令信息存储类 * 命令信息存储类
@ -29,6 +31,7 @@ public class CommandInfo {
public static final CommandInfo Unknow = new CommandInfo(); public static final CommandInfo Unknow = new CommandInfo();
private static final String onlyExecutor = "§c当前命令仅允许 §b%s §c执行!"; private static final String onlyExecutor = "§c当前命令仅允许 §b%s §c执行!";
private static final String losePerm = "§c你需要有 %s 的权限才能执行此命令!"; 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 cmdErr = "§6错误原因: §4命令参数不正确!";
private static final String cmdUse = "§6使用方法: §e/%s %s %s"; private static final String cmdUse = "§6使用方法: §e/%s %s %s";
private static final String cmdDes = "§6命令描述: §3%s"; private static final String cmdDes = "§6命令描述: §3%s";
@ -121,6 +124,8 @@ public class CommandInfo {
public void run() { public void run() {
try { try {
method.invoke(origin, parse.parse(cmdArgs)); method.invoke(origin, parse.parse(cmdArgs));
} catch (final CommandParseException | CommandArgumentException e) {
Log.toSender(cmdArgs.getSender(), argErr, e.getMessage());
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new CommandException(e); throw new CommandException(e);
} }