This commit is contained in:
YuTian 2025-01-24 22:41:52 +08:00
parent 601f3e2ea5
commit db6c29f103
46 changed files with 469 additions and 250 deletions

View File

@ -26,7 +26,7 @@ public final class ElementOriginLib extends JavaPlugin {
public void onEnable() { public void onEnable() {
instance = this; instance = this;
loadLibraries(); // loadLibraries();
new GuiHandlerListener(this); new GuiHandlerListener(this);
new PlayerChatInputListener(this); new PlayerChatInputListener(this);
@ -49,7 +49,7 @@ public final class ElementOriginLib extends JavaPlugin {
LibraryManager libraryManager = new BukkitLibraryManager(this); LibraryManager libraryManager = new BukkitLibraryManager(this);
libraryManager.addMavenCentral(); libraryManager.addMavenCentral();
libraryManager.setLogLevel(LogLevel.WARN); libraryManager.setLogLevel(LogLevel.WARN);
libraryManager.loadLibrary(Library.builder().groupId("org{}apache{}commons").artifactId("commons-compress").version("1.27.1").build()); // libraryManager.loadLibrary(Library.builder().groupId("org{}apache{}commons").artifactId("commons-compress").version("1.27.1").build());
// libraryManager.loadLibrary(Library.builder().groupId("com{}github{}luben").artifactId("zstd-jni").version("1.5.6-9").build()); // libraryManager.loadLibrary(Library.builder().groupId("com{}github{}luben").artifactId("zstd-jni").version("1.5.6-9").build());
// libraryManager.loadLibrary(Library.builder().groupId("com{}zaxxer").artifactId("HikariCP").version("6.2.1").build()); // libraryManager.loadLibrary(Library.builder().groupId("com{}zaxxer").artifactId("HikariCP").version("6.2.1").build());
// libraryManager.loadLibrary(Library.builder().groupId("org{}xerial").artifactId("sqlite-jdbc").version("3.46.0.0").build()); // libraryManager.loadLibrary(Library.builder().groupId("org{}xerial").artifactId("sqlite-jdbc").version("3.46.0.0").build());

View File

@ -3,13 +3,13 @@ package com.io.yutian.elementoriginlib.command;
import com.io.yutian.elementoriginlib.command.argument.Argument; import com.io.yutian.elementoriginlib.command.argument.Argument;
import com.io.yutian.elementoriginlib.command.argument.ArgumentType; import com.io.yutian.elementoriginlib.command.argument.ArgumentType;
import com.io.yutian.elementoriginlib.command.interfaces.Command; import com.io.yutian.elementoriginlib.command.interfaces.Command;
import com.io.yutian.elementoriginlib.command.interfaces.CommandArgument; import com.io.yutian.elementoriginlib.command.interfaces.Parameter;
import com.io.yutian.elementoriginlib.command.interfaces.SubCommand; import com.io.yutian.elementoriginlib.command.interfaces.SubCommand;
import com.io.yutian.elementoriginlib.exception.command.CommandRegisterException; import com.io.yutian.elementoriginlib.exception.command.CommandParseException;
import com.io.yutian.elementoriginlib.logger.Logger; import com.io.yutian.elementoriginlib.logger.Logger;
import org.bukkit.command.CommandSender;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.*; import java.util.*;
public class CommandEntity { public class CommandEntity {
@ -50,23 +50,37 @@ public class CommandEntity {
return childrens; return childrens;
} }
public static CommandEntity parseFromClass(Class clazz) { public boolean canInvoke(CommandSender sender) {
if (childrens.size() == 1 && childrens.get(0).isNodal()) {
CommandEntry child = childrens.get(0);
return child.canInvoke(sender);
}
return true;
}
public boolean hasPermission(CommandSender sender) {
if (childrens.size() == 1 && childrens.get(0).isNodal()) {
CommandEntry child = childrens.get(0);
return child.hasPermission(sender);
}
return sender.isOp() || sender.hasPermission(permission);
}
public static CommandEntity parseFromClass(Object instance, Class clazz) {
if (clazz == null) { if (clazz == null) {
LOGGER.warn("Class is null"); throw new NullPointerException("Class is null");
return null;
} }
if (!clazz.isAnnotationPresent(Command.class)) { if (!clazz.isAnnotationPresent(Command.class)) {
LOGGER.warn("Class " + clazz.getName() + " is not annotated with @Command"); throw new CommandParseException("" + clazz + " 未标注 @Command 注解");
return null;
} }
Object instance; // Object instance;
try { // try {
instance = clazz.getConstructor(null).newInstance(); // instance = clazz.getConstructor(null).newInstance();
} catch (Exception e) { // } catch (Exception e) {
LOGGER.warn("无法实例化类 " + clazz); // e.printStackTrace();
return null; // throw new CommandParseException("无法实例化类 "+clazz);
} // }
Command commandAnnotation = (Command) clazz.getAnnotation(Command.class); Command commandAnnotation = (Command) clazz.getAnnotation(Command.class);
String command = commandAnnotation.value(); String command = commandAnnotation.value();
@ -76,30 +90,41 @@ public class CommandEntity {
Map<String, CommandEntry> pathToEntryMap = new HashMap<>(); Map<String, CommandEntry> pathToEntryMap = new HashMap<>();
List<CommandEntry> rootEntries = new ArrayList<>(); List<CommandEntry> rootEntries = new ArrayList<>();
List<String> allPaths = new ArrayList<>();
boolean hasNodal = false;
try { try {
for (Method method : clazz.getDeclaredMethods()) { for (Method method : clazz.getDeclaredMethods()) {
if (!method.isAnnotationPresent(SubCommand.class)) { if (!method.isAnnotationPresent(SubCommand.class)) {
continue; continue;
} }
CommandEntry commandEntry = parseFromMethod(method); CommandEntry commandEntry = parseFromMethod(clazz, method);
if (commandEntry.isNodal()) {
if (hasNodal) {
throwParseException(clazz, "命令路径冲突: 命令 '" + command + "' 不能同时出现多个无节点命令(nodal=true)");
}
hasNodal = true;
commandEntry.setName(command);
}
if (commandEntry != null) { if (commandEntry != null) {
allEntries.add(commandEntry);
String path = commandEntry.getFullName(); String path = commandEntry.getFullName();
String parentPath = getParentPath(path); allPaths.add(path);
allEntries.add(commandEntry);
pathToEntryMap.put(path, commandEntry);
}
}
if (pathToEntryMap.containsKey(path)) { if (hasNodal && allEntries.size() > 1) {
LOGGER.warn("命令路径冲突: 子命令 '" + path + "' 已经定义, 不能再定义父命令 '" + parentPath + "'"); throwParseException(clazz, "命令路径冲突: 命令 '" + command + "' 不能同时包含子命令和无节点命令(nodal=true)");
throw new CommandRegisterException("命令路径冲突: 子命令 '" + path + "' 已经定义, 不能再定义父命令 '" + parentPath + "'"); }
}
if (!parentPath.isEmpty() && pathToEntryMap.containsKey(parentPath)) { for (String path : allPaths) {
LOGGER.warn("命令路径冲突: 子命令 '" + path + "' 已经定义, 不能再定义父命令 '" + parentPath + "'"); String parentPath = getParentPath(path);
throw new CommandRegisterException("命令路径冲突: 子命令 '" + path + "' 已经定义, 不能再定义父命令 '" + parentPath + "'");
}
pathToEntryMap.put(commandEntry.getFullName(), commandEntry); if (!parentPath.isEmpty() && pathToEntryMap.containsKey(parentPath)) {
throwParseException(clazz, "命令路径冲突: 子命令 '" + path + "' 已经定义, 不能再定义父命令 '" + parentPath + "'");
} }
} }
@ -122,6 +147,7 @@ public class CommandEntity {
parentEntry.getChildrens().add(entry); parentEntry.getChildrens().add(entry);
} }
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
return null; return null;
@ -130,6 +156,7 @@ public class CommandEntity {
return new CommandEntity(instance, command, permission, rootEntries); return new CommandEntity(instance, command, permission, rootEntries);
} }
private static String getParentPath(String path) { private static String getParentPath(String path) {
int lastDotIndex = path.lastIndexOf('.'); int lastDotIndex = path.lastIndexOf('.');
if (lastDotIndex == -1) { if (lastDotIndex == -1) {
@ -159,17 +186,17 @@ public class CommandEntity {
} }
private static CommandEntry parseFromMethod(Method method) { private static CommandEntry parseFromMethod(Class clazz, Method method) {
SubCommand subCommand = method.getAnnotation(SubCommand.class); SubCommand subCommand = method.getAnnotation(SubCommand.class);
String path = subCommand.value(); String path = subCommand.value();
String permission = subCommand.permission(); String permission = subCommand.permission();
boolean nodal = subCommand.nodal();
String[] senderRequireArray = subCommand.senderRequire(); String[] senderRequireArray = subCommand.senderRequire();
List<SenderRequire> senderRequireList = new ArrayList<>(); List<SenderRequire> senderRequireList = new ArrayList<>();
for (String senderRequire : senderRequireArray) { for (String senderRequire : senderRequireArray) {
SenderRequire senderRequire1 = SenderRequires.get(senderRequire); SenderRequire senderRequire1 = SenderRequires.get(senderRequire);
if (senderRequire1 == null) { if (senderRequire1 == null) {
LOGGER.warn("Sender require " + senderRequire + " is null"); throwParseException(clazz, "使用者权限 " + senderRequire + " 不存在");
continue;
} }
senderRequireList.add(SenderRequires.get(senderRequire)); senderRequireList.add(SenderRequires.get(senderRequire));
} }
@ -179,39 +206,54 @@ public class CommandEntity {
if (path.contains(".")) { if (path.contains(".")) {
int lastDotIndex = path.lastIndexOf('.'); int lastDotIndex = path.lastIndexOf('.');
if (lastDotIndex == -1 || lastDotIndex > path.length() - 1) { if (lastDotIndex == -1 || lastDotIndex > path.length() - 1) {
LOGGER.warn("Invalid command name '" + path + "'"); throwParseException(clazz, "命令名 '" + path + "' 无效");
return null;
} }
subName = path.substring(path.lastIndexOf('.') + 1); subName = path.substring(path.lastIndexOf('.') + 1);
} }
List<Argument> arguments = new ArrayList<>(); List<Argument> arguments = new ArrayList<>();
for (Parameter parameter : method.getParameters()) { int allArgumentsCount = (int) Arrays.stream(method.getParameters())
if (!parameter.isAnnotationPresent(CommandArgument.class)) { .filter(parameter -> parameter.isAnnotationPresent(Parameter.class))
.count();
int index = 0;
for (java.lang.reflect.Parameter parameter : method.getParameters()) {
if (!parameter.isAnnotationPresent(Parameter.class)) {
continue; continue;
} }
CommandArgument commandArgument = parameter.getAnnotation(CommandArgument.class); Parameter commandArgument = parameter.getAnnotation(Parameter.class);
String name = commandArgument.name(); String name = commandArgument.name();
String argumentName = name.isEmpty() ? parameter.getName() : name; String argumentName = name.isEmpty() ? parameter.getName() : name;
boolean required = commandArgument.required(); boolean required = commandArgument.required();
if (!required && index < allArgumentsCount - 1) {
throwParseException(clazz, "可选参数仅能在最后一个位置中使用");
}
String defaultValue = commandArgument.defaultValue();
String suggestionType = commandArgument.suggestionType(); String suggestionType = commandArgument.suggestionType();
Class<?> type = parameter.getType(); Class<?> type = parameter.getType();
ArgumentType argumentType = ArgumentType.get(parameter.getType()); ArgumentType argumentType = ArgumentType.get(parameter.getType());
if (argumentType == null) { if (argumentType == null) {
LOGGER.warn("Argument type " + parameter.getType().getName() + " is null"); throwParseException(clazz, "参数类型 " + parameter.getType().getName() + " 不存在");
continue;
} }
Argument argument = new Argument(argumentName, argumentType); Argument argument = new Argument(argumentName, argumentType);
if (!suggestionType.isEmpty()) { if (!suggestionType.isEmpty()) {
Suggest suggest = Suggests.getSuggest(suggestionType); Suggest suggest = Suggests.getSuggest(suggestionType);
if (suggest == null) { if (suggest == null) {
LOGGER.warn("Suggest type " + suggestionType + " is null"); throwParseException(clazz, "建议类型 " + parameter.getType().getName() + " 不存在");
} else { } else {
argument.suggest(suggest); argument.suggest(suggest);
} }
} }
if (!required) {
argument.optional(defaultValue);
}
arguments.add(argument); arguments.add(argument);
index++;
} }
return new CommandEntry(path, subName, permission, senderRequireList, arguments, method); return new CommandEntry(path, subName, permission, nodal, senderRequireList, arguments, method);
}
private static void throwParseException(Class clazz, String message) {
LOGGER.warn("解析命令 "+clazz+" 时出现错误");
throw new CommandParseException(message);
} }
@Override @Override
@ -222,4 +264,5 @@ public class CommandEntity {
", childrens=" + childrens + ", childrens=" + childrens +
'}'; '}';
} }
} }

View File

@ -2,15 +2,15 @@ package com.io.yutian.elementoriginlib.command;
import com.io.yutian.elementoriginlib.command.argument.Argument; import com.io.yutian.elementoriginlib.command.argument.Argument;
import com.io.yutian.elementoriginlib.command.argument.ArgumentValue; import com.io.yutian.elementoriginlib.command.argument.ArgumentValue;
import com.io.yutian.elementoriginlib.command.interfaces.CommandArgument; import com.io.yutian.elementoriginlib.command.interfaces.Parameter;
import com.io.yutian.elementoriginlib.logger.Logger; import com.io.yutian.elementoriginlib.logger.Logger;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
public class CommandEntry { public class CommandEntry {
@ -22,6 +22,8 @@ public class CommandEntry {
private String permission; private String permission;
private List<SenderRequire> senderRequires = new ArrayList<>(); private List<SenderRequire> senderRequires = new ArrayList<>();
private boolean nodal;
private List<Argument> arguments = new ArrayList<>(); private List<Argument> arguments = new ArrayList<>();
private List<CommandEntry> childrens = new ArrayList<>(); private List<CommandEntry> childrens = new ArrayList<>();
@ -33,10 +35,11 @@ public class CommandEntry {
private Class<?>[] parameterTypes; private Class<?>[] parameterTypes;
public CommandEntry(String fullName, String name, String permission, List<SenderRequire> senderRequires, List<Argument> arguments, Method method) { public CommandEntry(String fullName, String name, String permission, boolean nodal, List<SenderRequire> senderRequires, List<Argument> arguments, Method method) {
this.fullName = fullName; this.fullName = fullName;
this.name = name; this.name = name;
this.permission = permission; this.permission = permission;
this.nodal = nodal;
this.senderRequires = senderRequires; this.senderRequires = senderRequires;
this.arguments = arguments; this.arguments = arguments;
this.method = method; this.method = method;
@ -75,8 +78,8 @@ public class CommandEntry {
int argumentIndex = 0; int argumentIndex = 0;
for (int i = 0; i < parameterTypes.length; i++) { for (int i = 0; i < parameterTypes.length; i++) {
Parameter parameter = method.getParameters()[i]; java.lang.reflect.Parameter parameter = method.getParameters()[i];
if (parameter.isAnnotationPresent(CommandArgument.class)) { if (parameter.isAnnotationPresent(Parameter.class)) {
String paramName = arguments.get(argumentIndex).getName(); String paramName = arguments.get(argumentIndex).getName();
ArgumentValue argumentValue = commandContext.getArgumentsValue(paramName); ArgumentValue argumentValue = commandContext.getArgumentsValue(paramName);
if (argumentValue != null) { if (argumentValue != null) {
@ -205,6 +208,10 @@ public class CommandEntry {
return arguments; return arguments;
} }
public boolean isNodal() {
return nodal;
}
public List<CommandEntry> getChildrens() { public List<CommandEntry> getChildrens() {
return childrens; return childrens;
} }
@ -213,15 +220,24 @@ public class CommandEntry {
return depth; return depth;
} }
public void setName(String name) {
this.name = name;
}
@Override @Override
public String toString() { public String toString() {
return "CommandEntry{" + return "CommandEntry{" +
"fullName='" + fullName + '\'' + "fullName='" + fullName + '\'' +
", name='" + name + '\'' + ", name='" + name + '\'' +
", permission='" + permission + '\'' + ", permission='" + permission + '\'' +
", senderRequires=" + senderRequires +
", nodal=" + nodal +
", arguments=" + arguments + ", arguments=" + arguments +
", childrens=" + childrens + ", childrens=" + childrens +
", depth=" + depth +
", method=" + method +
", methodHandle=" + methodHandle +
", parameterTypes=" + Arrays.toString(parameterTypes) +
'}'; '}';
} }
} }

View File

@ -6,6 +6,6 @@ public interface ICommandManager {
String getName(); String getName();
List<CommandEntity> getCommands(); List<CommandEntity> getCommandEntities();
} }

View File

@ -22,35 +22,32 @@ public class SimpleCommandManager implements ICommandManager {
private final String name; private final String name;
@NotNull @NotNull
private List<Class<?>> commandClasses = new ArrayList<>(); private Map<Class<?>, Object> commands = new HashMap<>();
@NotNull @NotNull
private List<CommandEntity> commands = new ArrayList<>(); private List<CommandEntity> commandEntities = new ArrayList<>();
public SimpleCommandManager(Plugin plugin, String name) { public SimpleCommandManager(@NotNull Plugin plugin, @NotNull String name) {
this(plugin, name, new ArrayList<>());
}
public SimpleCommandManager(Plugin plugin, String name, @NotNull List<Class<?>> commandClasses) {
this.plugin = plugin; this.plugin = plugin;
this.name = name; this.name = name;
this.commandClasses = commandClasses;
} }
public void register(@NotNull Class<?> commandClass) { public <T> void register(@NotNull Object instance) {
if (commandClass == null) { if (instance == null) {
return; throw new NullPointerException("instance is null");
} }
CommandEntity command = CommandEntity.parseFromClass(commandClass); Class<?> instanceClass = instance.getClass();
CommandEntity command = CommandEntity.parseFromClass(instance, instanceClass);
if (command == null) { if (command == null) {
return; return;
} }
commandClasses.add(commandClass); commands.put(instanceClass, instance);
commands.add(command); commandEntities.add(command);
} }
public void unregisterAll() { public void unregisterAll() {
commands.clear(); commands.clear();
commandEntities.clear();
} }
public void unregister(Class<?> commandClass) { public void unregister(Class<?> commandClass) {
@ -58,6 +55,7 @@ public class SimpleCommandManager implements ICommandManager {
return; return;
} }
commands.remove(commandClass); commands.remove(commandClass);
commandEntities.clear();
} }
public void registerPluginCommand(@NotNull String commandName) { public void registerPluginCommand(@NotNull String commandName) {
@ -76,8 +74,8 @@ public class SimpleCommandManager implements ICommandManager {
@NotNull @NotNull
@Override @Override
public List<CommandEntity> getCommands() { public List<CommandEntity> getCommandEntities() {
return commands; return commandEntities;
} }
static { static {

View File

@ -11,14 +11,14 @@ public class Argument {
private Suggest suggest; private Suggest suggest;
private boolean optional = false; private boolean optional = false;
private Object defaultValue = null; private String defaultValue = null;
public Argument(String name, ArgumentType argumentsType) { public Argument(String name, ArgumentType argumentsType) {
this.name = name; this.name = name;
this.argumentsType = argumentsType; this.argumentsType = argumentsType;
} }
public Argument optional(Object defaultValue) { public Argument optional(String defaultValue) {
optional = true; optional = true;
this.defaultValue = defaultValue; this.defaultValue = defaultValue;
return this; return this;
@ -36,7 +36,7 @@ public class Argument {
return optional; return optional;
} }
public Object getDefaultValue() { public String getDefaultValue() {
return defaultValue; return defaultValue;
} }

View File

@ -1,12 +0,0 @@
package com.io.yutian.elementoriginlib.command.argument;
public class ArgumentNode extends Argument {
private static final ArgumentType<Object> NODE = new ArgumentType<>("node", null, null);
public ArgumentNode(String name) {
super(name, NODE);
}
}

View File

@ -26,7 +26,7 @@ public class CommandHandler implements CommandExecutor, TabCompleter {
return; return;
} }
String commandName = args[0]; String commandName = args[0];
Optional<CommandEntity> entityOptional = commandManager.getCommands().stream() Optional<CommandEntity> entityOptional = commandManager.getCommandEntities().stream()
.filter(entity -> entity.getCommand().equalsIgnoreCase(commandName)) .filter(entity -> entity.getCommand().equalsIgnoreCase(commandName))
.findFirst(); .findFirst();
@ -36,7 +36,11 @@ public class CommandHandler implements CommandExecutor, TabCompleter {
} }
CommandEntity commandEntity = entityOptional.get(); CommandEntity commandEntity = entityOptional.get();
handleCommand(commandEntity, sender, label, args, commandEntity.getChildrens(), 1, new StringBuilder()); int index = 1;
if (commandEntity.getChildrens().size() == 1 && commandEntity.getChildrens().get(0).isNodal()) {
index = 0;
}
handleCommand(commandEntity, sender, label, args, commandEntity.getChildrens(), index, new StringBuilder());
} }
private void handleCommand(CommandEntity commandEntity, CommandSender sender, String label, String[] args, List<CommandEntry> entries, int index, StringBuilder fullCommand) { private void handleCommand(CommandEntity commandEntity, CommandSender sender, String label, String[] args, List<CommandEntry> entries, int index, StringBuilder fullCommand) {
@ -109,16 +113,18 @@ public class CommandHandler implements CommandExecutor, TabCompleter {
int argIndex = startIndex + arguments.indexOf(argument); int argIndex = startIndex + arguments.indexOf(argument);
if (argIndex >= args.length) { if (argIndex >= args.length) {
if (argument.isOptional()) { if (!argument.isOptional()) {
parsedArguments.put(argument.getName(), new ArgumentValue(argument.getDefaultValue()));
} else {
sender.sendMessage(Lang.get("command.short-arg", argument.getName())); sender.sendMessage(Lang.get("command.short-arg", argument.getName()));
return null; return null;
} }
continue;
} }
String rawValue = args[argIndex]; String rawValue = null;
if (argument.isOptional() && argIndex >= args.length) {
rawValue = argument.getDefaultValue();
} else {
rawValue = args[argIndex];
}
if (!argument.getArgumentsType().test(rawValue)) { if (!argument.getArgumentsType().test(rawValue)) {
sender.sendMessage(Lang.get("command.error-arg", argIndex + 1, rawValue)); sender.sendMessage(Lang.get("command.error-arg", argIndex + 1, rawValue));
return null; return null;
@ -141,13 +147,13 @@ public class CommandHandler implements CommandExecutor, TabCompleter {
@Override @Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) { public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
if (args.length == 1) { if (args.length == 1) {
return commandManager.getCommands().stream() return commandManager.getCommandEntities().stream()
.map(CommandEntity::getCommand) .map(CommandEntity::getCommand)
.collect(Collectors.toList()); .collect(Collectors.toList());
} }
String commandName = args[0]; String commandName = args[0];
Optional<CommandEntity> entityOptional = commandManager.getCommands().stream() Optional<CommandEntity> entityOptional = commandManager.getCommandEntities().stream()
.filter(entity -> entity.getCommand().equalsIgnoreCase(commandName)) .filter(entity -> entity.getCommand().equalsIgnoreCase(commandName))
.findFirst(); .findFirst();
@ -158,15 +164,24 @@ public class CommandHandler implements CommandExecutor, TabCompleter {
CommandEntity commandEntity = entityOptional.get(); CommandEntity commandEntity = entityOptional.get();
List<CommandEntry> entries = commandEntity.getChildrens(); List<CommandEntry> entries = commandEntity.getChildrens();
if (entries.size() == 0) {
return Collections.emptyList();
}
int depth = args.length; int depth = args.length;
String currentArg = args[depth - 1]; String currentArg = args[depth - 1];
return getSuggestions(sender, entries, args, 1, depth - 1, currentArg);
// int index = depth - 1;
// if (commandEntity.getChildrens().size() == 1 && commandEntity.getChildrens().get(0).isNodal()) {
// index = depth - 2;
// }
return getSuggestions(sender, entries, args, 0, depth - 1, currentArg);
} }
private List<String> getSuggestions(CommandSender sender, List<CommandEntry> entries, String[] args, int start, int currentDepth, String currentArg) { private List<String> getSuggestions(CommandSender sender, List<CommandEntry> entries, String[] args, int start, int currentDepth, String currentArg) {
int maxDepth = -1;
CommandEntry commandEntry = null; CommandEntry commandEntry = null;
for (int i = start; i < currentDepth; i++) { for (int i = start; i < currentDepth; i++) {
String arg = args[i]; String arg = args[i];
Optional<CommandEntry> optionalEntry = entries.stream() Optional<CommandEntry> optionalEntry = entries.stream()
@ -180,15 +195,11 @@ public class CommandHandler implements CommandExecutor, TabCompleter {
commandEntry = optionalEntry.get(); commandEntry = optionalEntry.get();
entries = commandEntry.getChildrens(); entries = commandEntry.getChildrens();
if (entries.size() > 0) {
maxDepth = i + 1;
}
} }
if (entries.size() == 0) { if (entries.size() == 0) {
List<Argument> arguments = commandEntry.getArguments(); List<Argument> arguments = commandEntry.getArguments();
int index = (int) (currentDepth - commandEntry.getDepth() - 2); int index = (int) (currentDepth - commandEntry.getDepth() - 1);
if (index >= arguments.size()) { if (index >= arguments.size()) {
return Collections.emptyList(); return Collections.emptyList();
} }

View File

@ -7,12 +7,14 @@ import java.lang.annotation.Target;
@Target(ElementType.PARAMETER) @Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface CommandArgument { public @interface Parameter {
String name() default ""; String name() default "";
boolean required() default true; boolean required() default true;
String defaultValue() default "";
String suggestionType() default ""; String suggestionType() default "";
} }

View File

@ -15,4 +15,6 @@ public @interface SubCommand {
String[] senderRequire() default { "console", "player" }; String[] senderRequire() default { "console", "player" };
boolean nodal() default false;
} }

View File

@ -0,0 +1,126 @@
package com.io.yutian.elementoriginlib.command.list;
import com.io.yutian.elementoriginlib.command.CommandContext;
import com.io.yutian.elementoriginlib.command.CommandEntity;
import com.io.yutian.elementoriginlib.command.CommandEntry;
import com.io.yutian.elementoriginlib.command.interfaces.Command;
import com.io.yutian.elementoriginlib.command.interfaces.Parameter;
import com.io.yutian.elementoriginlib.command.interfaces.SubCommand;
import com.io.yutian.elementoriginlib.lang.Lang;
import com.io.yutian.elementoriginlib.list.PageList;
import com.io.yutian.elementoriginlib.manager.CommandManager;
import com.io.yutian.elementoriginlib.util.ComponentBuilder;
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 java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@Command("help")
public class CommandHelp {
private final static int MAX_PAGE_SIZE = 8;
private final CommandManager commandManager;
private final String alias;
public CommandHelp(CommandManager commandManager, String alias) {
this.commandManager = commandManager;
this.alias = alias;
}
@SubCommand(nodal = true)
public void help(CommandContext commandContext, @Parameter(required = false, defaultValue = "1") int page) {
String commandAlias = alias != null ? alias : commandContext.getLabel();
CommandSender sender = commandContext.getSender();
if (page <= 0) {
sender.sendMessage(Lang.get("command.help.page-error"));
return;
}
List<CommandEntity> commands = commandManager.getCommandEntities();
Stream<CommandEntity> stream = commands.stream().filter((c) -> c.hasPermission(sender) && c.canInvoke(sender));
List<CommandEntity> list = stream.collect(Collectors.toList());
PageList<CommandEntity> pageList = new PageList<>(list, MAX_PAGE_SIZE);
if (page > pageList.size()) {
sender.sendMessage(Lang.get("command.help.page-error"));
return;
}
sender.sendMessage(" ");
List<CommandEntity> commandList = pageList.getList(page);
sender.sendMessage("§7======[ §e§l"+commandManager.getName()+" §7]======");
for (CommandEntity command : commandList) {
StringBuilder stringBuilder = getCommandInfo(command, commandAlias);
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 StringBuilder getCommandInfo(CommandEntity command, String commandAlias) {
StringBuilder stringBuilder = new StringBuilder("§6/"+ commandAlias +" "+ command.getCommand());
stringBuilder.append("§f");
System.out.println(commandAlias);
if (command.getChildrens().size() > 0) {
} else {
}
Optional<String> optional = Lang.getOptional("command."+command.getCommand()+".description");
if (optional.isPresent()) {
stringBuilder.append(" ");
stringBuilder.append("§7- §f"+ optional.get());
}
// if (command.getChildrens().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()+">");
// }
// }
// Optional<String> optional = Lang.getOptional("command."+command.getName()+".description");
// if (optional.isPresent()) {
// stringBuilder.append(" ");
// stringBuilder.append("§7- §f"+ optional.get());
// }
return stringBuilder;
}
private String getColor(boolean hasPage) {
return hasPage ? "§a" : "§c";
}
}

View File

@ -3,32 +3,46 @@ package com.io.yutian.elementoriginlib.command.list;
import com.io.yutian.elementoriginlib.command.CommandContext; import com.io.yutian.elementoriginlib.command.CommandContext;
import com.io.yutian.elementoriginlib.command.interfaces.Command; import com.io.yutian.elementoriginlib.command.interfaces.Command;
import com.io.yutian.elementoriginlib.command.interfaces.SubCommand; import com.io.yutian.elementoriginlib.command.interfaces.SubCommand;
import com.io.yutian.elementoriginlib.command.interfaces.CommandArgument; import com.io.yutian.elementoriginlib.command.interfaces.Parameter;
import com.io.yutian.elementoriginlib.item.OriginItem;
import com.io.yutian.elementoriginlib.item.stat.ItemStats;
import com.io.yutian.elementoriginlib.item.stat.data.StringData;
import com.io.yutian.elementoriginlib.item.stat.list.IdStat;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
@Command("test") @Command("test")
public class CommandTest { public class CommandTest {
@SubCommand("list") @SubCommand("list")
public void list(CommandContext context, @CommandArgument int page) { public void list(CommandContext context, @Parameter(required = false, defaultValue = "1") int page) {
System.out.println(context.getSender()); System.out.println(context.getSender());
System.out.println("list:"+page); System.out.println("list:"+page);
} }
@SubCommand("item.load") @SubCommand("item.get")
public void item_load(@CommandArgument(suggestionType = "world_list") String id, int page, double k, CommandContext context) { public void item_get(CommandContext context) {
System.out.println(context.getSender()); Player player = (Player) context.getSender();
System.out.println("load:"+id);
System.out.println(page); OriginItem originItem = new OriginItem(new ItemStack(Material.IRON_AXE));
System.out.println(k); originItem.setStatData(ItemStats.getItemStat(IdStat.class), new StringData("test"));
player.getInventory().addItem(originItem.getItemStack());
} }
@SubCommand("item.save") @SubCommand("item.load")
public void item_save(@CommandArgument String id) { public void item_load(CommandContext context) {
System.out.println("save:"+id); Player player = (Player) context.getSender();
ItemStack itemStack = player.getInventory().getItemInMainHand();
if (itemStack == null || itemStack.getType() == Material.AIR) {
return;
}
OriginItem originItem = new OriginItem(itemStack);
System.out.println(originItem.getStats());
} }
@SubCommand("item.test") @SubCommand("item.test")
public void item_test(@CommandArgument String id) { public void item_test(@Parameter String id) {
System.out.println(id); System.out.println(id);
} }
} }

View File

@ -0,0 +1,21 @@
package com.io.yutian.elementoriginlib.exception.command;
public class CommandParseException extends RuntimeException {
public CommandParseException() {
super();
}
public CommandParseException(String s) {
super(s);
}
public CommandParseException(String message, Throwable cause) {
super(message, cause);
}
public CommandParseException(Throwable cause) {
super(cause);
}
}

View File

@ -1,21 +0,0 @@
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);
}
}

View File

@ -1,7 +1,7 @@
package com.io.yutian.elementoriginlib.gui.button; package com.io.yutian.elementoriginlib.gui.button;
import com.io.yutian.elementoriginlib.nbt.NBTItem; import com.io.yutian.elementoriginlib.tag.ItemProxy;
import com.io.yutian.elementoriginlib.nbt.TagString; import com.io.yutian.elementoriginlib.tag.TagString;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@ -20,11 +20,11 @@ public class ItemButton extends Button {
public ItemButton(ItemStack itemStack) { public ItemButton(ItemStack itemStack) {
super(itemStack); super(itemStack);
NBTItem nbtItem = new NBTItem(itemStack); ItemProxy itemProxy = new ItemProxy(itemStack);
nbtItem.editTag((nbtCompound -> { itemProxy.editTag((nbtCompound -> {
nbtCompound.putString("gui_meta", "item_button"); nbtCompound.putString("gui_meta", "item_button");
})); }));
setItemStack(nbtItem.getItemStack()); setItemStack(itemProxy.getItemStack());
} }
public ItemButton setItem(ItemStack item) { public ItemButton setItem(ItemStack item) {
@ -51,8 +51,8 @@ public class ItemButton extends Button {
} }
public boolean isItem(ItemStack item) { public boolean isItem(ItemStack item) {
NBTItem nbtItem = new NBTItem(item); ItemProxy itemProxy = new ItemProxy(item);
return nbtItem.has("gui_meta", TagString.TYPE_ID) && ((TagString) nbtItem.get("gui_meta")).getString().equals("item_button"); return itemProxy.has("gui_meta", TagString.TYPE_ID) && ((TagString) itemProxy.get("gui_meta")).getString().equals("item_button");
} }
public ItemButton clickItem(BiConsumer<Player, ItemStack> consumer) { public ItemButton clickItem(BiConsumer<Player, ItemStack> consumer) {

View File

@ -1,33 +1,37 @@
package com.io.yutian.elementoriginlib.item; package com.io.yutian.elementoriginlib.item;
import com.io.yutian.elementoriginlib.item.stat.ItemStat; import com.io.yutian.elementoriginlib.item.stat.ItemStat;
import com.io.yutian.elementoriginlib.item.stat.ItemStats;
import com.io.yutian.elementoriginlib.item.stat.StatData; import com.io.yutian.elementoriginlib.item.stat.StatData;
import com.io.yutian.elementoriginlib.nbt.NBTItem; import com.io.yutian.elementoriginlib.tag.ItemProxy;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.HashMap; import java.util.*;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class OriginItem { public class OriginItem {
private ItemStack itemStack; private ItemStack itemStack;
private NBTItem nbtItem; private ItemProxy itemProxy;
private Map<ItemStat, StatData> stats = new HashMap<>(); private Map<ItemStat, StatData> stats = new HashMap<>();
private OriginItemStackBuilder builder;
public OriginItem(ItemStack itemStack) { public OriginItem(ItemStack itemStack) {
this.itemStack = itemStack; this.itemStack = itemStack;
this.nbtItem = new NBTItem(itemStack); this.itemProxy = new ItemProxy(itemStack);
this.builder = new OriginItemStackBuilder(this);
} }
public void setStatData(@NotNull ItemStat stat, @NotNull StatData data) { public void setStatData(@NotNull ItemStat stat, @NotNull StatData data) {
this.stats.put(stat, data); this.stats.put(stat, data);
this.itemStack = builder().build();
} }
public void removeStatData(@NotNull ItemStat stat) { public void removeStatData(@NotNull ItemStat stat) {
this.stats.remove(stat); this.stats.remove(stat);
this.itemStack = builder().build();
} }
public <S extends StatData> S getStatData(@NotNull ItemStat<S> stat) { public <S extends StatData> S getStatData(@NotNull ItemStat<S> stat) {
@ -50,20 +54,34 @@ public class OriginItem {
@NotNull @NotNull
public OriginItemStackBuilder builder() { public OriginItemStackBuilder builder() {
return new OriginItemStackBuilder(this); return this.builder;
} }
@NotNull @NotNull
public Set<ItemStat> getStats() { public Set<ItemStat> getStatTypes() {
return this.stats.keySet(); return Collections.unmodifiableSet(this.stats.keySet());
}
@NotNull
public Map<ItemStat, StatData> getStats() {
for (ItemStat stat : ItemStats.getItemStats()) {
if (!hasStatData(stat)) {
try {
stat.load(this);
} catch (Exception e) {
e.printStackTrace();
}
}
}
return Collections.unmodifiableMap(stats);
} }
public ItemStack getItemStack() { public ItemStack getItemStack() {
return itemStack; return itemStack;
} }
public NBTItem getNBTItem() { public ItemProxy getItemProxy() {
return nbtItem; return itemProxy;
} }
@Override @Override

View File

@ -1,7 +1,7 @@
package com.io.yutian.elementoriginlib.item; package com.io.yutian.elementoriginlib.item;
import com.io.yutian.elementoriginlib.item.stat.StatData; import com.io.yutian.elementoriginlib.item.stat.StatData;
import com.io.yutian.elementoriginlib.nbt.NBTItem; import com.io.yutian.elementoriginlib.tag.ItemProxy;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -16,18 +16,18 @@ public class OriginItemStackBuilder {
protected ItemStack itemStack; protected ItemStack itemStack;
protected ItemMeta itemMeta; protected ItemMeta itemMeta;
protected NBTItem nbtItem; protected ItemProxy itemProxy;
public OriginItemStackBuilder(OriginItem originItem) { public OriginItemStackBuilder(OriginItem originItem) {
this.originItem = originItem; this.originItem = originItem;
this.itemStack = originItem.getItemStack(); this.itemStack = originItem.getItemStack();
this.itemMeta = itemStack.getItemMeta(); this.itemMeta = itemStack.getItemMeta();
this.nbtItem = originItem.getNBTItem(); this.itemProxy = originItem.getItemProxy();
} }
@NotNull @NotNull
public ItemStack build() { public ItemStack build() {
buildNBT(); buildCompounds();
return itemStack; return itemStack;
} }
@ -36,29 +36,20 @@ public class OriginItemStackBuilder {
return itemMeta; return itemMeta;
} }
private void buildNBT() { private void buildCompounds() {
originItem.getStats().forEach(stat -> { originItem.getStats().forEach((stat, statData) -> stat.whenApplied(this, statData));
StatData statData = originItem.getStatData(stat); itemStack = itemProxy.getItemStack();
stat.whenApplied(this, statData);
});
itemStack = nbtItem.getItemStack();
itemMeta = itemStack.getItemMeta(); itemMeta = itemStack.getItemMeta();
originItem.getStats().forEach(stat -> { originItem.getStats().forEach((stat, statData) -> stat.applyMeta(this, statData));
StatData statData = originItem.getStatData(stat);
stat.applyMeta(this, statData);
});
itemStack.setItemMeta(itemMeta); itemStack.setItemMeta(itemMeta);
List<String> lores = itemMeta.hasLore() ? itemMeta.getLore() : new ArrayList<>(); List<String> lores = itemMeta.hasLore() ? itemMeta.getLore() : new ArrayList<>();
originItem.getStats().forEach(stat -> { originItem.getStats().forEach((stat, statData) -> stat.whenApplyLore(this, statData, lores));
StatData statData = originItem.getStatData(stat);
stat.whenApplyLore(this, statData, lores);
});
itemStack.setLore(lores); itemStack.setLore(lores);
} }
@NotNull @NotNull
public NBTItem getNBTItem() { public ItemProxy getNBTItem() {
return nbtItem; return itemProxy;
} }
public OriginItem getOriginItem() { public OriginItem getOriginItem() {

View File

@ -2,7 +2,7 @@ package com.io.yutian.elementoriginlib.item.stat;
import com.io.yutian.elementoriginlib.item.OriginItem; import com.io.yutian.elementoriginlib.item.OriginItem;
import com.io.yutian.elementoriginlib.item.OriginItemStackBuilder; import com.io.yutian.elementoriginlib.item.OriginItemStackBuilder;
import com.io.yutian.elementoriginlib.nbt.NBTItem; import com.io.yutian.elementoriginlib.tag.ItemProxy;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -29,10 +29,10 @@ public abstract class ItemStat<S extends StatData> {
} }
@Nullable @Nullable
public abstract S getLoadedNBT(@NotNull NBTItem nbtItem); public abstract S getLoadedNBT(@NotNull ItemProxy itemProxy);
public void load(@NotNull OriginItem originItem) { public void load(@NotNull OriginItem originItem) {
S loadedNBT = getLoadedNBT(originItem.getNBTItem()); S loadedNBT = getLoadedNBT(originItem.getItemProxy());
if (loadedNBT != null) { if (loadedNBT != null) {
originItem.setStatData(this, loadedNBT); originItem.setStatData(this, loadedNBT);
} }

View File

@ -1,25 +1,30 @@
package com.io.yutian.elementoriginlib.item.stat; package com.io.yutian.elementoriginlib.item.stat;
import com.io.yutian.elementoriginlib.item.stat.list.ItemStatId; import com.io.yutian.elementoriginlib.item.stat.list.IdStat;
import com.io.yutian.elementoriginlib.logger.Logger;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class ItemStats { public class ItemStats {
private static final Logger LOGGER = Logger.getLogger(ItemStats.class);
private static Map<Class<? extends ItemStat>, ItemStat<?>> itemStats = new HashMap<>(); private static Map<Class<? extends ItemStat>, ItemStat<?>> itemStats = new HashMap<>();
static { static {
register(ItemStatId.class, new ItemStatId()); register(IdStat.class, new IdStat());
} }
public static <I extends ItemStat> I register(Class<I> clazz, I itemStat) { public static <I extends ItemStat> void register(Class<I> clazz, I itemStat) {
if (itemStats.containsKey(itemStat.getId())) { if (itemStats.containsKey(itemStat.getId())) {
return itemStat; LOGGER.warn("ItemStat "+clazz.getName()+" 已经注册过了");
return;
} }
itemStats.put(clazz, itemStat); itemStats.put(clazz, itemStat);
return itemStat;
} }
public static void unregister(ItemStat itemStat) { public static void unregister(ItemStat itemStat) {
@ -41,4 +46,8 @@ public class ItemStats {
return null; return null;
} }
public static Collection<ItemStat> getItemStats() {
return Collections.unmodifiableCollection(itemStats.values());
}
} }

View File

@ -2,9 +2,9 @@ package com.io.yutian.elementoriginlib.item.stat.list;
import com.io.yutian.elementoriginlib.item.stat.type.StringStat; import com.io.yutian.elementoriginlib.item.stat.type.StringStat;
public class ItemStatId extends StringStat { public class IdStat extends StringStat {
public ItemStatId() { public IdStat() {
super("id", "Id"); super("id", "Id");
} }

View File

@ -3,8 +3,8 @@ package com.io.yutian.elementoriginlib.item.stat.type;
import com.io.yutian.elementoriginlib.item.OriginItemStackBuilder; import com.io.yutian.elementoriginlib.item.OriginItemStackBuilder;
import com.io.yutian.elementoriginlib.item.stat.ItemStat; import com.io.yutian.elementoriginlib.item.stat.ItemStat;
import com.io.yutian.elementoriginlib.item.stat.data.BooleanData; import com.io.yutian.elementoriginlib.item.stat.data.BooleanData;
import com.io.yutian.elementoriginlib.nbt.TagByte; import com.io.yutian.elementoriginlib.tag.TagByte;
import com.io.yutian.elementoriginlib.nbt.NBTItem; import com.io.yutian.elementoriginlib.tag.ItemProxy;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -16,14 +16,14 @@ public abstract class BooleanStat extends ItemStat<BooleanData> {
@Override @Override
public void whenApplied(@NotNull OriginItemStackBuilder itemStackBuilder, @NotNull BooleanData statData) { public void whenApplied(@NotNull OriginItemStackBuilder itemStackBuilder, @NotNull BooleanData statData) {
NBTItem nbtItem = itemStackBuilder.getNBTItem(); ItemProxy itemProxy = itemStackBuilder.getNBTItem();
nbtItem.editTag(nbtCompound -> nbtCompound.putByte(getNBTPath(), (byte) (statData.getValue() ? 1 : 0))); itemProxy.editTag(nbtCompound -> nbtCompound.putByte(getNBTPath(), (byte) (statData.getValue() ? 1 : 0)));
} }
@Nullable @Nullable
@Override @Override
public BooleanData getLoadedNBT(@NotNull NBTItem nbtItem) { public BooleanData getLoadedNBT(@NotNull ItemProxy itemProxy) {
return new BooleanData(((TagByte) nbtItem.get(getNBTPath())).getByte() == 1); return new BooleanData(((TagByte) itemProxy.get(getNBTPath())).getByte() == 1);
} }
} }

View File

@ -3,8 +3,8 @@ package com.io.yutian.elementoriginlib.item.stat.type;
import com.io.yutian.elementoriginlib.item.OriginItemStackBuilder; import com.io.yutian.elementoriginlib.item.OriginItemStackBuilder;
import com.io.yutian.elementoriginlib.item.stat.ItemStat; import com.io.yutian.elementoriginlib.item.stat.ItemStat;
import com.io.yutian.elementoriginlib.item.stat.data.DoubleData; import com.io.yutian.elementoriginlib.item.stat.data.DoubleData;
import com.io.yutian.elementoriginlib.nbt.TagDouble; import com.io.yutian.elementoriginlib.tag.TagDouble;
import com.io.yutian.elementoriginlib.nbt.NBTItem; import com.io.yutian.elementoriginlib.tag.ItemProxy;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -16,14 +16,14 @@ public abstract class DoubleStat extends ItemStat<DoubleData> {
@Override @Override
public void whenApplied(@NotNull OriginItemStackBuilder itemStackBuilder, @NotNull DoubleData statData) { public void whenApplied(@NotNull OriginItemStackBuilder itemStackBuilder, @NotNull DoubleData statData) {
NBTItem nbtItem = itemStackBuilder.getNBTItem(); ItemProxy itemProxy = itemStackBuilder.getNBTItem();
nbtItem.editTag(nbtCompound -> nbtCompound.putDouble(getNBTPath(), statData.getValue())); itemProxy.editTag(nbtCompound -> nbtCompound.putDouble(getNBTPath(), statData.getValue()));
} }
@Nullable @Nullable
@Override @Override
public DoubleData getLoadedNBT(@NotNull NBTItem nbtItem) { public DoubleData getLoadedNBT(@NotNull ItemProxy itemProxy) {
return new DoubleData(((TagDouble) nbtItem.get(getNBTPath())).getDouble()); return new DoubleData(((TagDouble) itemProxy.get(getNBTPath())).getDouble());
} }
} }

View File

@ -3,8 +3,8 @@ package com.io.yutian.elementoriginlib.item.stat.type;
import com.io.yutian.elementoriginlib.item.OriginItemStackBuilder; import com.io.yutian.elementoriginlib.item.OriginItemStackBuilder;
import com.io.yutian.elementoriginlib.item.stat.ItemStat; import com.io.yutian.elementoriginlib.item.stat.ItemStat;
import com.io.yutian.elementoriginlib.item.stat.data.IntData; import com.io.yutian.elementoriginlib.item.stat.data.IntData;
import com.io.yutian.elementoriginlib.nbt.TagInt; import com.io.yutian.elementoriginlib.tag.TagInt;
import com.io.yutian.elementoriginlib.nbt.NBTItem; import com.io.yutian.elementoriginlib.tag.ItemProxy;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -16,14 +16,14 @@ public abstract class IntStat extends ItemStat<IntData> {
@Override @Override
public void whenApplied(@NotNull OriginItemStackBuilder itemStackBuilder, @NotNull IntData statData) { public void whenApplied(@NotNull OriginItemStackBuilder itemStackBuilder, @NotNull IntData statData) {
NBTItem nbtItem = itemStackBuilder.getNBTItem(); ItemProxy itemProxy = itemStackBuilder.getNBTItem();
nbtItem.editTag(nbtCompound -> nbtCompound.putInt(getNBTPath(), statData.getInt())); itemProxy.editTag(nbtCompound -> nbtCompound.putInt(getNBTPath(), statData.getInt()));
} }
@Nullable @Nullable
@Override @Override
public IntData getLoadedNBT(@NotNull NBTItem nbtItem) { public IntData getLoadedNBT(@NotNull ItemProxy itemProxy) {
return new IntData(((TagInt)nbtItem.get(getNBTPath())).getInt()); return new IntData(((TagInt) itemProxy.get(getNBTPath())).getInt());
} }
} }

View File

@ -3,9 +3,9 @@ package com.io.yutian.elementoriginlib.item.stat.type;
import com.io.yutian.elementoriginlib.item.OriginItemStackBuilder; import com.io.yutian.elementoriginlib.item.OriginItemStackBuilder;
import com.io.yutian.elementoriginlib.item.stat.ItemStat; import com.io.yutian.elementoriginlib.item.stat.ItemStat;
import com.io.yutian.elementoriginlib.item.stat.data.StringListData; import com.io.yutian.elementoriginlib.item.stat.data.StringListData;
import com.io.yutian.elementoriginlib.nbt.NBTItem; import com.io.yutian.elementoriginlib.tag.ItemProxy;
import com.io.yutian.elementoriginlib.nbt.TagList; import com.io.yutian.elementoriginlib.tag.TagList;
import com.io.yutian.elementoriginlib.nbt.TagString; import com.io.yutian.elementoriginlib.tag.TagString;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -20,19 +20,19 @@ public abstract class StringListStat extends ItemStat<StringListData> {
@Override @Override
public void whenApplied(@NotNull OriginItemStackBuilder itemStackBuilder, @NotNull StringListData statData) { public void whenApplied(@NotNull OriginItemStackBuilder itemStackBuilder, @NotNull StringListData statData) {
NBTItem nbtItem = itemStackBuilder.getNBTItem(); ItemProxy itemProxy = itemStackBuilder.getNBTItem();
TagList<TagString> tagList = new TagList<>(); TagList<TagString> tagList = new TagList<>();
statData.getList().forEach(s -> tagList.add(new TagString(s))); statData.getList().forEach(s -> tagList.add(new TagString(s)));
nbtItem.editTag(nbtCompound -> nbtCompound.put(getNBTPath(), tagList)); itemProxy.editTag(nbtCompound -> nbtCompound.put(getNBTPath(), tagList));
} }
@Nullable @Nullable
@Override @Override
public StringListData getLoadedNBT(@NotNull NBTItem nbtItem) { public StringListData getLoadedNBT(@NotNull ItemProxy itemProxy) {
if (!nbtItem.has(getNBTPath(), TagList.TYPE_ID)) { if (!itemProxy.has(getNBTPath(), TagList.TYPE_ID)) {
return new StringListData(new ArrayList<>()); return new StringListData(new ArrayList<>());
} }
TagList<TagString> tagList = (TagList<TagString>) nbtItem.get(getNBTPath()); TagList<TagString> tagList = (TagList<TagString>) itemProxy.get(getNBTPath());
List<String> list = new ArrayList<>(); List<String> list = new ArrayList<>();
for (int i = 0; i < tagList.size(); i++) { for (int i = 0; i < tagList.size(); i++) {
list.add(tagList.get(i).getString()); list.add(tagList.get(i).getString());

View File

@ -3,8 +3,8 @@ package com.io.yutian.elementoriginlib.item.stat.type;
import com.io.yutian.elementoriginlib.item.OriginItemStackBuilder; import com.io.yutian.elementoriginlib.item.OriginItemStackBuilder;
import com.io.yutian.elementoriginlib.item.stat.ItemStat; import com.io.yutian.elementoriginlib.item.stat.ItemStat;
import com.io.yutian.elementoriginlib.item.stat.data.StringData; import com.io.yutian.elementoriginlib.item.stat.data.StringData;
import com.io.yutian.elementoriginlib.nbt.NBTItem; import com.io.yutian.elementoriginlib.tag.ItemProxy;
import com.io.yutian.elementoriginlib.nbt.TagString; import com.io.yutian.elementoriginlib.tag.TagString;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -16,15 +16,15 @@ public abstract class StringStat extends ItemStat<StringData> {
@Override @Override
public void whenApplied(@NotNull OriginItemStackBuilder itemStackBuilder, @NotNull StringData statData) { public void whenApplied(@NotNull OriginItemStackBuilder itemStackBuilder, @NotNull StringData statData) {
NBTItem nbtItem = itemStackBuilder.getNBTItem(); ItemProxy itemProxy = itemStackBuilder.getNBTItem();
nbtItem.editTag(nbtCompound -> nbtCompound.putString(getNBTPath(), statData.getString())); itemProxy.editTag(nbtCompound -> nbtCompound.putString(getNBTPath(), statData.getString()));
} }
@Nullable @Nullable
@Override @Override
public StringData getLoadedNBT(@NotNull NBTItem nbtItem) { public StringData getLoadedNBT(@NotNull ItemProxy itemProxy) {
return new StringData(((TagString) nbtItem.get(getNBTPath())).getString()); return new StringData(((TagString) itemProxy.get(getNBTPath())).getString());
} }
} }

View File

@ -3,8 +3,8 @@ package com.io.yutian.elementoriginlib.item.stat.type;
import com.io.yutian.elementoriginlib.item.OriginItemStackBuilder; import com.io.yutian.elementoriginlib.item.OriginItemStackBuilder;
import com.io.yutian.elementoriginlib.item.stat.ItemStat; import com.io.yutian.elementoriginlib.item.stat.ItemStat;
import com.io.yutian.elementoriginlib.item.stat.data.UUIDData; import com.io.yutian.elementoriginlib.item.stat.data.UUIDData;
import com.io.yutian.elementoriginlib.nbt.NBTItem; import com.io.yutian.elementoriginlib.tag.ItemProxy;
import com.io.yutian.elementoriginlib.nbt.TagString; import com.io.yutian.elementoriginlib.tag.TagString;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -18,14 +18,14 @@ public abstract class UUIDStat extends ItemStat<UUIDData> {
@Override @Override
public void whenApplied(@NotNull OriginItemStackBuilder itemStackBuilder, @NotNull UUIDData statData) { public void whenApplied(@NotNull OriginItemStackBuilder itemStackBuilder, @NotNull UUIDData statData) {
NBTItem nbtItem = itemStackBuilder.getNBTItem(); ItemProxy itemProxy = itemStackBuilder.getNBTItem();
nbtItem.editTag(nbtCompound -> nbtCompound.putString(getNBTPath(), statData.getUUID().toString())); itemProxy.editTag(nbtCompound -> nbtCompound.putString(getNBTPath(), statData.getUUID().toString()));
} }
@Nullable @Nullable
@Override @Override
public UUIDData getLoadedNBT(@NotNull NBTItem nbtItem) { public UUIDData getLoadedNBT(@NotNull ItemProxy itemProxy) {
return new UUIDData(UUID.fromString(((TagString) nbtItem.get(getNBTPath())).getString())); return new UUIDData(UUID.fromString(((TagString) itemProxy.get(getNBTPath())).getString()));
} }
} }

View File

@ -1,6 +1,7 @@
package com.io.yutian.elementoriginlib.manager; package com.io.yutian.elementoriginlib.manager;
import com.io.yutian.elementoriginlib.command.SimpleCommandManager; import com.io.yutian.elementoriginlib.command.SimpleCommandManager;
import com.io.yutian.elementoriginlib.command.list.CommandHelp;
import com.io.yutian.elementoriginlib.command.list.CommandTest; import com.io.yutian.elementoriginlib.command.list.CommandTest;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
@ -8,8 +9,8 @@ public class CommandManager extends SimpleCommandManager {
public CommandManager(Plugin plugin) { public CommandManager(Plugin plugin) {
super(plugin, "elementoriginlib"); super(plugin, "elementoriginlib");
// register(new CommandHelp(this, "help")); register(new CommandHelp(this, "help"));
register(CommandTest.class); register(new CommandTest());
} }
} }

View File

@ -4,7 +4,7 @@ import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.JsonDeserializer;
import com.io.yutian.elementoriginlib.nbt.TagHelper; import com.io.yutian.elementoriginlib.tag.TagHelper;
import net.minecraft.core.HolderLookup; import net.minecraft.core.HolderLookup;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;

View File

@ -3,7 +3,7 @@ package com.io.yutian.elementoriginlib.serialize.serializers;
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.SerializerProvider;
import com.io.yutian.elementoriginlib.nbt.TagHelper; import com.io.yutian.elementoriginlib.tag.TagHelper;
import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;

View File

@ -1,4 +1,4 @@
package com.io.yutian.elementoriginlib.nbt; package com.io.yutian.elementoriginlib.tag;
import net.minecraft.nbt.*; import net.minecraft.nbt.*;

View File

@ -1,4 +1,4 @@
package com.io.yutian.elementoriginlib.nbt; package com.io.yutian.elementoriginlib.tag;
import com.io.yutian.elementoriginlib.serialize.serializers.ItemStackDeserializer; import com.io.yutian.elementoriginlib.serialize.serializers.ItemStackDeserializer;
import net.minecraft.core.component.DataComponents; import net.minecraft.core.component.DataComponents;
@ -11,23 +11,23 @@ import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.util.function.Consumer; import java.util.function.Consumer;
public class NBTItem { public class ItemProxy {
private ItemStack originalItemStack; private ItemStack originalItemStack;
private net.minecraft.world.item.ItemStack nmsItemStack; private net.minecraft.world.item.ItemStack nmsItemStack;
protected ItemStack resultItemStack; protected ItemStack resultItemStack;
public NBTItem(ItemStack itemStack) { public ItemProxy(ItemStack itemStack) {
this.originalItemStack = itemStack; this.originalItemStack = itemStack;
this.nmsItemStack = CraftItemStack.asNMSCopy(itemStack); this.nmsItemStack = CraftItemStack.asNMSCopy(itemStack);
} }
@NotNull @NotNull
public TagCompound getTag() { public TagCompound getTag() {
CompoundTag tag = nmsItemStack.getComponents().get(DataComponents.CUSTOM_DATA).getUnsafe(); CompoundTag tag = new CompoundTag();
if (tag == null) { if (nmsItemStack.getComponents().has(DataComponents.CUSTOM_DATA)) {
tag = new CompoundTag(); tag = nmsItemStack.getComponents().get(DataComponents.CUSTOM_DATA).getUnsafe();
} }
return (TagCompound) ITag.as(tag); return (TagCompound) ITag.as(tag);
} }
@ -71,13 +71,13 @@ public class NBTItem {
return nmsItemStack; return nmsItemStack;
} }
public static NBTItem build(ItemStack itemStack) { public static ItemProxy build(ItemStack itemStack) {
return new NBTItem(itemStack); return new ItemProxy(itemStack);
} }
public static NBTItem build(TagCompound tagCompound) { public static ItemProxy build(TagCompound tagCompound) {
net.minecraft.world.item.ItemStack nmsItemStack = net.minecraft.world.item.ItemStack.parse(ItemStackDeserializer.getRegistry(), ITag.asNMS(tagCompound)).get(); net.minecraft.world.item.ItemStack nmsItemStack = net.minecraft.world.item.ItemStack.parse(ItemStackDeserializer.getRegistry(), ITag.asNMS(tagCompound)).get();
return new NBTItem(CraftItemStack.asBukkitCopy(nmsItemStack)); return new ItemProxy(CraftItemStack.asBukkitCopy(nmsItemStack));
} }
} }

View File

@ -1,4 +1,4 @@
package com.io.yutian.elementoriginlib.nbt; package com.io.yutian.elementoriginlib.tag;
public class TagByte extends TagNumber { public class TagByte extends TagNumber {

View File

@ -1,4 +1,4 @@
package com.io.yutian.elementoriginlib.nbt; package com.io.yutian.elementoriginlib.tag;
import java.util.Arrays; import java.util.Arrays;

View File

@ -1,4 +1,4 @@
package com.io.yutian.elementoriginlib.nbt; package com.io.yutian.elementoriginlib.tag;
import java.util.*; import java.util.*;

View File

@ -1,4 +1,4 @@
package com.io.yutian.elementoriginlib.nbt; package com.io.yutian.elementoriginlib.tag;
public class TagDouble extends TagNumber { public class TagDouble extends TagNumber {

View File

@ -1,4 +1,4 @@
package com.io.yutian.elementoriginlib.nbt; package com.io.yutian.elementoriginlib.tag;
public class TagFloat extends TagNumber { public class TagFloat extends TagNumber {

View File

@ -1,4 +1,4 @@
package com.io.yutian.elementoriginlib.nbt; package com.io.yutian.elementoriginlib.tag;
import net.minecraft.nbt.*; import net.minecraft.nbt.*;
import net.minecraft.nbt.Tag; import net.minecraft.nbt.Tag;

View File

@ -1,4 +1,4 @@
package com.io.yutian.elementoriginlib.nbt; package com.io.yutian.elementoriginlib.tag;
public class TagInt extends TagNumber { public class TagInt extends TagNumber {

View File

@ -1,4 +1,4 @@
package com.io.yutian.elementoriginlib.nbt; package com.io.yutian.elementoriginlib.tag;
import java.util.Arrays; import java.util.Arrays;

View File

@ -1,4 +1,4 @@
package com.io.yutian.elementoriginlib.nbt; package com.io.yutian.elementoriginlib.tag;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;

View File

@ -1,4 +1,4 @@
package com.io.yutian.elementoriginlib.nbt; package com.io.yutian.elementoriginlib.tag;
public class TagLong extends TagNumber { public class TagLong extends TagNumber {

View File

@ -1,4 +1,4 @@
package com.io.yutian.elementoriginlib.nbt; package com.io.yutian.elementoriginlib.tag;
import java.util.Arrays; import java.util.Arrays;

View File

@ -1,4 +1,4 @@
package com.io.yutian.elementoriginlib.nbt; package com.io.yutian.elementoriginlib.tag;
public abstract class TagNumber implements ITag { public abstract class TagNumber implements ITag {

View File

@ -1,4 +1,4 @@
package com.io.yutian.elementoriginlib.nbt; package com.io.yutian.elementoriginlib.tag;
public class TagShort extends TagNumber { public class TagShort extends TagNumber {

View File

@ -1,4 +1,4 @@
package com.io.yutian.elementoriginlib.nbt; package com.io.yutian.elementoriginlib.tag;
import java.util.Objects; import java.util.Objects;

View File

@ -1,7 +1,7 @@
package com.io.yutian.elementoriginlib.util; package com.io.yutian.elementoriginlib.util;
import com.io.yutian.elementoriginlib.nbt.TagCompound; import com.io.yutian.elementoriginlib.tag.TagCompound;
import com.io.yutian.elementoriginlib.nbt.NBTItem; import com.io.yutian.elementoriginlib.tag.ItemProxy;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
@ -45,8 +45,8 @@ public class ItemStackUtil {
if (!flag) { if (!flag) {
return false; return false;
} }
NBTItem nbtOriginal = new NBTItem(original); ItemProxy nbtOriginal = new ItemProxy(original);
NBTItem nbtTester = new NBTItem(tester); ItemProxy nbtTester = new ItemProxy(tester);
TagCompound tagCompound0 = nbtOriginal.getTag(); TagCompound tagCompound0 = nbtOriginal.getTag();
TagCompound tagCompound1 = nbtTester.getTag(); TagCompound tagCompound1 = nbtTester.getTag();
return tagCompound0.equals(tagCompound1); return tagCompound0.equals(tagCompound1);