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>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>pw.yumc</groupId>
|
<groupId>pw.yumc</groupId>
|
||||||
<artifactId>YumCore</artifactId>
|
<artifactId>YumCore</artifactId>
|
||||||
<version>1.0</version>
|
<version>1.1</version>
|
||||||
<name>YumCore</name>
|
<name>YumCore</name>
|
||||||
<build>
|
<build>
|
||||||
<finalName>${project.name}</finalName>
|
<finalName>${project.name}</finalName>
|
||||||
|
@ -15,12 +15,14 @@ public class CommandArgument {
|
|||||||
private final Command command;
|
private final Command command;
|
||||||
private final String alias;
|
private final String alias;
|
||||||
private final String[] args;
|
private final String[] args;
|
||||||
|
private final CommandParse parses;
|
||||||
|
|
||||||
public CommandArgument(final CommandSender sender, final Command command, final String alias, final String[] args) {
|
public CommandArgument(final CommandSender sender, final Command command, final String alias, final String[] args) {
|
||||||
this.sender = sender;
|
this.sender = sender;
|
||||||
this.command = command;
|
this.command = command;
|
||||||
this.alias = alias;
|
this.alias = alias;
|
||||||
this.args = args;
|
this.args = args;
|
||||||
|
parses = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,8 +43,9 @@ public class CommandInfo {
|
|||||||
private final Cmd command;
|
private final Cmd command;
|
||||||
private final Help help;
|
private final Help help;
|
||||||
private final int sort;
|
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.method = method;
|
||||||
this.origin = origin;
|
this.origin = origin;
|
||||||
this.name = "".equals(command.value()) ? method.getName().toLowerCase() : command.value();
|
this.name = "".equals(command.value()) ? method.getName().toLowerCase() : command.value();
|
||||||
@ -55,6 +56,7 @@ public class CommandInfo {
|
|||||||
this.help = help;
|
this.help = help;
|
||||||
this.async = async;
|
this.async = async;
|
||||||
this.sort = sort;
|
this.sort = sort;
|
||||||
|
this.parse = parse;
|
||||||
}
|
}
|
||||||
|
|
||||||
private CommandInfo() {
|
private CommandInfo() {
|
||||||
@ -68,6 +70,7 @@ public class CommandInfo {
|
|||||||
this.help = null;
|
this.help = null;
|
||||||
this.async = false;
|
this.async = false;
|
||||||
this.sort = 0;
|
this.sort = 0;
|
||||||
|
this.parse = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -85,7 +88,8 @@ public class CommandInfo {
|
|||||||
final Help help = method.getAnnotation(Help.class);
|
final Help help = method.getAnnotation(Help.class);
|
||||||
final Async async = method.getAnnotation(Async.class);
|
final Async async = method.getAnnotation(Async.class);
|
||||||
final Sort sort = method.getAnnotation(Sort.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;
|
return null;
|
||||||
}
|
}
|
||||||
@ -117,7 +121,7 @@ public class CommandInfo {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
method.invoke(origin, cmdArgs);
|
method.invoke(origin, cmdArgs.getSender(), parse.parse(cmdArgs));
|
||||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
|
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
|
||||||
throw new CommandException(e);
|
throw new CommandException(e);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
package pw.yumc.YumCore.commands;
|
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.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -10,11 +13,15 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.command.PluginCommand;
|
import org.bukkit.command.PluginCommand;
|
||||||
|
import org.bukkit.command.SimpleCommandMap;
|
||||||
import org.bukkit.command.TabExecutor;
|
import org.bukkit.command.TabExecutor;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
import org.bukkit.plugin.PluginManager;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
import org.bukkit.util.StringUtil;
|
import org.bukkit.util.StringUtil;
|
||||||
|
|
||||||
@ -29,8 +36,33 @@ import pw.yumc.YumCore.bukkit.compatible.C;
|
|||||||
* @author 喵♂呜
|
* @author 喵♂呜
|
||||||
*/
|
*/
|
||||||
public class CommandManager implements TabExecutor {
|
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 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,7 +105,14 @@ public class CommandManager implements TabExecutor {
|
|||||||
public CommandManager(final String name) {
|
public CommandManager(final String name) {
|
||||||
cmd = plugin.getCommand(name);
|
cmd = plugin.getCommand(name);
|
||||||
if (cmd == null) {
|
if (cmd == null) {
|
||||||
throw new IllegalStateException("未找到命令 必须在plugin.yml先注册 " + name + " 命令!");
|
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.setExecutor(this);
|
||||||
cmd.setTabCompleter(this);
|
cmd.setTabCompleter(this);
|
||||||
@ -106,9 +145,8 @@ public class CommandManager implements TabExecutor {
|
|||||||
help.send(sender, command, label, args);
|
help.send(sender, command, label, args);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
final CommandArgument cmdArgs = new CommandArgument(sender, command, label, moveStrings(args, 1));
|
|
||||||
final CommandInfo ci = checkCache(subcmd);
|
final CommandInfo ci = checkCache(subcmd);
|
||||||
return ci.execute(cmdArgs);
|
return ci.execute(new CommandArgument(sender, command, label, moveStrings(args, 1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -245,7 +283,7 @@ public class CommandManager implements TabExecutor {
|
|||||||
final CommandInfo ci = CommandInfo.parse(method, clazz);
|
final CommandInfo ci = CommandInfo.parse(method, clazz);
|
||||||
if (ci != null) {
|
if (ci != null) {
|
||||||
final Class<?>[] params = method.getParameterTypes();
|
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) {
|
if (method.getReturnType() == boolean.class) {
|
||||||
defCmd = ci;
|
defCmd = ci;
|
||||||
return true;
|
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.Field;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
@ -12,6 +12,9 @@ import org.bukkit.ChatColor;
|
|||||||
import org.bukkit.configuration.ConfigurationSection;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
|
||||||
import pw.yumc.YumCore.bukkit.Log;
|
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
|
* @throws IllegalAccessException
|
||||||
*/
|
*/
|
||||||
private void hanldeValue(final String path, final Field field, Object value) throws IllegalAccessException, IllegalArgumentException, InstantiationException, InvocationTargetException, NoSuchMethodException, SecurityException, ParseException {
|
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();
|
final Class<?> type = field.getType();
|
||||||
if (!type.equals(value.getClass())) {
|
if (!type.equals(value.getClass())) {
|
||||||
value = convertType(type, path, value);
|
value = convertType(type, path, value);
|
||||||
@ -186,7 +188,7 @@ public abstract class AbstractInjectConfig {
|
|||||||
value = ChatColor.translateAlternateColorCodes('&', (String) value);
|
value = ChatColor.translateAlternateColorCodes('&', (String) value);
|
||||||
}
|
}
|
||||||
field.set(this, 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 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;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user