From 601f3e2ea5e7dec60e3d8ecdc38464e8c0c09270 Mon Sep 17 00:00:00 2001 From: YuTian <2953516620@qq.com> Date: Fri, 24 Jan 2025 19:39:16 +0800 Subject: [PATCH] new-1.1 --- pom.xml | 3 + .../elementoriginlib/ElementOriginLib.java | 6 + .../elementoriginlib/command/Command.java | 8 - .../command/CommandContext.java | 9 +- .../command/CommandEntity.java | 225 +++++++++ .../command/CommandEntry.java | 227 +++++++++ .../elementoriginlib/command/CommandNode.java | 91 ---- .../elementoriginlib/command/IAlias.java | 7 - .../elementoriginlib/command/ICommand.java | 67 --- .../command/ICommandManager.java | 2 +- .../command/SenderRequire.java | 10 + .../command/SenderRequires.java | 29 ++ .../command/SimpleCommandHandler.java | 295 ------------ .../command/SimpleCommandManager.java | 56 +-- .../elementoriginlib/command/Suggests.java | 23 + .../command/argument/Argument.java | 4 - .../command/argument/ArgumentNode.java | 12 + .../command/argument/ArgumentType.java | 87 ++++ .../command/argument/ArgumentTypes.java | 19 - .../command/argument/ArgumentValue.java | 4 - .../command/handler/CommandHandler.java | 444 +++++++----------- .../command/interfaces/Command.java | 16 + .../command/interfaces/CommandArgument.java | 18 + .../command/interfaces/SubCommand.java | 18 + .../command/list/CommandHelp.java | 117 ----- .../command/list/CommandTest.java | 34 ++ .../command/CommandRegisterException.java | 21 + .../elementoriginlib/item/stat/ItemStats.java | 27 +- .../list/{IDStat.java => ItemStatId.java} | 4 +- .../io/yutian/elementoriginlib/lang/Lang.java | 9 +- .../manager/CommandManager.java | 15 + .../elementoriginlib/util/ClassUtil.java | 9 + src/main/resources/lang.yml | 5 +- src/main/resources/plugin.yml | 5 +- 34 files changed, 973 insertions(+), 953 deletions(-) delete mode 100644 src/main/java/com/io/yutian/elementoriginlib/command/Command.java create mode 100644 src/main/java/com/io/yutian/elementoriginlib/command/CommandEntity.java create mode 100644 src/main/java/com/io/yutian/elementoriginlib/command/CommandEntry.java delete mode 100644 src/main/java/com/io/yutian/elementoriginlib/command/CommandNode.java delete mode 100644 src/main/java/com/io/yutian/elementoriginlib/command/IAlias.java delete mode 100644 src/main/java/com/io/yutian/elementoriginlib/command/ICommand.java create mode 100644 src/main/java/com/io/yutian/elementoriginlib/command/SenderRequire.java create mode 100644 src/main/java/com/io/yutian/elementoriginlib/command/SenderRequires.java delete mode 100644 src/main/java/com/io/yutian/elementoriginlib/command/SimpleCommandHandler.java create mode 100644 src/main/java/com/io/yutian/elementoriginlib/command/argument/ArgumentNode.java delete mode 100644 src/main/java/com/io/yutian/elementoriginlib/command/argument/ArgumentTypes.java create mode 100644 src/main/java/com/io/yutian/elementoriginlib/command/interfaces/Command.java create mode 100644 src/main/java/com/io/yutian/elementoriginlib/command/interfaces/CommandArgument.java create mode 100644 src/main/java/com/io/yutian/elementoriginlib/command/interfaces/SubCommand.java delete mode 100644 src/main/java/com/io/yutian/elementoriginlib/command/list/CommandHelp.java create mode 100644 src/main/java/com/io/yutian/elementoriginlib/command/list/CommandTest.java create mode 100644 src/main/java/com/io/yutian/elementoriginlib/exception/command/CommandRegisterException.java rename src/main/java/com/io/yutian/elementoriginlib/item/stat/list/{IDStat.java => ItemStatId.java} (69%) create mode 100644 src/main/java/com/io/yutian/elementoriginlib/manager/CommandManager.java diff --git a/pom.xml b/pom.xml index d827781..ef4224f 100644 --- a/pom.xml +++ b/pom.xml @@ -26,6 +26,9 @@ ${java.version} ${java.version} + + -parameters + diff --git a/src/main/java/com/io/yutian/elementoriginlib/ElementOriginLib.java b/src/main/java/com/io/yutian/elementoriginlib/ElementOriginLib.java index e260bef..889bcc7 100644 --- a/src/main/java/com/io/yutian/elementoriginlib/ElementOriginLib.java +++ b/src/main/java/com/io/yutian/elementoriginlib/ElementOriginLib.java @@ -4,6 +4,7 @@ import com.io.yutian.elementoriginlib.lang.Lang; import com.io.yutian.elementoriginlib.listener.GuiHandlerListener; import com.io.yutian.elementoriginlib.listener.PlayerChatInputListener; import com.io.yutian.elementoriginlib.logger.Logger; +import com.io.yutian.elementoriginlib.manager.CommandManager; import com.io.yutian.elementoriginlib.redis.RedisIO; import net.byteflux.libby.*; import net.byteflux.libby.logging.LogLevel; @@ -19,6 +20,8 @@ public final class ElementOriginLib extends JavaPlugin { private static RedisIO redisIO; + private static CommandManager commandManager; + @Override public void onEnable() { instance = this; @@ -28,6 +31,9 @@ public final class ElementOriginLib extends JavaPlugin { new GuiHandlerListener(this); new PlayerChatInputListener(this); + commandManager = new CommandManager(this); + commandManager.registerPluginCommand("elementoriginlib"); + Lang.registerLangFile(this); Lang.reload(); diff --git a/src/main/java/com/io/yutian/elementoriginlib/command/Command.java b/src/main/java/com/io/yutian/elementoriginlib/command/Command.java deleted file mode 100644 index 6c6972e..0000000 --- a/src/main/java/com/io/yutian/elementoriginlib/command/Command.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.io.yutian.elementoriginlib.command; - -@FunctionalInterface -public interface Command { - - void run(S context); - -} diff --git a/src/main/java/com/io/yutian/elementoriginlib/command/CommandContext.java b/src/main/java/com/io/yutian/elementoriginlib/command/CommandContext.java index f2d2f05..1d93a61 100644 --- a/src/main/java/com/io/yutian/elementoriginlib/command/CommandContext.java +++ b/src/main/java/com/io/yutian/elementoriginlib/command/CommandContext.java @@ -7,18 +7,25 @@ import java.util.Map; public class CommandContext { + private Object commandInstance; + private String command; private String label; private CommandSender sender; private Map argumentsValues; - public CommandContext(String command, String label, CommandSender sender, Map argumentsValues) { + public CommandContext(Object commandInstance, String command, String label, CommandSender sender, Map argumentsValues) { + this.commandInstance = commandInstance; this.command = command; this.label = label; this.sender = sender; this.argumentsValues = argumentsValues; } + public Object getCommandInstance() { + return commandInstance; + } + public String getCommand() { return command; } diff --git a/src/main/java/com/io/yutian/elementoriginlib/command/CommandEntity.java b/src/main/java/com/io/yutian/elementoriginlib/command/CommandEntity.java new file mode 100644 index 0000000..93add21 --- /dev/null +++ b/src/main/java/com/io/yutian/elementoriginlib/command/CommandEntity.java @@ -0,0 +1,225 @@ +package com.io.yutian.elementoriginlib.command; + +import com.io.yutian.elementoriginlib.command.argument.Argument; +import com.io.yutian.elementoriginlib.command.argument.ArgumentType; +import com.io.yutian.elementoriginlib.command.interfaces.Command; +import com.io.yutian.elementoriginlib.command.interfaces.CommandArgument; +import com.io.yutian.elementoriginlib.command.interfaces.SubCommand; +import com.io.yutian.elementoriginlib.exception.command.CommandRegisterException; +import com.io.yutian.elementoriginlib.logger.Logger; + +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.util.*; + +public class CommandEntity { + + private static final Logger LOGGER = Logger.getLogger(CommandEntity.class); + + private Object instance; + + private String command; + private String permission; + + private List childrens = new ArrayList<>(); + + public CommandEntity(Object instance, String command, String permission, List childrens) { + this.instance = instance; + this.command = command; + this.permission = permission; + this.childrens = childrens; + } + + public Object getInstance() { + return instance; + } + + public void addChild(CommandEntry child) { + childrens.add(child); + } + + public String getCommand() { + return command; + } + + public String getPermission() { + return permission; + } + + public List getChildrens() { + return childrens; + } + + public static CommandEntity parseFromClass(Class clazz) { + if (clazz == null) { + LOGGER.warn("Class is null"); + return null; + } + if (!clazz.isAnnotationPresent(Command.class)) { + LOGGER.warn("Class " + clazz.getName() + " is not annotated with @Command"); + return null; + } + + Object instance; + try { + instance = clazz.getConstructor(null).newInstance(); + } catch (Exception e) { + LOGGER.warn("无法实例化类 " + clazz); + return null; + } + + Command commandAnnotation = (Command) clazz.getAnnotation(Command.class); + String command = commandAnnotation.value(); + String permission = commandAnnotation.permission(); + + List allEntries = new ArrayList<>(); + Map pathToEntryMap = new HashMap<>(); + List rootEntries = new ArrayList<>(); + + try { + for (Method method : clazz.getDeclaredMethods()) { + if (!method.isAnnotationPresent(SubCommand.class)) { + continue; + } + + CommandEntry commandEntry = parseFromMethod(method); + if (commandEntry != null) { + allEntries.add(commandEntry); + + String path = commandEntry.getFullName(); + String parentPath = getParentPath(path); + + if (pathToEntryMap.containsKey(path)) { + LOGGER.warn("命令路径冲突: 子命令 '" + path + "' 已经定义, 不能再定义父命令 '" + parentPath + "'"); + throw new CommandRegisterException("命令路径冲突: 子命令 '" + path + "' 已经定义, 不能再定义父命令 '" + parentPath + "'"); + } + + if (!parentPath.isEmpty() && pathToEntryMap.containsKey(parentPath)) { + LOGGER.warn("命令路径冲突: 子命令 '" + path + "' 已经定义, 不能再定义父命令 '" + parentPath + "'"); + throw new CommandRegisterException("命令路径冲突: 子命令 '" + path + "' 已经定义, 不能再定义父命令 '" + parentPath + "'"); + } + + pathToEntryMap.put(commandEntry.getFullName(), commandEntry); + } + } + + for (CommandEntry entry : allEntries) { + String fullPath = entry.getFullName(); + int lastDotIndex = fullPath.lastIndexOf('.'); + + if (lastDotIndex == -1) { + rootEntries.add(entry); + } else { + String parentPath = fullPath.substring(0, lastDotIndex); + CommandEntry parentEntry = pathToEntryMap.get(parentPath); + + if (parentEntry == null) { + parentEntry = createParentNodes(pathToEntryMap, parentPath); + if (parentPath.indexOf('.') == -1) { + rootEntries.add(parentEntry); + } + } + parentEntry.getChildrens().add(entry); + } + } + } catch (Exception e) { + e.printStackTrace(); + return null; + } + + return new CommandEntity(instance, command, permission, rootEntries); + } + + private static String getParentPath(String path) { + int lastDotIndex = path.lastIndexOf('.'); + if (lastDotIndex == -1) { + return ""; + } + return path.substring(0, lastDotIndex); + } + + private static CommandEntry createParentNodes(Map pathToEntryMap, String currentPath) { + if (pathToEntryMap.containsKey(currentPath)) { + return pathToEntryMap.get(currentPath); + } + + int lastDotIndex = currentPath.lastIndexOf('.'); + CommandEntry parentEntry; + + if (lastDotIndex == -1) { + parentEntry = new CommandEntry(currentPath, currentPath); + } else { + String grandParentPath = currentPath.substring(0, lastDotIndex); + CommandEntry grandParentEntry = createParentNodes(pathToEntryMap, grandParentPath); + parentEntry = new CommandEntry(currentPath, currentPath.substring(lastDotIndex + 1)); + grandParentEntry.getChildrens().add(parentEntry); + } + pathToEntryMap.put(currentPath, parentEntry); + return parentEntry; + } + + + private static CommandEntry parseFromMethod(Method method) { + SubCommand subCommand = method.getAnnotation(SubCommand.class); + String path = subCommand.value(); + String permission = subCommand.permission(); + String[] senderRequireArray = subCommand.senderRequire(); + List senderRequireList = new ArrayList<>(); + for (String senderRequire : senderRequireArray) { + SenderRequire senderRequire1 = SenderRequires.get(senderRequire); + if (senderRequire1 == null) { + LOGGER.warn("Sender require " + senderRequire + " is null"); + continue; + } + senderRequireList.add(SenderRequires.get(senderRequire)); + } + + String subName = path; + + if (path.contains(".")) { + int lastDotIndex = path.lastIndexOf('.'); + if (lastDotIndex == -1 || lastDotIndex > path.length() - 1) { + LOGGER.warn("Invalid command name '" + path + "'"); + return null; + } + subName = path.substring(path.lastIndexOf('.') + 1); + } + List arguments = new ArrayList<>(); + for (Parameter parameter : method.getParameters()) { + if (!parameter.isAnnotationPresent(CommandArgument.class)) { + continue; + } + CommandArgument commandArgument = parameter.getAnnotation(CommandArgument.class); + String name = commandArgument.name(); + String argumentName = name.isEmpty() ? parameter.getName() : name; + boolean required = commandArgument.required(); + String suggestionType = commandArgument.suggestionType(); + Class type = parameter.getType(); + ArgumentType argumentType = ArgumentType.get(parameter.getType()); + if (argumentType == null) { + LOGGER.warn("Argument type " + parameter.getType().getName() + " is null"); + continue; + } + Argument argument = new Argument(argumentName, argumentType); + if (!suggestionType.isEmpty()) { + Suggest suggest = Suggests.getSuggest(suggestionType); + if (suggest == null) { + LOGGER.warn("Suggest type " + suggestionType + " is null"); + } else { + argument.suggest(suggest); + } + } + arguments.add(argument); + } + return new CommandEntry(path, subName, permission, senderRequireList, arguments, method); + } + + @Override + public String toString() { + return "CommandEntity{" + + "command='" + command + '\'' + + ", permission='" + permission + '\'' + + ", childrens=" + childrens + + '}'; + } +} diff --git a/src/main/java/com/io/yutian/elementoriginlib/command/CommandEntry.java b/src/main/java/com/io/yutian/elementoriginlib/command/CommandEntry.java new file mode 100644 index 0000000..b1fef56 --- /dev/null +++ b/src/main/java/com/io/yutian/elementoriginlib/command/CommandEntry.java @@ -0,0 +1,227 @@ +package com.io.yutian.elementoriginlib.command; + +import com.io.yutian.elementoriginlib.command.argument.Argument; +import com.io.yutian.elementoriginlib.command.argument.ArgumentValue; +import com.io.yutian.elementoriginlib.command.interfaces.CommandArgument; +import com.io.yutian.elementoriginlib.logger.Logger; +import org.bukkit.command.CommandSender; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.util.ArrayList; +import java.util.List; + +public class CommandEntry { + + private static final Logger LOGGER = Logger.getLogger(CommandEntry.class); + + private String fullName; + private String name; + private String permission; + private List senderRequires = new ArrayList<>(); + + private List arguments = new ArrayList<>(); + + private List childrens = new ArrayList<>(); + + private long depth = 0; + + private final Method method; + private final MethodHandle methodHandle; + + private Class[] parameterTypes; + + public CommandEntry(String fullName, String name, String permission, List senderRequires, List arguments, Method method) { + this.fullName = fullName; + this.name = name; + this.permission = permission; + this.senderRequires = senderRequires; + this.arguments = arguments; + this.method = method; + try { + this.methodHandle = MethodHandles.lookup().unreflect(this.method); + this.parameterTypes = methodHandle.type().parameterArray(); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + this.depth = fullName.chars().filter(ch -> ch == '.').count(); + } + + public CommandEntry(String fullName, String name) { + this.fullName = fullName; + this.name = name; + this.method = null; + this.methodHandle = null; + this.parameterTypes = new Class[0]; + } + + public void invoke(CommandContext commandContext) { + if (method == null || methodHandle == null) { + return; + } + + Object targetInstance = commandContext.getCommandInstance(); + if (targetInstance == null) { + LOGGER.warn("该命令的实例为空,无法执行命令: " + fullName); + return; + } + + try { + Class[] parameterTypes = method.getParameterTypes(); + Object[] parameters = new Object[parameterTypes.length]; + + int argumentIndex = 0; + + for (int i = 0; i < parameterTypes.length; i++) { + Parameter parameter = method.getParameters()[i]; + if (parameter.isAnnotationPresent(CommandArgument.class)) { + String paramName = arguments.get(argumentIndex).getName(); + ArgumentValue argumentValue = commandContext.getArgumentsValue(paramName); + if (argumentValue != null) { + parameters[i] = argumentValue.getValue(); + } else { + parameters[i] = null; + } + argumentIndex++; + } else if (parameter.getType() == CommandContext.class) { + parameters[i] = commandContext; + } else { + parameters[i] = getDefaultForType(parameterTypes[i]); + } + } + + Object[] parms = new Object[parameters.length+1]; + parms[0] = targetInstance; + System.arraycopy(parameters, 0, parms, 1, parameters.length); + methodHandle.invokeWithArguments(parms); + } catch (Exception e) { + e.printStackTrace(); + LOGGER.error("执行命令时出现异常: " + fullName); + } catch (Throwable e) { + e.printStackTrace(); + LOGGER.error("执行命令时出现异常: " + fullName); + } + } + + public boolean canInvoke(CommandSender sender) { + if (senderRequires != null && senderRequires.size() > 0) { + for (SenderRequire senderRequire : senderRequires) { + if (senderRequire.test(sender)) { + return true; + } + } + return false; + } + return true; + } + + public boolean hasPermission(CommandSender sender) { + if (permission != null && !permission.isEmpty()) { + return sender.isOp() || sender.hasPermission(permission); + } + return true; + } + + private Object[] convertToPrimitive(Object[] parameters) { + Object[] convertedParams = new Object[parameters.length]; + for (int i = 0; i < parameters.length; i++) { + Object param = parameters[i]; + Class parameterType = parameterTypes[i+1]; + if (parameterType.isPrimitive()) { + if (param instanceof Integer) { + convertedParams[i] = ((Integer) param).intValue(); + } else if (param instanceof Double) { + convertedParams[i] = ((Double) param).doubleValue(); + } else if (param instanceof Boolean) { + convertedParams[i] = ((Boolean) param).booleanValue(); + } else if (param instanceof Character) { + convertedParams[i] = ((Character) param).charValue(); + } else if (param instanceof Byte) { + convertedParams[i] = ((Byte) param).byteValue(); + } else if (param instanceof Short) { + convertedParams[i] = ((Short) param).shortValue(); + } else if (param instanceof Long) { + convertedParams[i] = ((Long) param).longValue(); + } else if (param instanceof Float) { + convertedParams[i] = ((Float) param).floatValue(); + } else { + convertedParams[i] = param; + } + } + } + return convertedParams; + } + + private Object getDefaultForType(Class parameterType) { + if (parameterType.isPrimitive()) { + if (parameterType == int.class) { + return 0; + } else if (parameterType == double.class) { + return 0.0; + } else if (parameterType == boolean.class) { + return false; + } else if (parameterType == char.class) { + return '\u0000'; + } else if (parameterType == byte.class) { + return (byte) 0; + } else if (parameterType == short.class) { + return (short) 0; + } else if (parameterType == long.class) { + return 0L; + } else if (parameterType == float.class) { + return 0.0f; + } + } + return null; + } + + public boolean isEmptyEntry() { + return method == null; + } + + public void addChild(CommandEntry child) { + childrens.add(child); + } + + public String getFullName() { + return fullName; + } + + public String getName() { + return name; + } + + public String getPermission() { + return permission; + } + + public List getSenderRequires() { + return senderRequires; + } + + public List getArguments() { + return arguments; + } + + public List getChildrens() { + return childrens; + } + + public long getDepth() { + return depth; + } + + @Override + public String toString() { + return "CommandEntry{" + + "fullName='" + fullName + '\'' + + ", name='" + name + '\'' + + ", permission='" + permission + '\'' + + ", arguments=" + arguments + + ", childrens=" + childrens + + '}'; + } + +} diff --git a/src/main/java/com/io/yutian/elementoriginlib/command/CommandNode.java b/src/main/java/com/io/yutian/elementoriginlib/command/CommandNode.java deleted file mode 100644 index 87c1d38..0000000 --- a/src/main/java/com/io/yutian/elementoriginlib/command/CommandNode.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.io.yutian.elementoriginlib.command; - -import com.io.yutian.elementoriginlib.command.argument.Argument; -import org.bukkit.command.CommandSender; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.function.Predicate; - -public class CommandNode { - - private String name; - - private List childrens = new ArrayList<>(); - private List arguments = new ArrayList<>(); - - private List alias = new ArrayList<>(); - - private Predicate commandSenderPredicate = (commandSender -> true); - private Command command; - - public CommandNode(String name) { - this.name = name; - } - - public CommandNode(String name, String[] alias) { - this.name = name; - this.alias = Arrays.asList(alias); - } - - public CommandNode(String name, List alias) { - this.name = name; - this.alias = alias; - } - - public CommandNode permission(Predicate commandSenderPredicate) { - this.commandSenderPredicate = commandSenderPredicate; - return this; - } - - public List getAlias() { - return alias; - } - - public CommandNode setAlias(List alias) { - this.alias = alias; - return this; - } - - public CommandNode addAilas(String alias) { - this.alias.add(alias); - return this; - } - - public CommandNode addArgument(Argument argument) { - arguments.add(argument); - return this; - } - - public CommandNode addChildren(CommandNode commandNode) { - this.childrens.add(commandNode); - return this; - } - - public List getChildrens() { - return childrens; - } - - public List getArguments() { - return arguments; - } - - public CommandNode executes(Command command) { - this.command = command; - return this; - } - - public Command getCommand() { - return command; - } - - public String getName() { - return name; - } - - public static CommandNode node(String name) { - return new CommandNode(name); - } - -} diff --git a/src/main/java/com/io/yutian/elementoriginlib/command/IAlias.java b/src/main/java/com/io/yutian/elementoriginlib/command/IAlias.java deleted file mode 100644 index 4f8fe79..0000000 --- a/src/main/java/com/io/yutian/elementoriginlib/command/IAlias.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.io.yutian.elementoriginlib.command; - -public interface IAlias { - - String[] getAlias(); - -} diff --git a/src/main/java/com/io/yutian/elementoriginlib/command/ICommand.java b/src/main/java/com/io/yutian/elementoriginlib/command/ICommand.java deleted file mode 100644 index e5e914c..0000000 --- a/src/main/java/com/io/yutian/elementoriginlib/command/ICommand.java +++ /dev/null @@ -1,67 +0,0 @@ -package com.io.yutian.elementoriginlib.command; - -import com.io.yutian.elementoriginlib.command.argument.Argument; -import org.bukkit.command.CommandSender; - -import java.util.ArrayList; -import java.util.List; - -public abstract class ICommand { - - private String name; - private String description; - - private List commandNodes = new ArrayList<>(); - private List arguments = new ArrayList<>(); - - public ICommand(String name) { - this(name, null); - } - - public ICommand(String name, String description) { - this.name = name; - this.description = description; - } - - public void executes(CommandContext commandContext) { - } - - public boolean emptyExecutes(CommandSender commandSender) { - return false; - } - - public boolean hasPermission(CommandSender sender) { - return sender.isOp() || sender.hasPermission(getPermissionPrefix()+"."+name); - } - - public String getPermissionPrefix() { - return "command."+name; - } - - public ICommand addArgument(Argument argument) { - arguments.add(argument); - return this; - } - - public ICommand addCommandNode(CommandNode commandNode) { - this.commandNodes.add(commandNode); - return this; - } - - public List getCommandNodes() { - return commandNodes; - } - - public List getArguments() { - return arguments; - } - - public String getName() { - return name; - } - - public String getDescription() { - return description; - } - -} diff --git a/src/main/java/com/io/yutian/elementoriginlib/command/ICommandManager.java b/src/main/java/com/io/yutian/elementoriginlib/command/ICommandManager.java index 9b7c580..86bf773 100644 --- a/src/main/java/com/io/yutian/elementoriginlib/command/ICommandManager.java +++ b/src/main/java/com/io/yutian/elementoriginlib/command/ICommandManager.java @@ -6,6 +6,6 @@ public interface ICommandManager { String getName(); - List getCommands(); + List getCommands(); } diff --git a/src/main/java/com/io/yutian/elementoriginlib/command/SenderRequire.java b/src/main/java/com/io/yutian/elementoriginlib/command/SenderRequire.java new file mode 100644 index 0000000..9e1fcf5 --- /dev/null +++ b/src/main/java/com/io/yutian/elementoriginlib/command/SenderRequire.java @@ -0,0 +1,10 @@ +package com.io.yutian.elementoriginlib.command; + +import org.bukkit.command.CommandSender; + +@FunctionalInterface +public interface SenderRequire { + + boolean test(CommandSender sender); + +} diff --git a/src/main/java/com/io/yutian/elementoriginlib/command/SenderRequires.java b/src/main/java/com/io/yutian/elementoriginlib/command/SenderRequires.java new file mode 100644 index 0000000..83d7316 --- /dev/null +++ b/src/main/java/com/io/yutian/elementoriginlib/command/SenderRequires.java @@ -0,0 +1,29 @@ +package com.io.yutian.elementoriginlib.command; + +import java.util.HashMap; +import java.util.Map; + +public class SenderRequires { + + public static final SenderRequire CONSOLE = (sender) -> sender instanceof org.bukkit.command.ConsoleCommandSender; + + public static final SenderRequire PLAYER = (sender) -> sender instanceof org.bukkit.entity.Player; + + private static Map requireMap = new HashMap<>(); + + public static void register(String name, SenderRequire require) { + requireMap.put(name, require); + } + + public static SenderRequire get(String name) { + return requireMap.get(name); + } + + static { + + register("console", CONSOLE); + register("player", PLAYER); + + } + +} diff --git a/src/main/java/com/io/yutian/elementoriginlib/command/SimpleCommandHandler.java b/src/main/java/com/io/yutian/elementoriginlib/command/SimpleCommandHandler.java deleted file mode 100644 index 3a90352..0000000 --- a/src/main/java/com/io/yutian/elementoriginlib/command/SimpleCommandHandler.java +++ /dev/null @@ -1,295 +0,0 @@ -package com.io.yutian.elementoriginlib.command; - -import com.io.yutian.elementoriginlib.command.argument.Argument; -import com.io.yutian.elementoriginlib.command.argument.ArgumentValue; -import com.io.yutian.elementoriginlib.command.handler.CommandHandler; -import com.io.yutian.elementoriginlib.lang.Lang; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; - -import java.util.*; -import java.util.stream.Stream; - -public class SimpleCommandHandler extends Command { - - private ICommand iCommand; - - public SimpleCommandHandler(String name, ICommand iCommand) { - super(name); - this.iCommand = iCommand; - } - - @Override - public boolean execute(CommandSender sender, String commandLabel, String[] args) { - executes(sender, commandLabel, args); - return true; - } - - public void executes(CommandSender sender, String commandLabel, String[] args) { - if (!iCommand.hasPermission(sender)) { - sender.sendMessage(Lang.get("command-no-permission")); - return; - } - List commandNodes = iCommand.getCommandNodes(); - StringBuilder stringBuilder = new StringBuilder(); - for (int i = 0; i < args.length; i++) { - stringBuilder.append(args[i]); - if (i < args.length - 1) { - stringBuilder.append(" "); - } - } - String commandString = stringBuilder.toString(); - if (commandNodes.size() == 0) { - Map map = new HashMap<>(); - if (iCommand.getArguments().size() > 0) { - int argSize = args.length; - List arguments = iCommand.getArguments(); - int k = 0; - if (arguments.get(arguments.size()-1).isOptional()) { - k++; - } - if (argSize < arguments.size()-k) { - sender.sendMessage(Lang.get("command-short-arg")); - return; - } - for (int l = 0; l < arguments.size(); l++) { - Argument a = arguments.get(l); - int index = l; - if (index >= args.length) { - break; - } - String arg = args[index]; - if (!a.getArgumentsType().test(arg)) { - sender.sendMessage(Lang.get("command-unknown-arg", index+1, arg)); - return; - } - } - map = parseArgumentValue(sender, arguments, args, -1); - } - iCommand.executes(new CommandContext(commandString, commandLabel, sender, map)); - return; - } - - int nodeSize = args.length; - - if (commandNodes.size() > 0 && nodeSize == 0) { - if (!iCommand.emptyExecutes(sender)) { - sender.sendMessage(Lang.get("command-short-arg")); - } - return; - } - - String mainNode = args[0]; - - Stream nodeStream = commandNodes.stream().filter((n) -> { - return n.getName().equalsIgnoreCase(mainNode) || n.getAlias().contains(mainNode); - }); - Optional nodeOptional = nodeStream.findFirst(); - if (!nodeOptional.isPresent()) { - sender.sendMessage(Lang.get("command-unknown-arg", 1, mainNode)); - return; - } - CommandNode node = nodeOptional.get(); - - if (node.getChildrens().size() > 0) { - checkClidren(commandString, commandLabel, sender, 0, args, node); - } else { - if (node.getCommand() != null) { - Map map = new HashMap<>(); - if (node.getArguments().size() > 0) { - int argSize = args.length - 1; - List arguments = node.getArguments(); - int k = 0; - if (arguments.get(arguments.size()-1).isOptional()) { - k++; - } - if (argSize < arguments.size()-k) { - sender.sendMessage(Lang.get("command-short-arg")); - return; - } - for (int l = 0; l < arguments.size(); l++) { - Argument a = arguments.get(l); - int index = l + 1; - if (index >= args.length) { - break; - } - String arg = args[index]; - if (!a.getArgumentsType().test(arg)) { - sender.sendMessage(Lang.get("command-error-arg", index+1, arg)); - return; - } - } - map = parseArgumentValue(sender, node.getArguments(), args, 0); - } - node.getCommand().run(new CommandContext(commandString, commandLabel, sender, map)); - } else { - sender.sendMessage(Lang.get("command-unknown-arg", 2, mainNode)); - return; - } - } - - } - - private void checkClidren(String commandString, String commandLabel, CommandSender sender, int i, String[] args, CommandNode node) { - i++; - if (i >= args.length) { - if (node.getCommand() == null) { - sender.sendMessage(Lang.get("command-short-arg")); - } else { - node.getCommand().run(new CommandContext(commandString, commandLabel, sender, new HashMap<>())); - } - return; - } - String s = args[i]; - Stream nodeStream = node.getChildrens().stream().filter((n) -> { - return n.getName().equalsIgnoreCase(s) || n.getAlias().contains(s); - }); - Optional nodeOptional = nodeStream.findFirst(); - if (!nodeOptional.isPresent()) { - sender.sendMessage(Lang.get("command-unknown-arg", i+1, s)); - return; - } - CommandNode node1 = nodeOptional.get(); - - if (node1.getChildrens().size() > 0) { - checkClidren(commandString, commandLabel, sender, i, args, node1); - } else { - if (node1.getCommand() != null) { - Map map = new HashMap<>(); - if (node1.getArguments().size() > 0) { - int argSize = args.length - i - 1; - List arguments = node1.getArguments(); - int k = 0; - if (arguments.get(arguments.size()-1).isOptional()) { - k++; - } - if (argSize < arguments.size()-k) { - sender.sendMessage(Lang.get("command-short-arg")); - return; - } - for (int l = 0; l < arguments.size(); l++) { - Argument a = arguments.get(l); - int index = i + l + 1; - if (index >= args.length) { - break; - } - String arg = args[index]; - if (!a.getArgumentsType().test(arg)) { - sender.sendMessage(Lang.get("command-unknown-arg", index+1, arg)); - return; - } - } - map = parseArgumentValue(sender, node1.getArguments(), args, i); - } - node1.getCommand().run(new CommandContext(commandString, commandLabel, sender, map)); - } else { - sender.sendMessage(Lang.get("command-unknown-arg", i+1, s)); - return; - } - } - - } - - private Map parseArgumentValue(CommandSender commandSender, List argumentList, String[] args, int i) { - Map map = new HashMap<>(); - List arguments = argumentList; - for (int l = 0; l < arguments.size(); l++) { - Argument a = arguments.get(l); - if (i+1+l >= args.length) { - if (a.isOptional()) { - map.put(a.getName(), new ArgumentValue(a.getDefaultValue())); - } - return map; - } - String arg = args[i+1+l]; - if (!a.getArgumentsType().test(arg)) { - continue; - } - ArgumentValue argumentValue = new ArgumentValue(a.getArgumentsType().get(arg)); - map.put(a.getName(), argumentValue); - } - return map; - } - - @Override - public List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException { - return onTabComplete(sender, alias, args); - } - - public List onTabComplete(CommandSender sender, String alias, String[] args) { - List list = new ArrayList<>(); - int index = args.length; - String arg = args[index-1]; - if (!iCommand.hasPermission(sender)) { - return list; - } - if (iCommand instanceof ITabCompleter) { - ITabCompleter tabCompleter = (ITabCompleter) iCommand; - return tabCompleter.onTabComplete(sender, args, index-1, arg); - } else { - Map> map = new HashMap<>(); - if (iCommand.getCommandNodes().size() > 0) { - List list1 = new ArrayList<>(); - for (CommandNode node : iCommand.getCommandNodes()) { - list1.add(node.getName()); - list1.addAll(node.getAlias()); - if (index >= 2) { - if (!node.getName().equalsIgnoreCase(args[0])) { - continue; - } - } - if (node.getChildrens().size() > 0) { - getTabComplete(node, 1, map); - } else if (node.getArguments().size() > 0) { - List arguments = node.getArguments(); - for (int l = 0; l < arguments.size(); l++) { - Argument argument = arguments.get(l); - if (argument.getSuggest() != null) { - map.put(2+l, argument.getSuggest().getSuggest()); - continue; - } - map.put(2+l, Arrays.asList("<"+argument.getName()+">")); - } - } - } - map.put(1, list1); - return CommandHandler.preseSuggest(map.getOrDefault(index, list), arg); - } else if (iCommand.getArguments().size() > 0) { - List arguments = iCommand.getArguments(); - for (int l = 0; l < arguments.size(); l++) { - Argument argument = arguments.get(l); - if (argument.getSuggest() != null) { - map.put(0+l+1, argument.getSuggest().getSuggest()); - continue; - } - map.put(0+l+1, Arrays.asList("<"+argument.getName()+">")); - } - return CommandHandler.preseSuggest(map.getOrDefault(index, list), arg); - } - } - return CommandHandler.preseSuggest(list, arg); - } - - private void getTabComplete(CommandNode node, int i, Map> map) { - i++; - List list = map.getOrDefault(i, new ArrayList<>()); - for (CommandNode c : node.getChildrens()) { - list.add(c.getName()); - if (c.getChildrens().size() > 0) { - getTabComplete(c, i, map); - } else if (c.getArguments().size() > 0) { - List arguments = c.getArguments(); - for (int l = 0; l < arguments.size(); l++) { - Argument argument = arguments.get(l); - if (argument.getSuggest() != null) { - map.put(i+l+1, argument.getSuggest().getSuggest()); - continue; - } - map.put(i+l+1, Arrays.asList("<"+argument.getName()+">")); - } - } - } - map.put(i, list); - } - -} \ No newline at end of file diff --git a/src/main/java/com/io/yutian/elementoriginlib/command/SimpleCommandManager.java b/src/main/java/com/io/yutian/elementoriginlib/command/SimpleCommandManager.java index 6113962..4c2d83e 100644 --- a/src/main/java/com/io/yutian/elementoriginlib/command/SimpleCommandManager.java +++ b/src/main/java/com/io/yutian/elementoriginlib/command/SimpleCommandManager.java @@ -1,7 +1,6 @@ package com.io.yutian.elementoriginlib.command; import com.io.yutian.elementoriginlib.command.handler.CommandHandler; -import com.io.yutian.elementoriginlib.command.list.CommandHelp; import org.bukkit.Bukkit; import org.bukkit.command.Command; import org.bukkit.command.CommandMap; @@ -23,65 +22,46 @@ public class SimpleCommandManager implements ICommandManager { private final String name; @NotNull - private List commands; + private List> commandClasses = new ArrayList<>(); + @NotNull + private List commands = new ArrayList<>(); public SimpleCommandManager(Plugin plugin, String name) { this(plugin, name, new ArrayList<>()); } - public SimpleCommandManager(Plugin plugin, String name, @NotNull List commands) { + public SimpleCommandManager(Plugin plugin, String name, @NotNull List> commandClasses) { this.plugin = plugin; this.name = name; - this.commands = commands; - register(new CommandHelp(this)); + this.commandClasses = commandClasses; } - public void register(@NotNull ICommand command) { + public void register(@NotNull Class commandClass) { + if (commandClass == null) { + return; + } + CommandEntity command = CommandEntity.parseFromClass(commandClass); if (command == null) { return; } + commandClasses.add(commandClass); commands.add(command); - if (command instanceof IAlias alias) { - String[] array = alias.getAlias(); - for (String s : array) { - registerPluginBukkitCommand(plugin, s, command); - } - } } public void unregisterAll() { - for (ICommand command : commands) { - if (command instanceof IAlias) { - unregister(command); - } - } + commands.clear(); } - public static void unregister(ICommand command) { - if (!(command instanceof IAlias)) { + public void unregister(Class commandClass) { + if (commandClass == null) { return; } - try { - Map map = (Map) commandMap.getClass().getMethod("getKnownCommands").invoke(commandMap); - for (String name : ((IAlias) command).getAlias()) { - map.remove(name); - Command bukkitCommand = bukkitCommandMap.get(name); - bukkitCommand.unregister(commandMap); - } - } catch (Exception e) { - e.printStackTrace(); - } + commands.remove(commandClass); } - public void registerPluginCommand(@NotNull Plugin plugin, String commandName) { - Bukkit.getPluginCommand(commandName).setExecutor(new CommandHandler(plugin, this)); - } - - protected static void registerPluginBukkitCommand(Plugin plugin, String name, ICommand command) { - SimpleCommandHandler simpleCommandHandler = new SimpleCommandHandler(name, command); - bukkitCommandMap.put(name, simpleCommandHandler); - commandMap.register(plugin.getName(), simpleCommandHandler); + public void registerPluginCommand(@NotNull String commandName) { + Bukkit.getPluginCommand(commandName).setExecutor(new CommandHandler(this)); } public Plugin getPlugin() { @@ -96,7 +76,7 @@ public class SimpleCommandManager implements ICommandManager { @NotNull @Override - public List getCommands() { + public List getCommands() { return commands; } diff --git a/src/main/java/com/io/yutian/elementoriginlib/command/Suggests.java b/src/main/java/com/io/yutian/elementoriginlib/command/Suggests.java index eb23c09..743dc35 100644 --- a/src/main/java/com/io/yutian/elementoriginlib/command/Suggests.java +++ b/src/main/java/com/io/yutian/elementoriginlib/command/Suggests.java @@ -4,8 +4,10 @@ import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.entity.Player; +import java.util.HashMap; import java.util.LinkedList; import java.util.List; +import java.util.Map; public class Suggests { @@ -25,4 +27,25 @@ public class Suggests { return list; }; + private static final Map suggests = new HashMap<>(); + + public static void registerSuggest(String name, Suggest suggest) { + suggests.put(name, suggest); + } + + public static Suggest getSuggest(String name) { + return suggests.get(name); + } + + public static void unregisterSuggest(String name) { + suggests.remove(name); + } + + static { + + registerSuggest("world_list", WORLD_LIST); + registerSuggest("player_list", PLAYER_LIST); + + } + } diff --git a/src/main/java/com/io/yutian/elementoriginlib/command/argument/Argument.java b/src/main/java/com/io/yutian/elementoriginlib/command/argument/Argument.java index 94f0f5f..4c3ba1e 100644 --- a/src/main/java/com/io/yutian/elementoriginlib/command/argument/Argument.java +++ b/src/main/java/com/io/yutian/elementoriginlib/command/argument/Argument.java @@ -49,8 +49,4 @@ public class Argument { return suggest; } - public static Argument argument(String name, ArgumentType type) { - return new Argument(name, type); - } - } diff --git a/src/main/java/com/io/yutian/elementoriginlib/command/argument/ArgumentNode.java b/src/main/java/com/io/yutian/elementoriginlib/command/argument/ArgumentNode.java new file mode 100644 index 0000000..3446a47 --- /dev/null +++ b/src/main/java/com/io/yutian/elementoriginlib/command/argument/ArgumentNode.java @@ -0,0 +1,12 @@ +package com.io.yutian.elementoriginlib.command.argument; + +public class ArgumentNode extends Argument { + + private static final ArgumentType NODE = new ArgumentType<>("node", null, null); + + public ArgumentNode(String name) { + super(name, NODE); + } + + +} diff --git a/src/main/java/com/io/yutian/elementoriginlib/command/argument/ArgumentType.java b/src/main/java/com/io/yutian/elementoriginlib/command/argument/ArgumentType.java index 122fa5d..2e41600 100644 --- a/src/main/java/com/io/yutian/elementoriginlib/command/argument/ArgumentType.java +++ b/src/main/java/com/io/yutian/elementoriginlib/command/argument/ArgumentType.java @@ -1,10 +1,52 @@ package com.io.yutian.elementoriginlib.command.argument; +import com.io.yutian.elementoriginlib.util.ClassUtil; +import com.io.yutian.elementoriginlib.util.StringUtil; + +import java.util.HashMap; +import java.util.Map; import java.util.function.Function; import java.util.function.Predicate; public class ArgumentType { + private static final ArgumentType STRING = new ArgumentType<>("string", (s) -> true, (s) -> s); + + private static final ArgumentType INTEGER = new ArgumentType<>("integer", StringUtil::isInt, Integer::parseInt); + + private static final ArgumentType DOUBLE = new ArgumentType<>("double", StringUtil::isDouble, Double::parseDouble); + + private static final ArgumentType BOOLEAN = new ArgumentType<>("boolean", StringUtil::isBoolean, Boolean::parseBoolean); + + private static final ArgumentType STRING_ARRAY = new ArgumentType<>("string[]", (s) -> true, (s) -> s.split(",")); + + private static final ArgumentType INTEGER_ARRAY = new ArgumentType<>("integer[]", (s) -> true, (s) -> { + String[] arr = s.split(","); + Integer[] result = new Integer[arr.length]; + for (int i = 0; i < arr.length; i++) { + result[i] = Integer.parseInt(arr[i]); + } + return result; + }); + private static final ArgumentType DOUBLE_ARRAY = new ArgumentType<>("double[]", (s) -> true, (s) -> { + String[] arr = s.split(","); + Double[] result = new Double[arr.length]; + for (int i = 0; i < arr.length; i++) { + result[i] = Double.parseDouble(arr[i]); + } + return result; + }); + private static final ArgumentType BOOLEAN_ARRAY = new ArgumentType<>("boolean[]", (s) -> true, (s) -> { + String[] arr = s.split(","); + Boolean[] result = new Boolean[arr.length]; + for (int i = 0; i < arr.length; i++) { + result[i] = Boolean.parseBoolean(arr[i]); + } + return result; + }); + + private static final Map, ArgumentType> ARGUMENT_TYPES = new HashMap<>(); + private final String name; private Predicate predicate; @@ -28,4 +70,49 @@ public class ArgumentType { return function.apply(t); } + static { + register(String.class, STRING); + register(Integer.class, INTEGER); + register(Double.class, DOUBLE); + register(Boolean.class, BOOLEAN); + register(String[].class, STRING_ARRAY); + register(Integer[].class, INTEGER_ARRAY); + register(Double[].class, DOUBLE_ARRAY); + register(Boolean[].class, BOOLEAN_ARRAY); + } + + public static void register(Class clazz, ArgumentType type) { + ARGUMENT_TYPES.put(clazz, type); + } + + public static Map, ArgumentType> getArgumentTypes() { + return ARGUMENT_TYPES; + } + + public static ArgumentType get(Class clazz) { + if (clazz.isEnum()) { + return new EnumArgumentType<>("enum_"+clazz.getSimpleName(), (Class)clazz); + } + Class c = ClassUtil.PRIMITIVE_TO_WRAPPER.getOrDefault(clazz, clazz); + return (ArgumentType) ARGUMENT_TYPES.get(c); + } + + private static class EnumArgumentType> extends ArgumentType { + + private final Class clazz; + + public EnumArgumentType(String name, Class clazz) { + super(name, (s)->{ + try { + Enum.valueOf(clazz, s); + return true; + } catch (Exception e) { + return false; + } + }, (s)-> Enum.valueOf(clazz, s)); + this.clazz = clazz; + } + + } + } diff --git a/src/main/java/com/io/yutian/elementoriginlib/command/argument/ArgumentTypes.java b/src/main/java/com/io/yutian/elementoriginlib/command/argument/ArgumentTypes.java deleted file mode 100644 index f4fcf3d..0000000 --- a/src/main/java/com/io/yutian/elementoriginlib/command/argument/ArgumentTypes.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.io.yutian.elementoriginlib.command.argument; - -import com.io.yutian.elementoriginlib.util.StringUtil; - -import java.util.UUID; - -public class ArgumentTypes { - - public static final ArgumentType STRING = new ArgumentType<>("string", (s) -> true, (s) -> s); - - public static final ArgumentType INTEGER = new ArgumentType<>("integer", StringUtil::isInt, Integer::parseInt); - - public static final ArgumentType DOUBLE = new ArgumentType<>("double", StringUtil::isDouble, Double::parseDouble); - - public static final ArgumentType UUID = new ArgumentType<>("uuid", StringUtil::isUUID, java.util.UUID::fromString); - - public static final ArgumentType BOOLEAN = new ArgumentType<>("boolean", StringUtil::isBoolean, Boolean::parseBoolean); - -} \ No newline at end of file diff --git a/src/main/java/com/io/yutian/elementoriginlib/command/argument/ArgumentValue.java b/src/main/java/com/io/yutian/elementoriginlib/command/argument/ArgumentValue.java index 74ac912..182a3ea 100644 --- a/src/main/java/com/io/yutian/elementoriginlib/command/argument/ArgumentValue.java +++ b/src/main/java/com/io/yutian/elementoriginlib/command/argument/ArgumentValue.java @@ -52,10 +52,6 @@ public class ArgumentValue { return (Boolean) value; } - public UUID getUUID() { - return (UUID) value; - } - @Override public String toString() { return "ArgumentValue{" + diff --git a/src/main/java/com/io/yutian/elementoriginlib/command/handler/CommandHandler.java b/src/main/java/com/io/yutian/elementoriginlib/command/handler/CommandHandler.java index fc35a19..60b0999 100644 --- a/src/main/java/com/io/yutian/elementoriginlib/command/handler/CommandHandler.java +++ b/src/main/java/com/io/yutian/elementoriginlib/command/handler/CommandHandler.java @@ -8,213 +8,128 @@ import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.bukkit.command.TabCompleter; -import org.bukkit.plugin.Plugin; import java.util.*; import java.util.stream.Collectors; -import java.util.stream.Stream; public class CommandHandler implements CommandExecutor, TabCompleter { - private ICommandManager commandManager; + private final ICommandManager commandManager; - public CommandHandler(Plugin plugin, ICommandManager commandManager) { + public CommandHandler(ICommandManager commandManager) { this.commandManager = commandManager; } public void execute(CommandSender sender, String label, String[] args) { if (args.length == 0) { - execute(sender, label, new String[]{"help", "1"}); + sender.sendMessage(Lang.get("command.short-arg")); return; } - List commands = commandManager.getCommands(); - String command = args[0]; - Stream stream = commands.stream().filter((c) -> c.getName().equalsIgnoreCase(command)); - Optional optional = stream.findFirst(); - if (!optional.isPresent()) { - sender.sendMessage(Lang.get("command-unknown", command)); - return; - } - ICommand iCommand = optional.get(); - if (!iCommand.hasPermission(sender)) { - sender.sendMessage(Lang.get("command-no-permission")); - return; - } - List commandNodes = iCommand.getCommandNodes(); - StringBuilder stringBuilder = new StringBuilder(); - for (int i = 0; i < args.length; i++) { - stringBuilder.append(args[i]); - if (i < args.length - 1) { - stringBuilder.append(" "); - } - } - String commandString = stringBuilder.toString(); - if (commandNodes.size() == 0) { - Map map = new HashMap<>(); - if (iCommand.getArguments().size() > 0) { - int argSize = args.length - 1; - List arguments = iCommand.getArguments(); - int k = 0; - if (arguments.get(arguments.size()-1).isOptional()) { - k++; - } - if (argSize < arguments.size()-k) { - sender.sendMessage(Lang.get("command-short-arg")); - return; - } - for (int l = 0; l < arguments.size(); l++) { - Argument a = arguments.get(l); - int index = l + 1; - if (index >= args.length) { - break; - } - String arg = args[index]; - if (!a.getArgumentsType().test(arg)) { - sender.sendMessage(Lang.get("command-unknown-arg", index+1, arg)); - return; - } - } - map = parseArgumentValue(sender, arguments, args, 0); - } - iCommand.executes(new CommandContext(commandString, label, sender, map)); + String commandName = args[0]; + Optional entityOptional = commandManager.getCommands().stream() + .filter(entity -> entity.getCommand().equalsIgnoreCase(commandName)) + .findFirst(); + + if (!entityOptional.isPresent()) { + sender.sendMessage(Lang.get("command.unknown", commandName)); return; } - int nodeSize = args.length - 1; - - if (commandNodes.size() > 0 && nodeSize == 0) { - if (!iCommand.emptyExecutes(sender)) { - sender.sendMessage(Lang.get("command-short-arg")); - } - return; - } - - String mainNode = args[1]; - Stream nodeStream = commandNodes.stream().filter((n) -> n.getName().equalsIgnoreCase(mainNode) || n.getAlias().contains(mainNode)); - Optional nodeOptional = nodeStream.findFirst(); - if (!nodeOptional.isPresent()) { - sender.sendMessage(Lang.get("command-unknown-arg", 2, mainNode)); - return; - } - CommandNode node = nodeOptional.get(); - - if (node.getChildrens().size() > 0) { - checkClidren(commandString, label, sender, 1, args, node); - } else { - if (node.getCommand() != null) { - Map map = new HashMap<>(); - if (node.getArguments().size() > 0) { - int argSize = args.length - 2; - List arguments = node.getArguments(); - int k = 0; - if (arguments.get(arguments.size()-1).isOptional()) { - k++; - } - if (argSize < arguments.size()-k) { - sender.sendMessage(Lang.get("command-short-arg")); - return; - } - for (int l = 0; l < arguments.size(); l++) { - Argument a = arguments.get(l); - int index = l + 1; - if (index >= args.length) { - break; - } - if (index+1 >= args.length) { - break; - } - String arg = args[index+1]; - if (!a.getArgumentsType().test(arg)) { - sender.sendMessage(Lang.get("command-error-arg", index+1, arg)); - return; - } - } - map = parseArgumentValue(sender, node.getArguments(), args, 1); - } - node.getCommand().run(new CommandContext(commandString, label, sender, map)); - } else { - sender.sendMessage(Lang.get("command-unknown-arg", 3, mainNode)); - } - } - + CommandEntity commandEntity = entityOptional.get(); + handleCommand(commandEntity, sender, label, args, commandEntity.getChildrens(), 1, new StringBuilder()); } - private Map parseArgumentValue(CommandSender commandSender, List argumentList, String[] args, int i) { - Map map = new HashMap<>(); - List arguments = argumentList; - for (int l = 0; l < arguments.size(); l++) { - Argument a = arguments.get(l); - if (i+1+l >= args.length) { - if (a.isOptional()) { - map.put(a.getName(), new ArgumentValue(a.getDefaultValue())); - } - return map; + private void handleCommand(CommandEntity commandEntity, CommandSender sender, String label, String[] args, List entries, int index, StringBuilder fullCommand) { + if (index >= args.length) { + sender.sendMessage(Lang.get("command.short-arg")); + return; + } + + String currentArg = args[index]; + Optional optionalEntry = entries.stream() + .filter(entry -> entry.getName().equalsIgnoreCase(currentArg)) + .findFirst(); + + if (!optionalEntry.isPresent()) { + sender.sendMessage(Lang.get("command.unknown-arg", index + 1, currentArg)); + return; + } + + CommandEntry entry = optionalEntry.get(); + fullCommand.append(currentArg); + + if (!entry.canInvoke(sender)) { + sender.sendMessage(Lang.get("command.error-sender-type")); + return; + } + + if (!entry.hasPermission(sender)) { + sender.sendMessage(Lang.get("command.no-permission")); + return; + } + + if (!entry.getChildrens().isEmpty()) { + fullCommand.append(" "); + handleCommand(commandEntity, sender, label, args, entry.getChildrens(), index + 1, fullCommand); + } else { + if (!validateArguments(sender, entry.getArguments(), args, index + 1)) { + return; } - String arg = args[i+1+l]; - if (!a.getArgumentsType().test(arg)) { + Map parsedArguments = parseArgumentValue(sender, entry.getArguments(), args, index + 1); + entry.invoke(new CommandContext(commandEntity.getInstance(), fullCommand.toString(), label, sender, parsedArguments)); + } + } + + private boolean validateArguments(CommandSender sender, List arguments, String[] args, int startIndex) { + for (int i = 0; i < arguments.size(); i++) { + Argument argument = arguments.get(i); + int argIndex = startIndex + i; + if (argIndex >= args.length) { + if (argument.isOptional()) { + continue; + } + sender.sendMessage(Lang.get("command.short-arg")); + return false; + } + + String arg = args[argIndex]; + if (!argument.getArgumentsType().test(arg)) { + sender.sendMessage(Lang.get("command.error-arg", argIndex + 1, arg)); + return false; + } + } + return true; + } + + private Map parseArgumentValue(CommandSender sender, List arguments, String[] args, int startIndex) { + Map parsedArguments = new HashMap<>(); + List methodParams = new ArrayList<>(); + + for (Argument argument : arguments) { + int argIndex = startIndex + arguments.indexOf(argument); + + if (argIndex >= args.length) { + if (argument.isOptional()) { + parsedArguments.put(argument.getName(), new ArgumentValue(argument.getDefaultValue())); + } else { + sender.sendMessage(Lang.get("command.short-arg", argument.getName())); + return null; + } continue; } - ArgumentValue argumentValue = new ArgumentValue(a.getArgumentsType().get(arg)); - map.put(a.getName(), argumentValue); - } - return map; - } - private void checkClidren(String commandString, String label, CommandSender sender, int i, String[] args, CommandNode node) { - i++; - if (i >= args.length) { - if (node.getCommand() == null) { - sender.sendMessage(Lang.get("command-short-arg")); - } else { - node.getCommand().run(new CommandContext(commandString, label, sender, new HashMap<>())); + String rawValue = args[argIndex]; + if (!argument.getArgumentsType().test(rawValue)) { + sender.sendMessage(Lang.get("command.error-arg", argIndex + 1, rawValue)); + return null; } - return; - } - String s = args[i]; - Stream nodeStream = node.getChildrens().stream().filter((n) -> n.getName().equalsIgnoreCase(s) || n.getAlias().contains(s)); - Optional nodeOptional = nodeStream.findFirst(); - if (!nodeOptional.isPresent()) { - sender.sendMessage(Lang.get("command-unknown-arg", i+1, s)); - return; - } - CommandNode node1 = nodeOptional.get(); + Object parsedValue = argument.getArgumentsType().get(rawValue); + parsedArguments.put(argument.getName(), new ArgumentValue(parsedValue)); - if (node1.getChildrens().size() > 0) { - checkClidren(commandString, label, sender, i, args, node1); - } else { - if (node1.getCommand() != null) { - Map map = new HashMap<>(); - if (node1.getArguments().size() > 0) { - int argSize = args.length - i - 1; - List arguments = node1.getArguments(); - int k = 0; - if (arguments.get(arguments.size()-1).isOptional()) { - k++; - } - if (argSize < arguments.size()-k) { - sender.sendMessage(Lang.get("command-short-arg")); - return; - } - for (int l = 0; l < arguments.size(); l++) { - Argument a = arguments.get(l); - int index = i + l + 1; - if (index >= args.length) { - break; - } - String arg = args[index]; - if (!a.getArgumentsType().test(arg)) { - sender.sendMessage(Lang.get("command-unknown-arg", index+1, arg)); - return; - } - } - map = parseArgumentValue(sender, node1.getArguments(), args, i); - } - node1.getCommand().run(new CommandContext(commandString, label, sender, map)); - } else { - sender.sendMessage(Lang.get("command-unknown-arg", i+1, s)); - } + methodParams.add(parsedValue); } + return parsedArguments; } @Override @@ -225,117 +140,74 @@ public class CommandHandler implements CommandExecutor, TabCompleter { @Override public List onTabComplete(CommandSender sender, Command command, String alias, String[] args) { - List list = new ArrayList<>(); - int index = args.length; - String arg = args[index-1]; - List commands = commandManager.getCommands(); - if (index == 1) { - List commandList = commands.stream().filter((c)->c.getName().startsWith(arg)).collect(Collectors.toList()); - if (commandList.size() > 0) { - commandList.forEach(c-> { - if (c.hasPermission(sender)) { - list.add(c.getName()); - } - }); - return list; + if (args.length == 1) { + return commandManager.getCommands().stream() + .map(CommandEntity::getCommand) + .collect(Collectors.toList()); + } + + String commandName = args[0]; + Optional entityOptional = commandManager.getCommands().stream() + .filter(entity -> entity.getCommand().equalsIgnoreCase(commandName)) + .findFirst(); + + if (!entityOptional.isPresent()) { + return Collections.emptyList(); + } + + CommandEntity commandEntity = entityOptional.get(); + List entries = commandEntity.getChildrens(); + + int depth = args.length; + String currentArg = args[depth - 1]; + return getSuggestions(sender, entries, args, 1, depth - 1, currentArg); + } + + + private List getSuggestions(CommandSender sender, List entries, String[] args, int start, int currentDepth, String currentArg) { + int maxDepth = -1; + CommandEntry commandEntry = null; + for (int i = start; i < currentDepth; i++) { + String arg = args[i]; + Optional optionalEntry = entries.stream() + .filter(entry -> entry.getName().equalsIgnoreCase(arg)) + .findFirst(); + + if (!optionalEntry.isPresent()) { + continue; } - commandList = commands.stream().filter((c)->c.getName().contains(arg)).collect(Collectors.toList()); - if (commandList.size() > 0) { - commandList.forEach(c-> { - if (c.hasPermission(sender)) { - list.add(c.getName()); - } - }); - return list; + + commandEntry = optionalEntry.get(); + + entries = commandEntry.getChildrens(); + + if (entries.size() > 0) { + maxDepth = i + 1; } - } else { - Optional iCommandOptional = commands.stream().filter((c)->c.getName().equalsIgnoreCase(args[0])).findFirst(); - if (!iCommandOptional.isPresent()) { - return list; + } + + if (entries.size() == 0) { + List arguments = commandEntry.getArguments(); + int index = (int) (currentDepth - commandEntry.getDepth() - 2); + if (index >= arguments.size()) { + return Collections.emptyList(); } - ICommand iCommand = iCommandOptional.get(); - if (!iCommand.hasPermission(sender)) { - return list; - } - if (iCommand instanceof ITabCompleter) { - ITabCompleter tabCompleter = (ITabCompleter) iCommand; - return tabCompleter.onTabComplete(sender, args, index-2, arg); - } else { - Map> map = new HashMap<>(); - if (iCommand.getCommandNodes().size() > 0) { - List list1 = new ArrayList<>(); - for (CommandNode node : iCommand.getCommandNodes()) { - list1.add(node.getName()); - list1.addAll(node.getAlias()); - if (index >= 2) { - if (!node.getName().equalsIgnoreCase(args[1])) { - continue; - } - } - if (node.getChildrens().size() > 0) { - getTabComplete(node, 2, map); - } else if (node.getArguments().size() > 0) { - List arguments = node.getArguments(); - for (int l = 0; l < arguments.size(); l++) { - Argument argument = arguments.get(l); - if (argument.getSuggest() != null) { - map.put(2+l+1, argument.getSuggest().getSuggest()); - continue; - } - map.put(2+l+1, Arrays.asList("<"+argument.getName()+">")); - } - } - } - map.put(2, list1); - return preseSuggest(map.getOrDefault(index, list), arg); - } else if (iCommand.getArguments().size() > 0) { - List arguments = iCommand.getArguments(); - for (int l = 0; l < arguments.size(); l++) { - Argument argument = arguments.get(l); - if (argument.getSuggest() != null) { - map.put(1+l+1, argument.getSuggest().getSuggest()); - continue; - } - map.put(1+l+1, Arrays.asList("<"+argument.getName()+">")); - } - return preseSuggest(map.getOrDefault(index, list), arg); + if (!arguments.isEmpty()) { + Argument argument = arguments.get(index); + Suggest suggest = argument.getSuggest(); + if (suggest != null) { + return suggest.getSuggest(); + } else { + return Collections.singletonList(new StringBuilder().append("<").append(argument.getName()).append(">").toString()); } } } - return preseSuggest(list, arg); + + return entries.stream() + .filter(entry -> entry.getName().toLowerCase().startsWith(currentArg.toLowerCase())) + .filter(entry -> entry.canInvoke(sender) && entry.hasPermission(sender)) + .map(CommandEntry::getName) + .collect(Collectors.toList()); } - public static List preseSuggest(List list, String arg) { - List newList = new ArrayList<>(); - List list1 = list.stream().filter((c)->c.startsWith(arg)||c.toLowerCase().startsWith(arg.toLowerCase())).collect(Collectors.toList()); - List list2 = list.stream().filter((c)->c.contains(arg)||c.toLowerCase().contains(arg.toLowerCase())).collect(Collectors.toList()); - List list3 = list.stream().filter((c)->c.equalsIgnoreCase(arg)|| c.equalsIgnoreCase(arg)).collect(Collectors.toList()); - newList.addAll(list1); - newList.addAll(list2); - newList.addAll(list3); - return newList; - } - - private void getTabComplete(CommandNode node, int i, Map> map) { - i++; - List list = map.getOrDefault(i, new ArrayList<>()); - for (CommandNode c : node.getChildrens()) { - list.add(c.getName()); - if (c.getChildrens().size() > 0) { - getTabComplete(c, i, map); - } else if (c.getArguments().size() > 0) { - List arguments = c.getArguments(); - for (int l = 0; l < arguments.size(); l++) { - Argument argument = arguments.get(l); - if (argument.getSuggest() != null) { - map.put(i+l+1, argument.getSuggest().getSuggest()); - continue; - } - map.put(i+l+1, Arrays.asList("<"+argument.getName()+">")); - } - } - } - map.put(i, list); - } - -} +} \ No newline at end of file diff --git a/src/main/java/com/io/yutian/elementoriginlib/command/interfaces/Command.java b/src/main/java/com/io/yutian/elementoriginlib/command/interfaces/Command.java new file mode 100644 index 0000000..4073eeb --- /dev/null +++ b/src/main/java/com/io/yutian/elementoriginlib/command/interfaces/Command.java @@ -0,0 +1,16 @@ +package com.io.yutian.elementoriginlib.command.interfaces; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface Command { + + String value(); + + String permission() default "command.elementoriginlib.default"; + +} diff --git a/src/main/java/com/io/yutian/elementoriginlib/command/interfaces/CommandArgument.java b/src/main/java/com/io/yutian/elementoriginlib/command/interfaces/CommandArgument.java new file mode 100644 index 0000000..e28d0ee --- /dev/null +++ b/src/main/java/com/io/yutian/elementoriginlib/command/interfaces/CommandArgument.java @@ -0,0 +1,18 @@ +package com.io.yutian.elementoriginlib.command.interfaces; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +public @interface CommandArgument { + + String name() default ""; + + boolean required() default true; + + String suggestionType() default ""; + +} diff --git a/src/main/java/com/io/yutian/elementoriginlib/command/interfaces/SubCommand.java b/src/main/java/com/io/yutian/elementoriginlib/command/interfaces/SubCommand.java new file mode 100644 index 0000000..58f3b70 --- /dev/null +++ b/src/main/java/com/io/yutian/elementoriginlib/command/interfaces/SubCommand.java @@ -0,0 +1,18 @@ +package com.io.yutian.elementoriginlib.command.interfaces; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface SubCommand { + + String value() default ""; + + String permission() default "command.elementoriginlib.default"; + + String[] senderRequire() default { "console", "player" }; + +} diff --git a/src/main/java/com/io/yutian/elementoriginlib/command/list/CommandHelp.java b/src/main/java/com/io/yutian/elementoriginlib/command/list/CommandHelp.java deleted file mode 100644 index 167897d..0000000 --- a/src/main/java/com/io/yutian/elementoriginlib/command/list/CommandHelp.java +++ /dev/null @@ -1,117 +0,0 @@ -package com.io.yutian.elementoriginlib.command.list; - -import com.io.yutian.elementoriginlib.command.CommandContext; -import com.io.yutian.elementoriginlib.command.CommandNode; -import com.io.yutian.elementoriginlib.command.ICommand; -import com.io.yutian.elementoriginlib.command.ICommandManager; -import com.io.yutian.elementoriginlib.command.argument.Argument; -import com.io.yutian.elementoriginlib.command.argument.ArgumentTypes; -import com.io.yutian.elementoriginlib.lang.Lang; -import com.io.yutian.elementoriginlib.util.ComponentBuilder; -import com.io.yutian.elementoriginlib.list.PageList; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.event.ClickEvent; -import net.kyori.adventure.text.event.HoverEvent; -import org.bukkit.command.CommandSender; -import org.jetbrains.annotations.Nullable; - -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -public class CommandHelp extends ICommand { - - private ICommandManager commandManager; - @Nullable - private String alias; - - public CommandHelp(ICommandManager commandManager) { - this(commandManager, null); - } - - public CommandHelp(ICommandManager commandManager, String alias) { - super("help"); - this.commandManager = commandManager; - this.alias = alias; - addArgument(Argument.argument("page", ArgumentTypes.INTEGER).optional(1)); - } - - @Override - public boolean hasPermission(CommandSender sender) { - return true; - } - - @Override - public void executes(CommandContext commandContext) { - String commandAlias = alias != null ? alias : commandContext.getLabel(); - CommandSender sender = commandContext.getSender(); - int page = commandContext.getArgumentsValue("page").getInt(); - if (page <= 0) { - sender.sendMessage(Lang.get("command.help.page-error")); - return; - } - List commands = commandManager.getCommands(); - Stream stream = commands.stream().filter((c) -> c.hasPermission(sender)); - List list = stream.collect(Collectors.toList()); - PageList pageList = new PageList<>(list, 8); - if (page > pageList.size()) { - sender.sendMessage(Lang.get("command.help.page-error")); - return; - } - sender.sendMessage(" "); - List commandList = pageList.getList(page); - sender.sendMessage("§7======[ §e§l"+commandManager.getName()+" §7]======"); - for (ICommand command : commandList) { - StringBuilder stringBuilder = new StringBuilder("§6/"+commandAlias+" "+command.getName()); - stringBuilder.append("§f"); - if (command.getCommandNodes().size() > 0) { - StringBuilder sb = new StringBuilder(); - sb.append(" ["); - int i = 0; - for (CommandNode node : command.getCommandNodes()) { - sb.append(node.getName()); - if (i + 1 < command.getCommandNodes().size()) { - sb.append("/"); - } - i++; - } - sb.append("]"); - stringBuilder.append(sb); - } else { - for (Argument argument : command.getArguments()) { - stringBuilder.append(" "); - stringBuilder.append("<"+argument.getName()+">"); - } - } - if (command.getDescription() != null) { - stringBuilder.append(" "); - stringBuilder.append("§7- §f"+command.getDescription()); - } - sender.sendMessage(stringBuilder.toString()); - } - ComponentBuilder componentBuilder = new ComponentBuilder(); - boolean hasUpPage = page > 1; - boolean hasNextPage = page < pageList.size(); - componentBuilder.add("§7====="); - if (hasUpPage) { - componentBuilder.add(" §7["+getColor(true)+"◀§7] ", ClickEvent.clickEvent(ClickEvent.Action.RUN_COMMAND, "/"+commandAlias+" help "+(page-1)), HoverEvent.hoverEvent(HoverEvent.Action.SHOW_TEXT, Component.text("§f上一页"))); - } else { - componentBuilder.add(" §7["+getColor(false)+"◀§7] "); - } - componentBuilder.add("§7===="); - componentBuilder.add("(§a"+page+"§f/§e"+pageList.size()+"§7)"); - componentBuilder.add("§7===="); - if (hasNextPage) { - componentBuilder.add(" §7["+getColor(true)+"▶§7] ", ClickEvent.clickEvent(ClickEvent.Action.RUN_COMMAND, "/"+commandAlias+" help "+(page+1)), HoverEvent.hoverEvent(HoverEvent.Action.SHOW_TEXT, Component.text("§f下一页"))); - } else { - componentBuilder.add(" §7["+getColor(false)+"▶§7] "); - } - componentBuilder.add("§7====="); - sender.sendMessage(componentBuilder.build()); - } - - private String getColor(boolean hasPage) { - return hasPage ? "§a" : "§c"; - } - -} \ No newline at end of file diff --git a/src/main/java/com/io/yutian/elementoriginlib/command/list/CommandTest.java b/src/main/java/com/io/yutian/elementoriginlib/command/list/CommandTest.java new file mode 100644 index 0000000..626e251 --- /dev/null +++ b/src/main/java/com/io/yutian/elementoriginlib/command/list/CommandTest.java @@ -0,0 +1,34 @@ +package com.io.yutian.elementoriginlib.command.list; + +import com.io.yutian.elementoriginlib.command.CommandContext; +import com.io.yutian.elementoriginlib.command.interfaces.Command; +import com.io.yutian.elementoriginlib.command.interfaces.SubCommand; +import com.io.yutian.elementoriginlib.command.interfaces.CommandArgument; + +@Command("test") +public class CommandTest { + + @SubCommand("list") + public void list(CommandContext context, @CommandArgument int page) { + System.out.println(context.getSender()); + System.out.println("list:"+page); + } + + @SubCommand("item.load") + public void item_load(@CommandArgument(suggestionType = "world_list") String id, int page, double k, CommandContext context) { + System.out.println(context.getSender()); + System.out.println("load:"+id); + System.out.println(page); + System.out.println(k); + } + + @SubCommand("item.save") + public void item_save(@CommandArgument String id) { + System.out.println("save:"+id); + } + + @SubCommand("item.test") + public void item_test(@CommandArgument String id) { + System.out.println(id); + } +} diff --git a/src/main/java/com/io/yutian/elementoriginlib/exception/command/CommandRegisterException.java b/src/main/java/com/io/yutian/elementoriginlib/exception/command/CommandRegisterException.java new file mode 100644 index 0000000..a00f918 --- /dev/null +++ b/src/main/java/com/io/yutian/elementoriginlib/exception/command/CommandRegisterException.java @@ -0,0 +1,21 @@ +package com.io.yutian.elementoriginlib.exception.command; + +public class CommandRegisterException extends RuntimeException { + + public CommandRegisterException() { + super(); + } + + public CommandRegisterException(String s) { + super(s); + } + + public CommandRegisterException(String message, Throwable cause) { + super(message, cause); + } + + public CommandRegisterException(Throwable cause) { + super(cause); + } + +} diff --git a/src/main/java/com/io/yutian/elementoriginlib/item/stat/ItemStats.java b/src/main/java/com/io/yutian/elementoriginlib/item/stat/ItemStats.java index 9c0c658..96689e1 100644 --- a/src/main/java/com/io/yutian/elementoriginlib/item/stat/ItemStats.java +++ b/src/main/java/com/io/yutian/elementoriginlib/item/stat/ItemStats.java @@ -1,22 +1,24 @@ package com.io.yutian.elementoriginlib.item.stat; -import com.io.yutian.elementoriginlib.item.stat.list.IDStat; -import com.io.yutian.elementoriginlib.item.stat.type.StringStat; +import com.io.yutian.elementoriginlib.item.stat.list.ItemStatId; +import org.jetbrains.annotations.Nullable; import java.util.HashMap; import java.util.Map; public class ItemStats { - private static Map> itemStats = new HashMap<>(); + private static Map, ItemStat> itemStats = new HashMap<>(); - public static final StringStat ID = register(new IDStat()); + static { + register(ItemStatId.class, new ItemStatId()); + } - public static I register(I itemStat) { + public static I register(Class clazz, I itemStat) { if (itemStats.containsKey(itemStat.getId())) { return itemStat; } - itemStats.put(itemStat.getId(), itemStat); + itemStats.put(clazz, itemStat); return itemStat; } @@ -24,8 +26,19 @@ public class ItemStats { itemStats.remove(itemStat.getId()); } + @Nullable + public static ItemStat getItemStat(Class clazz) { + return itemStats.get(clazz); + } + + @Nullable public static ItemStat getItemStat(String id) { - return itemStats.get(id); + for (ItemStat itemStat : itemStats.values()) { + if (itemStat.getId().equalsIgnoreCase(id)) { + return itemStat; + } + } + return null; } } diff --git a/src/main/java/com/io/yutian/elementoriginlib/item/stat/list/IDStat.java b/src/main/java/com/io/yutian/elementoriginlib/item/stat/list/ItemStatId.java similarity index 69% rename from src/main/java/com/io/yutian/elementoriginlib/item/stat/list/IDStat.java rename to src/main/java/com/io/yutian/elementoriginlib/item/stat/list/ItemStatId.java index 153ae63..38dd7b5 100644 --- a/src/main/java/com/io/yutian/elementoriginlib/item/stat/list/IDStat.java +++ b/src/main/java/com/io/yutian/elementoriginlib/item/stat/list/ItemStatId.java @@ -2,9 +2,9 @@ package com.io.yutian.elementoriginlib.item.stat.list; import com.io.yutian.elementoriginlib.item.stat.type.StringStat; -public class IDStat extends StringStat { +public class ItemStatId extends StringStat { - public IDStat() { + public ItemStatId() { super("id", "Id"); } diff --git a/src/main/java/com/io/yutian/elementoriginlib/lang/Lang.java b/src/main/java/com/io/yutian/elementoriginlib/lang/Lang.java index 188c355..acace9d 100644 --- a/src/main/java/com/io/yutian/elementoriginlib/lang/Lang.java +++ b/src/main/java/com/io/yutian/elementoriginlib/lang/Lang.java @@ -6,10 +6,7 @@ import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.plugin.Plugin; import java.io.File; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; public class Lang { @@ -29,6 +26,10 @@ public class Lang { return s; } + public static Optional getOptional(String key) { + return Optional.ofNullable(langMap.get(key)); + } + public static void reload(Plugin plugin) { if (!langFileMap.containsKey(plugin)) { return; diff --git a/src/main/java/com/io/yutian/elementoriginlib/manager/CommandManager.java b/src/main/java/com/io/yutian/elementoriginlib/manager/CommandManager.java new file mode 100644 index 0000000..98a70e2 --- /dev/null +++ b/src/main/java/com/io/yutian/elementoriginlib/manager/CommandManager.java @@ -0,0 +1,15 @@ +package com.io.yutian.elementoriginlib.manager; + +import com.io.yutian.elementoriginlib.command.SimpleCommandManager; +import com.io.yutian.elementoriginlib.command.list.CommandTest; +import org.bukkit.plugin.Plugin; + +public class CommandManager extends SimpleCommandManager { + + public CommandManager(Plugin plugin) { + super(plugin, "elementoriginlib"); +// register(new CommandHelp(this, "help")); + register(CommandTest.class); + } + +} diff --git a/src/main/java/com/io/yutian/elementoriginlib/util/ClassUtil.java b/src/main/java/com/io/yutian/elementoriginlib/util/ClassUtil.java index 401fa6e..b075d2d 100644 --- a/src/main/java/com/io/yutian/elementoriginlib/util/ClassUtil.java +++ b/src/main/java/com/io/yutian/elementoriginlib/util/ClassUtil.java @@ -49,6 +49,15 @@ public class ClassUtil { PRIMITIVE_TO_WRAPPER.put(long.class, Long.class); PRIMITIVE_TO_WRAPPER.put(float.class, Float.class); PRIMITIVE_TO_WRAPPER.put(double.class, Double.class); + PRIMITIVE_TO_WRAPPER.put(int[].class, Integer[].class); + PRIMITIVE_TO_WRAPPER.put(long[].class, Long[].class); + PRIMITIVE_TO_WRAPPER.put(float[].class, Float[].class); + PRIMITIVE_TO_WRAPPER.put(short[].class, Short[].class); + PRIMITIVE_TO_WRAPPER.put(byte[].class, Byte[].class); + PRIMITIVE_TO_WRAPPER.put(char[].class, Character[].class); + PRIMITIVE_TO_WRAPPER.put(boolean[].class, Boolean[].class); + PRIMITIVE_TO_WRAPPER.put(double[].class, Double[].class); + PRIMITIVE_TO_WRAPPER.put(void.class, Void.class); } } diff --git a/src/main/resources/lang.yml b/src/main/resources/lang.yml index c27e8d1..21e823c 100644 --- a/src/main/resources/lang.yml +++ b/src/main/resources/lang.yml @@ -4,9 +4,12 @@ command: short-arg: "&f缺少参数" unknown-arg: "&f未知的参数 &8(&7第$0个参数&8) &7&o[$1]" error-arg: "&f参数错误 &8(&7第$0个参数&8) &7&o[$1]" - no-player: "&f该指令只能由玩家执行" + error-sender-type: "&f无法执行此命令" player-no-online: "&f玩家 &e$0 &f不存在或不在线" no-permission: "&f你没有执行该命令的权限" + help: + description: "获得指令帮助" + page-error: "页码错误" playerchatinput: timeout: "&c输入超时" cancel: "&c输入已取消" \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 8505818..ceb4d50 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -2,4 +2,7 @@ name: ElementOriginLib version: '1.0' main: com.io.yutian.elementoriginlib.ElementOriginLib api-version: '1.20' -authors: [ SuperYuTian ] \ No newline at end of file +authors: [ SuperYuTian ] +commands: + elementoriginlib: + aliases: [ eol ] \ No newline at end of file