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
9539ef92d0
commit
f7e7355dba
@ -2,6 +2,7 @@ package pw.yumc.YumCore.commands;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -10,7 +11,6 @@ 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;
|
||||||
|
|
||||||
@ -29,12 +29,7 @@ public class CommandParse {
|
|||||||
private boolean isMain;
|
private boolean isMain;
|
||||||
private List<Parse> parse = new LinkedList<>();
|
private List<Parse> parse = new LinkedList<>();
|
||||||
static {
|
static {
|
||||||
new BooleanParse();
|
|
||||||
new FileParse();
|
new FileParse();
|
||||||
new IntegerParse();
|
|
||||||
new DoubleParse();
|
|
||||||
new LongParse();
|
|
||||||
new MaterialParse();
|
|
||||||
new PlayerParse();
|
new PlayerParse();
|
||||||
new StringParse();
|
new StringParse();
|
||||||
}
|
}
|
||||||
@ -46,8 +41,9 @@ public class CommandParse {
|
|||||||
Class clazz = classes[i];
|
Class clazz = classes[i];
|
||||||
Annotation[] annotations = annons[i];
|
Annotation[] annotations = annons[i];
|
||||||
Parse parse = allparses.get(clazz);
|
Parse parse = allparses.get(clazz);
|
||||||
if (clazz.isEnum()) {
|
try {
|
||||||
parse = new EnumParse(clazz);
|
parse = new ValueOfParse(clazz, clazz.getDeclaredMethod("valueOf", String.class));
|
||||||
|
} catch (NoSuchMethodException ignored) {
|
||||||
}
|
}
|
||||||
if (parse == null) { throw new ParseException(String.format("存在无法解析的参数类型 %s", clazz.getName())); }
|
if (parse == null) { throw new ParseException(String.format("存在无法解析的参数类型 %s", clazz.getName())); }
|
||||||
this.parse.add(parse.clone().parseAnnotation(annotations).handleAttrs());
|
this.parse.add(parse.clone().parseAnnotation(annotations).handleAttrs());
|
||||||
@ -93,136 +89,13 @@ public class CommandParse {
|
|||||||
}
|
}
|
||||||
pobjs.add(param == null ? null : p.parse(sender, param));
|
pobjs.add(param == null ? null : p.parse(sender, param));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new ParseException(String.format("第 %s 个参数 ", isMain ? 1 : 2 + i) + e.getMessage());
|
throw new ParseException(String.format("第 %s 个参数 %s", isMain ? 1 : 2 + i, e.getMessage()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Log.d("解析参数: %s => %s", Arrays.toString(args), pobjs);
|
Log.d("解析参数: %s => %s", Arrays.toString(args), pobjs);
|
||||||
return pobjs.toArray();
|
return pobjs.toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class BooleanParse extends Parse<Boolean> {
|
|
||||||
public BooleanParse() {
|
|
||||||
register(Boolean.class, this);
|
|
||||||
register(boolean.class, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean parse(CommandSender sender, String arg) {
|
|
||||||
try {
|
|
||||||
return Boolean.parseBoolean(arg);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new ParseException("必须为True或者False!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class EnumParse extends Parse<Enum> {
|
|
||||||
Enum[] elist;
|
|
||||||
Class<Enum> etype;
|
|
||||||
|
|
||||||
public EnumParse(Class<Enum> etype) {
|
|
||||||
this.etype = etype;
|
|
||||||
this.elist = etype.getEnumConstants();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Enum parse(CommandSender sender, String arg) {
|
|
||||||
try {
|
|
||||||
return Enum.valueOf(etype, arg);
|
|
||||||
} catch (IllegalArgumentException ex) {
|
|
||||||
throw new ParseException(String.format("不是 %s 有效值为 %s", etype.getSimpleName(), Arrays.toString(elist)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class FileParse extends Parse<File> {
|
|
||||||
public FileParse() {
|
|
||||||
register(File.class, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public File parse(CommandSender sender, String arg) throws ParseException {
|
|
||||||
File file = new File(arg);
|
|
||||||
if (attrs.containsKey("check") && !file.exists()) { throw new ParseException("文件 " + arg + " 不存在!"); }
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class IntegerParse extends Parse<Integer> {
|
|
||||||
public IntegerParse() {
|
|
||||||
register(Integer.class, this);
|
|
||||||
register(int.class, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Integer parse(CommandSender sender, String arg) {
|
|
||||||
try {
|
|
||||||
int result = Integer.parseInt(arg);
|
|
||||||
if (min > result || result > max) {
|
|
||||||
throwRange();
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
throw new ParseException("必须为数字!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class DoubleParse extends Parse<Double> {
|
|
||||||
public DoubleParse() {
|
|
||||||
register(Double.class, this);
|
|
||||||
register(double.class, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Double parse(CommandSender sender, String arg) {
|
|
||||||
try {
|
|
||||||
double result = Double.parseDouble(arg);
|
|
||||||
if (min > result || result > max) {
|
|
||||||
throwRange();
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
throw new ParseException("必须为数字!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class LongParse extends Parse<Long> {
|
|
||||||
public LongParse() {
|
|
||||||
register(Long.class, this);
|
|
||||||
register(long.class, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Long parse(CommandSender sender, String arg) {
|
|
||||||
try {
|
|
||||||
long result = Long.parseLong(arg);
|
|
||||||
if (min > result || result > max) {
|
|
||||||
throwRange();
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
throw new ParseException("必须为数字!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class MaterialParse extends Parse<Material> {
|
|
||||||
public MaterialParse() {
|
|
||||||
register(Material.class, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Material parse(CommandSender sender, String arg) {
|
|
||||||
try {
|
|
||||||
return Material.valueOf(arg);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new ParseException(String.format("%s 不是一个有效的Material枚举", arg), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static abstract class Parse<RT> implements Cloneable {
|
public static abstract class Parse<RT> implements Cloneable {
|
||||||
protected Map<String, String> attrs = new HashMap<>();
|
protected Map<String, String> attrs = new HashMap<>();
|
||||||
protected String def;
|
protected String def;
|
||||||
@ -275,16 +148,68 @@ public class CommandParse {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void throwException(String str, Object... objects) {
|
public <T> T throwException(String str, Object... objects) {
|
||||||
throw new ParseException(String.format(str, objects));
|
throw new ParseException(String.format(str, objects));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void throwRange() {
|
public <T> T throwRange() {
|
||||||
throwRange("");
|
return throwRange("");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void throwRange(String str) {
|
public <T> T throwRange(String str) {
|
||||||
throw new ParseException(String.format(str.isEmpty() ? "范围必须在 %s 到 %s 之间!" : str, min, max));
|
return throwException(str.isEmpty() ? "范围必须在 %s 到 %s 之间!" : str, min, max);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ValueOfParse extends Parse<Object> {
|
||||||
|
private Class etype;
|
||||||
|
private Enum[] elist;
|
||||||
|
private Method method;
|
||||||
|
private Method checker;
|
||||||
|
|
||||||
|
public ValueOfParse(Class etype, Method method) {
|
||||||
|
this.etype = etype;
|
||||||
|
try {
|
||||||
|
checker = etype.getDeclaredMethod("doubleValue");
|
||||||
|
} catch (NoSuchMethodException ignored) {
|
||||||
|
}
|
||||||
|
this.method = method;
|
||||||
|
if (etype.isEnum()) {
|
||||||
|
this.elist = ((Class<Enum>) etype).getEnumConstants();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object parse(CommandSender sender, String arg) {
|
||||||
|
try {
|
||||||
|
Object result = method.invoke(null, arg);
|
||||||
|
if (checker != null) {
|
||||||
|
double num = (double) checker.invoke(result);
|
||||||
|
if (min > num || num > max) {
|
||||||
|
throwRange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} catch (IllegalArgumentException | InvocationTargetException | IllegalAccessException ex) {
|
||||||
|
if (etype.isEnum() && elist.length < 21) {
|
||||||
|
return throwException("%s 不是 %s 有效值为 %s", arg, etype.getSimpleName(), Arrays.toString(elist));
|
||||||
|
} else {
|
||||||
|
return throwException("%s 不是一个有效的 %s", arg, etype.getSimpleName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class FileParse extends Parse<File> {
|
||||||
|
public FileParse() {
|
||||||
|
register(File.class, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public File parse(CommandSender sender, String arg) throws ParseException {
|
||||||
|
File file = new File(arg);
|
||||||
|
if (attrs.containsKey("check") && !file.exists()) { throw new ParseException("文件 " + arg + " 不存在!"); }
|
||||||
|
return file;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,7 +223,7 @@ public class CommandParse {
|
|||||||
@Override
|
@Override
|
||||||
public Player parse(CommandSender sender, String arg) {
|
public Player parse(CommandSender sender, String arg) {
|
||||||
Player p = Bukkit.getPlayerExact(arg);
|
Player p = Bukkit.getPlayerExact(arg);
|
||||||
if (check && p == null) { throw new ParseException("玩家 " + arg + " 不存在或不在线!"); }
|
if (check && p == null) { return throwException("玩家 %s 不存在或不在线!", arg); }
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,12 +243,8 @@ public class CommandParse {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String parse(CommandSender sender, String arg) {
|
public String parse(CommandSender sender, String arg) {
|
||||||
if (min > arg.length() || arg.length() > max) {
|
if (min > arg.length() || arg.length() > max) { return throwRange("长度必须在 %s 和 %s 之间!"); }
|
||||||
throwRange("长度必须在 %s 和 %s 之间!");
|
if (options != null && !options.contains(arg)) { return throwException("参数 %s 不是一个有效的选项 有效值为 %s", arg, options); }
|
||||||
}
|
|
||||||
if (options != null && !options.contains(arg)) {
|
|
||||||
throwException("参数 %s 不是一个有效的选项 有效值为 %s", arg, options);
|
|
||||||
}
|
|
||||||
return arg;
|
return arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user