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
8d29a90c04
commit
ea1ddd6385
2
pom.xml
2
pom.xml
@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>pw.yumc</groupId>
|
||||
<artifactId>YumCore</artifactId>
|
||||
<version>1.0</version>
|
||||
<version>1.1</version>
|
||||
<name>YumCore</name>
|
||||
<build>
|
||||
<finalName>${project.name}</finalName>
|
||||
|
@ -15,12 +15,14 @@ public class CommandArgument {
|
||||
private final Command command;
|
||||
private final String alias;
|
||||
private final String[] args;
|
||||
private final CommandParse parses;
|
||||
|
||||
public CommandArgument(final CommandSender sender, final Command command, final String alias, final String[] args) {
|
||||
this.sender = sender;
|
||||
this.command = command;
|
||||
this.alias = alias;
|
||||
this.args = args;
|
||||
parses = null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -43,8 +43,9 @@ public class CommandInfo {
|
||||
private final Cmd command;
|
||||
private final Help help;
|
||||
private final int sort;
|
||||
private final CommandParse parse;
|
||||
|
||||
public CommandInfo(final Method method, final Object origin, final Cmd command, final Help help, final boolean async, final int sort) {
|
||||
public CommandInfo(final Method method, final Object origin, final Cmd command, final Help help, final boolean async, final int sort, final CommandParse parse) {
|
||||
this.method = method;
|
||||
this.origin = origin;
|
||||
this.name = "".equals(command.value()) ? method.getName().toLowerCase() : command.value();
|
||||
@ -55,6 +56,7 @@ public class CommandInfo {
|
||||
this.help = help;
|
||||
this.async = async;
|
||||
this.sort = sort;
|
||||
this.parse = parse;
|
||||
}
|
||||
|
||||
private CommandInfo() {
|
||||
@ -68,6 +70,7 @@ public class CommandInfo {
|
||||
this.help = null;
|
||||
this.async = false;
|
||||
this.sort = 0;
|
||||
this.parse = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -85,7 +88,8 @@ public class CommandInfo {
|
||||
final Help help = method.getAnnotation(Help.class);
|
||||
final Async async = method.getAnnotation(Async.class);
|
||||
final Sort sort = method.getAnnotation(Sort.class);
|
||||
return new CommandInfo(method, origin, command, help != null ? help : Help.DEFAULT, async != null, sort != null ? sort.value() : 50);
|
||||
final CommandParse cp = CommandParse.get(method);
|
||||
return new CommandInfo(method, origin, command, help != null ? help : Help.DEFAULT, async != null, sort != null ? sort.value() : 50, cp);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -117,7 +121,7 @@ public class CommandInfo {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
method.invoke(origin, cmdArgs);
|
||||
method.invoke(origin, cmdArgs.getSender(), parse.parse(cmdArgs));
|
||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
|
||||
throw new CommandException(e);
|
||||
}
|
||||
|
@ -1,5 +1,8 @@
|
||||
package pw.yumc.YumCore.commands;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@ -10,11 +13,15 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.command.SimpleCommandMap;
|
||||
import org.bukkit.command.TabExecutor;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.util.StringUtil;
|
||||
|
||||
@ -29,8 +36,33 @@ import pw.yumc.YumCore.bukkit.compatible.C;
|
||||
* @author 喵♂呜
|
||||
*/
|
||||
public class CommandManager implements TabExecutor {
|
||||
private final static String argumentTypeError = "注解命令方法 %s 位于 %s 的参数错误 应只有 CommandArgument 参数!";
|
||||
private final static String argumentTypeError = "注解命令方法 %s 位于 %s 的参数错误 第一个参数应实现 CommandSender 接口!";
|
||||
private final static String returnTypeError = "注解命令补全 %s 位于 %s 的返回值错误 应实现 List 接口!";
|
||||
private static Constructor<PluginCommand> PluginCommandConstructor;
|
||||
private static Map<String, Command> knownCommands;
|
||||
private static Map<String, Plugin> lookupNames;
|
||||
static {
|
||||
try {
|
||||
final PluginManager pluginManager = Bukkit.getPluginManager();
|
||||
|
||||
final Field lookupNamesField = pluginManager.getClass().getDeclaredField("lookupNames");
|
||||
lookupNamesField.setAccessible(true);
|
||||
lookupNames = (Map<String, Plugin>) lookupNamesField.get(pluginManager);
|
||||
|
||||
final Field commandMapField = pluginManager.getClass().getDeclaredField("commandMap");
|
||||
commandMapField.setAccessible(true);
|
||||
final SimpleCommandMap commandMap = (SimpleCommandMap) commandMapField.get(pluginManager);
|
||||
|
||||
final Field knownCommandsField = commandMap.getClass().getDeclaredField("knownCommands");
|
||||
knownCommandsField.setAccessible(true);
|
||||
knownCommands = (Map<String, Command>) knownCommandsField.get(commandMap);
|
||||
|
||||
PluginCommandConstructor = PluginCommand.class.getConstructor(String.class, Plugin.class);
|
||||
} catch (NoSuchMethodException | SecurityException | NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) {
|
||||
Log.d("初始化命令管理器失败!");
|
||||
Log.debug(e);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 插件实例类
|
||||
*/
|
||||
@ -62,7 +94,7 @@ public class CommandManager implements TabExecutor {
|
||||
/**
|
||||
* 插件命令
|
||||
*/
|
||||
private final PluginCommand cmd;
|
||||
private PluginCommand cmd;
|
||||
|
||||
/**
|
||||
* 命令管理器
|
||||
@ -73,8 +105,15 @@ public class CommandManager implements TabExecutor {
|
||||
public CommandManager(final String name) {
|
||||
cmd = plugin.getCommand(name);
|
||||
if (cmd == null) {
|
||||
try {
|
||||
knownCommands.put(name, PluginCommandConstructor.newInstance(name, plugin));
|
||||
lookupNames.put(name, plugin);
|
||||
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
|
||||
}
|
||||
if ((cmd = plugin.getCommand(name)) == null) {
|
||||
throw new IllegalStateException("未找到命令 必须在plugin.yml先注册 " + name + " 命令!");
|
||||
}
|
||||
}
|
||||
cmd.setExecutor(this);
|
||||
cmd.setTabCompleter(this);
|
||||
}
|
||||
@ -106,9 +145,8 @@ public class CommandManager implements TabExecutor {
|
||||
help.send(sender, command, label, args);
|
||||
return true;
|
||||
}
|
||||
final CommandArgument cmdArgs = new CommandArgument(sender, command, label, moveStrings(args, 1));
|
||||
final CommandInfo ci = checkCache(subcmd);
|
||||
return ci.execute(cmdArgs);
|
||||
return ci.execute(new CommandArgument(sender, command, label, moveStrings(args, 1)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -245,7 +283,7 @@ public class CommandManager implements TabExecutor {
|
||||
final CommandInfo ci = CommandInfo.parse(method, clazz);
|
||||
if (ci != null) {
|
||||
final Class<?>[] params = method.getParameterTypes();
|
||||
if (params.length == 1 && params[0].equals(CommandArgument.class)) {
|
||||
if (params.length > 0 && params[0].equals(CommandArgument.class)) {
|
||||
if (method.getReturnType() == boolean.class) {
|
||||
defCmd = ci;
|
||||
return true;
|
||||
|
143
src/main/java/pw/yumc/YumCore/commands/CommandParse.java
Normal file
143
src/main/java/pw/yumc/YumCore/commands/CommandParse.java
Normal file
@ -0,0 +1,143 @@
|
||||
package pw.yumc.YumCore.commands;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import pw.yumc.YumCore.commands.exception.CommandException;
|
||||
import pw.yumc.YumCore.commands.exception.CommandParseException;
|
||||
|
||||
/**
|
||||
* 命令参数解析
|
||||
*
|
||||
* @author 喵♂呜
|
||||
* @since 2016年10月5日 下午4:02:04
|
||||
*/
|
||||
public class CommandParse {
|
||||
private static Map<Class, Parse> allparses;
|
||||
static {
|
||||
new IntegerParse();
|
||||
new LongParse();
|
||||
new BooleanParse();
|
||||
new PlayerParse();
|
||||
new StringParse();
|
||||
}
|
||||
public List<Parse> parse = new LinkedList<>();
|
||||
public List<Object> parsed = new LinkedList<>();
|
||||
|
||||
public CommandParse(final Class[] classes, final Annotation[][] annons) {
|
||||
for (final Class classe : classes) {
|
||||
final Class clazz = classe;
|
||||
if (!allparses.containsKey(clazz)) {
|
||||
throw new CommandParseException(String.format("无法解析的参数类型 %s !", clazz.getName()));
|
||||
}
|
||||
parse.add(allparses.get(clazz));
|
||||
}
|
||||
}
|
||||
|
||||
public static CommandParse get(final Method method) {
|
||||
return new CommandParse(method.getParameterTypes(), method.getParameterAnnotations());
|
||||
}
|
||||
|
||||
public static void registerParse(final Class clazz, final Parse parse) {
|
||||
allparses.put(clazz, parse);
|
||||
}
|
||||
|
||||
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++) {
|
||||
try {
|
||||
if (i < parse.size()) {
|
||||
pobjs.add(parse.get(i).parse(args[i]));
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
throw new CommandException(String.format(e.getMessage(), i + 1));
|
||||
}
|
||||
}
|
||||
return pobjs.toArray();
|
||||
}
|
||||
|
||||
public static class BooleanParse implements Parse<Boolean> {
|
||||
public BooleanParse() {
|
||||
allparses.put(Boolean.class, this);
|
||||
allparses.put(boolean.class, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean parse(final String arg) {
|
||||
try {
|
||||
return Boolean.parseBoolean(arg);
|
||||
} catch (final Exception e) {
|
||||
throw new CommandParseException("第 %s 个参数必须为True或者False!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class IntegerParse implements Parse<Integer> {
|
||||
public IntegerParse() {
|
||||
allparses.put(Integer.class, this);
|
||||
allparses.put(int.class, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer parse(final String arg) {
|
||||
try {
|
||||
return Integer.parseInt(arg);
|
||||
} catch (final Exception e) {
|
||||
throw new CommandParseException("第 %s 个参数必须为数字!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class LongParse implements Parse<Long> {
|
||||
public LongParse() {
|
||||
allparses.put(Long.class, this);
|
||||
allparses.put(long.class, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long parse(final String arg) {
|
||||
try {
|
||||
return Long.parseLong(arg);
|
||||
} catch (final Exception e) {
|
||||
throw new CommandParseException("第 %s 个参数必须为数字!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static interface Parse<RT> {
|
||||
public RT parse(String arg) throws CommandParseException;
|
||||
}
|
||||
|
||||
public static class PlayerParse implements Parse<Player> {
|
||||
public PlayerParse() {
|
||||
allparses.put(Player.class, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Player parse(final String arg) {
|
||||
return Bukkit.getPlayerExact(arg);
|
||||
}
|
||||
}
|
||||
|
||||
public static class StringParse implements Parse<String> {
|
||||
public StringParse() {
|
||||
allparses.put(String.class, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String parse(final String arg) {
|
||||
return arg;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package pw.yumc.YumCore.commands.exception;
|
||||
|
||||
/**
|
||||
* 命令参数解析异常
|
||||
*
|
||||
* @author 喵♂呜
|
||||
* @since 2016年10月5日 下午5:15:43
|
||||
*/
|
||||
public class CommandParseException extends CommandException {
|
||||
|
||||
public CommandParseException(final Exception e) {
|
||||
super(e);
|
||||
}
|
||||
|
||||
public CommandParseException(final String string) {
|
||||
super(string);
|
||||
}
|
||||
|
||||
public CommandParseException(final String string, final Exception e) {
|
||||
super(string, e);
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package pw.yumc.YumCore.config;
|
||||
package pw.yumc.YumCore.config.inject;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
@ -12,6 +12,9 @@ import org.bukkit.ChatColor;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
|
||||
import pw.yumc.YumCore.bukkit.Log;
|
||||
import pw.yumc.YumCore.config.ConfigNode;
|
||||
import pw.yumc.YumCore.config.Default;
|
||||
import pw.yumc.YumCore.config.Nullable;
|
||||
|
||||
/**
|
||||
* 抽象注入配置
|
||||
@ -177,7 +180,6 @@ public abstract class AbstractInjectConfig {
|
||||
* @throws IllegalAccessException
|
||||
*/
|
||||
private void hanldeValue(final String path, final Field field, Object value) throws IllegalAccessException, IllegalArgumentException, InstantiationException, InvocationTargetException, NoSuchMethodException, SecurityException, ParseException {
|
||||
final Object origin = field.get(this);
|
||||
final Class<?> type = field.getType();
|
||||
if (!type.equals(value.getClass())) {
|
||||
value = convertType(type, path, value);
|
||||
@ -186,7 +188,7 @@ public abstract class AbstractInjectConfig {
|
||||
value = ChatColor.translateAlternateColorCodes('&', (String) value);
|
||||
}
|
||||
field.set(this, value);
|
||||
Log.d("设置字段 %s 由 %s 为 %s ", field.getName(), origin, value);
|
||||
Log.d("设置字段 %s 为 %s ", field.getName(), value);
|
||||
}
|
||||
|
||||
/**
|
@ -1,7 +1,9 @@
|
||||
package pw.yumc.YumCore.config;
|
||||
package pw.yumc.YumCore.config.inject;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import pw.yumc.YumCore.config.FileConfig;
|
||||
|
||||
/**
|
||||
* 配置自动载入类
|
||||
*
|
@ -1,4 +1,4 @@
|
||||
package pw.yumc.YumCore.config;
|
||||
package pw.yumc.YumCore.config.inject;
|
||||
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
|
Loading…
Reference in New Issue
Block a user