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:
parent
2263ac395d
commit
467abec4af
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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)) {
|
||||||
|
@ -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
|
||||||
|
@ -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();
|
||||||
}
|
}
|
@ -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.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);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user